summaryrefslogtreecommitdiff
path: root/game/server/tf2/info_act.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/server/tf2/info_act.cpp')
-rw-r--r--game/server/tf2/info_act.cpp587
1 files changed, 587 insertions, 0 deletions
diff --git a/game/server/tf2/info_act.cpp b/game/server/tf2/info_act.cpp
new file mode 100644
index 0000000..2f18cc5
--- /dev/null
+++ b/game/server/tf2/info_act.cpp
@@ -0,0 +1,587 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "EntityOutput.h"
+#include "EntityList.h"
+#include "tf_team.h"
+#include "tier1/strtools.h"
+#include "baseentity.h"
+#include "tf_shareddefs.h"
+#include "info_act.h"
+
+// Global pointer to the current act
+CHandle<CInfoAct> g_hCurrentAct;
+
+BEGIN_DATADESC( CInfoAct )
+
+ // inputs
+ DEFINE_INPUTFUNC( FIELD_VOID, "Start", InputStart ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "FinishWinNone", InputFinishWinNone ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "FinishWin1", InputFinishWin1 ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "FinishWin2", InputFinishWin2 ),
+ DEFINE_INPUTFUNC( FIELD_FLOAT, "AddTime", InputAddTime ),
+
+ // outputs
+ DEFINE_OUTPUT( m_OnStarted, "OnStarted" ),
+ DEFINE_OUTPUT( m_OnFinishedTeamNone, "OnFinishedWinNone" ),
+ DEFINE_OUTPUT( m_OnFinishedTeam1, "OnFinishedWin1" ),
+ DEFINE_OUTPUT( m_OnFinishedTeam2, "OnFinishedWin2" ),
+ DEFINE_OUTPUT( m_OnTimerExpired, "OnTimerExpired" ),
+
+ DEFINE_OUTPUT( m_Respawn1Team1Events[CInfoAct::RESPAWN_TIMER_90_REMAINING], "OnRespawn1Team1_90sec" ),
+ DEFINE_OUTPUT( m_Respawn1Team1Events[CInfoAct::RESPAWN_TIMER_60_REMAINING], "OnRespawn1Team1_60sec" ),
+ DEFINE_OUTPUT( m_Respawn1Team1Events[CInfoAct::RESPAWN_TIMER_45_REMAINING], "OnRespawn1Team1_45sec" ),
+ DEFINE_OUTPUT( m_Respawn1Team1Events[CInfoAct::RESPAWN_TIMER_30_REMAINING], "OnRespawn1Team1_30sec" ),
+ DEFINE_OUTPUT( m_Respawn1Team1Events[CInfoAct::RESPAWN_TIMER_10_REMAINING], "OnRespawn1Team1_10sec" ),
+ DEFINE_OUTPUT( m_Respawn1Team1Events[CInfoAct::RESPAWN_TIMER_0_REMAINING], "OnRespawn1Team1" ),
+ DEFINE_OUTPUT( m_Respawn1Team1TimeRemaining, "Respawn1Team1TimeRemaining" ),
+
+ DEFINE_OUTPUT( m_Respawn2Team1Events[CInfoAct::RESPAWN_TIMER_90_REMAINING], "OnRespawn2Team1_90sec" ),
+ DEFINE_OUTPUT( m_Respawn2Team1Events[CInfoAct::RESPAWN_TIMER_60_REMAINING], "OnRespawn2Team1_60sec" ),
+ DEFINE_OUTPUT( m_Respawn2Team1Events[CInfoAct::RESPAWN_TIMER_45_REMAINING], "OnRespawn2Team1_45sec" ),
+ DEFINE_OUTPUT( m_Respawn2Team1Events[CInfoAct::RESPAWN_TIMER_30_REMAINING], "OnRespawn2Team1_30sec" ),
+ DEFINE_OUTPUT( m_Respawn2Team1Events[CInfoAct::RESPAWN_TIMER_10_REMAINING], "OnRespawn2Team1_10sec" ),
+ DEFINE_OUTPUT( m_Respawn2Team1Events[CInfoAct::RESPAWN_TIMER_0_REMAINING], "OnRespawn2Team1" ),
+ DEFINE_OUTPUT( m_Respawn2Team1TimeRemaining, "Respawn2Team1TimeRemaining" ),
+
+ DEFINE_OUTPUT( m_Respawn1Team2Events[CInfoAct::RESPAWN_TIMER_90_REMAINING], "OnRespawn1Team2_90sec" ),
+ DEFINE_OUTPUT( m_Respawn1Team2Events[CInfoAct::RESPAWN_TIMER_60_REMAINING], "OnRespawn1Team2_60sec" ),
+ DEFINE_OUTPUT( m_Respawn1Team2Events[CInfoAct::RESPAWN_TIMER_45_REMAINING], "OnRespawn1Team2_45sec" ),
+ DEFINE_OUTPUT( m_Respawn1Team2Events[CInfoAct::RESPAWN_TIMER_30_REMAINING], "OnRespawn1Team2_30sec" ),
+ DEFINE_OUTPUT( m_Respawn1Team2Events[CInfoAct::RESPAWN_TIMER_10_REMAINING], "OnRespawn1Team2_10sec" ),
+ DEFINE_OUTPUT( m_Respawn1Team2Events[CInfoAct::RESPAWN_TIMER_0_REMAINING], "OnRespawn1Team2" ),
+ DEFINE_OUTPUT( m_Respawn1Team2TimeRemaining, "Respawn1Team2TimeRemaining" ),
+
+ DEFINE_OUTPUT( m_Respawn2Team2Events[CInfoAct::RESPAWN_TIMER_90_REMAINING], "OnRespawn2Team2_90sec" ),
+ DEFINE_OUTPUT( m_Respawn2Team2Events[CInfoAct::RESPAWN_TIMER_60_REMAINING], "OnRespawn2Team2_60sec" ),
+ DEFINE_OUTPUT( m_Respawn2Team2Events[CInfoAct::RESPAWN_TIMER_45_REMAINING], "OnRespawn2Team2_45sec" ),
+ DEFINE_OUTPUT( m_Respawn2Team2Events[CInfoAct::RESPAWN_TIMER_30_REMAINING], "OnRespawn2Team2_30sec" ),
+ DEFINE_OUTPUT( m_Respawn2Team2Events[CInfoAct::RESPAWN_TIMER_10_REMAINING], "OnRespawn2Team2_10sec" ),
+ DEFINE_OUTPUT( m_Respawn2Team2Events[CInfoAct::RESPAWN_TIMER_0_REMAINING], "OnRespawn2Team2" ),
+ DEFINE_OUTPUT( m_Respawn2Team2TimeRemaining, "Respawn2Team2TimeRemaining" ),
+
+ DEFINE_OUTPUT( m_Team1RespawnDelayDone, "OnTeam1RespawnDelayDone" ),
+ DEFINE_OUTPUT( m_Team2RespawnDelayDone, "OnTeam2RespawnDelayDone" ),
+
+ // keys
+ DEFINE_KEYFIELD_NOT_SAVED( m_iActNumber, FIELD_INTEGER, "ActNumber" ),
+ DEFINE_KEYFIELD_NOT_SAVED( m_flActTimeLimit, FIELD_FLOAT, "ActTimeLimit" ),
+ DEFINE_KEYFIELD_NOT_SAVED( m_iszIntermissionCamera, FIELD_STRING, "IntermissionCamera" ),
+ DEFINE_KEYFIELD_NOT_SAVED( m_nRespawn1Team1Time, FIELD_INTEGER, "Respawn1Team1Time" ),
+ DEFINE_KEYFIELD_NOT_SAVED( m_nRespawn2Team1Time, FIELD_INTEGER, "Respawn2Team1Time" ),
+ DEFINE_KEYFIELD_NOT_SAVED( m_nRespawn1Team2Time, FIELD_INTEGER, "Respawn1Team2Time" ),
+ DEFINE_KEYFIELD_NOT_SAVED( m_nRespawn2Team2Time, FIELD_INTEGER, "Respawn2Team2Time" ),
+ DEFINE_KEYFIELD_NOT_SAVED( m_nRespawnTeam1Delay, FIELD_INTEGER, "RespawnTeam1InitialDelay" ),
+ DEFINE_KEYFIELD_NOT_SAVED( m_nRespawnTeam2Delay, FIELD_INTEGER, "RespawnTeam2InitialDelay" ),
+
+ // functions
+ DEFINE_FUNCTION( ActThink ),
+ DEFINE_FUNCTION( ActThinkEndActOverlayTime ),
+ DEFINE_FUNCTION( RespawnTimerThink ),
+ DEFINE_FUNCTION( Team1RespawnDelayThink ),
+ DEFINE_FUNCTION( Team2RespawnDelayThink ),
+
+END_DATADESC()
+
+IMPLEMENT_SERVERCLASS_ST(CInfoAct, DT_InfoAct)
+ SendPropInt(SENDINFO(m_iActNumber), 5 ),
+ SendPropInt(SENDINFO(m_spawnflags), SF_ACT_BITS, SPROP_UNSIGNED ),
+ SendPropFloat(SENDINFO(m_flActTimeLimit), 12 ),
+ SendPropInt(SENDINFO(m_nRespawn1Team1Time), 8 ),
+ SendPropInt(SENDINFO(m_nRespawn2Team1Time), 8 ),
+ SendPropInt(SENDINFO(m_nRespawn1Team2Time), 8 ),
+ SendPropInt(SENDINFO(m_nRespawn2Team2Time), 8 ),
+ SendPropInt(SENDINFO(m_nRespawnTeam1Delay), 8 ),
+ SendPropInt(SENDINFO(m_nRespawnTeam2Delay), 8 ),
+END_SEND_TABLE();
+
+LINK_ENTITY_TO_CLASS( info_act, CInfoAct );
+
+
+#define RESPAWN_TIMER_CONTEXT "RespawnTimerThink"
+#define RESPAWN_TEAM_1_DELAY_CONTEXT "RespawnTeam1DelayThink"
+#define RESPAWN_TEAM_2_DELAY_CONTEXT "RespawnTeam2DelayThink"
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CInfoAct::CInfoAct( void )
+{
+ // No act == -1
+ m_iActNumber = -1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CInfoAct::UpdateTransmitState()
+{
+ return SetTransmitState( FL_EDICT_ALWAYS );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CInfoAct::Spawn( void )
+{
+ m_flActStartedAt = 0;
+ m_iWinners = 0;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Set up respawn timers
+//-----------------------------------------------------------------------------
+void CInfoAct::SetUpRespawnTimers()
+{
+ // NOTE: Need to add the second there so the respawn timers don't immediately trigger
+ SetContextThink( RespawnTimerThink, gpGlobals->curtime + 1.0f, RESPAWN_TIMER_CONTEXT );
+
+ if (m_nRespawnTeam1Delay != 0)
+ {
+ SetContextThink( Team1RespawnDelayThink, gpGlobals->curtime + m_nRespawnTeam1Delay, RESPAWN_TEAM_1_DELAY_CONTEXT );
+ }
+ else
+ {
+ m_Team1RespawnDelayDone.FireOutput( this, this );
+ }
+
+ if (m_nRespawnTeam2Delay != 0)
+ {
+ SetContextThink( Team2RespawnDelayThink, gpGlobals->curtime + m_nRespawnTeam2Delay, RESPAWN_TEAM_2_DELAY_CONTEXT );
+ }
+ else
+ {
+ m_Team2RespawnDelayDone.FireOutput( this, this );
+ }
+}
+
+void CInfoAct::ShutdownRespawnTimers()
+{
+ SetContextThink( NULL, 0, RESPAWN_TIMER_CONTEXT );
+ SetContextThink( NULL, 0, RESPAWN_TEAM_1_DELAY_CONTEXT );
+ SetContextThink( NULL, 0, RESPAWN_TEAM_2_DELAY_CONTEXT );
+}
+
+
+//-----------------------------------------------------------------------------
+// Respawn delay
+//-----------------------------------------------------------------------------
+void CInfoAct::Team1RespawnDelayThink()
+{
+ m_Team1RespawnDelayDone.FireOutput( this, this );
+ SetContextThink( NULL, 0, RESPAWN_TEAM_1_DELAY_CONTEXT );
+}
+
+void CInfoAct::Team2RespawnDelayThink()
+{
+ m_Team2RespawnDelayDone.FireOutput( this, this );
+ SetContextThink( NULL, 0, RESPAWN_TEAM_2_DELAY_CONTEXT );
+}
+
+
+//-----------------------------------------------------------------------------
+// Computes the time remaining
+//-----------------------------------------------------------------------------
+int CInfoAct::ComputeTimeRemaining( int nPeriod, int nDelay )
+{
+ if (nPeriod <= 0)
+ return -1;
+
+ int nTimeDelta = (int)(gpGlobals->curtime - m_flActStartedAt);
+ Assert( nTimeDelta >= 0 );
+ nTimeDelta -= nDelay;
+
+ // This case takes care of the initial spawn delay time...
+ if (nTimeDelta <= 0)
+ {
+ return nPeriod - nTimeDelta;
+ }
+
+ int nFactor = nTimeDelta / nPeriod;
+ int nTimeRemainder = nTimeDelta - nFactor * nPeriod;
+ if (nTimeRemainder == 0)
+ return 0;
+
+ return nPeriod - nTimeRemainder;
+}
+
+
+//-----------------------------------------------------------------------------
+// Fires respawn events
+//-----------------------------------------------------------------------------
+void CInfoAct::FireRespawnEvents( int nTimeRemaining, COutputEvent *pRespawnEvents, COutputInt &respawnTime )
+{
+ if (nTimeRemaining < 0)
+ return;
+
+ switch (nTimeRemaining)
+ {
+ case 90:
+ pRespawnEvents[RESPAWN_TIMER_90_REMAINING].FireOutput( this, this );
+ break;
+ case 60:
+ pRespawnEvents[RESPAWN_TIMER_60_REMAINING].FireOutput( this, this );
+ break;
+ case 45:
+ pRespawnEvents[RESPAWN_TIMER_45_REMAINING].FireOutput( this, this );
+ break;
+ case 30:
+ pRespawnEvents[RESPAWN_TIMER_30_REMAINING].FireOutput( this, this );
+ break;
+ case 10:
+ pRespawnEvents[RESPAWN_TIMER_10_REMAINING].FireOutput( this, this );
+ break;
+ case 0:
+ pRespawnEvents[RESPAWN_TIMER_0_REMAINING].FireOutput( this, this );
+ break;
+ default:
+ break;
+ }
+
+ respawnTime.Set( nTimeRemaining, this, this );
+}
+
+
+//-----------------------------------------------------------------------------
+// Respawn timers
+//-----------------------------------------------------------------------------
+void CInfoAct::RespawnTimerThink()
+{
+ int nTimeRemaining = ComputeTimeRemaining( m_nRespawn1Team1Time, m_nRespawnTeam1Delay );
+ FireRespawnEvents( nTimeRemaining, m_Respawn1Team1Events, m_Respawn1Team1TimeRemaining );
+
+ nTimeRemaining = ComputeTimeRemaining( m_nRespawn2Team1Time, m_nRespawnTeam1Delay );
+ FireRespawnEvents( nTimeRemaining, m_Respawn2Team1Events, m_Respawn2Team1TimeRemaining );
+
+ nTimeRemaining = ComputeTimeRemaining( m_nRespawn1Team2Time, m_nRespawnTeam2Delay );
+ FireRespawnEvents( nTimeRemaining, m_Respawn1Team2Events, m_Respawn1Team2TimeRemaining );
+
+ nTimeRemaining = ComputeTimeRemaining( m_nRespawn2Team2Time, m_nRespawnTeam2Delay );
+ FireRespawnEvents( nTimeRemaining, m_Respawn2Team2Events, m_Respawn2Team2TimeRemaining );
+
+ SetNextThink( gpGlobals->curtime + 1.0f, RESPAWN_TIMER_CONTEXT );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: The act has started
+//-----------------------------------------------------------------------------
+void CInfoAct::StartAct( void )
+{
+ // FIXME: Should this change?
+ // Don't allow two simultaneous acts
+ if (g_hCurrentAct)
+ {
+ g_hCurrentAct->FinishAct( );
+ }
+
+ // Set the global act to this
+ g_hCurrentAct = this;
+
+ m_flActStartedAt = gpGlobals->curtime;
+ m_OnStarted.FireOutput( this, this );
+
+ // Do we have a timelimit?
+ if ( m_flActTimeLimit )
+ {
+ SetNextThink( gpGlobals->curtime + m_flActTimeLimit );
+ SetThink( ActThink );
+ }
+
+ SetUpRespawnTimers();
+
+ // Tell all the clients
+ CReliableBroadcastRecipientFilter filter;
+
+ UserMessageBegin( filter, "ActBegin" );
+ WRITE_BYTE( (byte)m_iActNumber );
+ WRITE_FLOAT( m_flActStartedAt );
+ MessageEnd();
+
+ // If we're not an intermission, clean up
+ if ( !HasSpawnFlags( SF_ACT_INTERMISSION ) )
+ {
+ CleanupOnActStart();
+ }
+
+ // Cycle through all players and start the act
+ for ( int i = 1; i <= gpGlobals->maxClients; i++ )
+ {
+ CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)UTIL_PlayerByIndex( i );
+ if ( pPlayer )
+ {
+ // Am I an intermission?
+ if ( HasSpawnFlags( SF_ACT_INTERMISSION ) )
+ {
+ StartIntermission( pPlayer );
+ }
+ else
+ {
+ StartActOverlayTime( pPlayer );
+ }
+ }
+ }
+
+ // Think again soon, to remove player locks
+ if ( !HasSpawnFlags(SF_ACT_INTERMISSION) )
+ {
+ SetNextThink( gpGlobals->curtime + MIN_ACT_OVERLAY_TIME );
+ SetThink( ActThinkEndActOverlayTime );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Update a client who joined during the middle of an act
+//-----------------------------------------------------------------------------
+void CInfoAct::UpdateClient( CBaseTFPlayer *pPlayer )
+{
+ CSingleUserRecipientFilter user( pPlayer );
+ user.MakeReliable();
+
+ UserMessageBegin( user, "ActBegin" );
+ WRITE_BYTE( (byte)m_iActNumber );
+ WRITE_FLOAT( m_flActStartedAt );
+ MessageEnd();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: The act has finished
+//-----------------------------------------------------------------------------
+void CInfoAct::FinishAct( )
+{
+ if ( g_hCurrentAct.Get() != this )
+ {
+ DevWarning( 2, "Attempted to finish an act which wasn't started!\n" );
+ return;
+ }
+
+ ShutdownRespawnTimers();
+
+ switch( m_iWinners)
+ {
+ case 0:
+ m_OnFinishedTeamNone.FireOutput( this, this );
+ break;
+
+ case 1:
+ m_OnFinishedTeam1.FireOutput( this, this );
+ break;
+
+ case 2:
+ m_OnFinishedTeam2.FireOutput( this, this );
+ break;
+
+ default:
+ Assert(0);
+ break;
+ }
+
+ g_hCurrentAct = NULL;
+
+ // Tell all the clients
+ CReliableBroadcastRecipientFilter filter;
+ UserMessageBegin( filter, "ActEnd" );
+ WRITE_BYTE( m_iWinners );
+ MessageEnd();
+
+ // Am I an intermission?
+ if ( HasSpawnFlags( SF_ACT_INTERMISSION ) )
+ {
+ // Cycle through all players and end the intermission for them
+ for ( int i = 1; i <= gpGlobals->maxClients; i++ )
+ {
+ CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)UTIL_PlayerByIndex( i );
+ if ( pPlayer )
+ {
+ EndIntermission( pPlayer );
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CInfoAct::ActThink( void )
+{
+ m_OnTimerExpired.FireOutput( this,this );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Force the players not to move to give them time to read the act overlays
+//-----------------------------------------------------------------------------
+void CInfoAct::StartActOverlayTime( CBaseTFPlayer *pPlayer )
+{
+ // Lock the player in place
+ pPlayer->CleanupOnActStart();
+ pPlayer->LockPlayerInPlace();
+
+ if ( pPlayer->GetActiveWeapon() )
+ {
+ pPlayer->GetActiveWeapon()->Holster();
+ }
+
+ pPlayer->m_Local.m_iHideHUD |= (HIDEHUD_WEAPONSELECTION | HIDEHUD_HEALTH);
+ pPlayer->GetLocalData()->m_bForceMapOverview = true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Release the players after overlay time has finished
+//-----------------------------------------------------------------------------
+void CInfoAct::EndActOverlayTime( CBaseTFPlayer *pPlayer )
+{
+ // Release the player
+ pPlayer->UnlockPlayer();
+
+ if ( pPlayer->GetActiveWeapon() )
+ {
+ pPlayer->GetActiveWeapon()->Deploy();
+ }
+
+ pPlayer->m_Local.m_iHideHUD &= ~(HIDEHUD_WEAPONSELECTION | HIDEHUD_HEALTH);
+ pPlayer->GetLocalData()->m_bForceMapOverview = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Unlock the players after an act has started
+//-----------------------------------------------------------------------------
+void CInfoAct::ActThinkEndActOverlayTime( void )
+{
+ // Cycle through all players and end the intermission for them
+ for ( int i = 1; i <= gpGlobals->maxClients; i++ )
+ {
+ CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)UTIL_PlayerByIndex( i );
+ if ( pPlayer )
+ {
+ EndActOverlayTime( pPlayer );
+ }
+ }
+
+ // Think again when the act ends, if we have a timelimit
+ if ( m_flActTimeLimit )
+ {
+ SetNextThink( gpGlobals->curtime + m_flActTimeLimit - MIN_ACT_OVERLAY_TIME );
+ SetThink( ActThink );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Clean up entities before a new act starts
+//-----------------------------------------------------------------------------
+void CInfoAct::CleanupOnActStart( void )
+{
+ // Remove all resource chunks
+ CBaseEntity *pEntity = NULL;
+ while ((pEntity = gEntList.FindEntityByClassname( pEntity, "resource_chunk" )) != NULL)
+ {
+ UTIL_Remove( pEntity );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Intermission handling
+//-----------------------------------------------------------------------------
+void CInfoAct::StartIntermission( CBaseTFPlayer *pPlayer )
+{
+ // Do we have a camera point?
+ if ( m_iszIntermissionCamera != NULL_STRING )
+ {
+ CBaseEntity *pCamera = gEntList.FindEntityByName( NULL, STRING(m_iszIntermissionCamera) );
+ if ( pCamera )
+ {
+ // Move the player to the camera point
+ pPlayer->SetViewEntity( pCamera );
+ pPlayer->m_Local.m_iHideHUD |= (HIDEHUD_WEAPONSELECTION | HIDEHUD_HEALTH | HIDEHUD_MISCSTATUS);
+ }
+ }
+
+ // Lock the player in place
+ pPlayer->LockPlayerInPlace();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Intermission handling
+//-----------------------------------------------------------------------------
+void CInfoAct::EndIntermission( CBaseTFPlayer *pPlayer )
+{
+ // Force the player to respawn
+ pPlayer->UnlockPlayer();
+ pPlayer->SetViewEntity( pPlayer );
+ pPlayer->ForceRespawn();
+ pPlayer->m_Local.m_iHideHUD &= ~(HIDEHUD_WEAPONSELECTION | HIDEHUD_HEALTH | HIDEHUD_MISCSTATUS);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Force the act to start
+//-----------------------------------------------------------------------------
+void CInfoAct::InputStart( inputdata_t &inputdata )
+{
+ StartAct();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Force the act to finish, with team 1 as the winners
+//-----------------------------------------------------------------------------
+void CInfoAct::InputFinishWinNone( inputdata_t &inputdata )
+{
+ m_iWinners = 0;
+ FinishAct();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Force the act to finish, with team 1 as the winners
+//-----------------------------------------------------------------------------
+void CInfoAct::InputFinishWin1( inputdata_t &inputdata )
+{
+ m_iWinners = 1;
+ FinishAct();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Force the act to finish, with team 2 as the winners
+//-----------------------------------------------------------------------------
+void CInfoAct::InputFinishWin2( inputdata_t &inputdata )
+{
+ m_iWinners = 2;
+ FinishAct();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Add time to the act's time
+//-----------------------------------------------------------------------------
+void CInfoAct::InputAddTime( inputdata_t &inputdata )
+{
+ float flNewTime = inputdata.value.Float();
+
+ // Think again when the act ends, if we have a timelimit
+ if ( flNewTime )
+ {
+ m_flActTimeLimit += flNewTime;
+ SetNextThink( GetNextThink() + flNewTime );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CInfoAct::IsAWaitingAct( void )
+{
+ return HasSpawnFlags(SF_ACT_WAITINGFORGAMESTART);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Return true if the current act (if any) is a waiting act.
+//-----------------------------------------------------------------------------
+bool CurrentActIsAWaitingAct( void )
+{
+ if ( g_hCurrentAct )
+ return g_hCurrentAct->IsAWaitingAct();
+
+ return false;
+} \ No newline at end of file