aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/shared/teamplay_round_timer.cpp
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/shared/teamplay_round_timer.cpp
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/shared/teamplay_round_timer.cpp')
-rw-r--r--mp/src/game/shared/teamplay_round_timer.cpp1429
1 files changed, 1429 insertions, 0 deletions
diff --git a/mp/src/game/shared/teamplay_round_timer.cpp b/mp/src/game/shared/teamplay_round_timer.cpp
new file mode 100644
index 00000000..72a324e8
--- /dev/null
+++ b/mp/src/game/shared/teamplay_round_timer.cpp
@@ -0,0 +1,1429 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Team gamerules round timer
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "teamplay_round_timer.h"
+#include "teamplayroundbased_gamerules.h"
+
+#ifdef CLIENT_DLL
+#include "iclientmode.h"
+#include "vgui_controls/AnimationController.h"
+#include "c_playerresource.h"
+#include "c_team_objectiveresource.h"
+#if defined( TF_CLIENT_DLL )
+#include "tf_gamerules.h"
+#include "c_tf_player.h"
+#endif // TF_CLIENT_DLL
+#else
+#include "team.h"
+#include "team_objectiveresource.h"
+#if defined( TF_DLL )
+#include "tf_player.h"
+#endif // TF_DLL
+#endif
+
+#define ROUND_TIMER_60SECS "Announcer.RoundEnds60seconds"
+#define ROUND_TIMER_30SECS "Announcer.RoundEnds30seconds"
+#define ROUND_TIMER_10SECS "Announcer.RoundEnds10seconds"
+#define ROUND_TIMER_5SECS "Announcer.RoundEnds5seconds"
+#define ROUND_TIMER_4SECS "Announcer.RoundEnds4seconds"
+#define ROUND_TIMER_3SECS "Announcer.RoundEnds3seconds"
+#define ROUND_TIMER_2SECS "Announcer.RoundEnds2seconds"
+#define ROUND_TIMER_1SECS "Announcer.RoundEnds1seconds"
+
+#define ROUND_SETUP_60SECS "Announcer.RoundBegins60Seconds"
+#define ROUND_SETUP_30SECS "Announcer.RoundBegins30Seconds"
+#define ROUND_SETUP_10SECS "Announcer.RoundBegins10Seconds"
+#define ROUND_SETUP_5SECS "Announcer.RoundBegins5Seconds"
+#define ROUND_SETUP_4SECS "Announcer.RoundBegins4Seconds"
+#define ROUND_SETUP_3SECS "Announcer.RoundBegins3Seconds"
+#define ROUND_SETUP_2SECS "Announcer.RoundBegins2Seconds"
+#define ROUND_SETUP_1SECS "Announcer.RoundBegins1Seconds"
+
+#define ROUND_START_BELL "Ambient.Siren"
+
+#define ROUND_TIMER_TIME_ADDED "Announcer.TimeAdded"
+#define ROUND_TIMER_TIME_ADDED_LOSER "Announcer.TimeAddedForEnemy"
+#define ROUND_TIMER_TIME_ADDED_WINNER "Announcer.TimeAwardedForTeam"
+
+enum
+{
+ RT_THINK_SETUP,
+ RT_THINK_NORMAL,
+};
+
+enum
+{
+ RT_WARNING_60SECS,
+ RT_WARNING_30SECS,
+ RT_WARNING_10SECS,
+ RT_WARNING_5SECS,
+ RT_WARNING_4SECS,
+ RT_WARNING_3SECS,
+ RT_WARNING_2SECS,
+ RT_WARNING_1SECS,
+ RT_WARNING_TIME_START,
+};
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+extern bool IsInCommentaryMode();
+
+#if defined( GAME_DLL ) && defined( TF_DLL )
+ConVar tf_overtime_nag( "tf_overtime_nag", "0", FCVAR_NOTIFY, "Announcer overtime nag." );
+#endif
+
+#ifdef CLIENT_DLL
+
+// Use this proxy to flash the round timer whenever the timer is restarted
+// because trapping the round start event doesn't work ( the event also flushes
+// all hud events and obliterates our TimerFlash event )
+static void RecvProxy_TimerPaused( const CRecvProxyData *pData, void *pStruct, void *pOut )
+{
+ CTeamRoundTimer *pTimer = (CTeamRoundTimer *) pStruct;
+
+ bool bTimerPaused = ( pData->m_Value.m_Int > 0 );
+
+ if ( bTimerPaused == false )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "TimerFlash" );
+ }
+
+ if ( pTimer )
+ {
+ pTimer->InternalSetPaused( bTimerPaused );
+ }
+}
+
+#endif
+
+LINK_ENTITY_TO_CLASS( team_round_timer, CTeamRoundTimer );
+PRECACHE_REGISTER( team_round_timer );
+
+IMPLEMENT_NETWORKCLASS_ALIASED( TeamRoundTimer, DT_TeamRoundTimer )
+
+BEGIN_NETWORK_TABLE_NOBASE( CTeamRoundTimer, DT_TeamRoundTimer )
+#ifdef CLIENT_DLL
+
+ RecvPropInt( RECVINFO( m_bTimerPaused ), 0, RecvProxy_TimerPaused ),
+ RecvPropTime( RECVINFO( m_flTimeRemaining ) ),
+ RecvPropTime( RECVINFO( m_flTimerEndTime ) ),
+ RecvPropInt( RECVINFO( m_nTimerMaxLength ) ),
+ RecvPropBool( RECVINFO( m_bIsDisabled ) ),
+ RecvPropBool( RECVINFO( m_bShowInHUD ) ),
+ RecvPropInt( RECVINFO( m_nTimerLength ) ),
+ RecvPropInt( RECVINFO( m_nTimerInitialLength ) ),
+ RecvPropBool( RECVINFO( m_bAutoCountdown ) ),
+ RecvPropInt( RECVINFO( m_nSetupTimeLength ) ),
+ RecvPropInt( RECVINFO( m_nState ) ),
+ RecvPropBool( RECVINFO( m_bStartPaused ) ),
+ RecvPropBool( RECVINFO( m_bShowTimeRemaining ) ),
+ RecvPropBool( RECVINFO( m_bInCaptureWatchState ) ),
+ RecvPropBool( RECVINFO( m_bStopWatchTimer ) ),
+ RecvPropTime( RECVINFO( m_flTotalTime ) ),
+
+#else
+
+ SendPropBool( SENDINFO( m_bTimerPaused ) ),
+ SendPropTime( SENDINFO( m_flTimeRemaining ) ),
+ SendPropTime( SENDINFO( m_flTimerEndTime ) ),
+ SendPropInt( SENDINFO( m_nTimerMaxLength ) ),
+ SendPropBool( SENDINFO( m_bIsDisabled ) ),
+ SendPropBool( SENDINFO( m_bShowInHUD ) ),
+ SendPropInt( SENDINFO( m_nTimerLength ) ),
+ SendPropInt( SENDINFO( m_nTimerInitialLength ) ),
+ SendPropBool( SENDINFO( m_bAutoCountdown ) ),
+ SendPropInt( SENDINFO( m_nSetupTimeLength ) ),
+ SendPropInt( SENDINFO( m_nState ) ),
+ SendPropBool( SENDINFO( m_bStartPaused ) ),
+ SendPropBool( SENDINFO( m_bShowTimeRemaining ) ),
+ SendPropBool( SENDINFO( m_bStopWatchTimer ) ),
+ SendPropBool( SENDINFO( m_bInCaptureWatchState ) ),
+ SendPropTime( SENDINFO( m_flTotalTime ) ),
+
+#endif
+END_NETWORK_TABLE()
+
+#ifndef CLIENT_DLL
+BEGIN_DATADESC(CTeamRoundTimer)
+ DEFINE_KEYFIELD( m_nTimerInitialLength, FIELD_INTEGER, "timer_length" ),
+ DEFINE_KEYFIELD( m_nTimerMaxLength, FIELD_INTEGER, "max_length" ),
+ DEFINE_KEYFIELD( m_bShowInHUD, FIELD_BOOLEAN, "show_in_hud" ),
+ DEFINE_KEYFIELD( m_bIsDisabled, FIELD_BOOLEAN, "StartDisabled" ),
+ DEFINE_KEYFIELD( m_bAutoCountdown, FIELD_BOOLEAN, "auto_countdown" ),
+ DEFINE_KEYFIELD( m_nSetupTimeLength, FIELD_INTEGER, "setup_length" ),
+ DEFINE_KEYFIELD( m_bResetTimeOnRoundStart, FIELD_BOOLEAN, "reset_time" ),
+ DEFINE_KEYFIELD( m_bStartPaused, FIELD_BOOLEAN, "start_paused" ),
+ DEFINE_KEYFIELD( m_bShowTimeRemaining, FIELD_BOOLEAN, "show_time_remaining" ),
+
+ DEFINE_FUNCTION( RoundTimerSetupThink ),
+ DEFINE_FUNCTION( RoundTimerThink ),
+
+ DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "Pause", InputPause ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "Resume", InputResume ),
+ DEFINE_INPUTFUNC( FIELD_INTEGER, "SetTime", InputSetTime ),
+ DEFINE_INPUTFUNC( FIELD_INTEGER, "AddTime", InputAddTime ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "Restart", InputRestart ),
+ DEFINE_INPUTFUNC( FIELD_INTEGER, "ShowInHUD", InputShowInHUD ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "RoundSpawn", InputRoundSpawn ),
+ DEFINE_INPUTFUNC( FIELD_INTEGER, "SetMaxTime", InputSetMaxTime ),
+ DEFINE_INPUTFUNC( FIELD_INTEGER, "AutoCountdown", InputAutoCountdown ),
+ DEFINE_INPUTFUNC( FIELD_STRING, "AddTeamTime", InputAddTeamTime ),
+ DEFINE_INPUTFUNC( FIELD_INTEGER, "SetSetupTime", InputSetSetupTime ),
+
+ DEFINE_OUTPUT( m_OnRoundStart, "OnRoundStart" ),
+ DEFINE_OUTPUT( m_OnFinished, "OnFinished" ),
+ DEFINE_OUTPUT( m_On5MinRemain, "On5MinRemain" ),
+ DEFINE_OUTPUT( m_On4MinRemain, "On4MinRemain" ),
+ DEFINE_OUTPUT( m_On3MinRemain, "On3MinRemain" ),
+ DEFINE_OUTPUT( m_On2MinRemain, "On2MinRemain" ),
+ DEFINE_OUTPUT( m_On1MinRemain, "On1MinRemain" ),
+ DEFINE_OUTPUT( m_On30SecRemain, "On30SecRemain" ),
+ DEFINE_OUTPUT( m_On10SecRemain, "On10SecRemain" ),
+ DEFINE_OUTPUT( m_On5SecRemain, "On5SecRemain" ),
+ DEFINE_OUTPUT( m_On4SecRemain, "On4SecRemain" ),
+ DEFINE_OUTPUT( m_On3SecRemain, "On3SecRemain" ),
+ DEFINE_OUTPUT( m_On2SecRemain, "On2SecRemain" ),
+ DEFINE_OUTPUT( m_On1SecRemain, "On1SecRemain" ),
+ DEFINE_OUTPUT( m_OnSetupStart, "OnSetupStart" ),
+ DEFINE_OUTPUT( m_OnSetupFinished, "OnSetupFinished" ),
+
+END_DATADESC();
+#endif
+
+#ifndef CLIENT_DLL
+#define ROUND_TIMER_THINK "CTeamplayRoundTimerThink"
+#define ROUND_TIMER_SETUP_THINK "CTeamplayRoundTimerSetupThink"
+#endif
+
+//-----------------------------------------------------------------------------
+// Purpose: constructor
+//-----------------------------------------------------------------------------
+CTeamRoundTimer::CTeamRoundTimer( void )
+{
+ m_bTimerPaused = false;
+ m_flTimeRemaining = 0;
+ m_nTimerLength = 0;
+ m_nTimerInitialLength = 0;
+ m_nTimerMaxLength = 0;
+ m_flTimerEndTime = 0;
+ m_bIsDisabled = false;
+ m_bAutoCountdown = true;
+ m_nState.Set( RT_STATE_NORMAL ); // we'll assume no setup time for now
+ m_bStartPaused = true;
+ m_bShowTimeRemaining = true;
+
+ m_bFireFinished = true;
+ m_bFire5MinRemain = true;
+ m_bFire4MinRemain = true;
+ m_bFire3MinRemain = true;
+ m_bFire2MinRemain = true;
+ m_bFire1MinRemain = true;
+ m_bFire30SecRemain = true;
+ m_bFire10SecRemain = true;
+ m_bFire5SecRemain = true;
+ m_bFire4SecRemain = true;
+ m_bFire3SecRemain = true;
+ m_bFire2SecRemain = true;
+ m_bFire1SecRemain = true;
+
+ m_bStopWatchTimer = false;
+
+ m_flTotalTime = 0.0f;
+
+ m_nSetupTimeLength = 0;
+
+#ifndef CLIENT_DLL
+ m_bPauseDueToWin = false;
+ m_bResetTimeOnRoundStart = false;
+ m_nTimeToUseAfterSetupFinished = 0;
+ m_flNextOvertimeNag = 0;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: destructor
+//-----------------------------------------------------------------------------
+CTeamRoundTimer::~CTeamRoundTimer( void )
+{
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: destructor
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::Precache( void )
+{
+#if defined( TF_DLL ) || defined( TF_CLIENT_DLL )
+ PrecacheScriptSound( ROUND_TIMER_60SECS );
+ PrecacheScriptSound( ROUND_TIMER_30SECS );
+ PrecacheScriptSound( ROUND_TIMER_10SECS );
+ PrecacheScriptSound( ROUND_TIMER_5SECS );
+ PrecacheScriptSound( ROUND_TIMER_4SECS );
+ PrecacheScriptSound( ROUND_TIMER_3SECS );
+ PrecacheScriptSound( ROUND_TIMER_2SECS );
+ PrecacheScriptSound( ROUND_TIMER_1SECS );
+ PrecacheScriptSound( ROUND_SETUP_60SECS );
+ PrecacheScriptSound( ROUND_SETUP_30SECS );
+ PrecacheScriptSound( ROUND_SETUP_10SECS );
+ PrecacheScriptSound( ROUND_SETUP_5SECS );
+ PrecacheScriptSound( ROUND_SETUP_4SECS );
+ PrecacheScriptSound( ROUND_SETUP_3SECS );
+ PrecacheScriptSound( ROUND_SETUP_2SECS );
+ PrecacheScriptSound( ROUND_SETUP_1SECS );
+ PrecacheScriptSound( ROUND_TIMER_TIME_ADDED );
+ PrecacheScriptSound( ROUND_TIMER_TIME_ADDED_LOSER );
+ PrecacheScriptSound( ROUND_TIMER_TIME_ADDED_WINNER );
+ PrecacheScriptSound( ROUND_START_BELL );
+#endif // TF_DLL || TF_CLIENT_DLL
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::Activate( void )
+{
+ BaseClass::Activate();
+
+#ifndef CLIENT_DLL
+ if ( m_bShowInHUD )
+ {
+ SetActiveTimer( this );
+ }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::Spawn( void )
+{
+ Precache();
+
+#ifdef CLIENT_DLL
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+#else
+
+ int nTimerTime = 0;
+
+ // do we have a setup time?
+ if ( m_nSetupTimeLength > 0 )
+ {
+ nTimerTime = m_nSetupTimeLength;
+ SetState( RT_STATE_SETUP );
+ }
+ else
+ {
+ nTimerTime = m_nTimerInitialLength;
+ SetState( RT_STATE_NORMAL );
+ }
+
+ m_nTimeToUseAfterSetupFinished = m_nTimerInitialLength;
+
+ if ( IsDisabled() ) // we need to get the data initialized before actually become disabled
+ {
+ m_bIsDisabled = false;
+ PauseTimer(); // start paused
+ SetTimeRemaining( nTimerTime );
+ m_bIsDisabled = true;
+ }
+ else
+ {
+ PauseTimer(); // start paused
+ SetTimeRemaining( nTimerTime );
+ }
+
+ m_nTimerLength = nTimerTime;
+
+ BaseClass::Spawn();
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CTeamRoundTimer::ShowInHud( void )
+{
+ return m_bShowInHUD;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Gets the seconds left on the timer, paused or not.
+//-----------------------------------------------------------------------------
+float CTeamRoundTimer::GetTimeRemaining( void )
+{
+ float flSecondsRemaining;
+
+ if ( IsStopWatchTimer() == true && m_bInCaptureWatchState == true )
+ {
+ flSecondsRemaining = m_flTotalTime;
+ }
+ else
+ {
+ if ( m_bTimerPaused )
+ {
+ flSecondsRemaining = m_flTimeRemaining;
+ }
+ else
+ {
+ flSecondsRemaining = m_flTimerEndTime - gpGlobals->curtime;
+ }
+ }
+
+ if ( flSecondsRemaining < 0 )
+ {
+ flSecondsRemaining = 0.0f;
+ }
+
+ return flSecondsRemaining;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::SetCaptureWatchState( bool bCaptureWatch )
+{
+ m_bInCaptureWatchState = bCaptureWatch;
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CTeamRoundTimer::GetTimerMaxLength( void )
+{
+ if ( m_nState == RT_STATE_SETUP )
+ {
+ return m_nSetupTimeLength;
+ }
+ else
+ {
+ if ( m_nTimerMaxLength )
+ return m_nTimerMaxLength;
+
+ return m_nTimerLength;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::CalculateOutputMessages( void )
+{
+ float flTime = GetTimeRemaining();
+
+#ifndef GAME_DLL
+ // We need to add a couple seconds to the time remaining because we've probably lost ~0.5 seconds from the timer while
+ // waiting for the update to arrive from the server and we don't want to miss any critical countdown messages. If the time
+ // remaining is over 10 seconds...adding 2 seconds to the total when calculating our output messages won't affect anything
+ if ( flTime > 10.0f )
+ {
+ flTime += 2.0f;
+ }
+#endif
+
+ m_bFireFinished = ( flTime > 0.0f );
+ m_bFire5MinRemain = ( flTime >= 300.0f );
+ m_bFire4MinRemain = ( flTime >= 240.0f );
+ m_bFire3MinRemain = ( flTime >= 180.0f );
+ m_bFire2MinRemain = ( flTime >= 120.0f );
+ m_bFire1MinRemain = ( flTime >= 60.0f );
+ m_bFire30SecRemain = ( flTime >= 30.0f );
+ m_bFire10SecRemain = ( flTime >= 10.0f );
+ m_bFire5SecRemain = ( flTime >= 5.0f );
+ m_bFire4SecRemain = ( flTime >= 4.0f );
+ m_bFire3SecRemain = ( flTime >= 3.0f );
+ m_bFire2SecRemain = ( flTime >= 2.0f );
+ m_bFire1SecRemain = ( flTime >= 1.0f );
+}
+
+#ifdef CLIENT_DLL
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::ClientThink()
+{
+ if ( IsDisabled() || m_bTimerPaused || IsInCommentaryMode() )
+ return;
+
+ if ( IsStopWatchTimer() == true && IsWatchingTimeStamps() == true )
+ return;
+
+ float flTime = GetTimeRemaining();
+
+ if ( flTime <= 61.0 && m_bFire1MinRemain )
+ {
+ m_bFire1MinRemain = false;
+ SendTimeWarning( RT_WARNING_60SECS );
+ }
+ else if ( flTime <= 31.0 && m_bFire30SecRemain )
+ {
+ m_bFire30SecRemain = false;
+ SendTimeWarning( RT_WARNING_30SECS );
+ }
+ else if ( flTime <= 11.0 && m_bFire10SecRemain )
+ {
+ m_bFire10SecRemain = false;
+ SendTimeWarning( RT_WARNING_10SECS );
+ }
+ else if ( flTime <= 6.0 && m_bFire5SecRemain )
+ {
+ m_bFire5SecRemain = false;
+ SendTimeWarning( RT_WARNING_5SECS );
+ }
+ else if ( flTime <= 5.0 && m_bFire4SecRemain )
+ {
+ m_bFire4SecRemain = false;
+ SendTimeWarning( RT_WARNING_4SECS );
+ }
+ else if ( flTime <= 4.0 && m_bFire3SecRemain )
+ {
+ m_bFire3SecRemain = false;
+ SendTimeWarning( RT_WARNING_3SECS );
+ }
+ else if ( flTime <= 3.0 && m_bFire2SecRemain )
+ {
+ m_bFire2SecRemain = false;
+ SendTimeWarning( RT_WARNING_2SECS );
+ }
+ else if ( flTime <= 2.0 && m_bFire1SecRemain )
+ {
+ m_bFire1SecRemain = false;
+ SendTimeWarning( RT_WARNING_1SECS );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::OnPreDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnPreDataChanged( updateType );
+
+ m_nOldTimerLength = m_nTimerLength;
+ m_nOldTimerState = m_nState;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::OnDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnDataChanged( updateType );
+
+ if ( m_nOldTimerLength != m_nTimerLength )
+ {
+ // recalculate our output messages because the timer length has changed
+ CalculateOutputMessages();
+ }
+
+ // if we were in state_setup and now we're in state_normal, play the bell sound
+ if ( ( m_nOldTimerState == RT_STATE_SETUP ) && ( m_nState == RT_STATE_NORMAL ) )
+ {
+ SendTimeWarning( RT_WARNING_TIME_START );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+const char *CTeamRoundTimer::GetTimeWarningSound( int nWarning )
+{
+ const char *pszRetVal;
+
+ switch( nWarning )
+ {
+ case RT_WARNING_60SECS:
+ if ( m_nState == RT_STATE_SETUP )
+ {
+ pszRetVal = ROUND_SETUP_60SECS;
+ }
+ else
+ {
+ pszRetVal = ROUND_TIMER_60SECS;
+ }
+ break;
+ case RT_WARNING_30SECS:
+ if ( m_nState == RT_STATE_SETUP )
+ {
+ pszRetVal = ROUND_SETUP_30SECS;
+ }
+ else
+ {
+ pszRetVal = ROUND_TIMER_30SECS;
+ }
+ break;
+ case RT_WARNING_10SECS:
+ if ( m_nState == RT_STATE_SETUP )
+ {
+ pszRetVal = ROUND_SETUP_10SECS;
+ }
+ else
+ {
+ pszRetVal = ROUND_TIMER_10SECS;
+ }
+ break;
+ case RT_WARNING_5SECS:
+ if ( m_nState == RT_STATE_SETUP )
+ {
+ pszRetVal = ROUND_SETUP_5SECS;
+ }
+ else
+ {
+ pszRetVal = ROUND_TIMER_5SECS;
+ }
+ break;
+ case RT_WARNING_4SECS:
+ if ( m_nState == RT_STATE_SETUP )
+ {
+ pszRetVal = ROUND_SETUP_4SECS;
+ }
+ else
+ {
+ pszRetVal = ROUND_TIMER_4SECS;
+ }
+ break;
+ case RT_WARNING_3SECS:
+ if ( m_nState == RT_STATE_SETUP )
+ {
+ pszRetVal = ROUND_SETUP_3SECS;
+ }
+ else
+ {
+ pszRetVal = ROUND_TIMER_3SECS;
+ }
+ break;
+ case RT_WARNING_2SECS:
+ if ( m_nState == RT_STATE_SETUP )
+ {
+ pszRetVal = ROUND_SETUP_2SECS;
+ }
+ else
+ {
+ pszRetVal = ROUND_TIMER_2SECS;
+ }
+ break;
+ case RT_WARNING_1SECS:
+ if ( m_nState == RT_STATE_SETUP )
+ {
+ pszRetVal = ROUND_SETUP_1SECS;
+ }
+ else
+ {
+ pszRetVal = ROUND_TIMER_1SECS;
+ }
+ break;
+ case RT_WARNING_TIME_START:
+ pszRetVal = ROUND_START_BELL;
+ break;
+ default:
+ pszRetVal = "";
+ }
+
+ return pszRetVal;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::SendTimeWarning( int nWarning )
+{
+ // don't play sounds if the level designer has turned them off or if it's during the WaitingForPlayers time
+ if ( !m_bTimerPaused && m_bAutoCountdown && !TeamplayRoundBasedRules()->IsInWaitingForPlayers() )
+ {
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( pPlayer )
+ {
+ if ( ObjectiveResource() )
+ {
+ bool bShouldPlaySound = false;
+
+ if ( TeamplayRoundBasedRules()->IsInTournamentMode() == true && TeamplayRoundBasedRules()->IsInStopWatch() == true )
+ {
+ int iActiveTimer = ObjectiveResource()->GetTimerToShowInHUD();
+ int iStopWatchTimer = ObjectiveResource()->GetStopWatchTimer();
+
+ if ( IsStopWatchTimer() == true && IsWatchingTimeStamps() == false )
+ {
+ CTeamRoundTimer *pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( iActiveTimer ) );
+
+ if ( pTimer && pTimer->IsTimerPaused() == false && pTimer->GetTimeRemaining() > GetTimeRemaining() )
+ {
+ bShouldPlaySound = true;
+ }
+ }
+ else
+ {
+ CTeamRoundTimer *pStopWatch = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( iStopWatchTimer ) );
+
+ if ( ObjectiveResource()->GetTimerToShowInHUD() == entindex() )
+ {
+ if ( pStopWatch )
+ {
+ if ( pStopWatch->IsTimerPaused() == true )
+ {
+ bShouldPlaySound = true;
+ }
+
+ if ( pStopWatch->GetTimeRemaining() > GetTimeRemaining() && pStopWatch->IsWatchingTimeStamps() == false )
+ {
+ bShouldPlaySound = true;
+ }
+
+ if ( pStopWatch->IsWatchingTimeStamps() == true )
+ {
+ bShouldPlaySound = true;
+ }
+ }
+ else
+ {
+ bShouldPlaySound = true;
+ }
+ }
+ }
+ }
+ else
+ {
+ if( ObjectiveResource()->GetTimerToShowInHUD() == entindex() )
+ {
+ bShouldPlaySound = true;
+ }
+
+ if ( TeamplayRoundBasedRules() && TeamplayRoundBasedRules()->IsInKothMode() )
+ {
+ bShouldPlaySound = true;
+ }
+ }
+
+#ifdef TF_CLIENT_DLL
+ if ( bShouldPlaySound == true )
+ {
+ pPlayer->EmitSound( GetTimeWarningSound( nWarning ) );
+ }
+#endif // TF_CLIENT_DLL
+ }
+ }
+ }
+}
+
+#else
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::SetState( int nState, bool bFireOutput )
+{
+ m_nState = nState;
+
+ if ( nState == RT_STATE_SETUP )
+ {
+ if ( IsStopWatchTimer() == false )
+ {
+ TeamplayRoundBasedRules()->SetSetup( true );
+ }
+
+ SetTimerThink( RT_THINK_SETUP );
+
+ if ( bFireOutput )
+ {
+ m_OnSetupStart.FireOutput( this, this );
+ }
+ }
+ else
+ {
+ if ( IsStopWatchTimer() == false )
+ {
+ TeamplayRoundBasedRules()->SetSetup( false );
+ }
+
+ SetTimerThink( RT_THINK_NORMAL );
+
+ if ( bFireOutput )
+ {
+ m_OnRoundStart.FireOutput( this, this );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::SetTimerThink( int nType )
+{
+ if ( nType == RT_THINK_SETUP )
+ {
+ SetContextThink( &CTeamRoundTimer::RoundTimerSetupThink, gpGlobals->curtime + 0.05, ROUND_TIMER_SETUP_THINK );
+ SetContextThink( NULL, 0, ROUND_TIMER_THINK );
+ }
+ else
+ {
+ SetContextThink( &CTeamRoundTimer::RoundTimerThink, gpGlobals->curtime + 0.05, ROUND_TIMER_THINK );
+ SetContextThink( NULL, 0, ROUND_TIMER_SETUP_THINK );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::RoundTimerSetupThink( void )
+{
+ if ( TeamplayRoundBasedRules()->IsInPreMatch() == true && IsDisabled() == false )
+ {
+ inputdata_t data;
+ InputDisable( data );
+ m_OnSetupFinished.FireOutput( this, this );
+ }
+
+ if ( IsDisabled() || m_bTimerPaused )
+ {
+ SetContextThink( &CTeamRoundTimer::RoundTimerSetupThink, gpGlobals->curtime + 0.05, ROUND_TIMER_SETUP_THINK );
+ return;
+ }
+
+ float flTime = GetTimeRemaining();
+ TeamplayRoundBasedRules()->SetOvertime( false );
+
+ if ( flTime <= 0.0f && m_bFireFinished )
+ {
+ IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_setup_finished" );
+ if ( event )
+ {
+ gameeventmanager->FireEvent( event );
+ }
+
+ m_OnSetupFinished.FireOutput( this, this );
+ m_bFireFinished = false;
+
+ SetTimeRemaining( m_nTimeToUseAfterSetupFinished );
+ SetState( RT_STATE_NORMAL );
+
+ if ( ShowInHud() && !TeamplayRoundBasedRules()->IsInWaitingForPlayers() )
+ {
+ UTIL_LogPrintf( "World triggered \"Round_Setup_End\"\n" );
+ }
+ return;
+ }
+ else if ( flTime <= 60.0 && m_bFire1MinRemain )
+ {
+ m_On1MinRemain.FireOutput( this, this );
+ m_bFire1MinRemain = false;
+ }
+ else if ( flTime <= 30.0 && m_bFire30SecRemain )
+ {
+ m_On30SecRemain.FireOutput( this, this );
+ m_bFire30SecRemain = false;
+ }
+ else if ( flTime <= 10.0 && m_bFire10SecRemain )
+ {
+ m_On10SecRemain.FireOutput( this, this );
+ m_bFire10SecRemain = false;
+ }
+ else if ( flTime <= 5.0 && m_bFire5SecRemain )
+ {
+ m_On5SecRemain.FireOutput( this, this );
+ m_bFire5SecRemain = false;
+ }
+ else if ( flTime <= 4.0 && m_bFire4SecRemain )
+ {
+ m_On4SecRemain.FireOutput( this, this );
+ m_bFire4SecRemain = false;
+ }
+ else if ( flTime <= 3.0 && m_bFire3SecRemain )
+ {
+ m_On3SecRemain.FireOutput( this, this );
+ m_bFire3SecRemain = false;
+ }
+ else if ( flTime <= 2.0 && m_bFire2SecRemain )
+ {
+ m_On2SecRemain.FireOutput( this, this );
+ m_bFire2SecRemain = false;
+ }
+ else if ( flTime <= 1.0 && m_bFire1SecRemain )
+ {
+ m_On1SecRemain.FireOutput( this, this );
+ m_bFire1SecRemain = false;
+ }
+
+ SetContextThink( &CTeamRoundTimer::RoundTimerSetupThink, gpGlobals->curtime + 0.05, ROUND_TIMER_SETUP_THINK );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::RoundTimerThink( void )
+{
+ if ( TeamplayRoundBasedRules()->IsInPreMatch() == true && IsDisabled() == false )
+ {
+ inputdata_t data;
+ InputDisable( data );
+ }
+
+ if ( IsDisabled() || m_bTimerPaused || IsInCommentaryMode() || gpGlobals->eLoadType == MapLoad_Background )
+ {
+ SetContextThink( &CTeamRoundTimer::RoundTimerThink, gpGlobals->curtime + 0.05, ROUND_TIMER_THINK );
+ return;
+ }
+
+ // Don't do anything when the game has been won or if we're loading a bugbait report
+ if ( TeamplayRoundBasedRules()->RoundHasBeenWon() ||
+ TeamplayRoundBasedRules()->IsLoadingBugBaitReport() )
+ {
+ // We want to stop timers when the round has been won, but we don't want to
+ // force mapmakers to deal with having to unpause it. This little hack works around that.
+ if ( !m_bTimerPaused )
+ {
+ PauseTimer();
+ m_bPauseDueToWin = true;
+ }
+
+ SetContextThink( &CTeamRoundTimer::RoundTimerThink, gpGlobals->curtime + 0.05, ROUND_TIMER_THINK );
+ return;
+ }
+ else if ( m_bPauseDueToWin )
+ {
+ ResumeTimer();
+ m_bPauseDueToWin = false;
+ }
+
+ float flTime = GetTimeRemaining();
+
+ if ( flTime > 0 && ShowInHud() ) // is this the timer we're showing in the HUD?
+ {
+ TeamplayRoundBasedRules()->SetOvertime( false );
+ }
+
+ if ( flTime <= 0.0f && m_bFireFinished )
+ {
+ // Allow the gamerules to prevent timer expiration (i.e. while a control point is contested)
+ if ( !TeamplayGameRules()->TimerMayExpire() )
+ {
+ // we don't want the timer to keep going (negative time)
+ m_flTimerEndTime = gpGlobals->curtime;
+
+ // is this the timer we're showing in the HUD?
+ if ( ShowInHud() )
+ {
+ if ( !TeamplayRoundBasedRules()->InOvertime() )
+ {
+ TeamplayRoundBasedRules()->SetOvertime( true );
+ }
+#if defined( TF_DLL )
+ else
+ {
+ if ( tf_overtime_nag.GetBool() && ( gpGlobals->curtime > m_flNextOvertimeNag ) )
+ {
+ m_flNextOvertimeNag = gpGlobals->curtime + 1.0f;
+
+ if ( RandomInt( 0, 1 ) > 0 )
+ {
+ IGameEvent *event = gameeventmanager->CreateEvent( "overtime_nag" );
+ if ( event )
+ {
+ gameeventmanager->FireEvent( event );
+ }
+ }
+ }
+ }
+#endif
+ }
+
+ SetContextThink( &CTeamRoundTimer::RoundTimerThink, gpGlobals->curtime + 0.05, ROUND_TIMER_THINK );
+ return;
+ }
+
+ m_OnFinished.FireOutput( this, this );
+ m_bFireFinished = false;
+ }
+ else if ( flTime <= 300.0 && m_bFire5MinRemain )
+ {
+ m_On5MinRemain.FireOutput( this, this );
+ m_bFire5MinRemain = false;
+ }
+ else if ( flTime <= 240.0 && m_bFire4MinRemain )
+ {
+ m_On4MinRemain.FireOutput( this, this );
+ m_bFire4MinRemain = false;
+ }
+ else if ( flTime <= 180.0 && m_bFire3MinRemain )
+ {
+ m_On3MinRemain.FireOutput( this, this );
+ m_bFire3MinRemain = false;
+ }
+ else if ( flTime <= 120.0 && m_bFire2MinRemain )
+ {
+ m_On2MinRemain.FireOutput( this, this );
+ m_bFire2MinRemain = false;
+ }
+ else if ( flTime <= 60.0 && m_bFire1MinRemain )
+ {
+ m_On1MinRemain.FireOutput( this, this );
+ m_bFire1MinRemain = false;
+ }
+ else if ( flTime <= 30.0 && m_bFire30SecRemain )
+ {
+ m_On30SecRemain.FireOutput( this, this );
+ m_bFire30SecRemain = false;
+ }
+ else if ( flTime <= 10.0 && m_bFire10SecRemain )
+ {
+ m_On10SecRemain.FireOutput( this, this );
+ m_bFire10SecRemain = false;
+ }
+ else if ( flTime <= 5.0 && m_bFire5SecRemain )
+ {
+ m_On5SecRemain.FireOutput( this, this );
+ m_bFire5SecRemain = false;
+ }
+ else if ( flTime <= 4.0 && m_bFire4SecRemain )
+ {
+ m_On4SecRemain.FireOutput( this, this );
+ m_bFire4SecRemain = false;
+ }
+ else if ( flTime <= 3.0 && m_bFire3SecRemain )
+ {
+ m_On3SecRemain.FireOutput( this, this );
+ m_bFire3SecRemain = false;
+ }
+ else if ( flTime <= 2.0 && m_bFire2SecRemain )
+ {
+ m_On2SecRemain.FireOutput( this, this );
+ m_bFire2SecRemain = false;
+ }
+ else if ( flTime <= 1.0 && m_bFire1SecRemain )
+ {
+ m_On1SecRemain.FireOutput( this, this );
+ m_bFire1SecRemain = false;
+ }
+
+ SetContextThink( &CTeamRoundTimer::RoundTimerThink, gpGlobals->curtime + 0.05, ROUND_TIMER_THINK );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::InputRoundSpawn( inputdata_t &input )
+{
+ if ( !m_bResetTimeOnRoundStart && ( m_nState == RT_STATE_NORMAL ) )
+ {
+ m_nTimeToUseAfterSetupFinished = GetTimeRemaining();
+ }
+ else
+ {
+ m_nTimeToUseAfterSetupFinished = m_nTimerInitialLength;
+ }
+
+ if ( m_nSetupTimeLength > 0 )
+ {
+ SetTimeRemaining( m_nSetupTimeLength );
+ SetState( RT_STATE_SETUP );
+
+ if ( ShowInHud() && !TeamplayRoundBasedRules()->IsInWaitingForPlayers() )
+ {
+ UTIL_LogPrintf( "World triggered \"Round_Setup_Begin\"\n" );
+ }
+ }
+ else
+ {
+ SetTimeRemaining( m_nTimeToUseAfterSetupFinished );
+ SetState( RT_STATE_NORMAL );
+ }
+
+ if ( !m_bStartPaused && !TeamplayRoundBasedRules()->IsInWaitingForPlayers() )
+ {
+ ResumeTimer();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: To set the initial timer duration
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::SetTimeRemaining( int iTimerSeconds )
+{
+ if ( IsDisabled() )
+ return;
+
+ // make sure we don't go over our max length
+ if ( m_nTimerMaxLength > 0 )
+ {
+ if ( iTimerSeconds > m_nTimerMaxLength )
+ {
+ iTimerSeconds = m_nTimerMaxLength;
+ }
+ }
+
+ m_flTimeRemaining = (float)iTimerSeconds;
+ m_flTimerEndTime = gpGlobals->curtime + m_flTimeRemaining;
+ m_nTimerLength = iTimerSeconds;
+
+ CalculateOutputMessages();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: To set the initial timer duration
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::SetStopWatchTimeStamp( void )
+{
+ if ( IsDisabled() )
+ return;
+
+ if ( IsWatchingTimeStamps() == false )
+ return;
+
+ m_flTotalTime = m_flTotalTime + (gpGlobals->curtime - m_flTimerEndTime);
+ m_flTimerEndTime = gpGlobals->curtime;
+
+ CalculateOutputMessages();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Timer is paused at round end, stops the countdown
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::PauseTimer( void )
+{
+ if ( IsDisabled() )
+ return;
+
+ if ( m_bTimerPaused == false )
+ {
+ m_bTimerPaused = true;
+
+ m_flTimeRemaining = m_flTimerEndTime - gpGlobals->curtime;
+ }
+
+ // Clear pause on win flag, because we've been set by the mapmaker
+ m_bPauseDueToWin = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: To start or re-start the timer after a pause
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::ResumeTimer( void )
+{
+ if ( IsDisabled() )
+ return;
+
+ if ( m_bTimerPaused == true )
+ {
+ m_bTimerPaused = false;
+
+ if ( IsStopWatchTimer() == true && m_bInCaptureWatchState == true )
+ {
+ m_flTimerEndTime = gpGlobals->curtime;
+ }
+ else
+ {
+ m_flTimerEndTime = gpGlobals->curtime + m_flTimeRemaining;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Add seconds to the timer while it is running or paused
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::AddTimerSeconds( int iSecondsToAdd, int iTeamResponsible /* = TEAM_UNASSIGNED*/ )
+{
+ if ( IsDisabled() )
+ return;
+
+ if ( TeamplayRoundBasedRules()->InStalemate() )
+ return;
+
+ // we only want to add time if we're round_running or team_win so the control points
+ // don't add time when they try to set their default owner when the map is first loading
+ if ( TeamplayRoundBasedRules()->State_Get() != GR_STATE_RND_RUNNING && TeamplayRoundBasedRules()->State_Get() != GR_STATE_TEAM_WIN )
+ return;
+
+ if ( m_nTimerMaxLength > 0 )
+ {
+ // will adding this many seconds push us over our max length?
+ if ( GetTimeRemaining() + iSecondsToAdd > m_nTimerMaxLength )
+ {
+ // adjust to only add up to our max length
+ iSecondsToAdd = m_nTimerMaxLength - GetTimeRemaining();
+ }
+ }
+
+ if ( m_bTimerPaused )
+ {
+ m_flTimeRemaining += (float)iSecondsToAdd;
+ }
+ else
+ {
+ m_flTimerEndTime += (float)iSecondsToAdd;
+ }
+
+ m_nTimerLength += iSecondsToAdd;
+ CalculateOutputMessages();
+
+ if ( ( ObjectiveResource() && ObjectiveResource()->GetTimerInHUD() == entindex() ) || ( TeamplayRoundBasedRules()->IsInKothMode() ) )
+ {
+ if ( !TeamplayRoundBasedRules()->InStalemate() && !TeamplayRoundBasedRules()->RoundHasBeenWon() && !TeamplayRoundBasedRules()->IsInKothMode() )
+ {
+ if ( iTeamResponsible >= LAST_SHARED_TEAM+1 )
+ {
+ for ( int iTeam = LAST_SHARED_TEAM+1 ; iTeam < GetNumberOfTeams(); iTeam++ )
+ {
+ if ( iTeam == iTeamResponsible )
+ {
+ CTeamRecipientFilter filter( iTeam, true );
+ EmitSound( filter, entindex(), ROUND_TIMER_TIME_ADDED_WINNER );
+
+ }
+ else
+ {
+ CTeamRecipientFilter filter( iTeam, true );
+ EmitSound( filter, entindex(), ROUND_TIMER_TIME_ADDED_LOSER );
+ }
+ }
+ }
+ else
+ {
+ CReliableBroadcastRecipientFilter filter;
+ EmitSound( filter, entindex(), ROUND_TIMER_TIME_ADDED );
+ }
+ }
+
+ // is this the timer we're showing in the HUD?
+ if ( m_bShowInHUD )
+ {
+ IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_timer_time_added" );
+ if ( event )
+ {
+ event->SetInt( "timer", entindex() );
+ event->SetInt( "seconds_added", iSecondsToAdd );
+ gameeventmanager->FireEvent( event );
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: The timer is always transmitted to clients
+//-----------------------------------------------------------------------------
+int CTeamRoundTimer::UpdateTransmitState()
+{
+ // ALWAYS transmit to all clients.
+ return SetTransmitState( FL_EDICT_ALWAYS );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::InputPause( inputdata_t &input )
+{
+ PauseTimer();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::InputResume( inputdata_t &input )
+{
+ ResumeTimer();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::InputSetTime( inputdata_t &input )
+{
+ if ( IsStopWatchTimer() == true && IsWatchingTimeStamps() == true )
+ {
+ SetStopWatchTimeStamp();
+ }
+ else
+ {
+ int nSeconds = input.value.Int();
+ SetTimeRemaining( nSeconds );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::InputSetMaxTime( inputdata_t &input )
+{
+ int nSeconds = input.value.Int();
+ m_nTimerMaxLength = nSeconds;
+
+ if ( m_nTimerMaxLength > 0 )
+ {
+ // make sure our current time is not above the max length
+ if ( GetTimeRemaining() > m_nTimerMaxLength )
+ {
+ SetTimeRemaining( m_nTimerMaxLength );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::InputAddTime( inputdata_t &input )
+{
+ int nSeconds = input.value.Int();
+ AddTimerSeconds( nSeconds );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::InputAddTeamTime( inputdata_t &input )
+{
+ char token[128];
+ const char *p = STRING( input.value.StringID() );
+ int nTeam = TEAM_UNASSIGNED;
+ int nSeconds = 0;
+
+ // get the team
+ p = nexttoken( token, p, ' ' );
+ if ( token )
+ {
+ nTeam = Q_atoi( token );
+ }
+
+ // get the time
+ p = nexttoken( token, p, ' ' );
+ if ( token )
+ {
+ nSeconds = Q_atoi( token );
+ }
+
+ if ( nSeconds != 0 )
+ {
+ AddTimerSeconds( nSeconds, nTeam );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::InputRestart( inputdata_t &input )
+{
+ SetTimeRemaining( m_nTimerInitialLength );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::InputEnable( inputdata_t &input )
+{
+ m_bIsDisabled = false;
+ ResumeTimer();
+
+ if ( m_bShowInHUD )
+ {
+ SetActiveTimer( this );
+ }
+
+ if ( IsStopWatchTimer() == true && IsWatchingTimeStamps() == true )
+ {
+ m_flTimerEndTime = gpGlobals->curtime;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::InputDisable( inputdata_t &input )
+{
+ PauseTimer();
+ m_bIsDisabled = true;
+
+ if ( m_bShowInHUD )
+ {
+ SetActiveTimer( NULL );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::InputShowInHUD( inputdata_t &input )
+{
+ int nShow = input.value.Int();
+
+ if ( m_bShowInHUD && !nShow )
+ {
+ SetActiveTimer( NULL );
+ }
+ else if ( nShow == 1 )
+ {
+ SetActiveTimer( this );
+ SetState( m_nState, false ); // set our current state again so the gamerules are updated with our setup state
+ }
+
+ m_bShowInHUD = ( nShow == 1 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::InputAutoCountdown( inputdata_t &input )
+{
+ int nAuto = input.value.Int();
+ SetAutoCountdown( nAuto == 1 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::InputSetSetupTime( inputdata_t &input )
+{
+ int nSetupTime = input.value.Int();
+ if ( nSetupTime >= 0 )
+ {
+ m_nSetupTimeLength = nSetupTime;
+ }
+
+ if ( !IsDisabled() )
+ {
+ if ( m_nState == RT_STATE_SETUP )
+ {
+ SetTimeRemaining( m_nSetupTimeLength );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamRoundTimer::SetActiveTimer( CTeamRoundTimer *pNewlyActive )
+{
+ CBaseEntity *pChosenTimer = pNewlyActive;
+
+ // Ensure all other timers are off.
+ CBaseEntity *pEntity = NULL;
+ while ((pEntity = gEntList.FindEntityByClassname( pEntity, "team_round_timer" )) != NULL)
+ {
+ if ( pEntity == pNewlyActive )
+ continue;
+
+ CTeamRoundTimer *pTimer = assert_cast< CTeamRoundTimer* >( pEntity );
+ if ( !pTimer->IsDisabled() && pTimer->ShowInHud() )
+ {
+ if ( pChosenTimer )
+ {
+ // Turn off all other hud timers
+ pTimer->SetShowInHud( false );
+ }
+ else
+ {
+ // Found a timer. Use it.
+ pChosenTimer = pTimer;
+ }
+ }
+ }
+
+ ObjectiveResource()->SetTimerInHUD( pChosenTimer );
+}
+
+#endif