FF Diff Viewer

Comparing 2006 Base SDK to Fortress Forever 2.46

cl_dll/game_controls/ClientScoreBoardDialog.cpp

2425262728293031323334353637
#include #include #include #include #include #include //#include "voice_status.h" //#include "Friends/IFriendsUser.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h"
24252627282930313233343536373839404142434445
#include #include #include #include #include #include #include "voice_status.h" //#include "Friends/IFriendsUser.h" #include "in_buttons.h" #include "IGameUIFuncs.h" // for key bindings extern IGameUIFuncs *gameuifuncs; // for key binding details #include "ff_gamerules.h" #include "c_ff_player.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h"
3839404142434445
// extern vars //extern IFriendsUser *g_pFriendsUser; using namespace vgui; //----------------------------------------------------------------------------- // Purpose: Constructor //-----------------------------------------------------------------------------
464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
// extern vars //extern IFriendsUser *g_pFriendsUser; extern bool g_fBlockedStatus[256]; // |-- Mirv: The blocked status of people's text static CClientScoreBoardDialog *g_pScoreboard = NULL; //ConVar row_alpha("ffdev_row_alpha", "0.55", FCVAR_REPLICATED); //ConVar header_alpha("ffdev_header_alpha", "0.6", FCVAR_REPLICATED); //ConVar local_row_alpha("ffdev_local_row_alpha", "0.9", FCVAR_REPLICATED); // Returns -1 if pLHS < pRHS, 1 if pLHS > pRHS, and 0 is pLHS == pRHS inline int ScoreboardSection_Sort( const ScoreboardSection_s *pLHS, const ScoreboardSection_s* pRHS ) { if( pLHS->m_iScore < pRHS->m_iScore ) return 1; else if( pLHS->m_iScore > pRHS->m_iScore ) return -1; else { // Scores are equal, sort by score time if( pLHS->m_flLastScored < pRHS->m_flLastScored ) return 1; else if( pLHS->m_flLastScored > pRHS->m_flLastScored ) return -1; else { // Score times are equal, sort by team if( pLHS->m_iTeam < pRHS->m_iTeam ) return -1; else if( pLHS->m_iTeam > pRHS->m_iTeam ) return 1; } } return 0; } inline char *GetFormattedMapName( void ) { static char szText[ 256 ]; Q_strcpy( szText, engine->GetLevelName() + 5 ); // Skip the "maps/" part szText[ ( int )strlen( szText ) - 4 ] = '\0'; // Skip the ".bsp" part return szText; } bool ActivateScoreboard() { // all these NULL checks, // because it's like ~CClientScoreBoardDialog can happen in the middle of this function happening, // or something weird like that...IT'S FUCKING CRAZY, SERIOUSLY, THIS CRASH WON'T GO AWAY // For real though, sometimes g_pScoreboard is NULL, but it still won't return right here...SEE IT'S FUCKING CRAZY, SERIOUSLY if (g_pScoreboard == NULL) return false; if (g_pScoreboard != NULL && !g_pScoreboard->IsVisible()) return false; // If not enabled, set mouse input as enabled and return true to swallow +attack if (g_pScoreboard != NULL && !g_pScoreboard->IsMouseInputEnabled()) { g_pScoreboard->SetMouseInputEnabled(true); return true; } return false; } using namespace vgui; const char *szClassName[] = { "", "#FF_SCOREBOARD_SCOUT", "#FF_SCOREBOARD_SNIPER", "#FF_SCOREBOARD_SOLDIER", "#FF_SCOREBOARD_DEMOMAN", "#FF_SCOREBOARD_MEDIC", "#FF_SCOREBOARD_HWGUY", "#FF_SCOREBOARD_PYRO", "#FF_SCOREBOARD_SPY", "#FF_SCOREBOARD_ENGINEER", "#FF_SCOREBOARD_CIVILIAN" }; //----------------------------------------------------------------------------- // Purpose: Constructor //-----------------------------------------------------------------------------
47484950515253
{ m_iPlayerIndexSymbol = KeyValuesSystem()->GetSymbolForString("playerIndex"); //memset(s_VoiceImage, 0x0, sizeof( s_VoiceImage )); TrackerImage = 0; m_pViewPort = pViewPort;
133134135136137138139140
{ m_iPlayerIndexSymbol = KeyValuesSystem()->GetSymbolForString("playerIndex"); memset( s_VoiceImage, 0x0, sizeof( s_VoiceImage ) ); //memset( s_ChannelImage, 0x0, sizeof( s_ChannelImage ) ); // |-- Mirv: Voice channels TrackerImage = 0; m_pViewPort = pViewPort;
54555657585960
// initialize dialog SetProportional(true); SetKeyBoardInputEnabled(false); SetMouseInputEnabled(false); SetSizeable(false); // hide the system buttons
141142143144145146147148149150
// initialize dialog SetProportional(true); SetKeyBoardInputEnabled(false); SetMouseInputEnabled(true); // We have to enable this in the constructor // even if it won't always be the case // Otherwise panels within this one will not // receive mouse input (thanks valve) SetSizeable(false); // hide the system buttons
636465666768697071727374
// set the scheme before any child control is created SetScheme("ClientScheme"); m_pPlayerList = new SectionedListPanel(this, "PlayerList"); m_pPlayerList->SetVerticalScrollbar(false); LoadControlSettings("Resource/UI/ScoreBoard.res"); m_iDesiredHeight = GetTall(); m_pPlayerList->SetVisible( false ); // hide this until we load the images in applyschemesettings m_HLTVSpectators = 0;
153154155156157158159160161162163164165166167168169
// set the scheme before any child control is created SetScheme("ClientScheme"); m_iJumpKey = -1; m_pMapName = new Label( this, "MapName", GetFormattedMapName() ); m_pPlayerList = new SectionedListPanel(this, "PlayerList"); //m_pPlayerList->SetVerticalScrollbar(false); LoadControlSettings("Resource/UI/ScoreBoard.res"); m_iDesiredHeight = GetTall(); m_pPlayerList->SetVisible( false ); // hide this until we load the images in applyschemesettings m_pPlayerList->AddActionSignalTarget( this ); m_HLTVSpectators = 0;
757677787980
// update scoreboard instantly if on of these events occure gameeventmanager->AddListener(this, "hltv_status", false ); gameeventmanager->AddListener(this, "server_spawn", false ); } //-----------------------------------------------------------------------------
170171172173174175176177
// update scoreboard instantly if on of these events occure gameeventmanager->AddListener(this, "hltv_status", false ); gameeventmanager->AddListener(this, "server_spawn", false ); g_pScoreboard = this; } //-----------------------------------------------------------------------------
8384858687888990919293949596979899100
CClientScoreBoardDialog::~CClientScoreBoardDialog() { gameeventmanager->RemoveListener(this); } //----------------------------------------------------------------------------- // Purpose: clears everything in the scoreboard and all it's state //----------------------------------------------------------------------------- void CClientScoreBoardDialog::Reset() { // clear m_pPlayerList->DeleteAllItems(); m_pPlayerList->RemoveAllSections(); m_iSectionId = 0; m_fNextUpdateTime = 0; // add all the sections InitScoreboardSections();
180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
CClientScoreBoardDialog::~CClientScoreBoardDialog() { gameeventmanager->RemoveListener(this); g_pScoreboard = NULL; } // --> Mirv: Catches the set channel button //----------------------------------------------------------------------------- // Purpose: Run the client command if needed //----------------------------------------------------------------------------- void CClientScoreBoardDialog::OnCommand( const char *command ) { DevMsg( "command: %s\n", command ); engine->ClientCmd( command ); // Update straight away Update(); BaseClass::OnCommand(command); } // <-- Mirv: Catches the set channel button //----------------------------------------------------------------------------- // Purpose: clears everything in the scoreboard and all it's state //----------------------------------------------------------------------------- void CClientScoreBoardDialog::Reset( void ) { // clear m_pPlayerList->RemoveAll(); m_pPlayerList->RemoveAllSections(); //m_iSectionId = 0; m_fNextUpdateTime = 0; // add all the sections InitScoreboardSections();
103104105106107108109110
//----------------------------------------------------------------------------- // Purpose: adds all the team sections to the scoreboard //----------------------------------------------------------------------------- void CClientScoreBoardDialog::InitScoreboardSections() { } //-----------------------------------------------------------------------------
218219220221222223224225226227228229230231232
//----------------------------------------------------------------------------- // Purpose: adds all the team sections to the scoreboard //----------------------------------------------------------------------------- void CClientScoreBoardDialog::InitScoreboardSections( void ) { // Do this initially m_hSections[ TEAM_BLUE ].m_iTeam = TEAM_BLUE; m_hSections[ TEAM_RED ].m_iTeam = TEAM_RED; m_hSections[ TEAM_YELLOW ].m_iTeam = TEAM_YELLOW; m_hSections[ TEAM_GREEN ].m_iTeam = TEAM_GREEN; AddHeader(); } //-----------------------------------------------------------------------------
113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
void CClientScoreBoardDialog::ApplySchemeSettings( IScheme *pScheme ) { BaseClass::ApplySchemeSettings( pScheme ); ImageList *imageList = new ImageList(false); // s_VoiceImage[0] = 0; // index 0 is always blank // s_VoiceImage[CVoiceStatus::VOICE_NEVERSPOKEN] = imageList->AddImage(scheme()->GetImage("gfx/vgui/640_speaker1", true)); // s_VoiceImage[CVoiceStatus::VOICE_NOTTALKING] = imageList->AddImage(scheme()->GetImage("gfx/vgui/640_speaker2", true)); // s_VoiceImage[CVoiceStatus::VOICE_TALKING] = imageList->AddImage(scheme()->GetImage( "gfx/vgui/640_speaker3", true)); // s_VoiceImage[CVoiceStatus::VOICE_BANNED] = imageList->AddImage(scheme()->GetImage("gfx/vgui/640_voiceblocked", true)); // TrackerImage = imageList->AddImage(scheme()->GetImage("gfx/vgui/640_scoreboardtracker", true)); // resize the images to our resolution for (int i = 0; i < imageList->GetImageCount(); i++ ) { int wide, tall; imageList->GetImage(i)->GetSize(wide, tall); imageList->GetImage(i)->SetSize(scheme()->GetProportionalScaledValueEx( GetScheme(),wide), scheme()->GetProportionalScaledValueEx( GetScheme(),tall)); } m_pPlayerList->SetImageList(imageList, false); m_pPlayerList->SetVisible( true ); // light up scoreboard a bit SetBgColor( Color( 0,0,0,0) ); } //----------------------------------------------------------------------------- // Purpose: //-----------------------------------------------------------------------------
235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
void CClientScoreBoardDialog::ApplySchemeSettings( IScheme *pScheme ) { BaseClass::ApplySchemeSettings( pScheme ); ImageList *imageList = new ImageList( false ); s_VoiceImage[ 0 ] = 0; // index 0 is always blank s_VoiceImage[ CVoiceStatus::VOICE_NEVERSPOKEN ] = imageList->AddImage( scheme( )->GetImage( "640_speaker1", true ) ); s_VoiceImage[ CVoiceStatus::VOICE_NOTTALKING ] = imageList->AddImage( scheme( )->GetImage( "640_speaker2", true ) ); s_VoiceImage[ CVoiceStatus::VOICE_TALKING ] = imageList->AddImage( scheme( )->GetImage( "640_speaker3", true ) ); s_VoiceImage[ CVoiceStatus::VOICE_BANNED ] = imageList->AddImage( scheme( )->GetImage( "640_voiceblocked", true ) ); s_VoiceImage[ CVoiceStatus::VOICE_BANNEDTEXT ] = imageList->AddImage( scheme( )->GetImage( "640_textblocked", true ) ); // |-- Mirv: Text ban s_VoiceImage[ CVoiceStatus::VOICE_ALLOWEDTEXT ] = imageList->AddImage( scheme( )->GetImage( "640_textallowed", true ) ); // |-- DrEvil: Text allowed // --> Mirv: Channel images //s_ChannelImage[0] = 0; //s_ChannelImage[ CHANNEL::NONE ] = imageList->AddImage( scheme()->GetImage( "640_channelnone", true ) ); //s_ChannelImage[ CHANNEL::CHANNELA ] = imageList->AddImage( scheme()->GetImage( "640_channela", true ) ); //s_ChannelImage[ CHANNEL::CHANNELB ] = imageList->AddImage( scheme()->GetImage( "640_channelb", true ) ); // <-- Mirv: Channel images TrackerImage = imageList->AddImage( scheme( )->GetImage( "640_scoreboardtracker", true ) ); // --> Mirv: Image resizing made things a mess // resize the images to our resolution /* for (int i = 0; i < imageList->GetImageCount(); i++ ) { int wide, tall; imageList->GetImage(i)->GetSize(wide, tall); imageList->GetImage(i)->SetSize(scheme()->GetProportionalScaledValueEx( GetScheme(),wide), scheme()->GetProportionalScaledValueEx( GetScheme(),tall)); }*/ // <-- Mirv: Image resizing made things a mess m_pPlayerList->SetImageList(imageList, false); m_pPlayerList->SetVisible( true ); m_pPlayerList->SetPaintBackgroundEnabled(false); m_pPlayerList->SetBorder(NULL); SetBgColor( Color( 0,0,0,0) ); SetPaintBackgroundEnabled(true); SetBorder(NULL); } extern bool Client_IsIntermission(); void ForceScoreboard() { // all these NULL checks, // because it's like ~CClientScoreBoardDialog can happen in the middle of this function happening, // or something weird like that...IT'S FUCKING CRAZY, SERIOUSLY, THIS CRASH WON'T GO AWAY // For real though, sometimes g_pScoreboard is NULL, but it still won't return right here...SEE IT'S FUCKING CRAZY, SERIOUSLY if (g_pScoreboard == NULL) return; // Force visible if (g_pScoreboard != NULL && !g_pScoreboard->IsVisible()) g_pScoreboard->ShowPanel(true); // Force mouse control if (g_pScoreboard != NULL && !g_pScoreboard->IsMouseInputEnabled()) g_pScoreboard->SetMouseInputEnabled(true); } //----------------------------------------------------------------------------- // Purpose: //-----------------------------------------------------------------------------
146147148149150151152153154155156157
if ( BaseClass::IsVisible() == bShow ) return; if ( bShow ) { Reset(); Update(); Activate(); } else {
303304305306307308309310311312313314315316317318319320321322323324325326327328329
if ( BaseClass::IsVisible() == bShow ) return; // Don't let them unshow the scoreboard if (Client_IsIntermission() && !bShow) return; m_pViewPort->ShowBackGround(false); if ( bShow ) { if( m_iJumpKey == -1 ) // you need to lookup the jump key AFTER the engine has loaded { m_iJumpKey = gameuifuncs->GetEngineKeyCodeForBind( "jump" ); } //SetMouseInputEnabled(true); Reset(); Update(); Activate(); SetMouseInputEnabled(false); } else {
161162163164165166167168
} } void CClientScoreBoardDialog::FireGameEvent( IGameEvent *event ) { const char * type = event->GetName();
333334335336337338
} } void CClientScoreBoardDialog::FireGameEvent( IGameEvent *event ) { const char * type = event->GetName();
173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
m_HLTVSpectators = event->GetInt( "clients" ); m_HLTVSpectators -= event->GetInt( "proxies" ); } else if ( Q_strcmp(type, "server_spawn") == 0 ) { // We'll post the message ourselves instead of using SetControlString() // so we don't try to translate the hostname. const char *hostname = event->GetString( "hostname" ); Panel *control = FindChildByName( "ServerName" ); if ( control ) { PostMessage( control, new KeyValues( "SetText", "text", hostname ) ); } control->MoveToFront(); } if( IsVisible() ) Update(); } bool CClientScoreBoardDialog::NeedsUpdate( void ) { return (m_fNextUpdateTime < gpGlobals->curtime); } //-----------------------------------------------------------------------------
343344345346347348349350351352353354355356357358359360361
m_HLTVSpectators = event->GetInt( "clients" ); m_HLTVSpectators -= event->GetInt( "proxies" ); } else if ( Q_strcmp(type, "server_spawn") == 0 ) { SetControlString("ServerName", event->GetString("hostname")); MoveLabelToFront("ServerName"); } if( IsVisible() ) Update(); } bool CClientScoreBoardDialog::NeedsUpdate( void ) { return (m_fNextUpdateTime < gpGlobals->curtime); } //-----------------------------------------------------------------------------
204205206207208209210211212213214215216217218219220221222223224225226227228229230231
//----------------------------------------------------------------------------- void CClientScoreBoardDialog::Update( void ) { // Set the title // Reset(); m_pPlayerList->DeleteAllItems(); FillScoreBoard(); // grow the scoreboard to fit all the players int wide, tall; m_pPlayerList->GetContentSize(wide, tall); wide = GetWide(); if (m_iDesiredHeight < tall) { SetSize(wide, tall); m_pPlayerList->SetSize(wide, tall); } else { SetSize(wide, m_iDesiredHeight); m_pPlayerList->SetSize(wide, m_iDesiredHeight); } MoveToCenterOfScreen(); // update every second
363364365366367368369370371372373374375376377378379380381382383384385386387388
//----------------------------------------------------------------------------- void CClientScoreBoardDialog::Update( void ) { // Update the scoreboard FillScoreBoard(); // grow the scoreboard to fit all the players // int wide, tall; // m_pPlayerList->GetContentSize(wide, tall); // wide = GetWide(); // if (m_iDesiredHeight < tall) // { // SetSize(wide, tall); // m_pPlayerList->SetSize(wide, tall); // } // else // { // SetSize(wide, m_iDesiredHeight); // m_pPlayerList->SetSize(wide, m_iDesiredHeight); // } m_pMapName->SetText( GetFormattedMapName() ); MoveToCenterOfScreen(); // update every second
233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
} //----------------------------------------------------------------------------- // Purpose: Sort all the teams //----------------------------------------------------------------------------- void CClientScoreBoardDialog::UpdateTeamInfo() { } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CClientScoreBoardDialog::UpdatePlayerInfo() { m_iSectionId = 0; // 0'th row is a header int selectedRow = -1; // walk all the players and make sure they're in the scoreboard for ( int i = 1; i <= gpGlobals->maxClients; ++i ) { IGameResources *gr = GameResources(); if ( gr && gr->IsConnected( i ) ) { // add the player to the list KeyValues *playerData = new KeyValues("data"); GetPlayerScoreInfo( i, playerData ); const char *oldName = playerData->GetString("name",""); int bufsize = strlen(oldName) * 2 + 1; char *newName = (char *)_alloca( bufsize ); UTIL_MakeSafeName( oldName, newName, bufsize ); playerData->SetString("name", newName); int itemID = FindItemIDForPlayerIndex( i ); int sectionID = gr->GetTeam( i ); if ( gr->IsLocalPlayer( i ) ) { selectedRow = itemID; } if (itemID == -1) { // add a new row itemID = m_pPlayerList->AddItem( sectionID, playerData ); } else { // modify the current row m_pPlayerList->ModifyItem( itemID, sectionID, playerData ); } // set the row color based on the players team m_pPlayerList->SetItemFgColor( itemID, gr->GetTeamColor( sectionID ) ); playerData->deleteThis(); } else { // remove the player int itemID = FindItemIDForPlayerIndex( i ); if (itemID != -1) { m_pPlayerList->RemoveItem(itemID); } } } if ( selectedRow != -1 ) { m_pPlayerList->SetSelectedItem(selectedRow); } } //----------------------------------------------------------------------------- // Purpose: adds the top header of the scoreboars //----------------------------------------------------------------------------- void CClientScoreBoardDialog::AddHeader() { // add the top header m_pPlayerList->AddSection(m_iSectionId, ""); m_pPlayerList->SetSectionAlwaysVisible(m_iSectionId); m_pPlayerList->AddColumnToSection(m_iSectionId, "name", "#PlayerName", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),NAME_WIDTH) ); m_pPlayerList->AddColumnToSection(m_iSectionId, "frags", "#PlayerScore", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),SCORE_WIDTH) ); m_pPlayerList->AddColumnToSection(m_iSectionId, "deaths", "#PlayerDeath", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),DEATH_WIDTH) ); m_pPlayerList->AddColumnToSection(m_iSectionId, "ping", "#PlayerPing", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),PING_WIDTH) ); // m_pPlayerList->AddColumnToSection(m_iSectionId, "voice", "#PlayerVoice", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_CENTER, scheme()->GetProportionalScaledValueEx( GetScheme(),VOICE_WIDTH) ); // m_pPlayerList->AddColumnToSection(m_iSectionId, "tracker", "#PlayerTracker", SectionedListPanel::COLUMN_IMAGE, scheme()->GetProportionalScaledValueEx( GetScheme(),FRIENDS_WIDTH) ); } //----------------------------------------------------------------------------- // Purpose: Adds a new section to the scoreboard (i.e the team header) //----------------------------------------------------------------------------- void CClientScoreBoardDialog::AddSection(int teamType, int teamNumber) { if ( teamType == TYPE_TEAM ) { IGameResources *gr = GameResources(); if ( !gr ) return; // setup the team name wchar_t *teamName = localize()->Find( gr->GetTeamName(teamNumber) ); wchar_t name[64]; wchar_t string1[1024]; if (!teamName) { localize()->ConvertANSIToUnicode(gr->GetTeamName(teamNumber), name, sizeof(name)); teamName = name; } localize()->ConstructString( string1, sizeof( string1 ), localize()->Find("#Player"), 2, teamName ); m_pPlayerList->AddSection(m_iSectionId, "", StaticPlayerSortFunc); m_pPlayerList->AddColumnToSection(m_iSectionId, "name", string1, 0, scheme()->GetProportionalScaledValueEx( GetScheme(),NAME_WIDTH) ); m_pPlayerList->AddColumnToSection(m_iSectionId, "frags", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),SCORE_WIDTH) ); m_pPlayerList->AddColumnToSection(m_iSectionId, "deaths", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),DEATH_WIDTH) ); m_pPlayerList->AddColumnToSection(m_iSectionId, "ping", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),PING_WIDTH) ); } else if ( teamType == TYPE_SPECTATORS ) { m_pPlayerList->AddSection(m_iSectionId, ""); m_pPlayerList->AddColumnToSection(m_iSectionId, "name", "#Spectators", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),NAME_WIDTH)); m_pPlayerList->AddColumnToSection(m_iSectionId, "frags", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),SCORE_WIDTH) ); } } //----------------------------------------------------------------------------- // Purpose: Used for sorting players //----------------------------------------------------------------------------- bool CClientScoreBoardDialog::StaticPlayerSortFunc(vgui::SectionedListPanel *list, int itemID1, int itemID2) { KeyValues *it1 = list->GetItemData(itemID1); KeyValues *it2 = list->GetItemData(itemID2); Assert(it1 && it2); // first compare frags int v1 = it1->GetInt("frags"); int v2 = it2->GetInt("frags"); if (v1 > v2) return true; else if (v1 < v2) return false; // next compare deaths v1 = it1->GetInt("deaths"); v2 = it2->GetInt("deaths"); if (v1 > v2) return false; else if (v1 < v2) return true; // the same, so compare itemID's (as a sentinel value to get deterministic sorts)
390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
} //----------------------------------------------------------------------------- // Purpose: Finds what section a team is in //----------------------------------------------------------------------------- int CClientScoreBoardDialog::FindSectionByTeam( int iTeam ) const { for( int i = 0; i < 8; i++ ) { if( m_hSections[ i ].m_iTeam == iTeam ) return i; } return TEAM_UNASSIGNED; } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CClientScoreBoardDialog::UpdatePlayerInfo( void ) { IGameResources *pGR = GameResources(); if( !pGR ) return; int iSelectedRow = -1; // walk all the players and make sure they're in the scoreboard for ( int i = 1; i <= gpGlobals->maxClients; ++i ) { if( pGR->IsConnected( i ) ) { // Add the player to the list KeyValues *pPlayerData = new KeyValues( "data" ); GetPlayerScoreInfo( i, pPlayerData ); const char *pszOldName = pPlayerData->GetString( "name", "" ); int iBufSize = ( int )strlen( pszOldName ) * 2; char *pszNewName = ( char * )_alloca( iBufSize ); UTIL_MakeSafeName( pszOldName, pszNewName, iBufSize ); pPlayerData->SetString( "name", pszNewName ); int iItemId = FindItemIDForPlayerIndex( i ); int iPlayerTeam = pGR->GetTeam( i ); int iSectionId = FindSectionByTeam( iPlayerTeam ); if( pGR->IsLocalPlayer( i ) ) iSelectedRow = iItemId; if( iItemId == -1 ) { // Add a new row iItemId = m_pPlayerList->AddItem( iSectionId, pPlayerData ); } else { // Modify current row m_pPlayerList->ModifyItem( iItemId, iSectionId, pPlayerData ); } Color cCol = pGR->GetTeamColor( iPlayerTeam ); // Set the row color based on players team if( pGR->IsLocalPlayer( i ) ) m_pPlayerList->SetItemFgColor( iItemId, Color( cCol.r() * 0.6f, cCol.g() * 0.6f, cCol.b() * 0.6f, cCol.a() * 0.9/*local_row_alpha.GetFloat()*/ ), true ); else m_pPlayerList->SetItemFgColor( iItemId, Color( cCol.r() * 0.6f, cCol.g() * 0.6f, cCol.b() * 0.6f, cCol.a() * 0.55/*row_alpha.GetFloat()*/ ) ); pPlayerData->deleteThis(); } else { // Remove the player int iItemId = FindItemIDForPlayerIndex( i ); if( iItemId != -1 ) m_pPlayerList->RemoveItem( iItemId ); } } if( iSelectedRow != -1 ) m_pPlayerList->SetSelectedItem( iSelectedRow ); } //----------------------------------------------------------------------------- // Purpose: adds the top header of the scoreboars //----------------------------------------------------------------------------- void CClientScoreBoardDialog::AddHeader( void ) { // We can get called back into here when teams // get sorted so that's why part is commented // out as the team values are already set by // the sort (or by the initial creation of the // scoreboard) int iSection = 0; m_hSections[ iSection ].m_iTeam = AddSection( TYPE_BLANK, iSection ); // 0 iSection++; m_hSections[ iSection ].m_iTeam = AddSection( TYPE_HEADER, iSection ); // 1 iSection++; /*m_hSections[ iSection ].m_iTeam =*/ AddSection( TYPE_TEAM, iSection ); // 2 iSection++; /*m_hSections[ iSection ].m_iTeam =*/ AddSection( TYPE_TEAM, iSection ); // 3 iSection++; /*m_hSections[ iSection ].m_iTeam =*/ AddSection( TYPE_TEAM, iSection ); // 4 iSection++; /*m_hSections[ iSection ].m_iTeam =*/ AddSection( TYPE_TEAM, iSection ); // 5 iSection++; m_hSections[ iSection ].m_iTeam = AddSection( TYPE_SPECTATORS, iSection ); // 6 iSection++; m_hSections[ iSection ].m_iTeam = AddSection( TYPE_UNASSIGNED, iSection ); // 7 } //----------------------------------------------------------------------------- // Purpose: Adds a new section to the scoreboard (i.e the team header) //----------------------------------------------------------------------------- int CClientScoreBoardDialog::AddSection( int iType, int iSection ) { int iRetval = -1; if( iType == TYPE_BLANK ) { m_pPlayerList->AddSection( iSection, "" ); m_pPlayerList->SetSectionAlwaysVisible( iSection ); m_pPlayerList->AddColumnToSection( iSection, "name", "", 0, scheme()->GetProportionalScaledValue( NAME_WIDTH ) ); } else if( iType == TYPE_HEADER ) { m_pPlayerList->AddSection( iSection, "" ); m_pPlayerList->SetSectionAlwaysVisible( iSection ); m_pPlayerList->AddColumnToSection( iSection, "name" , "#FF_PlayerName" , 0 , scheme()->GetProportionalScaledValue( NAME_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "class" , "#FF_PlayerClass" , 0 , scheme()->GetProportionalScaledValue( CLASS_WIDTH ) ); // |-- Mirv: Current class m_pPlayerList->AddColumnToSection( iSection, "fortpoints" , "#FF_PlayerFortPoints" , 0, scheme()->GetProportionalScaledValue( FORTPOINTS_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "score" , "#FF_PlayerScore" , 0, scheme()->GetProportionalScaledValue( SCORE_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "deaths" , "#FF_PlayerDeath" , 0, scheme()->GetProportionalScaledValue( DEATH_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "ping" , "#FF_PlayerPing" , 0, scheme()->GetProportionalScaledValue( PING_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "voice" , "#FF_PlayerVoice" , SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_CENTER, scheme( )->GetProportionalScaledValue( VOICE_WIDTH ) ); //m_pPlayerList->AddColumnToSection( iSection, "channel" , "#FF_PlayerChannel" , SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_CENTER, /*scheme( )->GetProportionalScaledValue(*/ CHANNEL_WIDTH /*)*/ ); // |-- Mirv: This should fix the messed up gfx settings } else if( iType == TYPE_TEAM ) { m_pPlayerList->AddSection( iSection, "", StaticPlayerSortFunc_Score ); //m_pPlayerList->SetSectionAlwaysVisible( iSection ); m_pPlayerList->AddColumnToSection( iSection, "name", "#FF_Team", 0, scheme()->GetProportionalScaledValue( NAME_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "class", "", 0, scheme()->GetProportionalScaledValue( CLASS_WIDTH ) ); // |-- Mirv: Current class m_pPlayerList->AddColumnToSection( iSection, "fortpoints", "", 0, scheme()->GetProportionalScaledValue( FORTPOINTS_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "score", "", 0, scheme()->GetProportionalScaledValue( SCORE_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "deaths", "", 0, scheme()->GetProportionalScaledValue( DEATH_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "ping", "", 0, scheme()->GetProportionalScaledValue( PING_WIDTH ) ); // --> Mirv: Voice and channel images m_pPlayerList->AddColumnToSection( iSection, "voice", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_CENTER, VOICE_WIDTH ); //m_pPlayerList->AddColumnToSection( iSection, "channel", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_CENTER, CHANNEL_WIDTH ); // <-- Mirv: Voice and channel images iRetval = iSection; } else if( iType == TYPE_SPECTATORS ) { m_pPlayerList->AddSection( iSection, "", StaticPlayerSortFunc_Name ); //m_pPlayerList->SetSectionAlwaysVisible( iSection ); m_pPlayerList->AddColumnToSection( iSection, "name", "#FF_Spectators", 0, scheme()->GetProportionalScaledValue( NAME_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "class", "", 0, scheme()->GetProportionalScaledValue( CLASS_WIDTH ) ); // |-- Mirv: Current class m_pPlayerList->AddColumnToSection( iSection, "fortpoints", "", 0, scheme()->GetProportionalScaledValue( FORTPOINTS_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "score", "", 0, scheme()->GetProportionalScaledValue( SCORE_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "deaths", "", 0, scheme()->GetProportionalScaledValue( DEATH_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "ping", "", 0, scheme()->GetProportionalScaledValue( PING_WIDTH ) ); iRetval = TEAM_SPECTATOR; } else if( iType == TYPE_UNASSIGNED ) { m_pPlayerList->AddSection( iSection, "" ); //m_pPlayerList->SetSectionAlwaysVisible( iSection ); m_pPlayerList->AddColumnToSection( iSection, "name", "#FF_Unassigned", 0, scheme()->GetProportionalScaledValue( NAME_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "class", "", 0, scheme()->GetProportionalScaledValue( CLASS_WIDTH ) ); // |-- Mirv: Current class m_pPlayerList->AddColumnToSection( iSection, "fortpoints", "", 0, scheme()->GetProportionalScaledValue( FORTPOINTS_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "score", "", 0, scheme()->GetProportionalScaledValue( SCORE_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "deaths", "", 0, scheme()->GetProportionalScaledValue( DEATH_WIDTH ) ); m_pPlayerList->AddColumnToSection( iSection, "ping", "", 0, scheme()->GetProportionalScaledValue( PING_WIDTH ) ); iRetval = TEAM_UNASSIGNED; } return iRetval; } //----------------------------------------------------------------------------- // Purpose: Update team sections to correct teams & colors //----------------------------------------------------------------------------- void CClientScoreBoardDialog::UpdateHeaders( void ) { // Go from m_hSections[ 2 -> 6 ] (ie. the team's that can be sorted) // Assumes m_hSections has been sorted properly before doing this IGameResources *pGR = GameResources(); if( !pGR ) return; for( int i = TEAM_BLUE; i <= TEAM_GREEN; i++ ) { int iTeam = m_hSections[ i ].m_iTeam; int iNumPlayers = m_hSections[ i ].m_iNumPlayers; int iLatency = m_hSections[ i ].m_iLatency; Color cCol = pGR->GetTeamColor( iTeam ); // This is nice and all but if teams get sorted while // you're viewing the scoreboard the color doesn't change :/ m_pPlayerList->SetSectionFgColor( i, Color(cCol.r(), cCol.g(), cCol.b(), cCol.a() * 0.6/*header_alpha.GetFloat()*/) ); wchar_t *szTeamName = localize()->Find( pGR->GetTeamName( iTeam ) ); wchar_t szName[ 256 ]; if( !szTeamName ) { // No localized text or team name not a resource string char szString[ 256 ]; Q_snprintf( szString, 256, "%s - (%i players)", pGR->GetTeamName( iTeam ), iNumPlayers ); localize()->ConvertANSIToUnicode( szString, szName, sizeof( szName ) ); szTeamName = szName; } else { swprintf( szName, L"%s - (%i players)", szTeamName, iNumPlayers ); szTeamName = szName; } m_pPlayerList->ModifyColumn( i, "name", szTeamName ); // Look up team fort points (currently hacked to get team score (frags) which is what was previously used) wchar_t szFortPoints[ 6 ]; swprintf( szFortPoints, L"%d", pGR->GetTeamScore( iTeam ) ); // Display team fort points (probably will actually be team score e.g. captures *10) m_pPlayerList->ModifyColumn( i, "fortpoints", szFortPoints ); // AfterShock - commented this out so teamfrags arent shown (and scores are clearer) // Look up team score (frags) //wchar_t szScore[ 6 ]; //swprintf( szScore, L"%d", pGR->GetTeamScore( iTeam ) ); // Display team frags //m_pPlayerList->ModifyColumn( i, "score", szScore ); // AfterShock - commented this out so teamdeaths arent shown (and scores are clearer) // Look up team deaths //wchar_t szDeaths[ 6 ]; //swprintf( szDeaths, L"%d", pGR->GetTeamDeaths( iTeam ) ); // Display team deaths //m_pPlayerList->ModifyColumn( i, "deaths", szDeaths ); // Set up team latency if( iNumPlayers > 0 ) iLatency /= iNumPlayers; else iLatency = 0; // Display team latency if( iLatency < 1 ) m_pPlayerList->ModifyColumn( i, "ping", L"0" ); else { wchar_t szLatency[ 12 ]; swprintf( szLatency, L"%i", iLatency ); m_pPlayerList->ModifyColumn( i, "ping", szLatency ); } } } //----------------------------------------------------------------------------- // Purpose: Used for sorting players //----------------------------------------------------------------------------- bool CClientScoreBoardDialog::StaticPlayerSortFunc_Score( vgui::SectionedListPanel *list, int itemID1, int itemID2 ) { KeyValues *it1 = list->GetItemData( itemID1 ); KeyValues *it2 = list->GetItemData( itemID2 ); Assert( it1 && it2 ); // first compare fortpoints int v1 = it1->GetInt( "fortpoints" ); int v2 = it2->GetInt( "fortpoints" ); if( v1 > v2 ) return true; else if( v1 < v2 ) return false; // next compare score v1 = it1->GetInt( "score" ); v2 = it2->GetInt( "score" ); if( v1 > v2 ) return false; else if( v1 < v2 ) return true; // the same, so compare itemID's (as a sentinel value to get deterministic sorts)
393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
} //----------------------------------------------------------------------------- // Purpose: Adds a new row to the scoreboard, from the playerinfo structure //----------------------------------------------------------------------------- bool CClientScoreBoardDialog::GetPlayerScoreInfo(int playerIndex, KeyValues *kv) { IGameResources *gr = GameResources(); if (!gr ) return false; kv->SetInt("deaths", gr->GetDeaths( playerIndex ) ); kv->SetInt("frags", gr->GetFrags( playerIndex ) ); kv->SetInt("ping", gr->GetPing( playerIndex ) ) ; kv->SetString("name", gr->GetPlayerName( playerIndex ) ); kv->SetInt("playerIndex", playerIndex); // kv->SetInt("voice", s_VoiceImage[GetClientVoice()->GetSpeakerStatus( playerIndex - 1) ]); /* // setup the tracker column if (g_pFriendsUser) { unsigned int trackerID = gEngfuncs.GetTrackerIDForPlayer(row); if (g_pFriendsUser->IsBuddy(trackerID) && trackerID != g_pFriendsUser->GetFriendsID()) { kv->SetInt("tracker",TrackerImage); } } */ return true; }
696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
} //----------------------------------------------------------------------------- // Purpose: Used for sorting players //----------------------------------------------------------------------------- bool CClientScoreBoardDialog::StaticPlayerSortFunc_Name( vgui::SectionedListPanel *list, int itemID1, int itemID2 ) { KeyValues *it1 = list->GetItemData( itemID1 ); KeyValues *it2 = list->GetItemData( itemID2 ); Assert( it1 && it2 ); // first compare frags const char *p1 = it1->GetString( "name" ); const char *p2 = it2->GetString( "name" ); if( Q_stricmp( p1, p2 ) < 0 ) return true; else if( Q_stricmp( p1, p2 ) > 0 ) return false; // the same, so compare itemID's (as a sentinel value to get deterministic sorts) return itemID1 < itemID2; } //----------------------------------------------------------------------------- // Purpose: Adds a new row to the scoreboard, from the playerinfo structure //----------------------------------------------------------------------------- bool CClientScoreBoardDialog::GetPlayerScoreInfo( int playerIndex, KeyValues *kv ) { IGameResources *pGR = GameResources(); if( !pGR ) return false; bool bFriendly = false; int iLocalPlayerTeam = TEAM_UNASSIGNED; int iPlayerTeam = TEAM_UNASSIGNED; // Get local player team. This will always be up to date // since the local player is the one viewing the scoreboard // and whose machine this stuff is running on. C_FFPlayer *pLocalPlayer = C_FFPlayer::GetLocalFFPlayer(); if( pLocalPlayer ) iLocalPlayerTeam = pLocalPlayer->GetTeamNumber(); // Check if player is connected. If connected, compare team to see if // friendly or not but use the player resource as it will be up to date // with server information. I think in the past there was a PVS issue // and the client who was viewing the scoreboard might see old (inaccurate) // data and draw stuff the class identifier wrong. Crosshair info needs // to be revisited for this reason too! if( pGR->IsConnected( playerIndex ) ) iPlayerTeam = pGR->GetTeam( playerIndex ); // Check if an ally bFriendly = FFGameRules()->IsTeam1AlliedToTeam2( iLocalPlayerTeam, iPlayerTeam ); kv->SetInt( "deaths", pGR->GetDeaths( playerIndex ) ); kv->SetInt( "fortpoints", pGR->GetFortPoints( playerIndex ) ); kv->SetInt( "score", pGR->GetFrags( playerIndex ) ); kv->SetInt( "ping", pGR->GetPing( playerIndex ) ) ; kv->SetString( "name", pGR->GetPlayerName( playerIndex ) ); if( bFriendly ) kv->SetString( "class", szClassName[ pGR->GetClass( playerIndex ) ] ); // |-- Mirv: Current class else kv->SetString( "class", "" ); kv->SetInt( "playerIndex", playerIndex ); // --> Mirv: Fixed for an extra setting // kv->SetInt( "voice", s_VoiceImage[ GetClientVoiceMgr()->GetSpeakerStatus( playerIndex - 1 ) ] ); if( bFriendly ) { kv->SetInt( "voice", s_VoiceImage[ GetClientVoiceMgr()->GetSpeakerStatus( playerIndex ) ] + ( g_fBlockedStatus[ playerIndex ] ? 1 : 0 ) ); //kv->SetInt( "channel", s_ChannelImage[ pGR->GetChannel( playerIndex ) ] + 1 ); } else { if(g_fBlockedStatus[playerIndex]) kv->SetInt( "voice", s_VoiceImage[ CVoiceStatus::VOICE_BANNEDTEXT ] ); else kv->SetInt( "voice", s_VoiceImage[ CVoiceStatus::VOICE_ALLOWEDTEXT ] ); //kv->SetInt( "channel", 0 ); } // <-- Mirv: Fixed for an extra setting return true; }
427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
//----------------------------------------------------------------------------- // Purpose: reload the player list on the scoreboard //----------------------------------------------------------------------------- void CClientScoreBoardDialog::FillScoreBoard() { // update totals information UpdateTeamInfo(); // update player info UpdatePlayerInfo(); } //----------------------------------------------------------------------------- // Purpose: searches for the player in the scoreboard //----------------------------------------------------------------------------- int CClientScoreBoardDialog::FindItemIDForPlayerIndex(int playerIndex) { for (int i = 0; i <= m_pPlayerList->GetHighestItemID(); i++) { if (m_pPlayerList->IsItemIDValid(i)) { KeyValues *kv = m_pPlayerList->GetItemData(i); kv = kv->FindKey(m_iPlayerIndexSymbol); if (kv && kv->GetInt() == playerIndex) return i; } } return -1; } //----------------------------------------------------------------------------- // Purpose: Sets the text of a control by name //----------------------------------------------------------------------------- void CClientScoreBoardDialog::MoveLabelToFront(const char *textEntryName) { Label *entry = dynamic_cast if (entry) { entry->MoveToFront(); } }
78678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
//----------------------------------------------------------------------------- // Purpose: reload the player list on the scoreboard //----------------------------------------------------------------------------- void CClientScoreBoardDialog::FillScoreBoard( void ) { IGameResources *pGR = GameResources(); if( !pGR ) return; bool bNeedToSort = NeedToSortTeams(); // Set up num players, latency, score, and time scored for each team for( int i = TEAM_BLUE; i <= TEAM_GREEN; i++ ) { int iTeam = m_hSections[ i ].m_iTeam; // Get team score m_hSections[ i ].m_iScore = pGR->GetTeamScore( iTeam ); // Get the time the team last scored m_hSections[ i ].m_flLastScored = pGR->GetTeamScoreTime( iTeam ); int iPlayerCount = 0, iLatency = 0; for( int j = 1; j <= gpGlobals->maxClients; j++ ) { if( pGR->IsConnected( j ) ) { // If the player is on iTeam if( pGR->GetTeam( j ) == iTeam ) { iPlayerCount++; iLatency += pGR->GetPing( j ); } } } // Set number of players on this team m_hSections[ i ].m_iNumPlayers = iPlayerCount; // Set the team's latency m_hSections[ i ].m_iLatency = iLatency; } // Do sorting if( bNeedToSort ) { // YES, THIS IS VERY CHEESY! CUtlVector< ScoreboardSection_s > hTemp; // Copy to vector... for( int i = TEAM_BLUE; i <= TEAM_GREEN; i++ ) hTemp.AddToTail( m_hSections[ i ] ); // Sort! hTemp.Sort( ScoreboardSection_Sort ); // Copy back over... for( int i = TEAM_BLUE; i <= TEAM_GREEN; i++ ) m_hSections[ i ] = hTemp[ i - TEAM_BLUE ]; // Have to remove all sections because if you're // viewing the scoreboard when teams get sorted // the team header doesn't change color until // you hide the scoreboard then bring it back up m_pPlayerList->RemoveAll(); m_pPlayerList->RemoveAllSections(); // Re-add all headers and sections AddHeader(); } // Update team headers UpdateHeaders(); // Update player info UpdatePlayerInfo(); } //----------------------------------------------------------------------------- // Purpose: checks to see if we need to sort the teams //----------------------------------------------------------------------------- bool CClientScoreBoardDialog::NeedToSortTeams( void ) const { bool bSort = false; int iLastScore = m_hSections[ TEAM_BLUE ].m_iScore; float flLastUpdate = m_hSections[ TEAM_BLUE ].m_flLastScored; for( int i = TEAM_RED; ( i <= TEAM_GREEN ) && !bSort; i++ ) { if( iLastScore < m_hSections[ i ].m_iScore ) bSort = true; else if( iLastScore == m_hSections [ i ].m_iScore ) { if( flLastUpdate < m_hSections[ i ].m_flLastScored ) bSort = true; } // Update 'last' iLastScore = m_hSections[ i ].m_iScore; flLastUpdate = m_hSections[ i ].m_flLastScored; } return bSort; } int CClientScoreBoardDialog::FindItemIDForPlayerIndex( int playerIndex ) { for( int i = 0; i <= m_pPlayerList->GetHighestItemID(); i++) { if( m_pPlayerList->IsItemIDValid( i ) ) { KeyValues *kv = m_pPlayerList->GetItemData( i ); kv = kv->FindKey( m_iPlayerIndexSymbol ); if( kv && kv->GetInt() == playerIndex ) return i; } } return -1; } //----------------------------------------------------------------------------- // Purpose: Sets the text of a control by name //----------------------------------------------------------------------------- void CClientScoreBoardDialog::MoveLabelToFront( const char *textEntryName ) { Label *entry = dynamic_cast< Label * >( FindChildByName( textEntryName ) ); if( entry ) { entry->MoveToFront(); } } void CClientScoreBoardDialog::OnKeyCodePressed( KeyCode code ) { int lastPressedEngineKey = engine->GetLastPressedEngineKey( ); if( ( m_iJumpKey != -1 ) && ( m_iJumpKey == lastPressedEngineKey ) ) { SetMouseInputEnabled( true ); } else { BaseClass::OnKeyCodePressed( code ); } } int CClientScoreBoardDialog::FindPlayerIndexForItemID( int iItemID ) { if( m_pPlayerList->IsItemIDValid( iItemID ) ) { KeyValues *kv = m_pPlayerList->GetItemData( iItemID ); kv = kv->FindKey( m_iPlayerIndexSymbol ); if( kv ) return kv->GetInt(); } return -1; } //----------------------------------------------------------------------------- // Purpose: Scroll between different block modes //----------------------------------------------------------------------------- void CClientScoreBoardDialog::OnItemSelected(KeyValues *data) { int iRowId = data->GetInt("itemID"); int playerIndex = FindPlayerIndexForItemID(iRowId); IGameResources *pGR = GameResources(); // Don't change local player info if (pGR && pGR->IsLocalPlayer(playerIndex)) return; // No valid player selected, do nothing! if( playerIndex == -1 ) return; // This line was causing one of the // Assert(i >= 0 && i < GetNumBits()); // bugs! It's fixed now! // If player is not audible, only toggle text block if (!GetClientVoiceMgr()->IsPlayerAudible(playerIndex)) { g_fBlockedStatus[playerIndex] = !g_fBlockedStatus[playerIndex]; return; } // Get some current states bool fVBlock = GetClientVoiceMgr()->GetSpeakerStatus(playerIndex) == CVoiceStatus::VOICE_BANNED; bool fTBlock = g_fBlockedStatus[playerIndex]; // We have everything blocked, so go onto nothing blocked if (fVBlock && fTBlock) { g_fBlockedStatus[playerIndex] = false; GetClientVoiceMgr()->SetPlayerBlockedState(playerIndex, false); } // We just have voice blocked, so go onto everything blocked else if (fVBlock) { g_fBlockedStatus[playerIndex] = true; GetClientVoiceMgr()->SetPlayerBlockedState(playerIndex, true); } // We have nothing blocked, so just block voice else { g_fBlockedStatus[playerIndex] = false; GetClientVoiceMgr()->SetPlayerBlockedState(playerIndex, true); } // Update right away to show voice icon change Update(); } void CClientScoreBoardDialog::PaintBackground() { int iYPos = scheme()->GetProportionalScaledValue(32); surface()->DrawSetColor(GetFgColor()); surface()->DrawFilledRect(0, iYPos, GetWide(), iYPos + 1); //BaseClass::PaintBackground(); }