Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1357 lines
37 KiB

  1. //========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Team gamerules round timer
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "teamplay_round_timer.h"
  9. #include "teamplayroundbased_gamerules.h"
  10. #ifdef CLIENT_DLL
  11. #include "IClientMode.h"
  12. #include "vgui_controls/AnimationController.h"
  13. #include "c_playerresource.h"
  14. #include "c_team_objectiveresource.h"
  15. #else
  16. #include "team.h"
  17. #include "team_objectiveresource.h"
  18. #endif
  19. #define ROUND_TIMER_60SECS "Announcer.RoundEnds60seconds"
  20. #define ROUND_TIMER_30SECS "Announcer.RoundEnds30seconds"
  21. #define ROUND_TIMER_10SECS "Announcer.RoundEnds10seconds"
  22. #define ROUND_TIMER_5SECS "Announcer.RoundEnds5seconds"
  23. #define ROUND_TIMER_4SECS "Announcer.RoundEnds4seconds"
  24. #define ROUND_TIMER_3SECS "Announcer.RoundEnds3seconds"
  25. #define ROUND_TIMER_2SECS "Announcer.RoundEnds2seconds"
  26. #define ROUND_TIMER_1SECS "Announcer.RoundEnds1seconds"
  27. #define ROUND_SETUP_60SECS "Announcer.RoundBegins60Seconds"
  28. #define ROUND_SETUP_30SECS "Announcer.RoundBegins30Seconds"
  29. #define ROUND_SETUP_10SECS "Announcer.RoundBegins10Seconds"
  30. #define ROUND_SETUP_5SECS "Announcer.RoundBegins5Seconds"
  31. #define ROUND_SETUP_4SECS "Announcer.RoundBegins4Seconds"
  32. #define ROUND_SETUP_3SECS "Announcer.RoundBegins3Seconds"
  33. #define ROUND_SETUP_2SECS "Announcer.RoundBegins2Seconds"
  34. #define ROUND_SETUP_1SECS "Announcer.RoundBegins1Seconds"
  35. #define ROUND_START_BELL "Ambient.Siren"
  36. #define ROUND_TIMER_TIME_ADDED "Announcer.TimeAdded"
  37. #define ROUND_TIMER_TIME_ADDED_LOSER "Announcer.TimeAddedForEnemy"
  38. #define ROUND_TIMER_TIME_ADDED_WINNER "Announcer.TimeAwardedForTeam"
  39. enum
  40. {
  41. RT_THINK_SETUP,
  42. RT_THINK_NORMAL,
  43. };
  44. enum
  45. {
  46. RT_WARNING_60SECS,
  47. RT_WARNING_30SECS,
  48. RT_WARNING_10SECS,
  49. RT_WARNING_5SECS,
  50. RT_WARNING_4SECS,
  51. RT_WARNING_3SECS,
  52. RT_WARNING_2SECS,
  53. RT_WARNING_1SECS,
  54. RT_WARNING_TIME_START,
  55. };
  56. // memdbgon must be the last include file in a .cpp file!!!
  57. #include "tier0/memdbgon.h"
  58. extern bool IsInCommentaryMode();
  59. #ifdef CLIENT_DLL
  60. // Use this proxy to flash the round timer whenever the timer is restarted
  61. // because trapping the round start event doesn't work ( the event also flushes
  62. // all hud events and obliterates our TimerFlash event )
  63. static void RecvProxy_TimerPaused( const CRecvProxyData *pData, void *pStruct, void *pOut )
  64. {
  65. CTeamRoundTimer *pTimer = (CTeamRoundTimer *) pStruct;
  66. bool bTimerPaused = ( pData->m_Value.m_Int > 0 );
  67. if ( bTimerPaused == false )
  68. {
  69. FOR_EACH_VALID_SPLITSCREEN_PLAYER( hh )
  70. {
  71. ACTIVE_SPLITSCREEN_PLAYER_GUARD( hh );
  72. GetClientMode()->GetViewportAnimationController()->StartAnimationSequence( "TimerFlash" );
  73. }
  74. }
  75. if ( pTimer )
  76. {
  77. pTimer->InternalSetPaused( bTimerPaused );
  78. }
  79. }
  80. #endif
  81. LINK_ENTITY_TO_CLASS( team_round_timer, CTeamRoundTimer );
  82. PRECACHE_REGISTER( team_round_timer );
  83. IMPLEMENT_NETWORKCLASS_ALIASED( TeamRoundTimer, DT_TeamRoundTimer )
  84. BEGIN_NETWORK_TABLE_NOBASE( CTeamRoundTimer, DT_TeamRoundTimer )
  85. #ifdef CLIENT_DLL
  86. RecvPropInt( RECVINFO( m_bTimerPaused ), 0, RecvProxy_TimerPaused ),
  87. RecvPropTime( RECVINFO( m_flTimeRemaining ) ),
  88. RecvPropTime( RECVINFO( m_flTimerEndTime ) ),
  89. RecvPropInt( RECVINFO( m_nTimerMaxLength ) ),
  90. RecvPropBool( RECVINFO( m_bIsDisabled ) ),
  91. RecvPropBool( RECVINFO( m_bShowInHUD ) ),
  92. RecvPropInt( RECVINFO( m_nTimerLength ) ),
  93. RecvPropInt( RECVINFO( m_nTimerInitialLength ) ),
  94. RecvPropBool( RECVINFO( m_bAutoCountdown ) ),
  95. RecvPropInt( RECVINFO( m_nSetupTimeLength ) ),
  96. RecvPropInt( RECVINFO( m_nState ) ),
  97. RecvPropBool( RECVINFO( m_bStartPaused ) ),
  98. RecvPropBool( RECVINFO( m_bInCaptureWatchState ) ),
  99. RecvPropBool( RECVINFO( m_bStopWatchTimer ) ),
  100. RecvPropTime( RECVINFO( m_flTotalTime ) ),
  101. #else
  102. SendPropBool( SENDINFO( m_bTimerPaused ) ),
  103. SendPropTime( SENDINFO( m_flTimeRemaining ) ),
  104. SendPropTime( SENDINFO( m_flTimerEndTime ) ),
  105. SendPropInt( SENDINFO( m_nTimerMaxLength ) ),
  106. SendPropBool( SENDINFO( m_bIsDisabled ) ),
  107. SendPropBool( SENDINFO( m_bShowInHUD ) ),
  108. SendPropInt( SENDINFO( m_nTimerLength ) ),
  109. SendPropInt( SENDINFO( m_nTimerInitialLength ) ),
  110. SendPropBool( SENDINFO( m_bAutoCountdown ) ),
  111. SendPropInt( SENDINFO( m_nSetupTimeLength ) ),
  112. SendPropInt( SENDINFO( m_nState ) ),
  113. SendPropBool( SENDINFO( m_bStartPaused ) ),
  114. SendPropBool( SENDINFO( m_bStopWatchTimer ) ),
  115. SendPropBool( SENDINFO( m_bInCaptureWatchState ) ),
  116. SendPropTime( SENDINFO( m_flTotalTime ) ),
  117. #endif
  118. END_NETWORK_TABLE()
  119. #ifndef CLIENT_DLL
  120. BEGIN_DATADESC(CTeamRoundTimer)
  121. DEFINE_KEYFIELD( m_nTimerInitialLength, FIELD_INTEGER, "timer_length" ),
  122. DEFINE_KEYFIELD( m_nTimerMaxLength, FIELD_INTEGER, "max_length" ),
  123. DEFINE_KEYFIELD( m_bShowInHUD, FIELD_BOOLEAN, "show_in_hud" ),
  124. DEFINE_KEYFIELD( m_bIsDisabled, FIELD_BOOLEAN, "StartDisabled" ),
  125. DEFINE_KEYFIELD( m_bAutoCountdown, FIELD_BOOLEAN, "auto_countdown" ),
  126. DEFINE_KEYFIELD( m_nSetupTimeLength, FIELD_INTEGER, "setup_length" ),
  127. DEFINE_KEYFIELD( m_bResetTimeOnRoundStart, FIELD_BOOLEAN, "reset_time" ),
  128. DEFINE_KEYFIELD( m_bStartPaused, FIELD_BOOLEAN, "start_paused" ),
  129. DEFINE_FUNCTION( RoundTimerSetupThink ),
  130. DEFINE_FUNCTION( RoundTimerThink ),
  131. DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
  132. DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
  133. DEFINE_INPUTFUNC( FIELD_VOID, "Pause", InputPause ),
  134. DEFINE_INPUTFUNC( FIELD_VOID, "Resume", InputResume ),
  135. DEFINE_INPUTFUNC( FIELD_INTEGER, "SetTime", InputSetTime ),
  136. DEFINE_INPUTFUNC( FIELD_INTEGER, "AddTime", InputAddTime ),
  137. DEFINE_INPUTFUNC( FIELD_VOID, "Restart", InputRestart ),
  138. DEFINE_INPUTFUNC( FIELD_INTEGER, "ShowInHUD", InputShowInHUD ),
  139. DEFINE_INPUTFUNC( FIELD_VOID, "RoundSpawn", InputRoundSpawn ),
  140. DEFINE_INPUTFUNC( FIELD_INTEGER, "SetMaxTime", InputSetMaxTime ),
  141. DEFINE_INPUTFUNC( FIELD_INTEGER, "AutoCountdown", InputAutoCountdown ),
  142. DEFINE_INPUTFUNC( FIELD_STRING, "AddTeamTime", InputAddTeamTime ),
  143. DEFINE_OUTPUT( m_OnRoundStart, "OnRoundStart" ),
  144. DEFINE_OUTPUT( m_OnFinished, "OnFinished" ),
  145. DEFINE_OUTPUT( m_On5MinRemain, "On5MinRemain" ),
  146. DEFINE_OUTPUT( m_On4MinRemain, "On4MinRemain" ),
  147. DEFINE_OUTPUT( m_On3MinRemain, "On3MinRemain" ),
  148. DEFINE_OUTPUT( m_On2MinRemain, "On2MinRemain" ),
  149. DEFINE_OUTPUT( m_On1MinRemain, "On1MinRemain" ),
  150. DEFINE_OUTPUT( m_On30SecRemain, "On30SecRemain" ),
  151. DEFINE_OUTPUT( m_On10SecRemain, "On10SecRemain" ),
  152. DEFINE_OUTPUT( m_On5SecRemain, "On5SecRemain" ),
  153. DEFINE_OUTPUT( m_On4SecRemain, "On4SecRemain" ),
  154. DEFINE_OUTPUT( m_On3SecRemain, "On3SecRemain" ),
  155. DEFINE_OUTPUT( m_On2SecRemain, "On2SecRemain" ),
  156. DEFINE_OUTPUT( m_On1SecRemain, "On1SecRemain" ),
  157. DEFINE_OUTPUT( m_OnSetupStart, "OnSetupStart" ),
  158. DEFINE_OUTPUT( m_OnSetupFinished, "OnSetupFinished" ),
  159. END_DATADESC();
  160. #endif
  161. #ifndef CLIENT_DLL
  162. #define ROUND_TIMER_THINK "CTeamplayRoundTimerThink"
  163. #define ROUND_TIMER_SETUP_THINK "CTeamplayRoundTimerSetupThink"
  164. #endif
  165. //-----------------------------------------------------------------------------
  166. // Purpose: constructor
  167. //-----------------------------------------------------------------------------
  168. CTeamRoundTimer::CTeamRoundTimer( void )
  169. {
  170. m_bTimerPaused = false;
  171. m_flTimeRemaining = 0;
  172. m_nTimerLength = 0;
  173. m_nTimerInitialLength = 0;
  174. m_nTimerMaxLength = 0;
  175. m_flTimerEndTime = 0;
  176. m_bIsDisabled = false;
  177. m_bAutoCountdown = true;
  178. m_nState.Set( RT_STATE_NORMAL ); // we'll assume no setup time for now
  179. m_bStartPaused = true;
  180. m_bFireFinished = true;
  181. m_bFire5MinRemain = true;
  182. m_bFire4MinRemain = true;
  183. m_bFire3MinRemain = true;
  184. m_bFire2MinRemain = true;
  185. m_bFire1MinRemain = true;
  186. m_bFire30SecRemain = true;
  187. m_bFire10SecRemain = true;
  188. m_bFire5SecRemain = true;
  189. m_bFire4SecRemain = true;
  190. m_bFire3SecRemain = true;
  191. m_bFire2SecRemain = true;
  192. m_bFire1SecRemain = true;
  193. m_bStopWatchTimer = false;
  194. m_flTotalTime = 0.0f;
  195. #ifndef CLIENT_DLL
  196. m_bPauseDueToWin = false;
  197. m_bResetTimeOnRoundStart = false;
  198. m_nTimeToUseAfterSetupFinished = 0;
  199. #endif
  200. }
  201. //-----------------------------------------------------------------------------
  202. // Purpose: destructor
  203. //-----------------------------------------------------------------------------
  204. CTeamRoundTimer::~CTeamRoundTimer( void )
  205. {
  206. }
  207. //-----------------------------------------------------------------------------
  208. // Purpose: destructor
  209. //-----------------------------------------------------------------------------
  210. void CTeamRoundTimer::Precache( void )
  211. {
  212. PrecacheScriptSound( ROUND_TIMER_60SECS );
  213. PrecacheScriptSound( ROUND_TIMER_30SECS );
  214. PrecacheScriptSound( ROUND_TIMER_10SECS );
  215. PrecacheScriptSound( ROUND_TIMER_5SECS );
  216. PrecacheScriptSound( ROUND_TIMER_4SECS );
  217. PrecacheScriptSound( ROUND_TIMER_3SECS );
  218. PrecacheScriptSound( ROUND_TIMER_2SECS );
  219. PrecacheScriptSound( ROUND_TIMER_1SECS );
  220. PrecacheScriptSound( ROUND_SETUP_60SECS );
  221. PrecacheScriptSound( ROUND_SETUP_30SECS );
  222. PrecacheScriptSound( ROUND_SETUP_10SECS );
  223. PrecacheScriptSound( ROUND_SETUP_5SECS );
  224. PrecacheScriptSound( ROUND_SETUP_4SECS );
  225. PrecacheScriptSound( ROUND_SETUP_3SECS );
  226. PrecacheScriptSound( ROUND_SETUP_2SECS );
  227. PrecacheScriptSound( ROUND_SETUP_1SECS );
  228. PrecacheScriptSound( ROUND_TIMER_TIME_ADDED );
  229. PrecacheScriptSound( ROUND_TIMER_TIME_ADDED_LOSER );
  230. PrecacheScriptSound( ROUND_TIMER_TIME_ADDED_WINNER );
  231. PrecacheScriptSound( ROUND_START_BELL );
  232. }
  233. //-----------------------------------------------------------------------------
  234. // Purpose:
  235. //-----------------------------------------------------------------------------
  236. void CTeamRoundTimer::Activate( void )
  237. {
  238. BaseClass::Activate();
  239. #ifndef CLIENT_DLL
  240. if ( m_bShowInHUD )
  241. {
  242. SetActiveTimer( this );
  243. }
  244. #endif
  245. }
  246. //-----------------------------------------------------------------------------
  247. // Purpose:
  248. //-----------------------------------------------------------------------------
  249. void CTeamRoundTimer::Spawn( void )
  250. {
  251. Precache();
  252. #ifdef CLIENT_DLL
  253. SetNextClientThink( CLIENT_THINK_ALWAYS );
  254. #else
  255. int nTimerTime = 0;
  256. // do we have a setup time?
  257. if ( m_nSetupTimeLength > 0 )
  258. {
  259. nTimerTime = m_nSetupTimeLength;
  260. SetState( RT_STATE_SETUP );
  261. }
  262. else
  263. {
  264. nTimerTime = m_nTimerInitialLength;
  265. SetState( RT_STATE_NORMAL );
  266. }
  267. m_nTimeToUseAfterSetupFinished = m_nTimerInitialLength;
  268. if ( IsDisabled() ) // we need to get the data initialized before actually become disabled
  269. {
  270. m_bIsDisabled = false;
  271. PauseTimer(); // start paused
  272. SetTimeRemaining( nTimerTime );
  273. m_bIsDisabled = true;
  274. }
  275. else
  276. {
  277. PauseTimer(); // start paused
  278. SetTimeRemaining( nTimerTime );
  279. }
  280. m_nTimerLength = nTimerTime;
  281. BaseClass::Spawn();
  282. #endif
  283. }
  284. //-----------------------------------------------------------------------------
  285. // Purpose:
  286. //-----------------------------------------------------------------------------
  287. bool CTeamRoundTimer::ShowInHud( void )
  288. {
  289. return m_bShowInHUD;
  290. }
  291. //-----------------------------------------------------------------------------
  292. // Purpose: Gets the seconds left on the timer, paused or not.
  293. //-----------------------------------------------------------------------------
  294. float CTeamRoundTimer::GetTimeRemaining( void )
  295. {
  296. float flSecondsRemaining;
  297. if ( IsStopWatchTimer() == true && m_bInCaptureWatchState == true )
  298. {
  299. flSecondsRemaining = m_flTotalTime;
  300. }
  301. else
  302. {
  303. if ( m_bTimerPaused )
  304. {
  305. flSecondsRemaining = m_flTimeRemaining;
  306. }
  307. else
  308. {
  309. flSecondsRemaining = m_flTimerEndTime - gpGlobals->curtime;
  310. }
  311. }
  312. if ( flSecondsRemaining < 0 )
  313. {
  314. flSecondsRemaining = 0.0f;
  315. }
  316. return flSecondsRemaining;
  317. }
  318. //-----------------------------------------------------------------------------
  319. // Purpose:
  320. //-----------------------------------------------------------------------------
  321. void CTeamRoundTimer::SetCaptureWatchState( bool bCaptureWatch )
  322. {
  323. m_bInCaptureWatchState = bCaptureWatch;
  324. }
  325. //-----------------------------------------------------------------------------
  326. // Purpose:
  327. //-----------------------------------------------------------------------------
  328. int CTeamRoundTimer::GetTimerMaxLength( void )
  329. {
  330. if ( m_nState == RT_STATE_SETUP )
  331. {
  332. return m_nSetupTimeLength;
  333. }
  334. else
  335. {
  336. if ( m_nTimerMaxLength )
  337. return m_nTimerMaxLength;
  338. return m_nTimerLength;
  339. }
  340. }
  341. //-----------------------------------------------------------------------------
  342. // Purpose:
  343. //-----------------------------------------------------------------------------
  344. void CTeamRoundTimer::CalculateOutputMessages( void )
  345. {
  346. float flTime = GetTimeRemaining();
  347. #ifndef GAME_DLL
  348. // We need to add a couple seconds to the time remaining because we've probably lost ~0.5 seconds from the timer while
  349. // waiting for the update to arrive from the server and we don't want to miss any critical countdown messages. If the time
  350. // remaining is over 10 seconds...adding 2 seconds to the total when calculating our output messages won't affect anything
  351. if ( flTime > 10.0f )
  352. {
  353. flTime += 2.0f;
  354. }
  355. #endif
  356. m_bFireFinished = ( flTime > 0.0f );
  357. m_bFire5MinRemain = ( flTime >= 300.0f );
  358. m_bFire4MinRemain = ( flTime >= 240.0f );
  359. m_bFire3MinRemain = ( flTime >= 180.0f );
  360. m_bFire2MinRemain = ( flTime >= 120.0f );
  361. m_bFire1MinRemain = ( flTime >= 60.0f );
  362. m_bFire30SecRemain = ( flTime >= 30.0f );
  363. m_bFire10SecRemain = ( flTime >= 10.0f );
  364. m_bFire5SecRemain = ( flTime >= 5.0f );
  365. m_bFire4SecRemain = ( flTime >= 4.0f );
  366. m_bFire3SecRemain = ( flTime >= 3.0f );
  367. m_bFire2SecRemain = ( flTime >= 2.0f );
  368. m_bFire1SecRemain = ( flTime >= 1.0f );
  369. }
  370. #ifdef CLIENT_DLL
  371. //-----------------------------------------------------------------------------
  372. // Purpose:
  373. //-----------------------------------------------------------------------------
  374. void CTeamRoundTimer::ClientThink()
  375. {
  376. if ( IsDisabled() || m_bTimerPaused || IsInCommentaryMode() )
  377. return;
  378. if ( IsStopWatchTimer() == true && IsWatchingTimeStamps() == true )
  379. return;
  380. float flTime = GetTimeRemaining();
  381. if ( flTime <= 61.0 && m_bFire1MinRemain )
  382. {
  383. m_bFire1MinRemain = false;
  384. SendTimeWarning( RT_WARNING_60SECS );
  385. }
  386. else if ( flTime <= 31.0 && m_bFire30SecRemain )
  387. {
  388. m_bFire30SecRemain = false;
  389. SendTimeWarning( RT_WARNING_30SECS );
  390. }
  391. else if ( flTime <= 11.0 && m_bFire10SecRemain )
  392. {
  393. m_bFire10SecRemain = false;
  394. SendTimeWarning( RT_WARNING_10SECS );
  395. }
  396. else if ( flTime <= 6.0 && m_bFire5SecRemain )
  397. {
  398. m_bFire5SecRemain = false;
  399. SendTimeWarning( RT_WARNING_5SECS );
  400. }
  401. else if ( flTime <= 5.0 && m_bFire4SecRemain )
  402. {
  403. m_bFire4SecRemain = false;
  404. SendTimeWarning( RT_WARNING_4SECS );
  405. }
  406. else if ( flTime <= 4.0 && m_bFire3SecRemain )
  407. {
  408. m_bFire3SecRemain = false;
  409. SendTimeWarning( RT_WARNING_3SECS );
  410. }
  411. else if ( flTime <= 3.0 && m_bFire2SecRemain )
  412. {
  413. m_bFire2SecRemain = false;
  414. SendTimeWarning( RT_WARNING_2SECS );
  415. }
  416. else if ( flTime <= 2.0 && m_bFire1SecRemain )
  417. {
  418. m_bFire1SecRemain = false;
  419. SendTimeWarning( RT_WARNING_1SECS );
  420. }
  421. }
  422. //-----------------------------------------------------------------------------
  423. // Purpose:
  424. //-----------------------------------------------------------------------------
  425. void CTeamRoundTimer::OnPreDataChanged( DataUpdateType_t updateType )
  426. {
  427. BaseClass::OnPreDataChanged( updateType );
  428. m_nOldTimerLength = m_nTimerLength;
  429. m_nOldTimerState = m_nState;
  430. }
  431. //-----------------------------------------------------------------------------
  432. // Purpose:
  433. //-----------------------------------------------------------------------------
  434. void CTeamRoundTimer::OnDataChanged( DataUpdateType_t updateType )
  435. {
  436. BaseClass::OnDataChanged( updateType );
  437. if ( m_nOldTimerLength != m_nTimerLength )
  438. {
  439. // recalculate our output messages because the timer length has changed
  440. CalculateOutputMessages();
  441. }
  442. // if we were in state_setup and now we're in state_normal, play the bell sound
  443. if ( ( m_nOldTimerState == RT_STATE_SETUP ) && ( m_nState == RT_STATE_NORMAL ) )
  444. {
  445. SendTimeWarning( RT_WARNING_TIME_START );
  446. }
  447. }
  448. //-----------------------------------------------------------------------------
  449. // Purpose:
  450. //-----------------------------------------------------------------------------
  451. const char *CTeamRoundTimer::GetTimeWarningSound( int nWarning )
  452. {
  453. const char *pszRetVal;
  454. switch( nWarning )
  455. {
  456. case RT_WARNING_60SECS:
  457. if ( m_nState == RT_STATE_SETUP )
  458. {
  459. pszRetVal = ROUND_SETUP_60SECS;
  460. }
  461. else
  462. {
  463. pszRetVal = ROUND_TIMER_60SECS;
  464. }
  465. break;
  466. case RT_WARNING_30SECS:
  467. if ( m_nState == RT_STATE_SETUP )
  468. {
  469. pszRetVal = ROUND_SETUP_30SECS;
  470. }
  471. else
  472. {
  473. pszRetVal = ROUND_TIMER_30SECS;
  474. }
  475. break;
  476. case RT_WARNING_10SECS:
  477. if ( m_nState == RT_STATE_SETUP )
  478. {
  479. pszRetVal = ROUND_SETUP_10SECS;
  480. }
  481. else
  482. {
  483. pszRetVal = ROUND_TIMER_10SECS;
  484. }
  485. break;
  486. case RT_WARNING_5SECS:
  487. if ( m_nState == RT_STATE_SETUP )
  488. {
  489. pszRetVal = ROUND_SETUP_5SECS;
  490. }
  491. else
  492. {
  493. pszRetVal = ROUND_TIMER_5SECS;
  494. }
  495. break;
  496. case RT_WARNING_4SECS:
  497. if ( m_nState == RT_STATE_SETUP )
  498. {
  499. pszRetVal = ROUND_SETUP_4SECS;
  500. }
  501. else
  502. {
  503. pszRetVal = ROUND_TIMER_4SECS;
  504. }
  505. break;
  506. case RT_WARNING_3SECS:
  507. if ( m_nState == RT_STATE_SETUP )
  508. {
  509. pszRetVal = ROUND_SETUP_3SECS;
  510. }
  511. else
  512. {
  513. pszRetVal = ROUND_TIMER_3SECS;
  514. }
  515. break;
  516. case RT_WARNING_2SECS:
  517. if ( m_nState == RT_STATE_SETUP )
  518. {
  519. pszRetVal = ROUND_SETUP_2SECS;
  520. }
  521. else
  522. {
  523. pszRetVal = ROUND_TIMER_2SECS;
  524. }
  525. break;
  526. case RT_WARNING_1SECS:
  527. if ( m_nState == RT_STATE_SETUP )
  528. {
  529. pszRetVal = ROUND_SETUP_1SECS;
  530. }
  531. else
  532. {
  533. pszRetVal = ROUND_TIMER_1SECS;
  534. }
  535. break;
  536. case RT_WARNING_TIME_START:
  537. pszRetVal = ROUND_START_BELL;
  538. break;
  539. default:
  540. pszRetVal = "";
  541. }
  542. return pszRetVal;
  543. }
  544. //-----------------------------------------------------------------------------
  545. // Purpose:
  546. //-----------------------------------------------------------------------------
  547. void CTeamRoundTimer::SendTimeWarning( int nWarning )
  548. {
  549. // don't play sounds if the level designer has turned them off or if it's during the WaitingForPlayers time
  550. if ( !m_bTimerPaused && m_bAutoCountdown && !TeamplayRoundBasedRules()->IsInWaitingForPlayers() )
  551. {
  552. HACK_GETLOCALPLAYER_GUARD( "CTeamRoundTimer::SendTimeWarning" );
  553. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  554. if ( pPlayer )
  555. {
  556. if ( ObjectiveResource() )
  557. {
  558. bool bShouldPlaySound = false;
  559. if ( TeamplayRoundBasedRules()->IsInTournamentMode() == true && TeamplayRoundBasedRules()->IsInStopWatch() == true )
  560. {
  561. int iActiveTimer = ObjectiveResource()->GetTimerToShowInHUD();
  562. int iStopWatchTimer = ObjectiveResource()->GetStopWatchTimer();
  563. if ( IsStopWatchTimer() == true && IsWatchingTimeStamps() == false )
  564. {
  565. CTeamRoundTimer *pTimer = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( iActiveTimer ) );
  566. if ( pTimer && pTimer->IsTimerPaused() == false && pTimer->GetTimeRemaining() > GetTimeRemaining() )
  567. {
  568. bShouldPlaySound = true;
  569. }
  570. }
  571. else
  572. {
  573. CTeamRoundTimer *pStopWatch = dynamic_cast< CTeamRoundTimer* >( ClientEntityList().GetEnt( iStopWatchTimer ) );
  574. if ( ObjectiveResource()->GetTimerToShowInHUD() == entindex() )
  575. {
  576. if ( pStopWatch )
  577. {
  578. if ( pStopWatch->IsTimerPaused() == true )
  579. {
  580. bShouldPlaySound = true;
  581. }
  582. if ( pStopWatch->GetTimeRemaining() > GetTimeRemaining() && pStopWatch->IsWatchingTimeStamps() == false )
  583. {
  584. bShouldPlaySound = true;
  585. }
  586. if ( pStopWatch->IsWatchingTimeStamps() == true )
  587. {
  588. bShouldPlaySound = true;
  589. }
  590. }
  591. else
  592. {
  593. bShouldPlaySound = true;
  594. }
  595. }
  596. }
  597. }
  598. else
  599. {
  600. if( ObjectiveResource()->GetTimerToShowInHUD() == entindex())
  601. {
  602. bShouldPlaySound = true;
  603. }
  604. }
  605. if ( bShouldPlaySound == true )
  606. {
  607. pPlayer->EmitSound( GetTimeWarningSound( nWarning ) );
  608. }
  609. }
  610. }
  611. }
  612. }
  613. #else
  614. //-----------------------------------------------------------------------------
  615. // Purpose:
  616. //-----------------------------------------------------------------------------
  617. void CTeamRoundTimer::SetState( int nState )
  618. {
  619. m_nState = nState;
  620. if ( nState == RT_STATE_SETUP )
  621. {
  622. if ( IsStopWatchTimer() == false )
  623. {
  624. TeamplayRoundBasedRules()->SetSetup( true );
  625. }
  626. SetTimerThink( RT_THINK_SETUP );
  627. m_OnSetupStart.FireOutput( this, this );
  628. }
  629. else
  630. {
  631. if ( IsStopWatchTimer() == false )
  632. {
  633. TeamplayRoundBasedRules()->SetSetup( false );
  634. }
  635. SetTimerThink( RT_THINK_NORMAL );
  636. m_OnRoundStart.FireOutput( this, this );
  637. }
  638. }
  639. //-----------------------------------------------------------------------------
  640. // Purpose:
  641. //-----------------------------------------------------------------------------
  642. void CTeamRoundTimer::SetTimerThink( int nType )
  643. {
  644. if ( nType == RT_THINK_SETUP )
  645. {
  646. SetContextThink( &CTeamRoundTimer::RoundTimerSetupThink, gpGlobals->curtime + 0.05, ROUND_TIMER_SETUP_THINK );
  647. SetContextThink( NULL, 0, ROUND_TIMER_THINK );
  648. }
  649. else
  650. {
  651. SetContextThink( &CTeamRoundTimer::RoundTimerThink, gpGlobals->curtime + 0.05, ROUND_TIMER_THINK );
  652. SetContextThink( NULL, 0, ROUND_TIMER_SETUP_THINK );
  653. }
  654. }
  655. //-----------------------------------------------------------------------------
  656. // Purpose:
  657. //-----------------------------------------------------------------------------
  658. void CTeamRoundTimer::RoundTimerSetupThink( void )
  659. {
  660. if ( TeamplayRoundBasedRules()->IsInPreMatch() == true && IsDisabled() == false )
  661. {
  662. inputdata_t data;
  663. InputDisable( data );
  664. m_OnSetupFinished.FireOutput( this, this );
  665. }
  666. if ( IsDisabled() || m_bTimerPaused )
  667. {
  668. SetContextThink( &CTeamRoundTimer::RoundTimerSetupThink, gpGlobals->curtime + 0.05, ROUND_TIMER_SETUP_THINK );
  669. return;
  670. }
  671. float flTime = GetTimeRemaining();
  672. TeamplayRoundBasedRules()->SetOvertime( false );
  673. if ( flTime <= 0.0f && m_bFireFinished )
  674. {
  675. IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_setup_finished" );
  676. if ( event )
  677. {
  678. gameeventmanager->FireEvent( event );
  679. }
  680. m_OnSetupFinished.FireOutput( this, this );
  681. m_bFireFinished = false;
  682. SetTimeRemaining( m_nTimeToUseAfterSetupFinished );
  683. SetState( RT_STATE_NORMAL );
  684. if ( ShowInHud() && !TeamplayRoundBasedRules()->IsInWaitingForPlayers() )
  685. {
  686. UTIL_LogPrintf( "World triggered \"Round_Setup_End\"\n" );
  687. }
  688. return;
  689. }
  690. else if ( flTime <= 60.0 && m_bFire1MinRemain )
  691. {
  692. m_On1MinRemain.FireOutput( this, this );
  693. m_bFire1MinRemain = false;
  694. }
  695. else if ( flTime <= 30.0 && m_bFire30SecRemain )
  696. {
  697. m_On30SecRemain.FireOutput( this, this );
  698. m_bFire30SecRemain = false;
  699. }
  700. else if ( flTime <= 10.0 && m_bFire10SecRemain )
  701. {
  702. m_On10SecRemain.FireOutput( this, this );
  703. m_bFire10SecRemain = false;
  704. }
  705. else if ( flTime <= 5.0 && m_bFire5SecRemain )
  706. {
  707. m_On5SecRemain.FireOutput( this, this );
  708. m_bFire5SecRemain = false;
  709. }
  710. else if ( flTime <= 4.0 && m_bFire4SecRemain )
  711. {
  712. m_On4SecRemain.FireOutput( this, this );
  713. m_bFire4SecRemain = false;
  714. }
  715. else if ( flTime <= 3.0 && m_bFire3SecRemain )
  716. {
  717. m_On3SecRemain.FireOutput( this, this );
  718. m_bFire3SecRemain = false;
  719. }
  720. else if ( flTime <= 2.0 && m_bFire2SecRemain )
  721. {
  722. m_On2SecRemain.FireOutput( this, this );
  723. m_bFire2SecRemain = false;
  724. }
  725. else if ( flTime <= 1.0 && m_bFire1SecRemain )
  726. {
  727. m_On1SecRemain.FireOutput( this, this );
  728. m_bFire1SecRemain = false;
  729. }
  730. SetContextThink( &CTeamRoundTimer::RoundTimerSetupThink, gpGlobals->curtime + 0.05, ROUND_TIMER_SETUP_THINK );
  731. }
  732. //-----------------------------------------------------------------------------
  733. // Purpose:
  734. //-----------------------------------------------------------------------------
  735. void CTeamRoundTimer::RoundTimerThink( void )
  736. {
  737. if ( TeamplayRoundBasedRules()->IsInPreMatch() == true && IsDisabled() == false )
  738. {
  739. inputdata_t data;
  740. InputDisable( data );
  741. }
  742. if ( IsDisabled() || m_bTimerPaused || IsInCommentaryMode() || gpGlobals->eLoadType == MapLoad_Background )
  743. {
  744. SetContextThink( &CTeamRoundTimer::RoundTimerThink, gpGlobals->curtime + 0.05, ROUND_TIMER_THINK );
  745. return;
  746. }
  747. // Don't do anything when the game has been won or if we're loading a bugbait report
  748. if ( TeamplayRoundBasedRules()->RoundHasBeenWon() ||
  749. TeamplayRoundBasedRules()->IsLoadingBugBaitReport() )
  750. {
  751. // We want to stop timers when the round has been won, but we don't want to
  752. // force mapmakers to deal with having to unpause it. This little hack works around that.
  753. if ( !m_bTimerPaused )
  754. {
  755. PauseTimer();
  756. m_bPauseDueToWin = true;
  757. }
  758. SetContextThink( &CTeamRoundTimer::RoundTimerThink, gpGlobals->curtime + 0.05, ROUND_TIMER_THINK );
  759. return;
  760. }
  761. else if ( m_bPauseDueToWin )
  762. {
  763. ResumeTimer();
  764. m_bPauseDueToWin = false;
  765. }
  766. float flTime = GetTimeRemaining();
  767. if ( flTime > 0 && ShowInHud() ) // is this the timer we're showing in the HUD?
  768. {
  769. TeamplayRoundBasedRules()->SetOvertime( false );
  770. }
  771. if ( flTime <= 0.0f && m_bFireFinished )
  772. {
  773. // Allow the gamerules to prevent timer expiration (i.e. while a control point is contested)
  774. if ( !TeamplayGameRules()->TimerMayExpire() )
  775. {
  776. // we don't want the timer to keep going (negative time)
  777. m_flTimerEndTime = gpGlobals->curtime;
  778. // is this the timer we're showing in the HUD?
  779. if ( ShowInHud() )
  780. {
  781. TeamplayRoundBasedRules()->SetOvertime( true );
  782. }
  783. // Think slower
  784. SetContextThink( &CTeamRoundTimer::RoundTimerThink, gpGlobals->curtime + 1.0, ROUND_TIMER_THINK );
  785. return;
  786. }
  787. m_OnFinished.FireOutput( this, this );
  788. m_bFireFinished = false;
  789. }
  790. else if ( flTime <= 300.0 && m_bFire5MinRemain )
  791. {
  792. m_On5MinRemain.FireOutput( this, this );
  793. m_bFire5MinRemain = false;
  794. }
  795. else if ( flTime <= 240.0 && m_bFire4MinRemain )
  796. {
  797. m_On4MinRemain.FireOutput( this, this );
  798. m_bFire4MinRemain = false;
  799. }
  800. else if ( flTime <= 180.0 && m_bFire3MinRemain )
  801. {
  802. m_On3MinRemain.FireOutput( this, this );
  803. m_bFire3MinRemain = false;
  804. }
  805. else if ( flTime <= 120.0 && m_bFire2MinRemain )
  806. {
  807. m_On2MinRemain.FireOutput( this, this );
  808. m_bFire2MinRemain = false;
  809. }
  810. else if ( flTime <= 60.0 && m_bFire1MinRemain )
  811. {
  812. m_On1MinRemain.FireOutput( this, this );
  813. m_bFire1MinRemain = false;
  814. }
  815. else if ( flTime <= 30.0 && m_bFire30SecRemain )
  816. {
  817. m_On30SecRemain.FireOutput( this, this );
  818. m_bFire30SecRemain = false;
  819. }
  820. else if ( flTime <= 10.0 && m_bFire10SecRemain )
  821. {
  822. m_On10SecRemain.FireOutput( this, this );
  823. m_bFire10SecRemain = false;
  824. }
  825. else if ( flTime <= 5.0 && m_bFire5SecRemain )
  826. {
  827. m_On5SecRemain.FireOutput( this, this );
  828. m_bFire5SecRemain = false;
  829. }
  830. else if ( flTime <= 4.0 && m_bFire4SecRemain )
  831. {
  832. m_On4SecRemain.FireOutput( this, this );
  833. m_bFire4SecRemain = false;
  834. }
  835. else if ( flTime <= 3.0 && m_bFire3SecRemain )
  836. {
  837. m_On3SecRemain.FireOutput( this, this );
  838. m_bFire3SecRemain = false;
  839. }
  840. else if ( flTime <= 2.0 && m_bFire2SecRemain )
  841. {
  842. m_On2SecRemain.FireOutput( this, this );
  843. m_bFire2SecRemain = false;
  844. }
  845. else if ( flTime <= 1.0 && m_bFire1SecRemain )
  846. {
  847. m_On1SecRemain.FireOutput( this, this );
  848. m_bFire1SecRemain = false;
  849. }
  850. SetContextThink( &CTeamRoundTimer::RoundTimerThink, gpGlobals->curtime + 0.05, ROUND_TIMER_THINK );
  851. }
  852. //-----------------------------------------------------------------------------
  853. // Purpose:
  854. //-----------------------------------------------------------------------------
  855. void CTeamRoundTimer::InputRoundSpawn( inputdata_t &input )
  856. {
  857. if ( !m_bResetTimeOnRoundStart && ( m_nState == RT_STATE_NORMAL ) )
  858. {
  859. m_nTimeToUseAfterSetupFinished = GetTimeRemaining();
  860. }
  861. else
  862. {
  863. m_nTimeToUseAfterSetupFinished = m_nTimerInitialLength;
  864. }
  865. if ( m_nSetupTimeLength > 0 )
  866. {
  867. SetTimeRemaining( m_nSetupTimeLength );
  868. SetState( RT_STATE_SETUP );
  869. if ( ShowInHud() && !TeamplayRoundBasedRules()->IsInWaitingForPlayers() )
  870. {
  871. UTIL_LogPrintf( "World triggered \"Round_Setup_Begin\"\n" );
  872. }
  873. }
  874. else
  875. {
  876. SetTimeRemaining( m_nTimeToUseAfterSetupFinished );
  877. SetState( RT_STATE_NORMAL );
  878. }
  879. if ( !m_bStartPaused && !TeamplayRoundBasedRules()->IsInWaitingForPlayers() )
  880. {
  881. ResumeTimer();
  882. }
  883. }
  884. //-----------------------------------------------------------------------------
  885. // Purpose: To set the initial timer duration
  886. //-----------------------------------------------------------------------------
  887. void CTeamRoundTimer::SetTimeRemaining( int iTimerSeconds )
  888. {
  889. if ( IsDisabled() )
  890. return;
  891. // make sure we don't go over our max length
  892. if ( m_nTimerMaxLength > 0 )
  893. {
  894. if ( iTimerSeconds > m_nTimerMaxLength )
  895. {
  896. iTimerSeconds = m_nTimerMaxLength;
  897. }
  898. }
  899. m_flTimeRemaining = (float)iTimerSeconds;
  900. m_flTimerEndTime = gpGlobals->curtime + m_flTimeRemaining;
  901. m_nTimerLength = iTimerSeconds;
  902. CalculateOutputMessages();
  903. }
  904. //-----------------------------------------------------------------------------
  905. // Purpose: To set the initial timer duration
  906. //-----------------------------------------------------------------------------
  907. void CTeamRoundTimer::SetStopWatchTimeStamp( void )
  908. {
  909. if ( IsDisabled() )
  910. return;
  911. if ( IsWatchingTimeStamps() == false )
  912. return;
  913. m_flTotalTime = m_flTotalTime + (gpGlobals->curtime - m_flTimerEndTime);
  914. m_flTimerEndTime = gpGlobals->curtime;
  915. CalculateOutputMessages();
  916. }
  917. //-----------------------------------------------------------------------------
  918. // Purpose: Timer is paused at round end, stops the countdown
  919. //-----------------------------------------------------------------------------
  920. void CTeamRoundTimer::PauseTimer( void )
  921. {
  922. if ( IsDisabled() )
  923. return;
  924. if ( m_bTimerPaused == false )
  925. {
  926. m_bTimerPaused = true;
  927. m_flTimeRemaining = m_flTimerEndTime - gpGlobals->curtime;
  928. }
  929. // Clear pause on win flag, because we've been set by the mapmaker
  930. m_bPauseDueToWin = false;
  931. }
  932. //-----------------------------------------------------------------------------
  933. // Purpose: To start or re-start the timer after a pause
  934. //-----------------------------------------------------------------------------
  935. void CTeamRoundTimer::ResumeTimer( void )
  936. {
  937. if ( IsDisabled() )
  938. return;
  939. if ( m_bTimerPaused == true )
  940. {
  941. m_bTimerPaused = false;
  942. if ( IsStopWatchTimer() == true && m_bInCaptureWatchState == true )
  943. {
  944. m_flTimerEndTime = gpGlobals->curtime;
  945. }
  946. else
  947. {
  948. m_flTimerEndTime = gpGlobals->curtime + m_flTimeRemaining;
  949. }
  950. }
  951. }
  952. //-----------------------------------------------------------------------------
  953. // Purpose: Add seconds to the timer while it is running or paused
  954. //-----------------------------------------------------------------------------
  955. void CTeamRoundTimer::AddTimerSeconds( int iSecondsToAdd, int iTeamResponsible /* = TEAM_UNASSIGNED*/ )
  956. {
  957. if ( IsDisabled() )
  958. return;
  959. if ( TeamplayRoundBasedRules()->InStalemate() )
  960. return;
  961. // we only want to add time if we're round_running or team_win so the control points
  962. // don't add time when they try to set their default owner when the map is first loading
  963. if ( TeamplayRoundBasedRules()->State_Get() != GR_STATE_RND_RUNNING && TeamplayRoundBasedRules()->State_Get() != GR_STATE_TEAM_WIN )
  964. return;
  965. if ( m_nTimerMaxLength > 0 )
  966. {
  967. // will adding this many seconds push us over our max length?
  968. if ( GetTimeRemaining() + iSecondsToAdd > m_nTimerMaxLength )
  969. {
  970. // adjust to only add up to our max length
  971. iSecondsToAdd = m_nTimerMaxLength - GetTimeRemaining();
  972. }
  973. }
  974. if ( m_bTimerPaused )
  975. {
  976. m_flTimeRemaining += (float)iSecondsToAdd;
  977. }
  978. else
  979. {
  980. m_flTimerEndTime += (float)iSecondsToAdd;
  981. }
  982. m_nTimerLength += iSecondsToAdd;
  983. CalculateOutputMessages();
  984. if ( ObjectiveResource() && ObjectiveResource()->GetTimerInHUD() == entindex() )
  985. {
  986. if ( !TeamplayRoundBasedRules()->InStalemate() && !TeamplayRoundBasedRules()->RoundHasBeenWon() )
  987. {
  988. if ( iTeamResponsible >= LAST_SHARED_TEAM+1 )
  989. {
  990. for ( int iTeam = LAST_SHARED_TEAM+1 ; iTeam < GetNumberOfTeams(); iTeam++ )
  991. {
  992. if ( iTeam == iTeamResponsible )
  993. {
  994. CTeamRecipientFilter filter( iTeam, true );
  995. EmitSound( filter, entindex(), ROUND_TIMER_TIME_ADDED_WINNER );
  996. }
  997. else
  998. {
  999. CTeamRecipientFilter filter( iTeam, true );
  1000. EmitSound( filter, entindex(), ROUND_TIMER_TIME_ADDED_LOSER );
  1001. }
  1002. }
  1003. }
  1004. else
  1005. {
  1006. CReliableBroadcastRecipientFilter filter;
  1007. EmitSound( filter, entindex(), ROUND_TIMER_TIME_ADDED );
  1008. }
  1009. }
  1010. // is this the timer we're showing in the HUD?
  1011. if ( m_bShowInHUD )
  1012. {
  1013. IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_timer_time_added" );
  1014. if ( event )
  1015. {
  1016. event->SetInt( "timer", entindex() );
  1017. event->SetInt( "seconds_added", iSecondsToAdd );
  1018. gameeventmanager->FireEvent( event );
  1019. }
  1020. }
  1021. }
  1022. }
  1023. //-----------------------------------------------------------------------------
  1024. // Purpose: The timer is always transmitted to clients
  1025. //-----------------------------------------------------------------------------
  1026. int CTeamRoundTimer::UpdateTransmitState()
  1027. {
  1028. // ALWAYS transmit to all clients.
  1029. return SetTransmitState( FL_EDICT_ALWAYS );
  1030. }
  1031. //-----------------------------------------------------------------------------
  1032. // Purpose:
  1033. //-----------------------------------------------------------------------------
  1034. void CTeamRoundTimer::InputPause( inputdata_t &input )
  1035. {
  1036. PauseTimer();
  1037. }
  1038. //-----------------------------------------------------------------------------
  1039. // Purpose:
  1040. //-----------------------------------------------------------------------------
  1041. void CTeamRoundTimer::InputResume( inputdata_t &input )
  1042. {
  1043. ResumeTimer();
  1044. }
  1045. //-----------------------------------------------------------------------------
  1046. // Purpose:
  1047. //-----------------------------------------------------------------------------
  1048. void CTeamRoundTimer::InputSetTime( inputdata_t &input )
  1049. {
  1050. if ( IsStopWatchTimer() == true && IsWatchingTimeStamps() == true )
  1051. {
  1052. SetStopWatchTimeStamp();
  1053. }
  1054. else
  1055. {
  1056. int nSeconds = input.value.Int();
  1057. SetTimeRemaining( nSeconds );
  1058. }
  1059. }
  1060. //-----------------------------------------------------------------------------
  1061. // Purpose:
  1062. //-----------------------------------------------------------------------------
  1063. void CTeamRoundTimer::InputSetMaxTime( inputdata_t &input )
  1064. {
  1065. int nSeconds = input.value.Int();
  1066. m_nTimerMaxLength = nSeconds;
  1067. if ( m_nTimerMaxLength > 0 )
  1068. {
  1069. // make sure our current time is not above the max length
  1070. if ( GetTimeRemaining() > m_nTimerMaxLength )
  1071. {
  1072. SetTimeRemaining( m_nTimerMaxLength );
  1073. }
  1074. }
  1075. }
  1076. //-----------------------------------------------------------------------------
  1077. // Purpose:
  1078. //-----------------------------------------------------------------------------
  1079. void CTeamRoundTimer::InputAddTime( inputdata_t &input )
  1080. {
  1081. int nSeconds = input.value.Int();
  1082. AddTimerSeconds( nSeconds );
  1083. }
  1084. //-----------------------------------------------------------------------------
  1085. // Purpose:
  1086. //-----------------------------------------------------------------------------
  1087. void CTeamRoundTimer::InputAddTeamTime( inputdata_t &input )
  1088. {
  1089. char token[128];
  1090. const char *p = STRING( input.value.StringID() );
  1091. int nTeam = TEAM_UNASSIGNED;
  1092. int nSeconds = 0;
  1093. // get the team
  1094. p = nexttoken( token, p, ' ' );
  1095. if ( token )
  1096. {
  1097. nTeam = Q_atoi( token );
  1098. }
  1099. // get the time
  1100. p = nexttoken( token, p, ' ' );
  1101. if ( token )
  1102. {
  1103. nSeconds = Q_atoi( token );
  1104. }
  1105. if ( nSeconds != 0 )
  1106. {
  1107. AddTimerSeconds( nSeconds, nTeam );
  1108. }
  1109. }
  1110. //-----------------------------------------------------------------------------
  1111. // Purpose:
  1112. //-----------------------------------------------------------------------------
  1113. void CTeamRoundTimer::InputRestart( inputdata_t &input )
  1114. {
  1115. SetTimeRemaining( m_nTimerInitialLength );
  1116. }
  1117. //-----------------------------------------------------------------------------
  1118. // Purpose:
  1119. //-----------------------------------------------------------------------------
  1120. void CTeamRoundTimer::InputEnable( inputdata_t &input )
  1121. {
  1122. m_bIsDisabled = false;
  1123. ResumeTimer();
  1124. if ( m_bShowInHUD )
  1125. {
  1126. SetActiveTimer( this );
  1127. }
  1128. if ( IsStopWatchTimer() == true && IsWatchingTimeStamps() == true )
  1129. {
  1130. m_flTimerEndTime = gpGlobals->curtime;
  1131. }
  1132. }
  1133. //-----------------------------------------------------------------------------
  1134. // Purpose:
  1135. //-----------------------------------------------------------------------------
  1136. void CTeamRoundTimer::InputDisable( inputdata_t &input )
  1137. {
  1138. PauseTimer();
  1139. m_bIsDisabled = true;
  1140. if ( m_bShowInHUD )
  1141. {
  1142. SetActiveTimer( NULL );
  1143. }
  1144. }
  1145. //-----------------------------------------------------------------------------
  1146. // Purpose:
  1147. //-----------------------------------------------------------------------------
  1148. void CTeamRoundTimer::InputShowInHUD( inputdata_t &input )
  1149. {
  1150. int nShow = input.value.Int();
  1151. if ( m_bShowInHUD && !nShow )
  1152. {
  1153. SetActiveTimer( NULL );
  1154. }
  1155. else if ( nShow == 1 )
  1156. {
  1157. SetActiveTimer( this );
  1158. }
  1159. m_bShowInHUD = ( nShow == 1 );
  1160. }
  1161. //-----------------------------------------------------------------------------
  1162. // Purpose:
  1163. //-----------------------------------------------------------------------------
  1164. void CTeamRoundTimer::InputAutoCountdown( inputdata_t &input )
  1165. {
  1166. int nAuto = input.value.Int();
  1167. SetAutoCountdown( nAuto == 1 );
  1168. }
  1169. //-----------------------------------------------------------------------------
  1170. // Purpose:
  1171. //-----------------------------------------------------------------------------
  1172. void CTeamRoundTimer::SetActiveTimer( CTeamRoundTimer *pNewlyActive )
  1173. {
  1174. CBaseEntity *pChosenTimer = pNewlyActive;
  1175. // Ensure all other timers are off.
  1176. CBaseEntity *pEntity = NULL;
  1177. while ((pEntity = gEntList.FindEntityByClassname( pEntity, "team_round_timer" )) != NULL)
  1178. {
  1179. if ( pEntity == pNewlyActive )
  1180. continue;
  1181. CTeamRoundTimer *pTimer = assert_cast< CTeamRoundTimer* >( pEntity );
  1182. if ( !pTimer->IsDisabled() && pTimer->ShowInHud() )
  1183. {
  1184. if ( pChosenTimer )
  1185. {
  1186. // Turn off all other hud timers
  1187. pTimer->SetShowInHud( false );
  1188. }
  1189. else
  1190. {
  1191. // Found a timer. Use it.
  1192. pChosenTimer = pTimer;
  1193. }
  1194. }
  1195. }
  1196. ObjectiveResource()->SetTimerInHUD( pChosenTimer );
  1197. }
  1198. #endif