Skip to content

Commit c5d3fa3

Browse files
committed
Add trace buttons to lobby menu
1 parent 29caf0d commit c5d3fa3

7 files changed

Lines changed: 198 additions & 39 deletions

File tree

src/game/client/swarm/asw_briefing.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,3 +1083,16 @@ const CRD_ItemInstance &CASW_Briefing::GetEquippedWeapon( int nLobbySlot, int nW
10831083

10841084
return instance;
10851085
}
1086+
1087+
int CASW_Briefing::GetPlayerIndex(int nLobbySlot)
1088+
{
1089+
if (nLobbySlot < 0 || nLobbySlot >= NUM_BRIEFING_LOBBY_SLOTS || !IsLobbySlotOccupied(nLobbySlot))
1090+
return -1;
1091+
1092+
C_ASW_Player* pPlayer = m_LobbySlotMapping[nLobbySlot].m_hPlayer.Get();
1093+
if (pPlayer)
1094+
{
1095+
return pPlayer->entindex();
1096+
}
1097+
return -1; // not found, or not a player
1098+
}

src/game/client/swarm/asw_briefing.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class CASW_Briefing : public IBriefing
7979

8080
int LobbySlotToMarineResourceIndex( int nLobbySlot );
8181
void UpdateLobbySlotMapping();
82+
virtual int GetPlayerIndex(int nLobbySlot);
8283

8384
int m_nLastLobbySlotMappingFrame;
8485
LobbySlotMapping_t m_LobbySlotMapping[ NUM_BRIEFING_LOBBY_SLOTS ];

src/game/client/swarm/c_asw_marine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ extern ConVar rd_team_color_enemy;
108108
extern float g_fMarinePoisonDuration;
109109

110110
#ifdef CLIENT_DLL
111-
std::vector<bool> g_bShouldTracePlayer = std::vector<bool>(MAX_PLAYERS, true); // whether we have a trace position for this player
111+
std::vector<bool> g_bShouldTracePlayer = std::vector<bool>(MAX_PLAYERS, false); // whether we have a trace position for this player
112112
const float TRACE_FADE_TIME = 60.0f; // how long to keep the trace positions for
113113
#endif
114114

src/game/client/swarm/ibriefing.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ abstract_class IBriefing
7171
virtual const IBriefing_ItemInstance &GetEquippedMedal( int nLobbySlot, int nMedalIndex ) = 0;
7272
virtual const IBriefing_ItemInstance &GetEquippedSuit( int nLobbySlot ) = 0;
7373
virtual const IBriefing_ItemInstance &GetEquippedWeapon( int nLobbySlot, int nWeaponSlot ) = 0;
74+
virtual int GetPlayerIndex(int nLobbySlot) { return -1; };
7475
};
7576

7677
#define NUM_BRIEFING_LOBBY_SLOTS ( ASW_MAX_MARINE_RESOURCES + MAX_PLAYERS - 1 ) // was 9, was 4

src/game/client/swarm/vgui/nb_lobby_row.cpp

Lines changed: 136 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@
2020
#include "gameui/swarm/vdropdownmenu.h"
2121
#include "gameui/swarm/vhybridbutton.h"
2222
#include "rd_inventory_shared.h"
23+
#include <vector>
2324

2425
// memdbgon must be the last include file in a .cpp file!!!
2526
#include "tier0/memdbgon.h"
2627

2728
extern ConVar rd_legacy_ui;
29+
#ifdef CLIENT_DLL
30+
extern std::vector<bool> g_bShouldTracePlayer;
31+
#endif
2832

2933
using namespace BaseModUI;
3034

@@ -98,10 +102,22 @@ CNB_Lobby_Row::CNB_Lobby_Row( vgui::Panel *parent, const char *name ) : BaseClas
98102
m_pXPBar->m_flBorder = 1.5f;
99103
m_nLobbySlot = 0;
100104

105+
// Create the TraceMe button
106+
m_pTraceMeButton = new CBitmapButton( this, "TraceMeButton", "");
107+
m_pTraceMeButton->AddActionSignalTarget( this );
108+
m_pTraceMeButton->SetCommand( "TraceMePressed" );
109+
110+
// Create and initialize TracePlayerButton
111+
m_pTracePlayerButton = new CBitmapButton( this, "TracePlayerButton", "" );
112+
m_pTracePlayerButton->AddActionSignalTarget( this );
113+
m_pTracePlayerButton->SetCommand( "TracePlayerPressed" );
114+
101115
GetControllerFocus()->AddToFocusList( m_pPortraitButton );
102116
GetControllerFocus()->AddToFocusList( m_pWeaponButton0 );
103117
GetControllerFocus()->AddToFocusList( m_pWeaponButton1 );
104118
GetControllerFocus()->AddToFocusList( m_pWeaponButton2 );
119+
GetControllerFocus()->AddToFocusList( m_pTraceMeButton );
120+
GetControllerFocus()->AddToFocusList( m_pTracePlayerButton );
105121
}
106122

107123
CNB_Lobby_Row::~CNB_Lobby_Row()
@@ -110,6 +126,8 @@ CNB_Lobby_Row::~CNB_Lobby_Row()
110126
GetControllerFocus()->RemoveFromFocusList( m_pWeaponButton0 );
111127
GetControllerFocus()->RemoveFromFocusList( m_pWeaponButton1 );
112128
GetControllerFocus()->RemoveFromFocusList( m_pWeaponButton2 );
129+
GetControllerFocus()->RemoveFromFocusList( m_pTraceMeButton );
130+
GetControllerFocus()->RemoveFromFocusList( m_pTracePlayerButton );
113131
}
114132

115133
void CNB_Lobby_Row::ApplySchemeSettings( vgui::IScheme *pScheme )
@@ -140,6 +158,8 @@ void CNB_Lobby_Row::OnThink()
140158

141159
UpdateDetails();
142160
UpdateChangingSlot();
161+
UpdateTraceMeButton(); // Update the TraceMe button state
162+
UpdateTracePlayerButton(); // Update the TracePlayer button state
143163
}
144164

145165
void CNB_Lobby_Row::UpdateDetails()
@@ -426,6 +446,16 @@ void CNB_Lobby_Row::UpdateDetails()
426446
pSilhouette->SetVisible( false );
427447
}
428448
}
449+
450+
// Set the images for the TraceMe button
451+
const char* szTraceMeButtonEnabled = "vgui/swarm/Emotes/EmoteSmile";
452+
const char* szTraceMeButtonDisabled = "vgui/swarm/Emotes/EmoteStop";
453+
const char* szTraceMeButtonPressed = "vgui/swarm/Emotes/EmoteAmmo";
454+
const char* szTraceMeButtonMouseOver = "vgui/swarm/Emotes/EmoteMedic";
455+
m_pTraceMeButton->SetImage(CBitmapButton::BUTTON_ENABLED, szTraceMeButtonEnabled, lightblue);
456+
m_pTraceMeButton->SetImage(CBitmapButton::BUTTON_DISABLED, szTraceMeButtonDisabled, lightblue);
457+
m_pTraceMeButton->SetImage(CBitmapButton::BUTTON_PRESSED, szTraceMeButtonPressed, white);
458+
m_pTraceMeButton->SetImage(CBitmapButton::BUTTON_ENABLED_MOUSE_OVER, szTraceMeButtonMouseOver, white);
429459
}
430460

431461
void CNB_Lobby_Row::CheckTooltip( CNB_Lobby_Tooltip *pTooltip )
@@ -465,61 +495,69 @@ void CNB_Lobby_Row::CheckTooltip( CNB_Lobby_Tooltip *pTooltip )
465495

466496
extern ConVar developer;
467497

468-
void CNB_Lobby_Row::OnCommand( const char *command )
498+
void CNB_Lobby_Row::OnCommand(const char* command)
469499
{
470-
CNB_Main_Panel *pMainPanel = GetMainPanel();
471-
if ( !pMainPanel )
500+
CNB_Main_Panel* pMainPanel = GetMainPanel();
501+
if (!pMainPanel)
472502
return;
473503

474-
if ( !Q_stricmp( command, "ChangeMarine" ) )
504+
if (!Q_stricmp(command, "ChangeMarine"))
475505
{
476-
pMainPanel->ChangeMarine( m_nLobbySlot );
506+
pMainPanel->ChangeMarine(m_nLobbySlot);
477507
}
478-
else if ( !Q_stricmp( command, "ChangeWeapon0" ) )
508+
else if (!Q_stricmp(command, "ChangeWeapon0"))
479509
{
480-
pMainPanel->ChangeWeapon( m_nLobbySlot, 0 );
481-
}
482-
else if ( !Q_stricmp( command, "ChangeWeapon1" ) )
510+
pMainPanel->ChangeWeapon(m_nLobbySlot, 0);
511+
}
512+
else if (!Q_stricmp(command, "ChangeWeapon1"))
483513
{
484-
pMainPanel->ChangeWeapon( m_nLobbySlot, 1 );
514+
pMainPanel->ChangeWeapon(m_nLobbySlot, 1);
485515
}
486-
else if ( !Q_stricmp( command, "ChangeWeapon2" ) )
516+
else if (!Q_stricmp(command, "ChangeWeapon2"))
487517
{
488-
pMainPanel->ChangeWeapon( m_nLobbySlot, 2 );
518+
pMainPanel->ChangeWeapon(m_nLobbySlot, 2);
489519
}
490-
else if ( !Q_stricmp( command, "PlayerFlyout" ) )
520+
else if (!Q_stricmp(command, "PlayerFlyout"))
491521
{
492-
if ( !Briefing()->IsLobbySlotBot( m_nLobbySlot ) && Briefing()->GetCommanderSteamID( m_nLobbySlot ).IsValid() )
522+
if (!Briefing()->IsLobbySlotBot(m_nLobbySlot) && Briefing()->GetCommanderSteamID(m_nLobbySlot).IsValid())
493523
{
494524
OpenPlayerFlyout();
495525
}
496526
}
497-
else if ( !Q_stricmp( command, "#L4D360UI_SendMessage" ) )
527+
else if (!Q_stricmp(command, "#L4D360UI_SendMessage"))
498528
{
499-
BaseModUI::CUIGameData::Get()->ExecuteOverlayCommand( "chat", pMainPanel->m_FlyoutSteamID );
529+
BaseModUI::CUIGameData::Get()->ExecuteOverlayCommand("chat", pMainPanel->m_FlyoutSteamID);
500530
}
501-
else if ( !Q_stricmp( command, "#L4D360UI_ViewSteamID" ) )
531+
else if (!Q_stricmp(command, "#L4D360UI_ViewSteamID"))
502532
{
503-
BaseModUI::CUIGameData::Get()->ExecuteOverlayCommand( "steamid", pMainPanel->m_FlyoutSteamID );
533+
BaseModUI::CUIGameData::Get()->ExecuteOverlayCommand("steamid", pMainPanel->m_FlyoutSteamID);
504534
}
505-
else if ( !Q_stricmp( command, "#L4D360UI_ViewSteamStats" ) )
535+
else if (!Q_stricmp(command, "#L4D360UI_ViewSteamStats"))
506536
{
507537
#if !defined( _X360 ) && !defined( NO_STEAM )
508-
if ( SteamUser() )
538+
if (SteamUser())
509539
{
510-
if ( developer.GetBool() )
540+
if (developer.GetBool())
511541
{
512-
Msg( "Local player SteamID = %I64u\n", SteamUser()->GetSteamID().ConvertToUint64() );
513-
Msg( "Activating stats for SteamID = %I64u\n", Briefing()->GetCommanderSteamID( m_nLobbySlot ).ConvertToUint64() );
542+
Msg("Local player SteamID = %I64u\n", SteamUser()->GetSteamID().ConvertToUint64());
543+
Msg("Activating stats for SteamID = %I64u\n", Briefing()->GetCommanderSteamID(m_nLobbySlot).ConvertToUint64());
514544
}
515545
char statsWeb[256];
516-
Q_snprintf( statsWeb, sizeof( statsWeb ), "https://stats.reactivedrop.com/profiles/%I64u?lang=%s&utm_source=briefing",
517-
Briefing()->GetCommanderSteamID( m_nLobbySlot ).ConvertToUint64(),
518-
SteamApps()->GetCurrentGameLanguage() );
519-
BaseModUI::CUIGameData::Get()->ExecuteOverlayUrl( statsWeb );
546+
Q_snprintf(statsWeb, sizeof(statsWeb), "https://stats.reactivedrop.com/profiles/%I64u?lang=%s&utm_source=briefing",
547+
Briefing()->GetCommanderSteamID(m_nLobbySlot).ConvertToUint64(),
548+
SteamApps()->GetCurrentGameLanguage());
549+
BaseModUI::CUIGameData::Get()->ExecuteOverlayUrl(statsWeb);
520550
}
521551
#endif
522552
}
553+
else if (!Q_stricmp(command, "TraceMePressed"))
554+
{
555+
TraceMePressed();
556+
}
557+
else if (!Q_stricmp(command, "TracePlayerPressed"))
558+
{
559+
TracePlayerPressed();
560+
}
523561
}
524562

525563
void CNB_Lobby_Row::OpenPlayerFlyout()
@@ -578,3 +616,74 @@ void CNB_Lobby_Row::UpdateChangingSlot()
578616
m_pChangingSlot[ 2 ]->SetVisible( nSlot == 3 );
579617
m_pChangingSlot[ 3 ]->SetVisible( nSlot == 4 );
580618
}
619+
620+
void CNB_Lobby_Row::UpdateTraceMeButton()
621+
{
622+
if (!m_pTraceMeButton)
623+
return;
624+
625+
// Check if the TraceMe button should be enabled or not
626+
// It should be enabled if it's an online game, the slot is the local player's slot, the slot is not a bot, the slot is occupied, and the marine profile exists
627+
if (!Briefing()
628+
|| Briefing()->IsOfflineGame()
629+
|| !Briefing()->IsLobbySlotLocal(m_nLobbySlot)
630+
|| Briefing()->IsLobbySlotBot(m_nLobbySlot)
631+
|| !Briefing()->IsLobbySlotOccupied(m_nLobbySlot)
632+
|| Briefing()->GetMarineProfile(m_nLobbySlot) == NULL)
633+
{
634+
m_pTraceMeButton->SetVisible(false);
635+
return;
636+
}
637+
m_pTraceMeButton->SetVisible(true);
638+
}
639+
640+
void CNB_Lobby_Row::TraceMePressed()
641+
{
642+
// Get the local player index
643+
int localPlayerIndex = -1;
644+
if (engine && engine->IsInGame())
645+
{
646+
localPlayerIndex = engine->GetLocalPlayer();
647+
if (localPlayerIndex < 0 || localPlayerIndex >= gpGlobals->maxClients)
648+
{
649+
return; // Invalid player index
650+
}
651+
652+
char cmd[128];
653+
Q_snprintf(cmd, sizeof(cmd), "rd_lobby_suggest_trace_player %d", localPlayerIndex);
654+
// Send a message in chat to all other players to suggest them to trace this player
655+
engine->ClientCmd_Unrestricted(cmd);
656+
}
657+
}
658+
659+
void CNB_Lobby_Row::UpdateTracePlayerButton()
660+
{
661+
if (!m_pTracePlayerButton)
662+
return;
663+
664+
// In online games, show the button only for other players (not local player, not bot, and occupied slot)
665+
if (!Briefing()
666+
|| Briefing()->IsOfflineGame()
667+
|| Briefing()->IsLobbySlotLocal(m_nLobbySlot)
668+
|| Briefing()->IsLobbySlotBot(m_nLobbySlot)
669+
|| !Briefing()->IsLobbySlotOccupied(m_nLobbySlot))
670+
{
671+
m_pTracePlayerButton->SetVisible(false);
672+
return;
673+
}
674+
675+
m_pTracePlayerButton->SetVisible(true);
676+
}
677+
678+
void CNB_Lobby_Row::TracePlayerPressed()
679+
{
680+
int playerIndex = Briefing()->GetPlayerIndex(m_nLobbySlot);
681+
if (playerIndex < 0 || playerIndex >= gpGlobals->maxClients)
682+
{
683+
Msg("Invalid player index for lobby slot %d\n", m_nLobbySlot);
684+
return; // Invalid player index
685+
}
686+
// flip the trace state for this player
687+
g_bShouldTracePlayer[playerIndex] = !g_bShouldTracePlayer[playerIndex];
688+
Msg("Trace player %d : %s\n", playerIndex, g_bShouldTracePlayer[playerIndex] ? "true" : "false");
689+
}

src/game/client/swarm/vgui/nb_lobby_row.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ class CNB_Lobby_Row : public vgui::EditablePanel
4343
virtual void CheckTooltip( CNB_Lobby_Tooltip *pTooltip );
4444

4545
void UpdateChangingSlot();
46+
47+
void UpdateTraceMeButton();
48+
void TraceMePressed();
49+
void UpdateTracePlayerButton();
50+
void TracePlayerPressed();
4651

4752
// == MANAGED_MEMBER_POINTERS_START: Do not edit by hand ==
4853
vgui::ImagePanel *m_pBackground;
@@ -79,16 +84,8 @@ class CNB_Lobby_Row : public vgui::EditablePanel
7984
SteamItemDef_t m_lastMedal[RD_STEAM_INVENTORY_NUM_MEDAL_SLOTS];
8085

8186
int m_nLobbySlot;
87+
CBitmapButton *m_pTraceMeButton;
88+
CBitmapButton* m_pTracePlayerButton;
8289
};
8390

84-
#endif // _INCLUDED_NB_LOBBY_ROW_H
85-
86-
87-
88-
89-
90-
91-
92-
93-
94-
91+
#endif // _INCLUDED_NB_LOBBY_ROW_H

src/game/shared/swarm/rd_lobby_utils.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,44 @@ CON_COMMAND( rd_lobby_debug_filter_distance, "1: close, 2: default, 3: far, 4: w
583583
}
584584
}
585585

586+
CON_COMMAND(rd_lobby_suggest_trace_player, "notify server to send a trace player suggestion to all clients.")
587+
{
588+
if (args.ArgC() < 2)
589+
{
590+
Msg("Usage: rd_lobby_suggest_trace_player <playerIndex>\n");
591+
return;
592+
}
593+
594+
int iPlayerIndex = atoi(args[1]);
595+
if (iPlayerIndex < 1 || iPlayerIndex > gpGlobals->maxClients)
596+
{
597+
Msg("Invalid playerIndex\n");
598+
return;
599+
}
600+
601+
CBasePlayer* pPlayer = UTIL_PlayerByIndex(iPlayerIndex);
602+
if (!pPlayer)
603+
{
604+
Msg("Can't find a player with index <%d>.\n", iPlayerIndex);
605+
return;
606+
}
607+
// Send the message to all players
608+
for (int i = 1; i <= gpGlobals->maxClients; i++)
609+
{
610+
CBasePlayer* pRecipient = UTIL_PlayerByIndex(i);
611+
if (!pRecipient)
612+
continue;
613+
if (pRecipient == pPlayer)
614+
{
615+
ClientPrint(pRecipient, HUD_PRINTTALK, "asw_trace_me_msg_to_self");
616+
}
617+
else
618+
{
619+
ClientPrint(pRecipient, HUD_PRINTTALK, "asw_trace_me_msg_to_others", pPlayer->GetPlayerName());
620+
}
621+
}
622+
}
623+
586624
CReactiveDropServerListHelper::CReactiveDropServerListHelper( const char *szDebugName )
587625
{
588626
m_pszDebugName = szDebugName;

0 commit comments

Comments
 (0)