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
2728extern ConVar rd_legacy_ui;
29+ #ifdef CLIENT_DLL
30+ extern std::vector<bool > g_bShouldTracePlayer;
31+ #endif
2832
2933using 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
107123CNB_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
115133void 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
145165void 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
431461void CNB_Lobby_Row::CheckTooltip ( CNB_Lobby_Tooltip *pTooltip )
@@ -465,61 +495,69 @@ void CNB_Lobby_Row::CheckTooltip( CNB_Lobby_Tooltip *pTooltip )
465495
466496extern 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
525563void 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+ }
0 commit comments