//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #include "cbase.h" #include "tf_hud_winpanel.h" #include "tf_hud_statpanel.h" #include "tf_spectatorgui.h" #include "vgui_controls/AnimationController.h" #include "iclientmode.h" #include "engine/IEngineSound.h" #include "c_tf_playerresource.h" #include "c_team.h" #include "tf_clientscoreboard.h" #include #include #include #include #include "vgui_avatarimage.h" #include "fmtstr.h" #include "teamplayroundbased_gamerules.h" #include "tf_gamerules.h" #include "tf_logic_halloween_2014.h" #include "c_tf_team.h" #include "tf_badge_panel.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" DECLARE_HUDELEMENT_DEPTH( CTFWinPanel, 1 ); //----------------------------------------------------------------------------- // Purpose: Constructor //----------------------------------------------------------------------------- CTFWinPanel::CTFWinPanel( const char *pElementName ) : EditablePanel( NULL, "WinPanel" ), CHudElement( pElementName ) { vgui::Panel *pParent = g_pClientMode->GetViewport(); SetParent( pParent ); m_bShouldBeVisible = false; SetAlpha( 0 ); SetScheme( "ClientScheme" ); m_pTeamScorePanel = new EditablePanel( this, "TeamScoresPanel" ); m_pRedTeamName = new CExLabel( m_pTeamScorePanel, "RedTeamLabel", "" ); m_pBlueTeamName = new CExLabel( m_pTeamScorePanel, "BlueTeamLabel", "" ); m_pRedLeaderAvatarImage = new CAvatarImagePanel( m_pTeamScorePanel, "RedLeaderAvatar" ); m_pBlueLeaderAvatarImage = new CAvatarImagePanel( m_pTeamScorePanel, "BlueLeaderAvatar" ); m_pRedLeaderAvatarBG = new EditablePanel( m_pTeamScorePanel, "RedLeaderAvatarBG" ); m_pBlueLeaderAvatarBG = new EditablePanel( m_pTeamScorePanel, "BlueLeaderAvatarBG" ); m_flTimeUpdateTeamScore = 0; m_iBlueTeamScore = 0; m_iRedTeamScore = 0; RegisterForRenderGroup( "mid" ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFWinPanel::ApplySettings( KeyValues *inResourceData ) { BaseClass::ApplySettings( inResourceData ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFWinPanel::Reset() { m_bShouldBeVisible = false; } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFWinPanel::Init() { // listen for events ListenForGameEvent( "teamplay_win_panel" ); ListenForGameEvent( "teamplay_round_start" ); ListenForGameEvent( "teamplay_game_over" ); ListenForGameEvent( "tf_game_over" ); ListenForGameEvent( "training_complete" ); ListenForGameEvent( "show_match_summary" ); m_bShouldBeVisible = false; CHudElement::Init(); } void CTFWinPanel::SetVisible( bool state ) { if ( state == IsVisible() ) return; if ( state ) { HideLowerPriorityHudElementsInGroup( "mid" ); } else { UnhideLowerPriorityHudElementsInGroup( "mid" ); } BaseClass::SetVisible( state ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFWinPanel::FireGameEvent( IGameEvent * event ) { const char *pEventName = event->GetName(); if ( FStrEq( "teamplay_round_start", pEventName ) || FStrEq( "teamplay_game_over", pEventName ) || FStrEq( "tf_game_over", pEventName ) || FStrEq( "training_complete", pEventName ) || FStrEq( "show_match_summary", pEventName ) ) { m_bShouldBeVisible = false; } else if ( Q_strcmp( "teamplay_win_panel", pEventName ) == 0 ) { if ( !g_PR ) return; vgui::IScheme* pScheme = scheme()->GetIScheme( GetScheme() ); int iWinningTeam = event->GetInt( "winning_team" ); int iWinReason = event->GetInt( "winreason" ); int iFlagCapLimit = event->GetInt( "flagcaplimit" ); bool bRoundComplete = (bool) event->GetInt( "round_complete" ); int iRoundsRemaining = event->GetInt( "rounds_remaining" ); bool bGameOver = event->GetBool( "game_over", false ); bool bUseMoreOpaqueBorder = false; if ( TFGameRules() && bGameOver ) { if ( TFGameRules()->IsMatchTypeCompetitive() ) { bUseMoreOpaqueBorder = true; } } // non-final rounds of stopwatch mode should say something different CTeamRoundTimer *pTimer = NULL; if ( TFGameRules() && TFGameRules()->IsInTournamentMode() && TFGameRules()->IsInStopWatch() ) { int iActiveTimer = ObjectiveResource()->GetStopWatchTimer(); pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( iActiveTimer ) ); if ( pTimer ) { if ( pTimer->IsWatchingTimeStamps() ) { iWinningTeam = TEAM_INVALID; iWinReason = bRoundComplete ? WINREASON_STOPWATCH_WATCHING_FINAL_ROUND : WINREASON_STOPWATCH_WATCHING_ROUNDS; } else { if ( !TFGameRules()->HaveStopWatchWinner() && !bRoundComplete ) { iWinningTeam = TEAM_INVALID; iWinReason = WINREASON_STOPWATCH_PLAYING_ROUNDS; } } } } LoadControlSettings( "resource/UI/WinPanel.res" ); InvalidateLayout( false, true ); SetDialogVariable( "WinningTeamLabel", "" ); SetDialogVariable( "AdvancingTeamLabel", "" ); SetDialogVariable( "WinReasonLabel", "" ); SetDialogVariable( "DetailsLabel", "" ); EditablePanel *pBGPanel = dynamic_cast( FindChildByName("WinPanelBGBorder") ); Assert( pBGPanel ); if ( !pBGPanel ) return; EditablePanel *pBlueBGPanel = FindControl< EditablePanel >( "BlueScoreBG", true ); Assert( pBlueBGPanel ); EditablePanel *pRedBGPanel = FindControl< EditablePanel >( "RedScoreBG", true ); Assert( pRedBGPanel ); if( !pBlueBGPanel || !pRedBGPanel ) return; pBlueBGPanel->SetBorder( pScheme->GetBorder( bUseMoreOpaqueBorder ? "TFFatLineBorderBlueBGMoreOpaque" : "TFFatLineBorderBlueBG" ) ); pRedBGPanel->SetBorder( pScheme->GetBorder( bUseMoreOpaqueBorder ? "TFFatLineBorderRedBGMoreOpaque" : "TFFatLineBorderRedBG" ) ) ; // we want to suppress the winreason for sd_doomsday_event and plr_hightower_event if ( TFGameRules() ) { if ( ( TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_DOOMSDAY ) && CTFMinigameLogic::GetMinigameLogic() && CTFMinigameLogic::GetMinigameLogic()->GetActiveMinigame() ) || ( TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_HIGHTOWER ) ) ) { iWinReason = WINREASON_NONE; } } // this is an area defense, but not a round win, if this was a successful defend until time limit but not a complete round bool bIsAreaDefense = ( ( WINREASON_DEFEND_UNTIL_TIME_LIMIT == iWinReason ) && !bRoundComplete ); // set the appropriate background image and label text const wchar_t *pTeamLabel = L""; const wchar_t *pTopPlayersLabel = L""; const wchar_t *pLocalizedTeamName = L""; const char *pWinTeamLabel = ( bRoundComplete ? "#Winpanel_TeamWins" : ( bIsAreaDefense ? "#Winpanel_TeamDefends" : "#Winpanel_TeamAdvances" ) ); C_TFTeam *pBlueTeam = GetGlobalTFTeam( TF_TEAM_BLUE ); const wchar_t *pBlueTeamName = pBlueTeam ? pBlueTeam->Get_Localized_Name() : L"BLU"; C_TFTeam *pRedTeam = GetGlobalTFTeam( TF_TEAM_RED ); const wchar_t *pRedTeamName = pRedTeam ? pRedTeam->Get_Localized_Name() : L"RED"; if ( TFGameRules() && TFGameRules()->IsInTournamentMode() ) { pWinTeamLabel = ( bRoundComplete ? "#Winpanel_TournamentTeamWins" : ( bIsAreaDefense ? "#Winpanel_TournamentTeamDefends" : "#Winpanel_TournamentTeamAdvances" ) ); } wchar_t wzTeamWin[256] = L""; switch ( iWinningTeam ) { case TF_TEAM_BLUE: pBGPanel->SetBorder( pScheme->GetBorder( bUseMoreOpaqueBorder ? "TFFatLineBorderBlueBGMoreOpaque" : "TFFatLineBorderBlueBG" ) ); pTopPlayersLabel = g_pVGuiLocalize->Find( "#Winpanel_BlueMVPs" ); pLocalizedTeamName = pBlueTeamName; g_pVGuiLocalize->ConstructString_safe( wzTeamWin, g_pVGuiLocalize->Find( pWinTeamLabel ), 2, pLocalizedTeamName, g_pVGuiLocalize->Find( "#Winpanel_Team1" ) ); pTeamLabel = wzTeamWin; break; case TF_TEAM_RED: pBGPanel->SetBorder( pScheme->GetBorder( bUseMoreOpaqueBorder ? "TFFatLineBorderRedBGMoreOpaque" : "TFFatLineBorderRedBG" ) ); pTopPlayersLabel = g_pVGuiLocalize->Find( "#Winpanel_RedMVPs" ); pLocalizedTeamName = pRedTeamName; break; case TEAM_UNASSIGNED: // stalemate pBGPanel->SetBorder( pScheme->GetBorder( "TFFatLineBorder" ) ); pTeamLabel = g_pVGuiLocalize->Find( "#Winpanel_Stalemate" ); pTopPlayersLabel = g_pVGuiLocalize->Find( "#Winpanel_TopPlayers" ); break; case TEAM_INVALID: // used for stopwatch mode when it's not the final victory yet pBGPanel->SetBorder( pScheme->GetBorder( "TFFatLineBorder" ) ); pTopPlayersLabel = g_pVGuiLocalize->Find( "#Winpanel_TopPlayers" ); pTeamLabel = L""; if ( pBlueTeam && pBlueTeamName && pRedTeamName ) { if ( bRoundComplete ) { pTeamLabel = g_pVGuiLocalize->Find( "#WinPanel_StopWatch_Watching_RoundFinal" ); } else { bool bBlueAttackers = ( pBlueTeam->GetRole() == TEAM_ROLE_ATTACKERS ); g_pVGuiLocalize->ConstructString_safe( wzTeamWin, g_pVGuiLocalize->Find( "#WinPanel_StopWatch_Round_Complete" ), 1, bBlueAttackers ? pBlueTeamName : pRedTeamName ); pTeamLabel = wzTeamWin; } } break; default: Assert( false ); break; } SetDialogVariable( "TopPlayersLabel", pTopPlayersLabel ); if ( TFGameRules() && TFGameRules()->IsInTournamentMode() && !TFGameRules()->IsInStopWatch() ) { g_pVGuiLocalize->ConstructString_safe( wzTeamWin, g_pVGuiLocalize->Find( pWinTeamLabel ), 1, pLocalizedTeamName ); wchar_t wzTeamMPVs[256]; g_pVGuiLocalize->ConstructString_safe( wzTeamMPVs, g_pVGuiLocalize->Find( "#Winpanel_TournamentMVPs" ), 1, pLocalizedTeamName ); if ( iWinningTeam != TEAM_UNASSIGNED ) { SetDialogVariable( "TopPlayersLabel", wzTeamMPVs ); } } else if ( ( iWinningTeam != TEAM_UNASSIGNED ) && ( iWinningTeam != TEAM_INVALID ) ) { g_pVGuiLocalize->ConstructString_safe( wzTeamWin, g_pVGuiLocalize->Find( pWinTeamLabel ), 2, pLocalizedTeamName, g_pVGuiLocalize->Find( "#Winpanel_Team1" ) ); } if ( ( iWinningTeam != TEAM_UNASSIGNED ) && ( iWinningTeam != TEAM_INVALID ) ) { pTeamLabel = wzTeamWin; } SetDialogVariable( bRoundComplete ? "WinningTeamLabel" : "AdvancingTeamLabel", pTeamLabel ); wchar_t wzWinReason[256] = L""; switch ( iWinReason ) { case WINREASON_ALL_POINTS_CAPTURED: { if ( TFGameRules() && ( TFGameRules()->GetGameType() == TF_GAMETYPE_ESCORT ) && ( TFGameRules()->HasMultipleTrains() == true ) && ( iRoundsRemaining == 0 ) ) { g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_PayloadRace" ), 1, pLocalizedTeamName ); } else { g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_AllPointsCaptured" ), 1, pLocalizedTeamName ); } } break; case WINREASON_FLAG_CAPTURE_LIMIT: { wchar_t wzFlagCaptureLimit[16]; _snwprintf( wzFlagCaptureLimit, ARRAYSIZE( wzFlagCaptureLimit), L"%i", iFlagCapLimit ); const wchar_t *wpszFormatString = NULL; if ( iFlagCapLimit == 1 ) { wpszFormatString = g_pVGuiLocalize->Find( "#Winreason_FlagCaptureLimit_One" ); } if ( !wpszFormatString ) { wpszFormatString = g_pVGuiLocalize->Find( "#Winreason_FlagCaptureLimit" ); } g_pVGuiLocalize->ConstructString_safe( wzWinReason, wpszFormatString, 2, pLocalizedTeamName, wzFlagCaptureLimit ); } break; case WINREASON_OPPONENTS_DEAD: g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_OpponentsDead" ), 1, pLocalizedTeamName ); break; case WINREASON_DEFEND_UNTIL_TIME_LIMIT: g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_DefendedUntilTimeLimit" ), 1, pLocalizedTeamName ); break; case WINREASON_STALEMATE: if ( !TFGameRules() || !TFGameRules()->IsCompetitiveMode() ) { g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_Stalemate" ), 0 ); } break; case WINREASON_TIMELIMIT: g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_TimeLimit" ), 1, pLocalizedTeamName ); break; case WINREASON_WINLIMIT: g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_WinLimit" ), 1, pLocalizedTeamName ); break; case WINREASON_WINDIFFLIMIT: g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_WinDiffLimit" ), 1, pLocalizedTeamName ); break; case WINREASON_RD_REACTOR_CAPTURED: g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_ReactorCaptured" ), 1, pLocalizedTeamName ); break; case WINREASON_RD_CORES_COLLECTED: g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_CoresCollected" ), 1, pLocalizedTeamName ); break; case WINREASON_RD_REACTOR_RETURNED: g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_ReactorReturned" ), 1, pLocalizedTeamName ); break; case WINREASON_PD_POINTS: g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_PlayerDestructionPoints" ), 1, pLocalizedTeamName ); break; case WINREASON_SCORED: { wchar_t wzScoreLimit[16]; _snwprintf( wzScoreLimit, ARRAYSIZE( wzScoreLimit ), L"%i", iFlagCapLimit ); const wchar_t *wpszFormatString = NULL; if ( iFlagCapLimit == 1 ) { wpszFormatString = g_pVGuiLocalize->Find( "#Winreason_ScoreLimit_One" ); } if ( !wpszFormatString ) { wpszFormatString = g_pVGuiLocalize->Find( "#Winreason_ScoreLimit" ); } g_pVGuiLocalize->ConstructString_safe( wzWinReason, wpszFormatString, 2, pLocalizedTeamName, wzScoreLimit ); } break; case WINREASON_STOPWATCH_WATCHING_ROUNDS: if ( pBlueTeam && pBlueTeamName && pRedTeamName ) { bool bBlueAttackers = ( pBlueTeam->GetRole() == TEAM_ROLE_ATTACKERS ); g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_Stopwatch_Watching_Rounds" ), 2, bBlueAttackers ? pBlueTeamName : pRedTeamName, bBlueAttackers ? pRedTeamName : pBlueTeamName ); } break; case WINREASON_STOPWATCH_WATCHING_FINAL_ROUND: if ( pBlueTeam && pBlueTeamName && pRedTeamName ) { bool bBlueAttackers = ( pBlueTeam->GetRole() == TEAM_ROLE_ATTACKERS ); g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_Stopwatch_SwitchSides" ), 2, bBlueAttackers ? pRedTeamName : pBlueTeamName, bBlueAttackers ? pBlueTeamName : pRedTeamName ); } break; case WINREASON_STOPWATCH_PLAYING_ROUNDS: if ( pBlueTeam && pBlueTeamName && pRedTeamName ) { bool bBlueAttackers = ( pBlueTeam->GetRole() == TEAM_ROLE_ATTACKERS ); g_pVGuiLocalize->ConstructString_safe( wzWinReason, g_pVGuiLocalize->Find( "#Winreason_Stopwatch_Playing_Rounds" ), 2, bBlueAttackers ? pBlueTeamName : pRedTeamName, bBlueAttackers ? pRedTeamName : pBlueTeamName ); } break; default: // This happens at the end of the Soldier training mission, FYI Assert( false ); break; } SetDialogVariable( "WinReasonLabel", wzWinReason ); if ( !bRoundComplete && ( WINREASON_STALEMATE != iWinReason ) && ( WINREASON_STOPWATCH_WATCHING_ROUNDS != iWinReason ) && ( WINREASON_STOPWATCH_WATCHING_FINAL_ROUND != iWinReason ) && ( WINREASON_STOPWATCH_PLAYING_ROUNDS != iWinReason ) ) { // if this was a mini-round, show # of capture points remaining wchar_t wzNumCapturesRemaining[16]; wchar_t wzCapturesRemainingMsg[256]=L""; _snwprintf( wzNumCapturesRemaining, ARRAYSIZE( wzNumCapturesRemaining ), L"%i", iRoundsRemaining ); g_pVGuiLocalize->ConstructString_safe( wzCapturesRemainingMsg, g_pVGuiLocalize->Find( 1 == iRoundsRemaining ? "#Winpanel_CapturePointRemaining" : "Winpanel_CapturePointsRemaining" ), 1, wzNumCapturesRemaining ); SetDialogVariable( "DetailsLabel", wzCapturesRemainingMsg ); } else if ( ( WINREASON_ALL_POINTS_CAPTURED == iWinReason ) || ( WINREASON_FLAG_CAPTURE_LIMIT == iWinReason ) ) { // if this was a full round that ended with point capture or flag capture, show the winning cappers const char *pCappers = event->GetString( "cappers" ); int iCappers = Q_strlen( pCappers ); if ( iCappers > 0 ) { char szPlayerNames[256]=""; wchar_t wzPlayerNames[256]=L""; wchar_t wzCapMsg[512]=L""; for ( int i = 0; i < iCappers; i++ ) { Q_strncat( szPlayerNames, g_PR->GetPlayerName( (int) pCappers[i] ), ARRAYSIZE( szPlayerNames ) ); if ( i < iCappers - 1 ) { Q_strncat( szPlayerNames, ", ", ARRAYSIZE( szPlayerNames ) ); } } g_pVGuiLocalize->ConvertANSIToUnicode( szPlayerNames, wzPlayerNames, sizeof( wzPlayerNames ) ); g_pVGuiLocalize->ConstructString_safe( wzCapMsg, g_pVGuiLocalize->Find( "#Winpanel_WinningCapture" ), 1, wzPlayerNames ); SetDialogVariable( "DetailsLabel", wzCapMsg ); } } // get the current & previous team scores int iBlueTeamPrevScore = event->GetInt( "blue_score_prev", 0 ); int iRedTeamPrevScore = event->GetInt( "red_score_prev", 0 ); m_iBlueTeamScore = event->GetInt( "blue_score", 0 ); m_iRedTeamScore = event->GetInt( "red_score", 0 ); if ( m_pTeamScorePanel ) { m_pTeamScorePanel->SetDialogVariable( "blueteamname", pBlueTeamName ); m_pTeamScorePanel->SetDialogVariable( "redteamname", pRedTeamName ); if ( bRoundComplete ) { // set the previous team scores in scoreboard m_pTeamScorePanel->SetDialogVariable( "blueteamscore", iBlueTeamPrevScore ); m_pTeamScorePanel->SetDialogVariable( "redteamscore", iRedTeamPrevScore ); if ( ( m_iBlueTeamScore != iBlueTeamPrevScore ) || ( m_iRedTeamScore != iRedTeamPrevScore ) ) { // if the new scores are different, set ourselves to update the scoreboard to the new values after a short delay, so players // see the scores tick up m_flTimeUpdateTeamScore = gpGlobals->curtime + 2.0f; } } // only show team scores if round is complete m_pTeamScorePanel->SetVisible( bRoundComplete ); } if ( !g_TF_PR ) return; // look for the top 3 players sent in the event for ( int i = 1; i <= 3; i++ ) { bool bShow = false; char szPlayerIndexVal[64]="", szPlayerScoreVal[64]=""; // get player index and round points from the event Q_snprintf( szPlayerIndexVal, ARRAYSIZE( szPlayerIndexVal ), "player_%d", i ); Q_snprintf( szPlayerScoreVal, ARRAYSIZE( szPlayerScoreVal ), "player_%d_points", i ); int iPlayerIndex = event->GetInt( szPlayerIndexVal, 0 ); int iRoundScore = event->GetInt( szPlayerScoreVal, 0 ); // round score of 0 means no player to show for that position (not enough players, or didn't score any points that round) if ( iRoundScore > 0 ) bShow = true; CAvatarImagePanel *pPlayerAvatar = dynamic_cast( FindChildByName( CFmtStr( "Player%dAvatar", i ) ) ); if ( pPlayerAvatar ) { pPlayerAvatar->SetShouldScaleImage( true ); pPlayerAvatar->SetShouldDrawFriendIcon( false ); if ( bShow ) { CBasePlayer *pPlayer = UTIL_PlayerByIndex( iPlayerIndex ); pPlayerAvatar->SetPlayer( pPlayer ); } pPlayerAvatar->SetVisible( bShow ); } CTFBadgePanel *pBadgePanel = dynamic_cast( FindChildByName( CFmtStr( "Player%dBadge", i ) ) ); if ( pBadgePanel ) { const IMatchGroupDescription *pMatchDesc = TFGameRules() ? GetMatchGroupDescription( TFGameRules()->GetCurrentMatchGroup() ) : NULL; const IProgressionDesc *pProgressionDesc = pMatchDesc ? pMatchDesc->m_pProgressionDesc : NULL; bool bVisible = ( pMatchDesc && pProgressionDesc ); if ( bVisible ) { if ( !bGameOver && TFGameRules()->IsMatchTypeCompetitive() ) { bVisible = false; } } if ( bVisible ) { const CSteamID steamID = GetSteamIDForPlayerIndex( iPlayerIndex ); if ( steamID.IsValid() ) { pBadgePanel->SetupBadge( pProgressionDesc, steamID ); } else { bVisible = false; } } if ( pBadgePanel->IsVisible() != bVisible ) { pBadgePanel->SetVisible( bVisible ); } } vgui::Label *pPlayerName = dynamic_cast