summaryrefslogtreecommitdiff
path: root/game/client/tf/tf_hud_tournament.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf/tf_hud_tournament.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/tf/tf_hud_tournament.cpp')
-rw-r--r--game/client/tf/tf_hud_tournament.cpp1566
1 files changed, 1566 insertions, 0 deletions
diff --git a/game/client/tf/tf_hud_tournament.cpp b/game/client/tf/tf_hud_tournament.cpp
new file mode 100644
index 0000000..43965a8
--- /dev/null
+++ b/game/client/tf/tf_hud_tournament.cpp
@@ -0,0 +1,1566 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================
+
+#include "cbase.h"
+#include "hud.h"
+#include "hudelement.h"
+#include "c_tf_player.h"
+#include "iclientmode.h"
+#include "ienginevgui.h"
+#include <vgui/ILocalize.h>
+#include <vgui/ISurface.h>
+#include <vgui/IVGui.h>
+#include <vgui_controls/Label.h>
+#include <vgui_controls/EditablePanel.h>
+#include "tf_imagepanel.h"
+#include "tf_gamerules.h"
+#include "c_tf_team.h"
+#include "vgui/tf_controls.h"
+#include <vgui_controls/TextEntry.h>
+#include "vgui_controls/AnimationController.h"
+#include "hud_basechat.h"
+#include "clientmode_shared.h"
+#include "c_playerresource.h"
+#include "c_tf_playerresource.h"
+#include "tf_hud_objectivestatus.h"
+#include "c_team_objectiveresource.h"
+#include "c_tf_team.h"
+#include "tf_clientscoreboard.h"
+#include "tf_playerpanel.h"
+#include "tf_hud_tournament.h"
+#include "c_tf_objective_resource.h"
+#include "tf_time_panel.h"
+#include "tf_hud_match_status.h"
+
+#include "tf_gc_client.h"
+#include "tf_lobby_server.h"
+
+#include "inputsystem/iinputsystem.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+void AddSubKeyNamed( KeyValues *pKeys, const char *pszName );
+
+using namespace vgui;
+
+#define TOURNAMENT_PANEL_UPDATE_INTERVAL 0.25f
+
+extern ConVar mp_timelimit;
+extern ConVar mp_winlimit;
+extern ConVar mp_maxrounds;
+extern ConVar mp_tournament;
+
+class CHudChat;
+
+DECLARE_HUDELEMENT( CHudTournament );
+
+static const wchar_t* GetSCGlyph( const char* action )
+{
+ auto origin = g_pInputSystem->GetSteamControllerActionOrigin( action, GAME_ACTION_SET_FPSCONTROLS );
+ return g_pInputSystem->GetSteamControllerFontCharacterForActionOrigin( origin );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHudTournament::CHudTournament( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudTournament" )
+{
+ Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ SetHiddenBits( HIDEHUD_MISCSTATUS );
+
+ vgui::ivgui()->AddTickSignal( GetVPanel(), 50 );
+
+ for ( int i = 0; i < MAX_TEAMS; i++ )
+ {
+ m_bTeamReady[i] = false;
+ }
+
+ m_bReadyStatusMode = false;
+ m_bCompetitiveMode = false;
+ m_bReadyTextBlinking = false;
+ m_bCountDownVisible = false;
+
+ m_pPlayerPanelKVs = NULL;
+ m_bReapplyPlayerPanelKVs = false;
+
+ m_pScoreboard = NULL;
+
+ m_pCountdownBG = new vgui::ScalableImagePanel( this, "CountdownBG" );
+ m_pCountdownLabel = new CExLabel( this, "CountdownLabel", L"" );
+ m_pCountdownLabelShadow = new CExLabel( this, "CountdownLabelShadow", L"" );
+ m_pModeImage = new vgui::ImagePanel( this, "ModeImage" );
+ m_pHudTournamentBG = new vgui::ScalableImagePanel( this, "HudTournamentBG" );
+ m_pTournamentConditionLabel = new CExLabel( this, "TournamentConditionLabel", L"" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHudTournament::~CHudTournament()
+{
+ if ( m_pPlayerPanelKVs )
+ {
+ m_pPlayerPanelKVs->deleteThis();
+ m_pPlayerPanelKVs = NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournament::Init( void )
+{
+ // listen for events
+ ListenForGameEvent( "tournament_stateupdate" );
+ ListenForGameEvent( "teams_changed" );
+ ListenForGameEvent( "localplayer_respawn" );
+ ListenForGameEvent( "restart_timer_time" );
+ ListenForGameEvent( "competitive_victory" );
+
+ m_bShouldBeVisible = false;
+ SetVisible( false );
+ CHudElement::Init();
+ m_flNextUpdate = gpGlobals->curtime;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournament::PlaySounds( int nTime )
+{
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+
+ if ( !pLocalPlayer )
+ return;
+
+ bool bCompetitiveMode = TFGameRules() && TFGameRules()->IsCompetitiveMode();
+
+ switch( nTime )
+ {
+ case 60:
+ {
+ if ( bCompetitiveMode )
+ {
+ pLocalPlayer->EmitSound( "Announcer.CompGame1Begins60Seconds" );
+ }
+ break;
+ }
+ case 30:
+ {
+ if ( bCompetitiveMode )
+ {
+ pLocalPlayer->EmitSound( "Announcer.CompGame1Begins30Seconds" );
+ }
+ break;
+ }
+ case 10:
+ {
+ if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
+ {
+ if ( TFObjectiveResource()->GetMannVsMachineWaveCount() >= TFObjectiveResource()->GetMannVsMachineMaxWaveCount() )
+ {
+ pLocalPlayer->EmitSound( "Announcer.MVM_Final_Wave_Start" );
+ }
+ else if ( TFObjectiveResource()->GetMannVsMachineWaveCount() <= 1 )
+ {
+ if ( GTFGCClientSystem()->GetLobby() && IsMannUpGroup( GTFGCClientSystem()->GetLobby()->GetMatchGroup() ) )
+ {
+ pLocalPlayer->EmitSound( "Announcer.MVM_Manned_Up" );
+ }
+ else
+ {
+ pLocalPlayer->EmitSound( "Announcer.MVM_First_Wave_Start" );
+ }
+ }
+ else
+ {
+ pLocalPlayer->EmitSound( "Announcer.MVM_Wave_Start" );
+ }
+ }
+ else
+ {
+ pLocalPlayer->EmitSound( bCompetitiveMode ? "Announcer.CompGame1Begins10Seconds" : "Announcer.RoundBegins10Seconds" );
+ }
+ break;
+ }
+ case 9:
+ {
+ if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
+ {
+ int nMaxWaves = TFObjectiveResource()->GetMannVsMachineMaxWaveCount();
+ int nCurWave = TFObjectiveResource()->GetMannVsMachineWaveCount();
+ bool bHasTank = false;
+ for ( int i = 0; i < MVM_CLASS_TYPES_PER_WAVE_MAX_NEW; ++i )
+ {
+ // int nClassCount = TFObjectiveResource()->GetMannVsMachineWaveClassCount( i );
+ const char *pchClassIconName = TFObjectiveResource()->GetMannVsMachineWaveClassName( i );
+ if( V_stristr( pchClassIconName, "tank" ))
+ {
+ bHasTank = true;
+ }
+ }
+ if( nCurWave == nMaxWaves )
+ {
+ pLocalPlayer->EmitSound( "music.mvm_start_last_wave" );
+ }
+ else if( bHasTank )
+ {
+ pLocalPlayer->EmitSound( "music.mvm_start_tank_wave" );
+ }
+ else if( nCurWave > ( nMaxWaves / 2 ) )
+ {
+ pLocalPlayer->EmitSound( "music.mvm_start_mid_wave" );
+ }
+ else
+ {
+ pLocalPlayer->EmitSound( "music.mvm_start_wave" );
+ }
+ }
+ break;
+ }
+ case 5:
+ {
+ pLocalPlayer->EmitSound( bCompetitiveMode ? "Announcer.CompGameBegins05Seconds" : "Announcer.RoundBegins5Seconds" );
+ break;
+ }
+ case 4:
+ {
+ pLocalPlayer->EmitSound( bCompetitiveMode ? "Announcer.CompGameBegins04Seconds" : "Announcer.RoundBegins4Seconds" );
+ break;
+ }
+ case 3:
+ {
+ pLocalPlayer->EmitSound( bCompetitiveMode ? "Announcer.CompGameBegins03Seconds" : "Announcer.RoundBegins3Seconds" );
+ break;
+ }
+ case 2:
+ {
+ pLocalPlayer->EmitSound( bCompetitiveMode ? "Announcer.CompGameBegins02Seconds" : "Announcer.RoundBegins2Seconds" );
+ break;
+ }
+ case 1:
+ {
+ pLocalPlayer->EmitSound( bCompetitiveMode ? "Announcer.CompGameBegins01Seconds" : "Announcer.RoundBegins1Seconds" );
+ break;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournament::PreparePanel( void )
+{
+ if ( m_flNextUpdate > gpGlobals->curtime )
+ return;
+
+ if ( !TFGameRules() )
+ return;
+
+ bool bSteamController = ::input->IsSteamControllerActive();
+ bool bShowReadyHintIcon = false;
+
+ if ( TFGameRules()->IsInPreMatch() )
+ {
+ bool bCountdownVisible = false;
+ bool bAutoReady = false;
+ const IMatchGroupDescription* pMatchDesc = GetMatchGroupDescription( TFGameRules()->GetCurrentMatchGroup() );
+ if ( pMatchDesc )
+ {
+ bAutoReady = pMatchDesc->m_params.m_bAutoReady;
+ }
+
+ if ( !bAutoReady && ( TFGameRules()->IsWaitingForTeams() || TFGameRules()->GetRoundRestartTime() < 0 ) )
+ {
+ if ( m_bReadyStatusMode )
+ {
+ const char *pszLabelText;
+ if ( TFGameRules() && TFGameRules()->PlayerReadyStatus_HaveMinPlayersToEnable() )
+ {
+ if ( bSteamController )
+ {
+ pszLabelText = "Tournament_Instructions_Ready_NoKeyHintText";
+ bShowReadyHintIcon = true;
+ }
+ else
+ {
+ pszLabelText = "Tournament_Instructions_Ready";
+ }
+ }
+ else
+ {
+ pszLabelText = "Tournament_Instructions_Waiting";
+ }
+
+ SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( pszLabelText ) );
+ SetDialogVariable( "tournamentstatelabel", g_pVGuiLocalize->Find( "Tournament_WaitingForTeam" ) );
+ SetPlayerPanelsVisible( true );
+ m_pModeImage->SetVisible( m_bCompetitiveMode );
+ }
+ else
+ {
+ SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( "Tournament_Instructions" ) );
+ SetDialogVariable( "tournamentstatelabel", g_pVGuiLocalize->Find( "Tournament_WaitingForTeams" ) );
+ SetPlayerPanelsVisible( false );
+ m_pModeImage->SetVisible( false );
+ }
+ }
+ else
+ {
+ float flTime = TFGameRules()->GetRoundRestartTime() - gpGlobals->curtime;
+ int nTime = (int)( ceil( flTime ) );
+
+ wchar szCountdown[64];
+ wchar_t wzVal[16];
+
+ const char *szCountDown = m_bReadyStatusMode ? "Tournament_CountDownTime" : "Tournament_Countdown";
+ const char *szCountDownSec = m_bReadyStatusMode ? "Tournament_CountDownTime" : "Tournament_Countdown_Sec";
+
+ swprintf( wzVal, ARRAYSIZE( wzVal ), L"%d", nTime );
+ wchar_t *pFormatString = g_pVGuiLocalize->Find( szCountDown );
+ if ( nTime == 1 )
+ {
+ pFormatString = g_pVGuiLocalize->Find( szCountDownSec );
+ }
+
+ if ( pFormatString )
+ {
+ g_pVGuiLocalize->ConstructString_safe( szCountdown, pFormatString, 1, wzVal );
+ SetDialogVariable( "tournamentstatelabel", szCountdown );
+ }
+
+ if ( bAutoReady )
+ {
+ SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( "" ) );
+ m_pModeImage->SetVisible( false );
+ SetPlayerPanelsVisible( false );
+ }
+ else if ( nTime <= TOURNAMENT_NOCANCEL_TIME )
+ {
+ SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( "" ) );
+ }
+ else
+ {
+ if ( m_bReadyStatusMode )
+ {
+ if ( bSteamController )
+ {
+ SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( "Tournament_Instructions_Ready_NoKeyHintText" ) );
+ bShowReadyHintIcon = true;
+ }
+ else
+ {
+ SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( "Tournament_Instructions_Ready" ) );
+ }
+ }
+ else
+ {
+ SetDialogVariable( "readylabel", g_pVGuiLocalize->Find( "" ) );
+ }
+ }
+
+ if ( m_bReadyStatusMode && nTime >= 0 )
+ {
+ bCountdownVisible = true;
+ }
+ }
+
+ // Show the Steam Controller hint icon if need be
+ auto pReadyHintIcon = dynamic_cast< CExLabel* >( FindChildByName( "TournamentReadyHintIcon" ) );
+ if ( pReadyHintIcon )
+ {
+ if ( bShowReadyHintIcon && !bAutoReady )
+ {
+ pReadyHintIcon->SetText( GetSCGlyph( "toggleready" ) );
+ pReadyHintIcon->SetVisible( true );
+ pReadyHintIcon->SetEnabled( true );
+ }
+ else
+ {
+ pReadyHintIcon->SetVisible( false );
+ pReadyHintIcon->SetEnabled( false );
+ }
+ }
+
+ if ( m_bCountDownVisible != bCountdownVisible )
+ {
+ m_bCountDownVisible = bCountdownVisible;
+
+ if ( m_bCountDownVisible )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence(this, m_bCompetitiveMode ? "HudTournament_ShowTimerCompetitive" : "HudTournament_ShowTimerDefault", false);
+ }
+ else
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence(this, "HudTournament_HideTimer", false);
+ }
+ }
+ }
+
+#ifdef WIN32
+#define STRING_FMT L"%s"
+#else
+#define STRING_FMT L"%S"
+#endif
+
+ C_TFTeam *pBlueTeam = GetGlobalTFTeam( TF_TEAM_BLUE );
+ SetDialogVariable( "bluenamelabel", pBlueTeam ? pBlueTeam->Get_Localized_Name() : L"BLU" );
+
+ C_TFTeam *pRedTeam = GetGlobalTFTeam( TF_TEAM_RED );
+ SetDialogVariable( "rednamelabel", pRedTeam ? pRedTeam->Get_Localized_Name() : L"RED" );
+
+ SetDialogVariable( "bluestate", TFGameRules()->IsTeamReady( TF_TEAM_BLUE ) ? g_pVGuiLocalize->Find( "Tournament_TeamReady" ) : g_pVGuiLocalize->Find( "Tournament_TeamNotReady" ) );
+ SetDialogVariable( "redstate", TFGameRules()->IsTeamReady( TF_TEAM_RED ) ? g_pVGuiLocalize->Find( "Tournament_TeamReady" ) : g_pVGuiLocalize->Find( "Tournament_TeamNotReady" ) );
+
+ if ( m_bTeamReady[TF_TEAM_BLUE] != TFGameRules()->IsTeamReady( TF_TEAM_BLUE ) || m_bTeamReady[TF_TEAM_RED] != TFGameRules()->IsTeamReady( TF_TEAM_RED ) )
+ {
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+
+ if ( pLocalPlayer )
+ {
+ pLocalPlayer->EmitSound( "Hud.Hint" );
+ }
+ }
+
+ m_bTeamReady[TF_TEAM_BLUE] = TFGameRules()->IsTeamReady( TF_TEAM_BLUE );
+ m_bTeamReady[TF_TEAM_RED] = TFGameRules()->IsTeamReady( TF_TEAM_RED );
+
+ wchar_t szWindConditions[1024];
+ _snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), STRING_FMT, g_pVGuiLocalize->Find( "Tournament_WinConditions" ) );
+
+ if ( mp_timelimit.GetInt() > 0 || mp_winlimit.GetInt() > 0 || mp_maxrounds.GetInt() )
+ {
+ bool bPrev = false;
+
+ if ( mp_timelimit.GetInt() > 0 )
+ {
+ _snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), STRING_FMT L"%d " STRING_FMT, szWindConditions, mp_timelimit.GetInt(), mp_timelimit.GetInt() == 1 ? g_pVGuiLocalize->Find( "Tournament_WinConditionsMinute" ) : g_pVGuiLocalize->Find( "Tournament_WinConditionsMinutes" ) );
+ bPrev = true;
+ }
+
+ if ( mp_winlimit.GetInt() > 0 )
+ {
+ if ( bPrev )
+ {
+#ifdef WIN32
+ _snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), L"%s, ", szWindConditions );
+#else
+ _snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), L"%S, ", szWindConditions );
+#endif
+ }
+
+ _snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), STRING_FMT L"%d " STRING_FMT, szWindConditions, mp_winlimit.GetInt(), mp_winlimit.GetInt() == 1 ? g_pVGuiLocalize->Find( "Tournament_WinConditionsWin" ) : g_pVGuiLocalize->Find( "Tournament_WinConditionsWins" ) );
+ bPrev = true;
+ }
+
+ if ( mp_maxrounds.GetInt() > 0 )
+ {
+ if ( bPrev )
+ {
+ _snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), STRING_FMT L", ", szWindConditions );
+ }
+
+ _snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), STRING_FMT L"%d " STRING_FMT, szWindConditions, mp_maxrounds.GetInt(), mp_maxrounds.GetInt() == 1 ? g_pVGuiLocalize->Find( "Tournament_WinConditionsRound" ) : g_pVGuiLocalize->Find( "Tournament_WinConditionsRounds" ) );
+ }
+ }
+ else
+ {
+ _snwprintf( szWindConditions, ARRAYSIZE( szWindConditions ), STRING_FMT STRING_FMT, szWindConditions, g_pVGuiLocalize->Find( "Tournament_WinConditionsNone" ) );
+ }
+
+ SetDialogVariable( "winconditions", szWindConditions );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournament::FireGameEvent( IGameEvent * event )
+{
+ const char *pEventName = event->GetName();
+ CBaseHudChat *pHUDChat = (CBaseHudChat *)GET_HUDELEMENT( CHudChat );
+
+ if ( Q_strcmp( "tournament_stateupdate", pEventName ) == 0 )
+ {
+ if ( !g_TF_PR )
+ return;
+
+ if ( !pHUDChat )
+ return;
+
+ wchar_t wszLocalized[100];
+
+ bool bNameChange = event->GetBool( "namechange" );
+ int iTeamState = event->GetInt( "readystate", -1 );
+ int iIndex = event->GetInt("userid");
+
+ const char *pszName = g_TF_PR->GetPlayerName( iIndex );
+
+ wchar_t wszPlayerName[MAX_PLAYER_NAME_LENGTH];
+ g_pVGuiLocalize->ConvertANSIToUnicode( pszName, wszPlayerName, sizeof(wszPlayerName) );
+
+ if ( bNameChange )
+ {
+ wchar_t wszTeam[16];
+ g_pVGuiLocalize->ConvertANSIToUnicode( event->GetString( "newname" ), wszTeam, sizeof(wszTeam) );
+
+ g_pVGuiLocalize->ConstructString_safe( wszLocalized, g_pVGuiLocalize->Find( "#Tournament_TeamName_Change" ), 2, wszPlayerName, wszTeam );
+ }
+ else
+ {
+ g_pVGuiLocalize->ConstructString_safe( wszLocalized, g_pVGuiLocalize->Find( "#Tournament_ReadyState_Change" ), 2, wszPlayerName, iTeamState == 1 ? g_pVGuiLocalize->Find( "#Tournament_TeamReady" ) : g_pVGuiLocalize->Find( "#Tournament_TeamNotReady" ) );
+ }
+
+ char szLocalized[100];
+ g_pVGuiLocalize->ConvertUnicodeToANSI( wszLocalized, szLocalized, sizeof(szLocalized) );
+
+ pHUDChat->ChatPrintf( iIndex, CHAT_FILTER_NONE, "%s ", szLocalized );
+ }
+ else if ( Q_strcmp( "localplayer_respawn", pEventName ) == 0 )
+ {
+ if ( m_bReadyStatusMode )
+ {
+ if ( m_bReadyTextBlinking )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudReadyPulse" );
+ }
+ }
+ }
+ else if ( FStrEq( "restart_timer_time", pEventName ) )
+ {
+ PlaySounds( event->GetInt( "time" ) );
+
+ if ( TFGameRules()->GetRoundsPlayed() == 0 && m_bCompetitiveMode )
+ {
+ if ( event->GetInt( "time" ) == 10 )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudTournament_MoveTimerDown", false );
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudTournament_MoveChatWindow", false );
+ }
+ }
+ }
+ else if ( FStrEq( "competitive_victory", pEventName ) )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudTournament_DoorsCloseEndRound", false );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CHudTournament::OnTick( void )
+{
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+
+ if ( !pLocalPlayer )
+ return;
+
+ if ( TFGameRules() )
+ {
+ if ( TFGameRules()->IsInTournamentMode() )
+ {
+ if ( TFGameRules()->IsInWaitingForPlayers() && TFGameRules()->State_Get() != GR_STATE_GAME_OVER )
+ {
+ m_bShouldBeVisible = true;
+ PreparePanel();
+
+ if ( !TFGameRules()->IsInArenaMode() )
+ {
+ if ( !pLocalPlayer->IsAlive() )
+ {
+ m_bShouldBeVisible = false;
+ }
+ }
+ }
+ else
+ {
+ m_bShouldBeVisible = false;
+ }
+
+ if ( TFGameRules()->UsePlayerReadyStatusMode() )
+ {
+ if ( !m_bReadyStatusMode )
+ {
+ m_bReadyStatusMode = true;
+ InvalidateLayout( false, true );
+ }
+ }
+ else if ( m_bReadyStatusMode )
+ {
+ m_bReadyStatusMode = false;
+ InvalidateLayout( false, true );
+ }
+
+ if ( TFGameRules()->IsCompetitiveMode() )
+ {
+ if ( !m_bCompetitiveMode )
+ {
+ m_bCompetitiveMode = true;
+ InvalidateLayout( false, true );
+ }
+ }
+ else if ( m_bCompetitiveMode )
+ {
+ m_bCompetitiveMode = false;
+ InvalidateLayout( false, true );
+ }
+ }
+ else
+ {
+ m_bShouldBeVisible = false;
+ }
+
+ if ( m_bReadyStatusMode )
+ {
+ const IMatchGroupDescription* pMatchDesc = GetMatchGroupDescription( TFGameRules()->GetCurrentMatchGroup() );
+ if ( !pMatchDesc || !pMatchDesc->m_params.m_bAutoReady )
+ {
+ RecalculatePlayerPanels();
+
+ // Ready text animation
+ if ( !TFGameRules()->IsPlayerReady( GetLocalPlayerIndex() ) && !m_bReadyTextBlinking )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudReadyPulse" );
+ m_bReadyTextBlinking = true;
+ }
+ else if ( TFGameRules()->IsPlayerReady( GetLocalPlayerIndex() ) && m_bReadyTextBlinking )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudReadyPulseEnd" );
+ m_bReadyTextBlinking = false;
+ }
+ }
+
+ if ( !m_pScoreboard.Get() && gViewPortInterface )
+ {
+ m_pScoreboard = (CTFClientScoreBoardDialog *)( gViewPortInterface->FindPanelByName( PANEL_SCOREBOARD ) );
+ }
+
+ if ( m_pScoreboard.Get() && m_pScoreboard->IsVisible() )
+ {
+ m_bShouldBeVisible = false;
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournament::LevelInit( void )
+{
+ m_bShouldBeVisible = false;
+ SetVisible( false );
+ Init();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournament::SetVisible( bool state )
+{
+ // we can only turn on tournament mode if we're in prematch
+ if ( state )
+ {
+ if ( m_bReadyStatusMode )
+ {
+ if ( m_bReadyTextBlinking )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudReadyPulse" );
+ }
+ }
+
+ if ( TeamplayRoundBasedRules() && !TeamplayRoundBasedRules()->IsInPreMatch() )
+ return;
+ }
+
+ BaseClass::SetVisible( state );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournament::ApplySchemeSettings( IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ m_bReapplyPlayerPanelKVs = true;
+
+ KeyValues *pConditions = NULL;
+ if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
+ {
+ pConditions = new KeyValues( "conditions" );
+ AddSubKeyNamed( pConditions, "if_mvm" );
+ }
+ else if ( m_bCompetitiveMode )
+ {
+ pConditions = new KeyValues( "conditions" );
+ AddSubKeyNamed( pConditions, "if_competitive" );
+ }
+ else if ( m_bReadyStatusMode )
+ {
+ pConditions = new KeyValues( "conditions" );
+ AddSubKeyNamed( pConditions, "if_readymode" );
+ }
+
+ // load control settings...
+ LoadControlSettings( "resource/UI/HudTournament.res", NULL, NULL, pConditions );
+
+ if ( pConditions )
+ {
+ pConditions->deleteThis();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournament::ApplySettings( KeyValues *inResourceData )
+{
+ BaseClass::ApplySettings( inResourceData );
+
+ KeyValues *pItemKV = inResourceData->FindKey( "playerpanels_kv" );
+ if ( pItemKV )
+ {
+ if ( m_pPlayerPanelKVs )
+ {
+ m_pPlayerPanelKVs->deleteThis();
+ }
+ m_pPlayerPanelKVs = new KeyValues("playerpanels_kv");
+ pItemKV->CopySubkeys( m_pPlayerPanelKVs );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournament::PerformLayout( void )
+{
+ BaseClass::PerformLayout();
+
+ if ( m_bReapplyPlayerPanelKVs )
+ {
+ m_bReapplyPlayerPanelKVs = false;
+
+ if ( m_pPlayerPanelKVs )
+ {
+ for ( int i = 0; i < m_PlayerPanels.Count(); i++ )
+ {
+ m_PlayerPanels[i]->ApplySettings( m_pPlayerPanelKVs );
+ m_PlayerPanels[i]->InvalidateLayout( false, true );
+ }
+ }
+ }
+
+ bool bShowTournamentConditions = !m_bCompetitiveMode && TFGameRules() && !TFGameRules()->IsMannVsMachineMode();
+
+ // Hide some elements when in competitive mode
+ if ( m_pTournamentConditionLabel )
+ {
+ m_pTournamentConditionLabel->SetVisible( bShowTournamentConditions );
+ }
+
+ Panel* pTournamentBG = FindChildByName( "HudTournamentBG" );
+ if ( pTournamentBG )
+ {
+ pTournamentBG->SetVisible( bShowTournamentConditions );
+ }
+
+ UpdatePlayerPanels();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournament::SetPlayerPanelsVisible( bool bVisible )
+{
+ for ( int i = 0; i < m_PlayerPanels.Count(); i++ )
+ {
+ if ( m_PlayerPanels[i] )
+ {
+ if ( m_PlayerPanels[i]->IsVisible() != bVisible )
+ {
+ m_PlayerPanels[i]->SetVisible( bVisible );
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Create a new panel if necessary
+//-----------------------------------------------------------------------------
+CTFPlayerPanel *CHudTournament::GetOrAddPanel( int iPanelIndex )
+{
+ if ( iPanelIndex < m_PlayerPanels.Count() )
+ {
+ return m_PlayerPanels[ iPanelIndex ];
+ }
+ Assert( iPanelIndex == m_PlayerPanels.Count() );
+ CTFPlayerPanel *pPanel = new CTFPlayerPanel( this, VarArgs("playerpanel%d", iPanelIndex) );
+ if ( m_pPlayerPanelKVs )
+ {
+ pPanel->ApplySettings( m_pPlayerPanelKVs );
+ pPanel->InvalidateLayout( false, true );
+ }
+ m_PlayerPanels.AddToTail( pPanel );
+ return pPanel;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Decide which players we will show
+//-----------------------------------------------------------------------------
+void CHudTournament::RecalculatePlayerPanels( void )
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer || !g_TF_PR )
+ return;
+
+ int iLocalTeam = g_TF_PR->GetTeam( pPlayer->entindex() );
+
+ int iPanel = 0;
+ for ( int i = 1; i <= MAX_PLAYERS; i++ )
+ {
+ if ( !g_TF_PR->IsConnected( i ) )
+ continue;
+
+ int iTeam = g_TF_PR->GetTeam( i );
+ if ( iTeam == TEAM_UNASSIGNED && !m_bReadyStatusMode )
+ continue;
+
+ // Spectators see all players, team members only see their team.
+ if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() && iTeam != iLocalTeam && iLocalTeam != TEAM_SPECTATOR )
+ continue;
+
+ if ( iTeam != TF_TEAM_RED && iTeam != TF_TEAM_BLUE )
+ continue;
+
+ // Add an entry for him
+ CTFPlayerPanel *pPanel = GetOrAddPanel( iPanel );
+ pPanel->SetPlayerIndex( i );
+ ++iPanel;
+ }
+
+ // Check if we have a lobby, then add in players that have a reservation in the lobby,
+ // but aren't in the game yet
+
+ // XXX(JohnS): Once eric's change to mirror the match info to playerresource is in, we should just trust that and
+ // not look at the lobby on our end. Eventually client lobbies shouldn't even have other members in
+ // them.
+ CTFGSLobby *pLobby = GTFGCClientSystem()->GetLobby();
+ if ( pLobby )
+ {
+ for ( int i = 0; i < pLobby->GetNumMembers(); ++i )
+ {
+ CSteamID steamID = pLobby->GetMember( i );
+
+ // Already have a panel for him?
+ bool bFound = false;
+ for ( int j = 0; j < iPanel; ++j )
+ {
+ if ( m_PlayerPanels[j]->GetSteamID() == steamID )
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if ( !bFound )
+ {
+ CTFPlayerPanel *pPanel = GetOrAddPanel( iPanel );
+ pPanel->Setup( 0, steamID, pLobby->GetMemberDetails( i )->name().c_str(), pLobby->GetMemberDetails( steamID )->team() );
+ ++iPanel;
+ }
+ }
+ }
+
+ // Clear out any extra panels
+ for ( int i = iPanel; i < m_PlayerPanels.Count(); i++ )
+ {
+ m_PlayerPanels[i]->SetPlayerIndex( 0 );
+ }
+
+ UpdatePlayerPanels();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournament::UpdatePlayerPanels( void )
+{
+ if ( !g_TF_PR )
+ return;
+
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( !pPlayer )
+ return;
+
+ if ( !TFGameRules() )
+ return;
+
+ // Hide panels for players when they're no longer able to stop the countdown
+ if ( TFGameRules()->GetRoundRestartTime() >= 0.f && TFGameRules()->GetRoundRestartTime() - gpGlobals->curtime <= TOURNAMENT_NOCANCEL_TIME )
+ {
+ SetPlayerPanelsVisible( false );
+ m_pModeImage->SetVisible( false );
+
+ return;
+ }
+
+ bool bNeedsPlayerLayout = false;
+ for ( int i = 0; i < m_PlayerPanels.Count(); i++ )
+ {
+ if ( m_PlayerPanels[i]->Update() )
+ {
+ bNeedsPlayerLayout = true;
+ }
+ }
+
+ if ( !bNeedsPlayerLayout || !TFGameRules() )
+ return;
+
+ // Try and always put the local player's team on team1, if he's in a team
+ int iTeam1 = TF_TEAM_BLUE;
+ int iTeam2 = TF_TEAM_RED;
+ int iLocalTeam = g_TF_PR->GetTeam( pPlayer->entindex() );
+ if ( ( iLocalTeam == TF_TEAM_RED || iLocalTeam == TF_TEAM_BLUE ) && !TFGameRules()->IsCompetitiveMode() ) // Blue always on left in comp
+ {
+ iTeam1 = iLocalTeam;
+ iTeam2 = ( iTeam1 == TF_TEAM_BLUE ) ? TF_TEAM_RED : TF_TEAM_BLUE;
+ }
+
+ int iTeam1Count = g_TF_PR->GetNumPlayersForTeam( iTeam1, false );
+ if ( GTFGCClientSystem()->GetLobby() )
+ {
+ // Everyone's on the same team in MvM, and any other lobby-based game is assumed to be two teams.
+ iTeam1Count = TFGameRules()->IsMannVsMachineMode() ?
+ GTFGCClientSystem()->GetLobby()->GetNumMembers() :
+ GTFGCClientSystem()->GetLobby()->GetNumMembers()>>1;
+ }
+ int iTeam1Processed = 0;
+ int iTeam2Processed = 0;
+ int iCenter = GetWide() * 0.5;
+
+ for ( int i = 0; i < m_PlayerPanels.Count(); i++ )
+ {
+ int iTeam = m_PlayerPanels[i]->GetTeam();
+
+ if ( !m_PlayerPanels[i]->GetPlayerIndex() && iTeam == TEAM_INVALID )
+ continue;
+
+ int iXPos = ( m_bCompetitiveMode ) ? -XRES( 30 ) : 0; // Hack to make space for the season image
+ int iYPos = ( m_iTeam1PlayerBaseY + m_iTeam1PlayerDeltaY );
+ int nOffset = ( m_bCompetitiveMode ) ? m_iTeamsPlayerDeltaXComp : m_iTeam2PlayerDeltaX;
+
+ if ( iTeam == iTeam1 )
+ {
+ // Two teams. First team left of center.
+ if ( m_bReadyStatusMode && !TFGameRules()->IsMannVsMachineMode() )
+ {
+ int iTeam1LeftCorner = iCenter - ( iTeam1Count * nOffset );
+ iXPos += ( iTeam1LeftCorner + ( iTeam1Processed * nOffset ) );
+ }
+ // One team. Centered.
+ else
+ {
+ int iTeam1LeftCorner = ( iCenter - ( iTeam1Count * nOffset ) * 0.5 );
+ iXPos += ( iTeam1LeftCorner + ( iTeam1Processed * nOffset ) );
+ }
+ m_PlayerPanels[i]->SetSpecIndex( 6 - iTeam1Processed );
+ ++iTeam1Processed;
+ }
+ else if ( iTeam == iTeam2 )
+ {
+ // Two teams. Second team right of center.
+ iXPos = ( iCenter + ( iTeam2Processed * nOffset ) );
+ iXPos += ( m_bCompetitiveMode ) ? XRES( 30 ) : 0; // Hack to make space for the season image
+ m_PlayerPanels[i]->SetSpecIndex( 7 + iTeam2Processed );
+ ++iTeam2Processed;
+ }
+
+ m_PlayerPanels[i]->SetPos( iXPos, iYPos );
+ }
+}
+
+DECLARE_HUDELEMENT( CHudTournamentSetup );
+
+bool TournamentHudElementKeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding )
+{
+ CHudTournamentSetup *pTournamentPanel = ( CHudTournamentSetup * )GET_HUDELEMENT( CHudTournamentSetup );
+
+ if ( pTournamentPanel && down == 1 )
+ {
+ return pTournamentPanel->ToggleState( keynum );
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHudTournamentSetup::CHudTournamentSetup( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudTournamentSetup" )
+{
+ Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ SetHiddenBits( HIDEHUD_MISCSTATUS );
+
+ vgui::ivgui()->AddTickSignal( GetVPanel(), 100 );
+
+ m_pNameEntry = new TextEntry(this, "TournamentNameEdit" );
+ m_pEntryBG = new CTFImagePanel(this, "HudTournamentNameBG" );
+ m_pReadyButton = new CExButton(this, "TournamentReadyButton", "" );
+ m_pNotReadyButton = new CExButton(this, "TournamentNotReadyButton", "" );
+
+ m_pTeamNameLabel = NULL;
+ m_flNextThink = gpGlobals->curtime;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournamentSetup::Init( void )
+{
+ SetVisible( false );
+ CHudElement::Init();
+
+ DisableInput();
+
+ m_pNameEntry->SetText( g_pVGuiLocalize->Find( "Tournament_TeamNameNotSet" ) );
+
+ m_flNextThink = gpGlobals->curtime;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournamentSetup::OnCommand( const char *command )
+{
+ if ( !Q_strcmp( command, "teamready" ) )
+ {
+ char szText[64];
+ m_pNameEntry->GetText( szText, sizeof( szText ) );
+
+ char szTeamName[64];
+ Q_snprintf ( szTeamName, sizeof( szTeamName ), "tournament_teamname %s", szText );
+ engine->ClientCmd_Unrestricted( szTeamName );
+
+ engine->ClientCmd_Unrestricted( "tournament_readystate 1" );
+ DisableInput();
+ }
+ else if ( !Q_strcmp( command, "teamnotready" ) )
+ {
+ engine->ClientCmd_Unrestricted( "tournament_readystate 0" );
+ DisableInput();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CHudTournamentSetup::ToggleState( ButtonCode_t code )
+{
+ if ( !IsVisible() )
+ return false;
+
+ if ( !g_TF_PR )
+ return false;
+
+ if ( code == KEY_F4 || code == STEAMCONTROLLER_F4 )
+ {
+ if ( TFGameRules() && TFGameRules()->UsePlayerReadyStatusMode() )
+ {
+ int nReady = ( TFGameRules()->IsPlayerReady( GetLocalPlayerIndex() ) ) ? 0 : 1;
+ char szCommand[64];
+ Q_snprintf( szCommand, sizeof( szCommand ), "tournament_player_readystate %d", nReady );
+ engine->ClientCmd_Unrestricted( szCommand );
+ }
+ else
+ {
+ if ( IsMouseInputEnabled() )
+ {
+ DisableInput();
+ return true;
+ }
+ else
+ {
+ EnableInput();
+ return true;
+ }
+ }
+ }
+
+ if ( IsMouseInputEnabled() )
+ {
+ if ( code == KEY_ESCAPE || code == KEY_ENTER )
+ {
+ if ( code == KEY_ENTER )
+ {
+ char szText[64];
+ m_pNameEntry->GetText( szText, sizeof( szText ) );
+
+ char szTeamName[64];
+ Q_snprintf ( szTeamName, sizeof( szTeamName ), "tournament_teamname %s", szText );
+ engine->ClientCmd_Unrestricted( szTeamName );
+
+ m_flNextThink = gpGlobals->curtime + TOURNAMENT_PANEL_UPDATE_INTERVAL;
+ }
+
+ DisableInput();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournamentSetup::FireGameEvent( IGameEvent * event )
+{
+ const char *pEventName = event->GetName();
+
+ if ( Q_strcmp( "tournament_stateupdate", pEventName ) == 0 )
+ {
+ if ( TFGameRules()->IsInTournamentMode() && TFGameRules()->IsInWaitingForPlayers() )
+ {
+ m_flNextThink = gpGlobals->curtime;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CHudTournamentSetup::OnTick( void )
+{
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+ if ( !pLocalPlayer )
+ return;
+
+ if ( !g_TF_PR )
+ return;
+
+ int iLocalTeam = g_TF_PR->GetTeam( pLocalPlayer->entindex() );
+ if ( iLocalTeam <= LAST_SHARED_TEAM || TFGameRules()->State_Get() == GR_STATE_GAME_OVER )
+ {
+ SetVisible( false );
+ return;
+ }
+
+ if ( TFGameRules() )
+ {
+ if ( TFGameRules()->UsePlayerReadyStatusMode() )
+ {
+ if ( TFGameRules()->IsInTournamentMode() && TFGameRules()->IsInWaitingForPlayers() )
+ {
+ if ( !IsVisible() )
+ {
+ SetVisible( true );
+ }
+ SetPos( 0, YRES( -100 ) ); // make sure the panel is WAY off the screen for MvM mode
+ }
+ else
+ {
+ if ( IsVisible() )
+ {
+ SetVisible( false );
+ }
+ }
+ }
+ else if ( TFGameRules()->IsInTournamentMode() && TFGameRules()->IsInWaitingForPlayers() )
+ {
+ if ( !IsVisible() )
+ {
+ SetVisible( true );
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudTournamentSetupPanelClose" );
+ }
+ }
+ else
+ {
+ if ( IsVisible() )
+ {
+ SetVisible( false );
+ }
+ }
+ }
+
+ if ( m_flNextThink <= gpGlobals->curtime )
+ {
+ if ( !IsMouseInputEnabled() )
+ {
+ m_pNameEntry->SetText( ( iLocalTeam == TF_TEAM_BLUE ) ? mp_tournament_blueteamname.GetString() : mp_tournament_redteamname.GetString() );
+ }
+
+ SetDialogVariable( "tournamentstatelabel", TFGameRules()->IsTeamReady( iLocalTeam ) ? g_pVGuiLocalize->Find( "Tournament_TeamSetupReady" ) : g_pVGuiLocalize->Find( "Tournament_TeamSetupNotReady" ) );
+
+ m_flNextThink = gpGlobals->curtime + TOURNAMENT_PANEL_UPDATE_INTERVAL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournamentSetup::EnableInput( void )
+{
+ SetVisible( true );
+ vgui::SETUP_PANEL( this );
+ SetKeyBoardInputEnabled( true );
+ SetMouseInputEnabled( true );
+ m_pNameEntry->SetVisible( true );
+ vgui::surface()->CalculateMouseVisible();
+ m_pNameEntry->RequestFocus();
+ m_pNameEntry->SetPaintBorderEnabled( true );
+ m_pNameEntry->SetMouseInputEnabled( true );
+ m_pNameEntry->SetKeyBoardInputEnabled( true );
+ MakePopup();
+
+ m_pEntryBG->SetVisible( true );
+ m_pReadyButton->SetVisible( true );
+ m_pReadyButton->SetMouseInputEnabled( true );
+ m_pNotReadyButton->SetVisible( true );
+ m_pNotReadyButton->SetMouseInputEnabled( true );
+
+ m_pTeamNameLabel->SetVisible( true );
+
+ engine->ClientCmd_Unrestricted( "gameui_preventescapetoshow\n" );
+
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudTournamentSetupPanelOpen" );
+}
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournamentSetup::DisableInput( void )
+{
+ SetKeyBoardInputEnabled( false );
+ SetMouseInputEnabled( false );
+
+ m_pNameEntry->SetMouseInputEnabled( false );
+ m_pNameEntry->SetKeyBoardInputEnabled( false );
+
+ engine->ClientCmd_Unrestricted( "gameui_allowescapetoshow\n" );
+
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudTournamentSetupPanelClose" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournamentSetup::LevelInit( void )
+{
+ SetVisible( false );
+ Init();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CHudTournamentSetup::ShouldDraw( void )
+{
+ return ( IsVisible() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudTournamentSetup::ApplySchemeSettings( IScheme *pScheme )
+{
+ // load control settings...
+ LoadControlSettings( "resource/UI/HudTournamentSetup.res" );
+
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ m_pNameEntry->SetFont( pScheme->GetFont( "HudFontSmallest", IsProportional() ) );
+ m_pTeamNameLabel = dynamic_cast<Label *>( FindChildByName( "TournamentTeamNameLabel" ) );
+}
+
+
+DECLARE_HUDELEMENT( CHudStopWatch );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHudStopWatch::CHudStopWatch( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudStopWatch" )
+{
+ Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ SetHiddenBits( HIDEHUD_MISCSTATUS );
+
+ m_bShouldBeVisible = false;
+ vgui::ivgui()->AddTickSignal( GetVPanel(), 100 );
+
+ m_pTimePanel = new CTFHudTimeStatus( this, "ObjectiveStatusTimePanel" );
+ m_pStopWatchLabel = new CExLabel( this, "StopWatchLabel", "" );
+ m_pStopWatchScore = new CExLabel( this, "StopWatchScoreToBeat", "" );
+ m_pStopWatchPointsLabel = new CExLabel( this, "StopWatchPointsLabel", "" );
+ m_pStopWatchImage = new ImagePanel( this, "StopWatchImageCaptureTime" );
+ m_pStopWatchDescriptionLabel = new CExLabel( this, "StopWatchDescriptionLabel", "" );
+
+ ListenForGameEvent( "competitive_state_changed" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CHudStopWatch::ShouldDraw( void )
+{
+ bool bRetVal = m_bShouldBeVisible;
+ if ( bRetVal )
+ {
+ // give the HUD a chance to turn us off when we should be hidden
+ bRetVal = CHudElement::ShouldDraw();
+ }
+
+ return bRetVal;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudStopWatch::LevelInit( void )
+{
+ m_bShouldBeVisible = true;
+
+ if ( m_pTimePanel )
+ {
+ m_pTimePanel->SetVisible( true );
+ m_pTimePanel->Reset();
+ }
+
+ m_pStopWatchLabel->SetVisible( false );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudStopWatch::ApplySchemeSettings( IScheme *pScheme )
+{
+ KeyValues *pConditions = NULL;
+ if ( ShouldUseMatchHUD() )
+ {
+ pConditions = new KeyValues( "conditions" );
+ AddSubKeyNamed( pConditions, "if_comp" );
+ }
+
+ // load control settings...
+ LoadControlSettings( "resource/UI/HudStopWatch.res", NULL, NULL, pConditions );
+
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ m_pStopWatchDescriptionBG = FindChildByName( "HudStopWatchDescriptionBG" );
+
+ if ( pConditions )
+ {
+ pConditions->deleteThis();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudStopWatch::OnTick( void )
+{
+ BaseClass::OnTick();
+
+ if ( !TFGameRules() )
+ return;
+
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+
+ if ( !pPlayer )
+ return;
+
+ bool bInFreezeCam = ( pPlayer && pPlayer->GetObserverMode() == OBS_MODE_FREEZECAM );
+
+ bool bProperMatch = TFGameRules()->IsInTournamentMode() || TFGameRules()->IsCompetitiveMode();
+ if ( !bProperMatch || TFGameRules()->IsInPreMatch() || !TFGameRules()->IsInStopWatch() || bInFreezeCam || TFGameRules()->State_Get() == GR_STATE_GAME_OVER )
+ {
+ m_bShouldBeVisible = false;
+ return;
+ }
+ else
+ {
+ m_bShouldBeVisible = true;
+ }
+
+ if ( m_pTimePanel && ObjectiveResource() )
+ {
+ int iActiveTimer = ObjectiveResource()->GetStopWatchTimer();
+ m_pTimePanel->SetTimerIndex( iActiveTimer );
+
+ C_TFTeam *pAttacker = NULL;
+ C_TFTeam *pDefender = NULL;
+
+ for ( int i = LAST_SHARED_TEAM+1; i < GetNumberOfTeams(); i++ )
+ {
+ C_TFTeam *pTeam = GetGlobalTFTeam( i );
+
+ if ( pTeam )
+ {
+ if ( pTeam->GetRole() == TEAM_ROLE_DEFENDERS )
+ {
+ pDefender = pTeam;
+ }
+
+ if ( pTeam->GetRole() == TEAM_ROLE_ATTACKERS )
+ {
+ pAttacker = pTeam;
+ }
+ }
+ }
+
+ if ( !pAttacker || !pDefender )
+ return;
+
+ if ( TFGameRules()->GetStopWatchState() == STOPWATCH_CAPTURE_TIME_NOT_SET )
+ {
+ m_pTimePanel->SetVisible( false );
+ m_pStopWatchLabel->SetVisible( true );
+ m_pStopWatchScore->SetVisible( false );
+ m_pStopWatchPointsLabel->SetVisible( false );
+ m_pStopWatchDescriptionBG->SetVisible( false );
+ m_pStopWatchDescriptionLabel->SetVisible( false );
+
+ m_pStopWatchImage->SetImage( "../hud/ico_time_none" );
+
+ SetDialogVariable( "stopwatchlabel", g_pVGuiLocalize->Find( "Tournament_StopWatchNoCap" ) );
+ }
+ else if ( TFGameRules()->GetStopWatchState() == STOPWATCH_RUNNING )
+ {
+ m_pTimePanel->SetVisible( true );
+ m_pStopWatchLabel->SetVisible( false );
+ m_pStopWatchScore->SetVisible( true );
+ m_pStopWatchPointsLabel->SetVisible( true );
+
+ m_pStopWatchImage->SetImage( "../hud/ico_time_10" );
+
+ CTeamRoundTimer *pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( iActiveTimer ) );
+
+ int iPoints = 0;
+
+ if ( pTimer )
+ {
+ if ( pTimer->IsWatchingTimeStamps() )
+ {
+ iPoints = pAttacker->Get_Score();
+ }
+ else
+ {
+ iPoints = pDefender->Get_Score() - pAttacker->Get_Score();
+ }
+ }
+
+ wchar_t wzScoreVal[128];
+ static wchar_t wzScore[128];
+ wchar_t *pszPoints = NULL;
+ _snwprintf( wzScoreVal, ARRAYSIZE( wzScoreVal ), L"%i", iPoints );
+
+ if ( 1 == iPoints )
+ {
+ pszPoints = g_pVGuiLocalize->Find( "#Tournament_StopWatch_Point" );
+ }
+ else
+ {
+ pszPoints = g_pVGuiLocalize->Find( "#Tournament_StopWatch_Points" );
+ }
+
+ SetDialogVariable( "pointslabel", pszPoints );
+ SetDialogVariable( "scoretobeat", wzScoreVal );
+
+ wchar_t wzHelp[128];
+
+ if ( pPlayer->GetTeam() == pAttacker )
+ {
+ g_pVGuiLocalize->ConstructString_safe( wzHelp, g_pVGuiLocalize->Find( "Tournament_StopWatch_TimeVictory" ), 1, pDefender->Get_Localized_Name() );
+ }
+ else
+ {
+ g_pVGuiLocalize->ConstructString_safe( wzHelp, g_pVGuiLocalize->Find( "Tournament_StopWatch_TimeVictoryDefender" ), 1, pDefender->Get_Localized_Name() );
+ }
+
+ SetDialogVariable( "descriptionlabel", wzHelp );
+
+ if ( pTimer && !pTimer->IsWatchingTimeStamps() )
+ {
+ m_pStopWatchDescriptionBG->SetVisible( true );
+ m_pStopWatchDescriptionLabel->SetVisible( true );
+ }
+ else
+ {
+ m_pStopWatchDescriptionBG->SetVisible( false );
+ m_pStopWatchDescriptionLabel->SetVisible( false );
+ }
+ }
+ else if ( TFGameRules()->GetStopWatchState() == STOPWATCH_OVERTIME )
+ {
+ m_pTimePanel->SetVisible( false );
+ m_pStopWatchLabel->SetVisible( true );
+ m_pStopWatchScore->SetVisible( false );
+ m_pStopWatchPointsLabel->SetVisible( false );
+
+ m_pStopWatchDescriptionBG->SetVisible( false );
+ m_pStopWatchDescriptionLabel->SetVisible( false );
+
+ SetDialogVariable( "descriptionlabel", g_pVGuiLocalize->Find( "#Tournament_StopWatch_CapVictory" ) );
+
+ m_pStopWatchImage->SetImage( "../hud/ico_time_60" );
+
+ wchar_t wzScoreVal[128];
+
+ int iPoints = (pDefender->Get_Score() - pAttacker->Get_Score()) + 1;
+ wchar_t wzVal[16];
+
+ swprintf( wzVal, ARRAYSIZE( wzVal ), L"%x", iPoints );
+
+ if ( pPlayer->GetTeam() == pAttacker )
+ {
+ g_pVGuiLocalize->ConstructString_safe( wzScoreVal, g_pVGuiLocalize->Find( "Tournament_StopWatchPointCaptureAttacker" ), 2, wzVal, iPoints == 1 ? g_pVGuiLocalize->Find( "#Tournament_StopWatch_Point" ) : g_pVGuiLocalize->Find( "#Tournament_StopWatch_Points" ) );
+ }
+ else if ( pPlayer->GetTeam() == pDefender )
+ {
+ g_pVGuiLocalize->ConstructString_safe( wzScoreVal, g_pVGuiLocalize->Find( "Tournament_StopWatchPointCaptureDefender" ), 2, wzVal, iPoints == 1 ? g_pVGuiLocalize->Find( "#Tournament_StopWatch_Point" ) : g_pVGuiLocalize->Find( "#Tournament_StopWatch_Points" ) );
+ }
+ else
+ {
+ g_pVGuiLocalize->ConstructString_safe( wzScoreVal, g_pVGuiLocalize->Find( "Tournament_StopWatchPointCaptureSpectator" ), 2, wzVal, iPoints == 1 ? g_pVGuiLocalize->Find( "#Tournament_StopWatch_Point" ) : g_pVGuiLocalize->Find( "#Tournament_StopWatch_Points" ) );
+ }
+
+ SetDialogVariable( "stopwatchlabel", wzScoreVal );
+ }
+ }
+}
+
+void CHudStopWatch::FireGameEvent( IGameEvent * event )
+{
+ if ( FStrEq( event->GetName(), "competitive_state_changed" ) )
+ {
+ InvalidateLayout( false, true );
+ return;
+ }
+
+ CHudElement::FireGameEvent( event );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CON_COMMAND( player_ready_toggle, "Toggle player ready state" )
+{
+ C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer();
+ if ( pPlayer )
+ {
+ CHudTournamentSetup *pTournamentPanel = dynamic_cast< CHudTournamentSetup* >( GET_HUDELEMENT( CHudTournamentSetup ) );
+ if ( pTournamentPanel )
+ {
+ pTournamentPanel->ToggleState( KEY_F4 );
+ }
+ }
+}