aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/server/team_control_point.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/server/team_control_point.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/server/team_control_point.cpp')
-rw-r--r--mp/src/game/server/team_control_point.cpp2154
1 files changed, 1077 insertions, 1077 deletions
diff --git a/mp/src/game/server/team_control_point.cpp b/mp/src/game/server/team_control_point.cpp
index e3f06b8b..1bbec70a 100644
--- a/mp/src/game/server/team_control_point.cpp
+++ b/mp/src/game/server/team_control_point.cpp
@@ -1,1077 +1,1077 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//===========================================================================//
-
-#include "cbase.h"
-#include "team_control_point.h"
-#include "player.h"
-#include "teamplay_gamerules.h"
-#include "teamplayroundbased_gamerules.h"
-#include "team.h"
-#include "team_control_point_master.h"
-#include "mp_shareddefs.h"
-#include "engine/IEngineSound.h"
-#include "soundenvelope.h"
-
-#ifdef TF_DLL
-#include "tf_shareddefs.h"
-#endif
-
-#define CONTROL_POINT_UNLOCK_THINK "UnlockThink"
-
-BEGIN_DATADESC(CTeamControlPoint)
- DEFINE_KEYFIELD( m_iszPrintName, FIELD_STRING, "point_printname" ),
- DEFINE_KEYFIELD( m_iCPGroup, FIELD_INTEGER, "point_group" ),
- DEFINE_KEYFIELD( m_iDefaultOwner, FIELD_INTEGER, "point_default_owner" ),
- DEFINE_KEYFIELD( m_iPointIndex, FIELD_INTEGER, "point_index" ),
- DEFINE_KEYFIELD( m_iWarnOnCap, FIELD_INTEGER, "point_warn_on_cap" ),
- DEFINE_KEYFIELD( m_iszWarnSound, FIELD_STRING, "point_warn_sound" ),
-
- DEFINE_KEYFIELD( m_iszCaptureStartSound, FIELD_STRING, "point_capture_start_sound" ),
- DEFINE_KEYFIELD( m_iszCaptureEndSound, FIELD_STRING, "point_capture_end_sound" ),
- DEFINE_KEYFIELD( m_iszCaptureInProgress, FIELD_STRING, "point_capture_progress_sound" ),
- DEFINE_KEYFIELD( m_iszCaptureInterrupted, FIELD_STRING, "point_capture_interrupted_sound" ),
- DEFINE_KEYFIELD( m_bRandomOwnerOnRestart, FIELD_BOOLEAN, "random_owner_on_restart" ),
- DEFINE_KEYFIELD( m_bLocked, FIELD_BOOLEAN, "point_start_locked" ),
-
- DEFINE_FUNCTION( UnlockThink ),
-
-// DEFINE_FIELD( m_iTeam, FIELD_INTEGER ),
-// DEFINE_FIELD( m_iIndex, FIELD_INTEGER ),
-// DEFINE_FIELD( m_TeamData, CUtlVector < perteamdata_t > ),
-// DEFINE_FIELD( m_bPointVisible, FIELD_INTEGER ),
-// DEFINE_FIELD( m_bActive, FIELD_BOOLEAN ),
-// DEFINE_FIELD( m_iszName, FIELD_STRING ),
-// DEFINE_FIELD( m_bStartDisabled, FIELD_BOOLEAN ),
-// DEFINE_FIELD( m_flLastContestedAt, FIELD_FLOAT ),
-// DEFINE_FIELD( m_pCaptureInProgressSound, CSoundPatch ),
-
- DEFINE_INPUTFUNC( FIELD_INTEGER, "SetOwner", InputSetOwner ),
- DEFINE_INPUTFUNC( FIELD_VOID, "ShowModel", InputShowModel ),
- DEFINE_INPUTFUNC( FIELD_VOID, "HideModel", InputHideModel ),
- DEFINE_INPUTFUNC( FIELD_VOID, "RoundActivate", InputRoundActivate ),
- DEFINE_INPUTFUNC( FIELD_INTEGER, "SetLocked", InputSetLocked ),
- DEFINE_INPUTFUNC( FIELD_INTEGER, "SetUnlockTime", InputSetUnlockTime ),
-
- DEFINE_OUTPUT( m_OnCapTeam1, "OnCapTeam1" ), // these are fired whenever the point changes modes
- DEFINE_OUTPUT( m_OnCapTeam2, "OnCapTeam2" ),
- DEFINE_OUTPUT( m_OnCapReset, "OnCapReset" ),
-
- DEFINE_OUTPUT( m_OnOwnerChangedToTeam1, "OnOwnerChangedToTeam1" ), // these are fired when a team does the work to change the owner
- DEFINE_OUTPUT( m_OnOwnerChangedToTeam2, "OnOwnerChangedToTeam2" ),
-
- DEFINE_OUTPUT( m_OnRoundStartOwnedByTeam1, "OnRoundStartOwnedByTeam1" ), // these are fired when a round is starting
- DEFINE_OUTPUT( m_OnRoundStartOwnedByTeam2, "OnRoundStartOwnedByTeam2" ),
-
- DEFINE_OUTPUT( m_OnUnlocked, "OnUnlocked" ),
-
- DEFINE_THINKFUNC( AnimThink ),
-END_DATADESC();
-
-LINK_ENTITY_TO_CLASS( team_control_point, CTeamControlPoint );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CTeamControlPoint::CTeamControlPoint()
-{
- m_TeamData.SetSize( GetNumberOfTeams() );
- m_pCaptureInProgressSound = NULL;
-
- m_bLocked = false;
- m_flUnlockTime = -1;
-
-#ifdef TF_DLL
- UseClientSideAnimation();
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::Spawn( void )
-{
- // Validate our default team
- if ( m_iDefaultOwner < 0 || m_iDefaultOwner >= GetNumberOfTeams() )
- {
- Warning( "team_control_point '%s' has bad point_default_owner.\n", GetDebugName() );
- m_iDefaultOwner = TEAM_UNASSIGNED;
- }
-
-#ifdef TF_DLL
- if ( m_iszCaptureStartSound == NULL_STRING )
- {
- m_iszCaptureStartSound = AllocPooledString( "Hologram.Start" );
- }
- if ( m_iszCaptureEndSound == NULL_STRING )
- {
- m_iszCaptureEndSound = AllocPooledString( "Hologram.Stop" );
- }
- if ( m_iszCaptureInProgress == NULL_STRING )
- {
- m_iszCaptureInProgress = AllocPooledString( "Hologram.Move" );
- }
- if ( m_iszCaptureInterrupted == NULL_STRING )
- {
- m_iszCaptureInterrupted = AllocPooledString( "Hologram.Interrupted" );
- }
-#endif
-
- Precache();
-
- InternalSetOwner( m_iDefaultOwner, false ); //init the owner of this point
- TeamplayRoundBasedRules()->RecalculateControlPointState();
-
- SetActive( !m_bStartDisabled );
-
- BaseClass::Spawn();
-
- SetPlaybackRate( 1.0 );
- SetThink( &CTeamControlPoint::AnimThink );
- SetNextThink( gpGlobals->curtime + 0.1f );
-
- if ( FBitSet( m_spawnflags, SF_CAP_POINT_HIDE_MODEL ) )
- {
- AddEffects( EF_NODRAW );
- }
-
- if ( FBitSet( m_spawnflags, SF_CAP_POINT_HIDE_SHADOW ) )
- {
- AddEffects( EF_NOSHADOW );
- }
-
- m_flLastContestedAt = -1;
-
- m_pCaptureInProgressSound = NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool CTeamControlPoint::KeyValue( const char *szKeyName, const char *szValue )
-{
- if ( !Q_strncmp( szKeyName, "team_capsound_", 14 ) )
- {
- int iTeam = atoi(szKeyName+14);
- Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
-
- m_TeamData[iTeam].iszCapSound = AllocPooledString(szValue);
- }
- else if ( !Q_strncmp( szKeyName, "team_model_", 11 ) )
- {
- int iTeam = atoi(szKeyName+11);
- Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
-
- m_TeamData[iTeam].iszModel = AllocPooledString(szValue);
- }
- else if ( !Q_strncmp( szKeyName, "team_timedpoints_", 17 ) )
- {
- int iTeam = atoi(szKeyName+17);
- Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
-
- m_TeamData[iTeam].iTimedPoints = atoi(szValue);
- }
- else if ( !Q_strncmp( szKeyName, "team_bodygroup_", 15 ) )
- {
- int iTeam = atoi(szKeyName+15);
- Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
-
- m_TeamData[iTeam].iModelBodygroup = atoi(szValue);
- }
- else if ( !Q_strncmp( szKeyName, "team_icon_", 10 ) )
- {
- int iTeam = atoi(szKeyName+10);
- Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
-
- m_TeamData[iTeam].iszIcon = AllocPooledString(szValue);
- }
- else if ( !Q_strncmp( szKeyName, "team_overlay_", 13 ) )
- {
- int iTeam = atoi(szKeyName+13);
- Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
-
- m_TeamData[iTeam].iszOverlay = AllocPooledString(szValue);
- }
- else if ( !Q_strncmp( szKeyName, "team_previouspoint_", 19 ) )
- {
- int iTeam;
- int iPoint = 0;
- sscanf( szKeyName+19, "%d_%d", &iTeam, &iPoint );
- Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
- Assert( iPoint >= 0 && iPoint < MAX_PREVIOUS_POINTS );
- m_TeamData[iTeam].iszPreviousPoint[iPoint] = AllocPooledString(szValue);
- }
- else
- {
- return BaseClass::KeyValue( szKeyName, szValue );
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::Precache( void )
-{
- for ( int i = 0; i < m_TeamData.Count(); i++ )
- {
- // Skip over spectator
- if ( i == TEAM_SPECTATOR )
- continue;
-
- if ( m_TeamData[i].iszCapSound != NULL_STRING )
- {
- PrecacheScriptSound( STRING(m_TeamData[i].iszCapSound) );
- }
-
- if ( m_TeamData[i].iszModel != NULL_STRING )
- {
- PrecacheModel( STRING(m_TeamData[i].iszModel) );
- }
-
- if ( m_TeamData[i].iszIcon != NULL_STRING )
- {
- PrecacheMaterial( STRING( m_TeamData[i].iszIcon ) );
- m_TeamData[i].iIcon = GetMaterialIndex( STRING( m_TeamData[i].iszIcon ) );
- Assert( m_TeamData[i].iIcon != 0 );
- }
-
- if ( !m_TeamData[i].iIcon )
- {
- Warning( "Invalid hud icon material for team %d in control point '%s' ( point index %d )\n", i, GetDebugName(), GetPointIndex() );
- }
-
- if ( m_TeamData[i].iszOverlay != NULL_STRING )
- {
- PrecacheMaterial( STRING( m_TeamData[i].iszOverlay ) );
- m_TeamData[i].iOverlay = GetMaterialIndex( STRING( m_TeamData[i].iszOverlay ) );
- Assert( m_TeamData[i].iOverlay != 0 );
-
- if ( !m_TeamData[i].iOverlay )
- {
- Warning( "Invalid hud overlay material for team %d in control point '%s' ( point index %d )\n", i, GetDebugName(), GetPointIndex() );
- }
- }
- }
-
- PrecacheScriptSound( STRING( m_iszCaptureStartSound ) );
- PrecacheScriptSound( STRING( m_iszCaptureEndSound ) );
- PrecacheScriptSound( STRING( m_iszCaptureInProgress ) );
- PrecacheScriptSound( STRING( m_iszCaptureInterrupted ) );
-
- if ( m_iszWarnSound != NULL_STRING )
- {
- PrecacheScriptSound( STRING( m_iszWarnSound ) );
- }
-
-#ifdef TF_DLL
- PrecacheScriptSound( "Announcer.ControlPointContested" );
-#endif
-}
-
-//------------------------------------------------------------------------------
-// Purpose:
-//------------------------------------------------------------------------------
-void CTeamControlPoint::AnimThink( void )
-{
- StudioFrameAdvance();
- DispatchAnimEvents(this);
- SetNextThink( gpGlobals->curtime + 0.1f );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Used by ControlMaster to this point to its default owner
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::InputReset( inputdata_t &input )
-{
- m_flLastContestedAt = -1;
- InternalSetOwner( m_iDefaultOwner, false );
- ObjectiveResource()->SetOwningTeam( GetPointIndex(), m_iTeam );
- TeamplayRoundBasedRules()->RecalculateControlPointState();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::HandleScoring( int iTeam )
-{
- if ( TeamplayRoundBasedRules() && !TeamplayRoundBasedRules()->ShouldScorePerRound() )
- {
- GetGlobalTeam( iTeam )->AddScore( 1 );
- TeamplayRoundBasedRules()->HandleTeamScoreModify( iTeam, 1 );
-
- CTeamControlPointMaster *pMaster = g_hControlPointMasters.Count() ? g_hControlPointMasters[0] : NULL;
- if ( pMaster && !pMaster->WouldNewCPOwnerWinGame( this, iTeam ) )
- {
-#ifdef TF_DLL
- if ( TeamplayRoundBasedRules()->GetGameType() == TF_GAMETYPE_ESCORT )
- {
- CBroadcastRecipientFilter filter;
- EmitSound( filter, entindex(), "Hud.EndRoundScored" );
- }
- else
-#endif
- {
- CTeamRecipientFilter filter( iTeam );
- EmitSound( filter, entindex(), "Hud.EndRoundScored" );
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Used by Area caps to set the owner
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::InputSetOwner( inputdata_t &input )
-{
- int iCapTeam = input.value.Int();
-
- Assert( iCapTeam >= 0 && iCapTeam < GetNumberOfTeams() );
-
- Assert( input.pCaller );
-
- if ( !input.pCaller )
- return;
-
- if ( GetOwner() == iCapTeam )
- return;
-
- if ( TeamplayGameRules()->PointsMayBeCaptured() )
- {
- // must be done before setting the owner
- HandleScoring( iCapTeam );
-
- if ( input.pCaller->IsPlayer() )
- {
- int iCappingPlayer = input.pCaller->entindex();
- InternalSetOwner( iCapTeam, true, 1, &iCappingPlayer );
- }
- else
- {
- InternalSetOwner( iCapTeam, false );
- }
-
- ObjectiveResource()->SetOwningTeam( GetPointIndex(), m_iTeam );
- TeamplayRoundBasedRules()->RecalculateControlPointState();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::InputShowModel( inputdata_t &input )
-{
- RemoveEffects( EF_NODRAW );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::InputHideModel( inputdata_t &input )
-{
- AddEffects( EF_NODRAW );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CTeamControlPoint::GetCurrentHudIconIndex( void )
-{
- return m_TeamData[GetOwner()].iIcon;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CTeamControlPoint::GetHudIconIndexForTeam( int iGameTeam )
-{
- return m_TeamData[iGameTeam].iIcon;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CTeamControlPoint::GetHudOverlayIndexForTeam( int iGameTeam )
-{
- return m_TeamData[iGameTeam].iOverlay;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CTeamControlPoint::GetPreviousPointForTeam( int iGameTeam, int iPrevPoint )
-{
- Assert( iPrevPoint >= 0 && iPrevPoint < MAX_PREVIOUS_POINTS );
-
- int iRetVal = -1;
- CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, STRING(m_TeamData[iGameTeam].iszPreviousPoint[iPrevPoint]) );
-
- if ( pEntity )
- {
- CTeamControlPoint *pPoint = dynamic_cast<CTeamControlPoint*>( pEntity );
-
- if ( pPoint )
- {
- iRetVal = pPoint->GetPointIndex();
- }
- }
-
- return iRetVal;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::ForceOwner( int iTeam )
-{
- InternalSetOwner( iTeam, false, 0, 0 );
- ObjectiveResource()->SetOwningTeam( GetPointIndex(), m_iTeam );
- TeamplayRoundBasedRules()->RecalculateControlPointState();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::SetOwner( int iCapTeam, bool bMakeSound, int iNumCappers, int *pCappingPlayers )
-{
- if ( TeamplayGameRules()->PointsMayBeCaptured() )
- {
- // must be done before setting the owner
- HandleScoring( iCapTeam );
-
- InternalSetOwner( iCapTeam, bMakeSound, iNumCappers, pCappingPlayers );
- ObjectiveResource()->SetOwningTeam( GetPointIndex(), m_iTeam );
- TeamplayRoundBasedRules()->RecalculateControlPointState();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::CaptureStart( int iCapTeam, int iNumCappingPlayers, int *pCappingPlayers )
-{
- int iNumCappers = iNumCappingPlayers;
-
- float flLastOwnershipChangeTime = -1.f;
- CBaseEntity *pEnt = gEntList.FindEntityByClassname( NULL, GetControlPointMasterName() );
- while( pEnt )
- {
- CTeamControlPointMaster *pMaster = dynamic_cast<CTeamControlPointMaster *>( pEnt );
- if ( pMaster && pMaster->IsActive() )
- {
- flLastOwnershipChangeTime = pMaster->GetLastOwnershipChangeTime();
- }
- pEnt = gEntList.FindEntityByClassname( pEnt, GetControlPointMasterName() );
- }
-
- IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_point_startcapture" );
- if ( event )
- {
- event->SetInt( "cp", m_iPointIndex );
- event->SetString( "cpname", STRING( m_iszPrintName ) );
- event->SetInt( "team", m_iTeam );
- event->SetInt( "capteam", iCapTeam );
- event->SetFloat( "captime", gpGlobals->curtime - flLastOwnershipChangeTime );
-
- // safety check
- if ( iNumCappers > 8 )
- {
- iNumCappers = 8;
- }
-
- char cappers[9]; // pCappingPlayers should be max length 8
- int i;
- for( i = 0 ; i < iNumCappers ; i++ )
- {
- cappers[i] = (char)pCappingPlayers[i];
- }
-
- cappers[i] = '\0';
-
- // pCappingPlayers is a null terminated list of player indices
- event->SetString( "cappers", cappers );
- event->SetInt( "priority", 7 );
-
- gameeventmanager->FireEvent( event );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::CaptureEnd( void )
-{
- StopLoopingSounds();
-
- if ( !FBitSet( m_spawnflags, SF_CAP_POINT_NO_CAP_SOUNDS ) )
- {
- EmitSound( STRING( m_iszCaptureEndSound ) );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::CaptureInterrupted( bool bBlocked )
-{
- StopLoopingSounds();
-
- if ( FBitSet( m_spawnflags, SF_CAP_POINT_NO_CAP_SOUNDS ) )
- {
- return;
- }
-
- const char *pSoundName = NULL;
-
- if ( bBlocked == true )
- {
- pSoundName = STRING( m_iszCaptureInterrupted );
- }
- else
- {
- pSoundName = STRING( m_iszCaptureInProgress );
- EmitSound( STRING( m_iszCaptureStartSound ) );
- }
-
- if ( m_pCaptureInProgressSound == NULL && pSoundName != NULL )
- {
- CPASFilter filter( GetAbsOrigin() );
-
- CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
- m_pCaptureInProgressSound = controller.SoundCreate( filter, entindex(), pSoundName );
-
- controller.Play( m_pCaptureInProgressSound, 1.0, 100 );
- }
-
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::StopLoopingSounds( void )
-{
- CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
-
- if ( m_pCaptureInProgressSound )
- {
- controller.SoundDestroy( m_pCaptureInProgressSound );
- m_pCaptureInProgressSound = NULL;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sets the new owner of the point, plays the appropriate sound and shows the right model
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::InternalSetOwner( int iCapTeam, bool bMakeSound, int iNumCappers, int *pCappingPlayers )
-{
- Assert( iCapTeam >= 0 && iCapTeam < GetNumberOfTeams() );
-
- int iOldTeam = m_iTeam;
-
- m_iTeam = iCapTeam;
- ChangeTeam( iCapTeam );
-
- if ( bMakeSound )
- {
- CBroadcastRecipientFilter filter;
- EmitSound( filter, entindex(), STRING( m_TeamData[m_iTeam].iszCapSound ) );
- }
-
- // Update visuals
- SetModel( STRING(m_TeamData[m_iTeam].iszModel) );
- SetBodygroup( 0, m_iTeam );
- m_nSkin = ( m_iTeam == TEAM_UNASSIGNED ) ? 2 : (m_iTeam - 2);
- ResetSequence( LookupSequence("idle") );
-
- // We add 1 to the index because we consider the default "no points capped" as 0.
- TeamplayGameRules()->SetLastCapPointChanged( m_iPointIndex+1 );
-
- // Determine the pose parameters for each team
- for ( int i = 0; i < m_TeamData.Count(); i++ )
- {
- // Skip spectator
- if ( i == TEAM_SPECTATOR )
- continue;
-
- if ( GetModelPtr() && GetModelPtr()->SequencesAvailable() )
- {
- m_TeamData[i].iTeamPoseParam = LookupPoseParameter( UTIL_VarArgs( "cappoint_%d_percentage", i ) );
- }
- else
- {
- m_TeamData[i].iTeamPoseParam = -1;
- }
- }
- UpdateCapPercentage();
-
- if ( m_iTeam == TEAM_UNASSIGNED )
- {
- m_OnCapReset.FireOutput( this, this );
- }
- else
- {
- // Remap team to get first game team = 1
- switch ( m_iTeam - FIRST_GAME_TEAM+1 )
- {
- case 1:
- m_OnCapTeam1.FireOutput( this, this );
- break;
- case 2:
- m_OnCapTeam2.FireOutput( this, this );
- break;
- default:
- Assert(0);
- break;
- }
- }
-
- // If we're playing a sound, this is a true cap by players.
- if ( bMakeSound )
- {
- if ( iOldTeam > LAST_SHARED_TEAM && iOldTeam != m_iTeam )
- {
- // Make the members of our old team say something
- for ( int i = 1; i <= gpGlobals->maxClients; i++ )
- {
- CBaseMultiplayerPlayer *pPlayer = ToBaseMultiplayerPlayer( UTIL_PlayerByIndex( i ) );
- if ( !pPlayer )
- continue;
- if ( pPlayer->GetTeamNumber() == iOldTeam )
- {
- pPlayer->SpeakConceptIfAllowed( MP_CONCEPT_LOST_CONTROL_POINT );
- }
- }
- }
-
- for( int i = 0; i < iNumCappers; i++ )
- {
- int playerIndex = pCappingPlayers[i];
-
- Assert( playerIndex > 0 && playerIndex <= gpGlobals->maxClients );
-
- PlayerCapped( ToBaseMultiplayerPlayer(UTIL_PlayerByIndex( playerIndex )) );
- }
-
- // Remap team to get first game team = 1
- switch ( m_iTeam - FIRST_GAME_TEAM+1 )
- {
- case 1:
- m_OnOwnerChangedToTeam1.FireOutput( this, this );
- break;
- case 2:
- m_OnOwnerChangedToTeam2.FireOutput( this, this );
- break;
- }
-
- if ( m_iTeam != TEAM_UNASSIGNED && iNumCappers )
- {
- SendCapString( m_iTeam, iNumCappers, pCappingPlayers );
- }
- }
-
- // Have control point master check the win conditions now!
- CBaseEntity *pEnt = gEntList.FindEntityByClassname( NULL, GetControlPointMasterName() );
-
- while( pEnt )
- {
- CTeamControlPointMaster *pMaster = dynamic_cast<CTeamControlPointMaster *>( pEnt );
-
- if ( pMaster->IsActive() )
- {
- pMaster->CheckWinConditions();
- pMaster->SetLastOwnershipChangeTime( gpGlobals->curtime );
- }
-
- pEnt = gEntList.FindEntityByClassname( pEnt, GetControlPointMasterName() );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::SendCapString( int iCapTeam, int iNumCappingPlayers, int *pCappingPlayers )
-{
- if ( strlen( STRING(m_iszPrintName) ) <= 0 )
- return;
-
- int iNumCappers = iNumCappingPlayers;
-
- IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_point_captured" );
- if ( event )
- {
- event->SetInt( "cp", m_iPointIndex );
- event->SetString( "cpname", STRING( m_iszPrintName ) );
- event->SetInt( "team", iCapTeam );
-
- // safety check
- if ( iNumCappers > 8 )
- {
- iNumCappers = 8;
- }
-
- char cappers[9]; // pCappingPlayers should be max length 8
- int i;
- for( i = 0 ; i < iNumCappers ; i++ )
- {
- cappers[i] = (char)pCappingPlayers[i];
- }
-
- cappers[i] = '\0';
-
- // pCappingPlayers is a null terminated list of player indices
- event->SetString( "cappers", cappers );
- event->SetInt( "priority", 9 );
-
- gameeventmanager->FireEvent( event );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::CaptureBlocked( CBaseMultiplayerPlayer *pPlayer )
-{
- if( strlen( STRING(m_iszPrintName) ) <= 0 )
- return;
-
- IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_capture_blocked" );
-
- if ( event )
- {
- event->SetInt( "cp", m_iPointIndex );
- event->SetString( "cpname", STRING(m_iszPrintName) );
- event->SetInt( "blocker", pPlayer->entindex() );
- event->SetInt( "priority", 9 );
-
- gameeventmanager->FireEvent( event );
- }
-
- PlayerBlocked( pPlayer );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CTeamControlPoint::GetOwner( void ) const
-{
- return m_iTeam;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CTeamControlPoint::GetDefaultOwner( void ) const
-{
- return m_iDefaultOwner;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CTeamControlPoint::GetCPGroup( void )
-{
- return m_iCPGroup;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Returns the time-based point value of this control point
-//-----------------------------------------------------------------------------
-int CTeamControlPoint::PointValue( void )
-{
- if ( GetOwner() != m_iDefaultOwner )
- return m_TeamData[ GetOwner() ].iTimedPoints;
-
- return 0;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::SetActive( bool active )
-{
- m_bActive = active;
-
- if( active )
- {
- RemoveEffects( EF_NODRAW );
- }
- else
- {
- AddEffects( EF_NODRAW );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::SetCappersRequiredForTeam( int iGameTeam, int iCappers )
-{
- m_TeamData[iGameTeam].iPlayersRequired = iCappers;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Return true if this point has ever been contested, false if the enemy has never contested this point yet
-//-----------------------------------------------------------------------------
-bool CTeamControlPoint::HasBeenContested( void ) const
-{
- return m_flLastContestedAt > 0.0f;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-float CTeamControlPoint::LastContestedAt( void )
-{
- return m_flLastContestedAt;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::SetLastContestedAt( float flTime )
-{
- m_flLastContestedAt = flTime;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::UpdateCapPercentage( void )
-{
- for ( int i = LAST_SHARED_TEAM+1; i < m_TeamData.Count(); i++ )
- {
- // Skip spectator
- if ( i == TEAM_SPECTATOR )
- continue;
-
- float flPerc = GetTeamCapPercentage(i);
-
- if ( m_TeamData[i].iTeamPoseParam != -1 )
- {
- SetPoseParameter( m_TeamData[i].iTeamPoseParam, flPerc );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-float CTeamControlPoint::GetTeamCapPercentage( int iTeam )
-{
- int iCappingTeam = ObjectiveResource()->GetCappingTeam( GetPointIndex() );
- if ( iCappingTeam == TEAM_UNASSIGNED )
- {
- // No-one's capping this point.
- if ( iTeam == m_iTeam )
- return 1.0;
-
- return 0.0;
- }
-
- float flCapPerc = ObjectiveResource()->GetCPCapPercentage( GetPointIndex() );
- if ( iTeam == iCappingTeam )
- return (1.0 - flCapPerc);
- if ( iTeam == m_iTeam )
- return flCapPerc;
-
- return 0.0;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CTeamControlPoint::DrawDebugTextOverlays( void )
-{
- int text_offset = BaseClass::DrawDebugTextOverlays();
-
- if (m_debugOverlays & OVERLAY_TEXT_BIT)
- {
- char tempstr[1024];
- Q_snprintf(tempstr, sizeof(tempstr), "INDEX: (%d)", GetPointIndex() );
- EntityText(text_offset,tempstr,0);
- text_offset++;
-
- Q_snprintf( tempstr, sizeof(tempstr), "Red Previous Points: ");
- for ( int i = 0; i < MAX_PREVIOUS_POINTS; i++ )
- {
- if ( m_TeamData[2].iszPreviousPoint[i] != NULL_STRING )
- {
- Q_strncat( tempstr, STRING(m_TeamData[2].iszPreviousPoint[i]), 1024, COPY_ALL_CHARACTERS );
- Q_strncat( tempstr, ", ", 1024, COPY_ALL_CHARACTERS );
- }
- }
- EntityText(text_offset,tempstr,0);
- text_offset++;
-
- Q_snprintf( tempstr, sizeof(tempstr), "Blue Previous Points: " );
- for ( int i = 0; i < MAX_PREVIOUS_POINTS; i++ )
- {
- if ( m_TeamData[3].iszPreviousPoint[i] != NULL_STRING )
- {
- Q_strncat( tempstr, STRING(m_TeamData[3].iszPreviousPoint[i]), 1024, COPY_ALL_CHARACTERS );
- Q_strncat( tempstr, ", ", 1024, COPY_ALL_CHARACTERS );
- }
- }
- EntityText(text_offset,tempstr,0);
- text_offset++;
-
- for ( int i = 0; i < MAX_CONTROL_POINT_TEAMS; i++ )
- {
- if ( ObjectiveResource()->GetBaseControlPointForTeam(i) == GetPointIndex() )
- {
- Q_snprintf(tempstr, sizeof(tempstr), "Base Control Point for Team %d", i );
- EntityText(text_offset,tempstr,0);
- text_offset++;
- }
- }
- }
-
- return text_offset;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: The specified player took part in capping this point.
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::PlayerCapped( CBaseMultiplayerPlayer *pPlayer )
-{
- if ( pPlayer )
- {
- pPlayer->SpeakConceptIfAllowed( MP_CONCEPT_CAPTURED_POINT );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: The specified player blocked the enemy team from capping this point.
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::PlayerBlocked( CBaseMultiplayerPlayer *pPlayer )
-{
- if ( pPlayer )
- {
- pPlayer->SpeakConceptIfAllowed( MP_CONCEPT_CAPTURE_BLOCKED );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::InputRoundActivate( inputdata_t &inputdata )
-{
- switch ( m_iTeam - FIRST_GAME_TEAM+1 )
- {
- case 1:
- m_OnRoundStartOwnedByTeam1.FireOutput( this, this );
- break;
- case 2:
- m_OnRoundStartOwnedByTeam2.FireOutput( this, this );
- break;
- }
-
- InternalSetLocked( m_bLocked );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::InputSetLocked( inputdata_t &inputdata )
-{
- // never lock/unlock the point if we're in waiting for players
- if ( TeamplayRoundBasedRules() && TeamplayRoundBasedRules()->IsInWaitingForPlayers() )
- return;
-
- bool bLocked = inputdata.value.Int() > 0;
- InternalSetLocked( bLocked );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::InternalSetLocked( bool bLocked )
-{
- if ( !bLocked && m_bLocked )
- {
- // unlocked this point
- IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_point_unlocked" );
- if ( event )
- {
- event->SetInt( "cp", m_iPointIndex );
- event->SetString( "cpname", STRING( m_iszPrintName ) );
- event->SetInt( "team", m_iTeam );
- gameeventmanager->FireEvent( event );
- }
- }
- else if ( bLocked && !m_bLocked )
- {
- // locked this point
- IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_point_locked" );
- if ( event )
- {
- event->SetInt( "cp", m_iPointIndex );
- event->SetString( "cpname", STRING( m_iszPrintName ) );
- event->SetInt( "team", m_iTeam );
- gameeventmanager->FireEvent( event );
- }
- }
-
- m_bLocked = bLocked;
-
- if ( ObjectiveResource() && GetPointIndex() < ObjectiveResource()->GetNumControlPoints() )
- {
- ObjectiveResource()->SetCPLocked( GetPointIndex(), m_bLocked );
- ObjectiveResource()->SetCPUnlockTime( GetPointIndex(), 0.0f );
- }
-
- if ( !m_bLocked )
- {
- m_flUnlockTime = -1;
- m_OnUnlocked.FireOutput( this, this );
- SetContextThink( NULL, 0, CONTROL_POINT_UNLOCK_THINK );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::InputSetUnlockTime( inputdata_t &inputdata )
-{
- // never lock/unlock the point if we're in waiting for players
- if ( TeamplayRoundBasedRules() && TeamplayRoundBasedRules()->IsInWaitingForPlayers() )
- return;
-
- int nTime = inputdata.value.Int();
-
- if ( nTime <= 0 )
- {
- InternalSetLocked( false );
- return;
- }
-
- m_flUnlockTime = gpGlobals->curtime + nTime;
-
- if ( ObjectiveResource() )
- {
- ObjectiveResource()->SetCPUnlockTime( GetPointIndex(), m_flUnlockTime );
- }
-
- SetContextThink( &CTeamControlPoint::UnlockThink, gpGlobals->curtime + 0.1, CONTROL_POINT_UNLOCK_THINK );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTeamControlPoint::UnlockThink( void )
-{
- if ( m_flUnlockTime > 0 &&
- m_flUnlockTime < gpGlobals->curtime &&
- ( TeamplayRoundBasedRules() && TeamplayRoundBasedRules()->State_Get() == GR_STATE_RND_RUNNING ) )
- {
- InternalSetLocked( false );
- return;
- }
-
- SetContextThink( &CTeamControlPoint::UnlockThink, gpGlobals->curtime + 0.1, CONTROL_POINT_UNLOCK_THINK );
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//===========================================================================//
+
+#include "cbase.h"
+#include "team_control_point.h"
+#include "player.h"
+#include "teamplay_gamerules.h"
+#include "teamplayroundbased_gamerules.h"
+#include "team.h"
+#include "team_control_point_master.h"
+#include "mp_shareddefs.h"
+#include "engine/IEngineSound.h"
+#include "soundenvelope.h"
+
+#ifdef TF_DLL
+#include "tf_shareddefs.h"
+#endif
+
+#define CONTROL_POINT_UNLOCK_THINK "UnlockThink"
+
+BEGIN_DATADESC(CTeamControlPoint)
+ DEFINE_KEYFIELD( m_iszPrintName, FIELD_STRING, "point_printname" ),
+ DEFINE_KEYFIELD( m_iCPGroup, FIELD_INTEGER, "point_group" ),
+ DEFINE_KEYFIELD( m_iDefaultOwner, FIELD_INTEGER, "point_default_owner" ),
+ DEFINE_KEYFIELD( m_iPointIndex, FIELD_INTEGER, "point_index" ),
+ DEFINE_KEYFIELD( m_iWarnOnCap, FIELD_INTEGER, "point_warn_on_cap" ),
+ DEFINE_KEYFIELD( m_iszWarnSound, FIELD_STRING, "point_warn_sound" ),
+
+ DEFINE_KEYFIELD( m_iszCaptureStartSound, FIELD_STRING, "point_capture_start_sound" ),
+ DEFINE_KEYFIELD( m_iszCaptureEndSound, FIELD_STRING, "point_capture_end_sound" ),
+ DEFINE_KEYFIELD( m_iszCaptureInProgress, FIELD_STRING, "point_capture_progress_sound" ),
+ DEFINE_KEYFIELD( m_iszCaptureInterrupted, FIELD_STRING, "point_capture_interrupted_sound" ),
+ DEFINE_KEYFIELD( m_bRandomOwnerOnRestart, FIELD_BOOLEAN, "random_owner_on_restart" ),
+ DEFINE_KEYFIELD( m_bLocked, FIELD_BOOLEAN, "point_start_locked" ),
+
+ DEFINE_FUNCTION( UnlockThink ),
+
+// DEFINE_FIELD( m_iTeam, FIELD_INTEGER ),
+// DEFINE_FIELD( m_iIndex, FIELD_INTEGER ),
+// DEFINE_FIELD( m_TeamData, CUtlVector < perteamdata_t > ),
+// DEFINE_FIELD( m_bPointVisible, FIELD_INTEGER ),
+// DEFINE_FIELD( m_bActive, FIELD_BOOLEAN ),
+// DEFINE_FIELD( m_iszName, FIELD_STRING ),
+// DEFINE_FIELD( m_bStartDisabled, FIELD_BOOLEAN ),
+// DEFINE_FIELD( m_flLastContestedAt, FIELD_FLOAT ),
+// DEFINE_FIELD( m_pCaptureInProgressSound, CSoundPatch ),
+
+ DEFINE_INPUTFUNC( FIELD_INTEGER, "SetOwner", InputSetOwner ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "ShowModel", InputShowModel ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "HideModel", InputHideModel ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "RoundActivate", InputRoundActivate ),
+ DEFINE_INPUTFUNC( FIELD_INTEGER, "SetLocked", InputSetLocked ),
+ DEFINE_INPUTFUNC( FIELD_INTEGER, "SetUnlockTime", InputSetUnlockTime ),
+
+ DEFINE_OUTPUT( m_OnCapTeam1, "OnCapTeam1" ), // these are fired whenever the point changes modes
+ DEFINE_OUTPUT( m_OnCapTeam2, "OnCapTeam2" ),
+ DEFINE_OUTPUT( m_OnCapReset, "OnCapReset" ),
+
+ DEFINE_OUTPUT( m_OnOwnerChangedToTeam1, "OnOwnerChangedToTeam1" ), // these are fired when a team does the work to change the owner
+ DEFINE_OUTPUT( m_OnOwnerChangedToTeam2, "OnOwnerChangedToTeam2" ),
+
+ DEFINE_OUTPUT( m_OnRoundStartOwnedByTeam1, "OnRoundStartOwnedByTeam1" ), // these are fired when a round is starting
+ DEFINE_OUTPUT( m_OnRoundStartOwnedByTeam2, "OnRoundStartOwnedByTeam2" ),
+
+ DEFINE_OUTPUT( m_OnUnlocked, "OnUnlocked" ),
+
+ DEFINE_THINKFUNC( AnimThink ),
+END_DATADESC();
+
+LINK_ENTITY_TO_CLASS( team_control_point, CTeamControlPoint );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CTeamControlPoint::CTeamControlPoint()
+{
+ m_TeamData.SetSize( GetNumberOfTeams() );
+ m_pCaptureInProgressSound = NULL;
+
+ m_bLocked = false;
+ m_flUnlockTime = -1;
+
+#ifdef TF_DLL
+ UseClientSideAnimation();
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::Spawn( void )
+{
+ // Validate our default team
+ if ( m_iDefaultOwner < 0 || m_iDefaultOwner >= GetNumberOfTeams() )
+ {
+ Warning( "team_control_point '%s' has bad point_default_owner.\n", GetDebugName() );
+ m_iDefaultOwner = TEAM_UNASSIGNED;
+ }
+
+#ifdef TF_DLL
+ if ( m_iszCaptureStartSound == NULL_STRING )
+ {
+ m_iszCaptureStartSound = AllocPooledString( "Hologram.Start" );
+ }
+ if ( m_iszCaptureEndSound == NULL_STRING )
+ {
+ m_iszCaptureEndSound = AllocPooledString( "Hologram.Stop" );
+ }
+ if ( m_iszCaptureInProgress == NULL_STRING )
+ {
+ m_iszCaptureInProgress = AllocPooledString( "Hologram.Move" );
+ }
+ if ( m_iszCaptureInterrupted == NULL_STRING )
+ {
+ m_iszCaptureInterrupted = AllocPooledString( "Hologram.Interrupted" );
+ }
+#endif
+
+ Precache();
+
+ InternalSetOwner( m_iDefaultOwner, false ); //init the owner of this point
+ TeamplayRoundBasedRules()->RecalculateControlPointState();
+
+ SetActive( !m_bStartDisabled );
+
+ BaseClass::Spawn();
+
+ SetPlaybackRate( 1.0 );
+ SetThink( &CTeamControlPoint::AnimThink );
+ SetNextThink( gpGlobals->curtime + 0.1f );
+
+ if ( FBitSet( m_spawnflags, SF_CAP_POINT_HIDE_MODEL ) )
+ {
+ AddEffects( EF_NODRAW );
+ }
+
+ if ( FBitSet( m_spawnflags, SF_CAP_POINT_HIDE_SHADOW ) )
+ {
+ AddEffects( EF_NOSHADOW );
+ }
+
+ m_flLastContestedAt = -1;
+
+ m_pCaptureInProgressSound = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CTeamControlPoint::KeyValue( const char *szKeyName, const char *szValue )
+{
+ if ( !Q_strncmp( szKeyName, "team_capsound_", 14 ) )
+ {
+ int iTeam = atoi(szKeyName+14);
+ Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
+
+ m_TeamData[iTeam].iszCapSound = AllocPooledString(szValue);
+ }
+ else if ( !Q_strncmp( szKeyName, "team_model_", 11 ) )
+ {
+ int iTeam = atoi(szKeyName+11);
+ Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
+
+ m_TeamData[iTeam].iszModel = AllocPooledString(szValue);
+ }
+ else if ( !Q_strncmp( szKeyName, "team_timedpoints_", 17 ) )
+ {
+ int iTeam = atoi(szKeyName+17);
+ Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
+
+ m_TeamData[iTeam].iTimedPoints = atoi(szValue);
+ }
+ else if ( !Q_strncmp( szKeyName, "team_bodygroup_", 15 ) )
+ {
+ int iTeam = atoi(szKeyName+15);
+ Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
+
+ m_TeamData[iTeam].iModelBodygroup = atoi(szValue);
+ }
+ else if ( !Q_strncmp( szKeyName, "team_icon_", 10 ) )
+ {
+ int iTeam = atoi(szKeyName+10);
+ Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
+
+ m_TeamData[iTeam].iszIcon = AllocPooledString(szValue);
+ }
+ else if ( !Q_strncmp( szKeyName, "team_overlay_", 13 ) )
+ {
+ int iTeam = atoi(szKeyName+13);
+ Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
+
+ m_TeamData[iTeam].iszOverlay = AllocPooledString(szValue);
+ }
+ else if ( !Q_strncmp( szKeyName, "team_previouspoint_", 19 ) )
+ {
+ int iTeam;
+ int iPoint = 0;
+ sscanf( szKeyName+19, "%d_%d", &iTeam, &iPoint );
+ Assert( iTeam >= 0 && iTeam < m_TeamData.Count() );
+ Assert( iPoint >= 0 && iPoint < MAX_PREVIOUS_POINTS );
+ m_TeamData[iTeam].iszPreviousPoint[iPoint] = AllocPooledString(szValue);
+ }
+ else
+ {
+ return BaseClass::KeyValue( szKeyName, szValue );
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::Precache( void )
+{
+ for ( int i = 0; i < m_TeamData.Count(); i++ )
+ {
+ // Skip over spectator
+ if ( i == TEAM_SPECTATOR )
+ continue;
+
+ if ( m_TeamData[i].iszCapSound != NULL_STRING )
+ {
+ PrecacheScriptSound( STRING(m_TeamData[i].iszCapSound) );
+ }
+
+ if ( m_TeamData[i].iszModel != NULL_STRING )
+ {
+ PrecacheModel( STRING(m_TeamData[i].iszModel) );
+ }
+
+ if ( m_TeamData[i].iszIcon != NULL_STRING )
+ {
+ PrecacheMaterial( STRING( m_TeamData[i].iszIcon ) );
+ m_TeamData[i].iIcon = GetMaterialIndex( STRING( m_TeamData[i].iszIcon ) );
+ Assert( m_TeamData[i].iIcon != 0 );
+ }
+
+ if ( !m_TeamData[i].iIcon )
+ {
+ Warning( "Invalid hud icon material for team %d in control point '%s' ( point index %d )\n", i, GetDebugName(), GetPointIndex() );
+ }
+
+ if ( m_TeamData[i].iszOverlay != NULL_STRING )
+ {
+ PrecacheMaterial( STRING( m_TeamData[i].iszOverlay ) );
+ m_TeamData[i].iOverlay = GetMaterialIndex( STRING( m_TeamData[i].iszOverlay ) );
+ Assert( m_TeamData[i].iOverlay != 0 );
+
+ if ( !m_TeamData[i].iOverlay )
+ {
+ Warning( "Invalid hud overlay material for team %d in control point '%s' ( point index %d )\n", i, GetDebugName(), GetPointIndex() );
+ }
+ }
+ }
+
+ PrecacheScriptSound( STRING( m_iszCaptureStartSound ) );
+ PrecacheScriptSound( STRING( m_iszCaptureEndSound ) );
+ PrecacheScriptSound( STRING( m_iszCaptureInProgress ) );
+ PrecacheScriptSound( STRING( m_iszCaptureInterrupted ) );
+
+ if ( m_iszWarnSound != NULL_STRING )
+ {
+ PrecacheScriptSound( STRING( m_iszWarnSound ) );
+ }
+
+#ifdef TF_DLL
+ PrecacheScriptSound( "Announcer.ControlPointContested" );
+#endif
+}
+
+//------------------------------------------------------------------------------
+// Purpose:
+//------------------------------------------------------------------------------
+void CTeamControlPoint::AnimThink( void )
+{
+ StudioFrameAdvance();
+ DispatchAnimEvents(this);
+ SetNextThink( gpGlobals->curtime + 0.1f );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Used by ControlMaster to this point to its default owner
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::InputReset( inputdata_t &input )
+{
+ m_flLastContestedAt = -1;
+ InternalSetOwner( m_iDefaultOwner, false );
+ ObjectiveResource()->SetOwningTeam( GetPointIndex(), m_iTeam );
+ TeamplayRoundBasedRules()->RecalculateControlPointState();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::HandleScoring( int iTeam )
+{
+ if ( TeamplayRoundBasedRules() && !TeamplayRoundBasedRules()->ShouldScorePerRound() )
+ {
+ GetGlobalTeam( iTeam )->AddScore( 1 );
+ TeamplayRoundBasedRules()->HandleTeamScoreModify( iTeam, 1 );
+
+ CTeamControlPointMaster *pMaster = g_hControlPointMasters.Count() ? g_hControlPointMasters[0] : NULL;
+ if ( pMaster && !pMaster->WouldNewCPOwnerWinGame( this, iTeam ) )
+ {
+#ifdef TF_DLL
+ if ( TeamplayRoundBasedRules()->GetGameType() == TF_GAMETYPE_ESCORT )
+ {
+ CBroadcastRecipientFilter filter;
+ EmitSound( filter, entindex(), "Hud.EndRoundScored" );
+ }
+ else
+#endif
+ {
+ CTeamRecipientFilter filter( iTeam );
+ EmitSound( filter, entindex(), "Hud.EndRoundScored" );
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Used by Area caps to set the owner
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::InputSetOwner( inputdata_t &input )
+{
+ int iCapTeam = input.value.Int();
+
+ Assert( iCapTeam >= 0 && iCapTeam < GetNumberOfTeams() );
+
+ Assert( input.pCaller );
+
+ if ( !input.pCaller )
+ return;
+
+ if ( GetOwner() == iCapTeam )
+ return;
+
+ if ( TeamplayGameRules()->PointsMayBeCaptured() )
+ {
+ // must be done before setting the owner
+ HandleScoring( iCapTeam );
+
+ if ( input.pCaller->IsPlayer() )
+ {
+ int iCappingPlayer = input.pCaller->entindex();
+ InternalSetOwner( iCapTeam, true, 1, &iCappingPlayer );
+ }
+ else
+ {
+ InternalSetOwner( iCapTeam, false );
+ }
+
+ ObjectiveResource()->SetOwningTeam( GetPointIndex(), m_iTeam );
+ TeamplayRoundBasedRules()->RecalculateControlPointState();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::InputShowModel( inputdata_t &input )
+{
+ RemoveEffects( EF_NODRAW );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::InputHideModel( inputdata_t &input )
+{
+ AddEffects( EF_NODRAW );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CTeamControlPoint::GetCurrentHudIconIndex( void )
+{
+ return m_TeamData[GetOwner()].iIcon;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CTeamControlPoint::GetHudIconIndexForTeam( int iGameTeam )
+{
+ return m_TeamData[iGameTeam].iIcon;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CTeamControlPoint::GetHudOverlayIndexForTeam( int iGameTeam )
+{
+ return m_TeamData[iGameTeam].iOverlay;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CTeamControlPoint::GetPreviousPointForTeam( int iGameTeam, int iPrevPoint )
+{
+ Assert( iPrevPoint >= 0 && iPrevPoint < MAX_PREVIOUS_POINTS );
+
+ int iRetVal = -1;
+ CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, STRING(m_TeamData[iGameTeam].iszPreviousPoint[iPrevPoint]) );
+
+ if ( pEntity )
+ {
+ CTeamControlPoint *pPoint = dynamic_cast<CTeamControlPoint*>( pEntity );
+
+ if ( pPoint )
+ {
+ iRetVal = pPoint->GetPointIndex();
+ }
+ }
+
+ return iRetVal;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::ForceOwner( int iTeam )
+{
+ InternalSetOwner( iTeam, false, 0, 0 );
+ ObjectiveResource()->SetOwningTeam( GetPointIndex(), m_iTeam );
+ TeamplayRoundBasedRules()->RecalculateControlPointState();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::SetOwner( int iCapTeam, bool bMakeSound, int iNumCappers, int *pCappingPlayers )
+{
+ if ( TeamplayGameRules()->PointsMayBeCaptured() )
+ {
+ // must be done before setting the owner
+ HandleScoring( iCapTeam );
+
+ InternalSetOwner( iCapTeam, bMakeSound, iNumCappers, pCappingPlayers );
+ ObjectiveResource()->SetOwningTeam( GetPointIndex(), m_iTeam );
+ TeamplayRoundBasedRules()->RecalculateControlPointState();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::CaptureStart( int iCapTeam, int iNumCappingPlayers, int *pCappingPlayers )
+{
+ int iNumCappers = iNumCappingPlayers;
+
+ float flLastOwnershipChangeTime = -1.f;
+ CBaseEntity *pEnt = gEntList.FindEntityByClassname( NULL, GetControlPointMasterName() );
+ while( pEnt )
+ {
+ CTeamControlPointMaster *pMaster = dynamic_cast<CTeamControlPointMaster *>( pEnt );
+ if ( pMaster && pMaster->IsActive() )
+ {
+ flLastOwnershipChangeTime = pMaster->GetLastOwnershipChangeTime();
+ }
+ pEnt = gEntList.FindEntityByClassname( pEnt, GetControlPointMasterName() );
+ }
+
+ IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_point_startcapture" );
+ if ( event )
+ {
+ event->SetInt( "cp", m_iPointIndex );
+ event->SetString( "cpname", STRING( m_iszPrintName ) );
+ event->SetInt( "team", m_iTeam );
+ event->SetInt( "capteam", iCapTeam );
+ event->SetFloat( "captime", gpGlobals->curtime - flLastOwnershipChangeTime );
+
+ // safety check
+ if ( iNumCappers > 8 )
+ {
+ iNumCappers = 8;
+ }
+
+ char cappers[9]; // pCappingPlayers should be max length 8
+ int i;
+ for( i = 0 ; i < iNumCappers ; i++ )
+ {
+ cappers[i] = (char)pCappingPlayers[i];
+ }
+
+ cappers[i] = '\0';
+
+ // pCappingPlayers is a null terminated list of player indices
+ event->SetString( "cappers", cappers );
+ event->SetInt( "priority", 7 );
+
+ gameeventmanager->FireEvent( event );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::CaptureEnd( void )
+{
+ StopLoopingSounds();
+
+ if ( !FBitSet( m_spawnflags, SF_CAP_POINT_NO_CAP_SOUNDS ) )
+ {
+ EmitSound( STRING( m_iszCaptureEndSound ) );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::CaptureInterrupted( bool bBlocked )
+{
+ StopLoopingSounds();
+
+ if ( FBitSet( m_spawnflags, SF_CAP_POINT_NO_CAP_SOUNDS ) )
+ {
+ return;
+ }
+
+ const char *pSoundName = NULL;
+
+ if ( bBlocked == true )
+ {
+ pSoundName = STRING( m_iszCaptureInterrupted );
+ }
+ else
+ {
+ pSoundName = STRING( m_iszCaptureInProgress );
+ EmitSound( STRING( m_iszCaptureStartSound ) );
+ }
+
+ if ( m_pCaptureInProgressSound == NULL && pSoundName != NULL )
+ {
+ CPASFilter filter( GetAbsOrigin() );
+
+ CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
+ m_pCaptureInProgressSound = controller.SoundCreate( filter, entindex(), pSoundName );
+
+ controller.Play( m_pCaptureInProgressSound, 1.0, 100 );
+ }
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::StopLoopingSounds( void )
+{
+ CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
+
+ if ( m_pCaptureInProgressSound )
+ {
+ controller.SoundDestroy( m_pCaptureInProgressSound );
+ m_pCaptureInProgressSound = NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the new owner of the point, plays the appropriate sound and shows the right model
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::InternalSetOwner( int iCapTeam, bool bMakeSound, int iNumCappers, int *pCappingPlayers )
+{
+ Assert( iCapTeam >= 0 && iCapTeam < GetNumberOfTeams() );
+
+ int iOldTeam = m_iTeam;
+
+ m_iTeam = iCapTeam;
+ ChangeTeam( iCapTeam );
+
+ if ( bMakeSound )
+ {
+ CBroadcastRecipientFilter filter;
+ EmitSound( filter, entindex(), STRING( m_TeamData[m_iTeam].iszCapSound ) );
+ }
+
+ // Update visuals
+ SetModel( STRING(m_TeamData[m_iTeam].iszModel) );
+ SetBodygroup( 0, m_iTeam );
+ m_nSkin = ( m_iTeam == TEAM_UNASSIGNED ) ? 2 : (m_iTeam - 2);
+ ResetSequence( LookupSequence("idle") );
+
+ // We add 1 to the index because we consider the default "no points capped" as 0.
+ TeamplayGameRules()->SetLastCapPointChanged( m_iPointIndex+1 );
+
+ // Determine the pose parameters for each team
+ for ( int i = 0; i < m_TeamData.Count(); i++ )
+ {
+ // Skip spectator
+ if ( i == TEAM_SPECTATOR )
+ continue;
+
+ if ( GetModelPtr() && GetModelPtr()->SequencesAvailable() )
+ {
+ m_TeamData[i].iTeamPoseParam = LookupPoseParameter( UTIL_VarArgs( "cappoint_%d_percentage", i ) );
+ }
+ else
+ {
+ m_TeamData[i].iTeamPoseParam = -1;
+ }
+ }
+ UpdateCapPercentage();
+
+ if ( m_iTeam == TEAM_UNASSIGNED )
+ {
+ m_OnCapReset.FireOutput( this, this );
+ }
+ else
+ {
+ // Remap team to get first game team = 1
+ switch ( m_iTeam - FIRST_GAME_TEAM+1 )
+ {
+ case 1:
+ m_OnCapTeam1.FireOutput( this, this );
+ break;
+ case 2:
+ m_OnCapTeam2.FireOutput( this, this );
+ break;
+ default:
+ Assert(0);
+ break;
+ }
+ }
+
+ // If we're playing a sound, this is a true cap by players.
+ if ( bMakeSound )
+ {
+ if ( iOldTeam > LAST_SHARED_TEAM && iOldTeam != m_iTeam )
+ {
+ // Make the members of our old team say something
+ for ( int i = 1; i <= gpGlobals->maxClients; i++ )
+ {
+ CBaseMultiplayerPlayer *pPlayer = ToBaseMultiplayerPlayer( UTIL_PlayerByIndex( i ) );
+ if ( !pPlayer )
+ continue;
+ if ( pPlayer->GetTeamNumber() == iOldTeam )
+ {
+ pPlayer->SpeakConceptIfAllowed( MP_CONCEPT_LOST_CONTROL_POINT );
+ }
+ }
+ }
+
+ for( int i = 0; i < iNumCappers; i++ )
+ {
+ int playerIndex = pCappingPlayers[i];
+
+ Assert( playerIndex > 0 && playerIndex <= gpGlobals->maxClients );
+
+ PlayerCapped( ToBaseMultiplayerPlayer(UTIL_PlayerByIndex( playerIndex )) );
+ }
+
+ // Remap team to get first game team = 1
+ switch ( m_iTeam - FIRST_GAME_TEAM+1 )
+ {
+ case 1:
+ m_OnOwnerChangedToTeam1.FireOutput( this, this );
+ break;
+ case 2:
+ m_OnOwnerChangedToTeam2.FireOutput( this, this );
+ break;
+ }
+
+ if ( m_iTeam != TEAM_UNASSIGNED && iNumCappers )
+ {
+ SendCapString( m_iTeam, iNumCappers, pCappingPlayers );
+ }
+ }
+
+ // Have control point master check the win conditions now!
+ CBaseEntity *pEnt = gEntList.FindEntityByClassname( NULL, GetControlPointMasterName() );
+
+ while( pEnt )
+ {
+ CTeamControlPointMaster *pMaster = dynamic_cast<CTeamControlPointMaster *>( pEnt );
+
+ if ( pMaster->IsActive() )
+ {
+ pMaster->CheckWinConditions();
+ pMaster->SetLastOwnershipChangeTime( gpGlobals->curtime );
+ }
+
+ pEnt = gEntList.FindEntityByClassname( pEnt, GetControlPointMasterName() );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::SendCapString( int iCapTeam, int iNumCappingPlayers, int *pCappingPlayers )
+{
+ if ( strlen( STRING(m_iszPrintName) ) <= 0 )
+ return;
+
+ int iNumCappers = iNumCappingPlayers;
+
+ IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_point_captured" );
+ if ( event )
+ {
+ event->SetInt( "cp", m_iPointIndex );
+ event->SetString( "cpname", STRING( m_iszPrintName ) );
+ event->SetInt( "team", iCapTeam );
+
+ // safety check
+ if ( iNumCappers > 8 )
+ {
+ iNumCappers = 8;
+ }
+
+ char cappers[9]; // pCappingPlayers should be max length 8
+ int i;
+ for( i = 0 ; i < iNumCappers ; i++ )
+ {
+ cappers[i] = (char)pCappingPlayers[i];
+ }
+
+ cappers[i] = '\0';
+
+ // pCappingPlayers is a null terminated list of player indices
+ event->SetString( "cappers", cappers );
+ event->SetInt( "priority", 9 );
+
+ gameeventmanager->FireEvent( event );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::CaptureBlocked( CBaseMultiplayerPlayer *pPlayer )
+{
+ if( strlen( STRING(m_iszPrintName) ) <= 0 )
+ return;
+
+ IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_capture_blocked" );
+
+ if ( event )
+ {
+ event->SetInt( "cp", m_iPointIndex );
+ event->SetString( "cpname", STRING(m_iszPrintName) );
+ event->SetInt( "blocker", pPlayer->entindex() );
+ event->SetInt( "priority", 9 );
+
+ gameeventmanager->FireEvent( event );
+ }
+
+ PlayerBlocked( pPlayer );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CTeamControlPoint::GetOwner( void ) const
+{
+ return m_iTeam;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CTeamControlPoint::GetDefaultOwner( void ) const
+{
+ return m_iDefaultOwner;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CTeamControlPoint::GetCPGroup( void )
+{
+ return m_iCPGroup;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns the time-based point value of this control point
+//-----------------------------------------------------------------------------
+int CTeamControlPoint::PointValue( void )
+{
+ if ( GetOwner() != m_iDefaultOwner )
+ return m_TeamData[ GetOwner() ].iTimedPoints;
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::SetActive( bool active )
+{
+ m_bActive = active;
+
+ if( active )
+ {
+ RemoveEffects( EF_NODRAW );
+ }
+ else
+ {
+ AddEffects( EF_NODRAW );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::SetCappersRequiredForTeam( int iGameTeam, int iCappers )
+{
+ m_TeamData[iGameTeam].iPlayersRequired = iCappers;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Return true if this point has ever been contested, false if the enemy has never contested this point yet
+//-----------------------------------------------------------------------------
+bool CTeamControlPoint::HasBeenContested( void ) const
+{
+ return m_flLastContestedAt > 0.0f;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+float CTeamControlPoint::LastContestedAt( void )
+{
+ return m_flLastContestedAt;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::SetLastContestedAt( float flTime )
+{
+ m_flLastContestedAt = flTime;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::UpdateCapPercentage( void )
+{
+ for ( int i = LAST_SHARED_TEAM+1; i < m_TeamData.Count(); i++ )
+ {
+ // Skip spectator
+ if ( i == TEAM_SPECTATOR )
+ continue;
+
+ float flPerc = GetTeamCapPercentage(i);
+
+ if ( m_TeamData[i].iTeamPoseParam != -1 )
+ {
+ SetPoseParameter( m_TeamData[i].iTeamPoseParam, flPerc );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+float CTeamControlPoint::GetTeamCapPercentage( int iTeam )
+{
+ int iCappingTeam = ObjectiveResource()->GetCappingTeam( GetPointIndex() );
+ if ( iCappingTeam == TEAM_UNASSIGNED )
+ {
+ // No-one's capping this point.
+ if ( iTeam == m_iTeam )
+ return 1.0;
+
+ return 0.0;
+ }
+
+ float flCapPerc = ObjectiveResource()->GetCPCapPercentage( GetPointIndex() );
+ if ( iTeam == iCappingTeam )
+ return (1.0 - flCapPerc);
+ if ( iTeam == m_iTeam )
+ return flCapPerc;
+
+ return 0.0;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CTeamControlPoint::DrawDebugTextOverlays( void )
+{
+ int text_offset = BaseClass::DrawDebugTextOverlays();
+
+ if (m_debugOverlays & OVERLAY_TEXT_BIT)
+ {
+ char tempstr[1024];
+ Q_snprintf(tempstr, sizeof(tempstr), "INDEX: (%d)", GetPointIndex() );
+ EntityText(text_offset,tempstr,0);
+ text_offset++;
+
+ Q_snprintf( tempstr, sizeof(tempstr), "Red Previous Points: ");
+ for ( int i = 0; i < MAX_PREVIOUS_POINTS; i++ )
+ {
+ if ( m_TeamData[2].iszPreviousPoint[i] != NULL_STRING )
+ {
+ Q_strncat( tempstr, STRING(m_TeamData[2].iszPreviousPoint[i]), 1024, COPY_ALL_CHARACTERS );
+ Q_strncat( tempstr, ", ", 1024, COPY_ALL_CHARACTERS );
+ }
+ }
+ EntityText(text_offset,tempstr,0);
+ text_offset++;
+
+ Q_snprintf( tempstr, sizeof(tempstr), "Blue Previous Points: " );
+ for ( int i = 0; i < MAX_PREVIOUS_POINTS; i++ )
+ {
+ if ( m_TeamData[3].iszPreviousPoint[i] != NULL_STRING )
+ {
+ Q_strncat( tempstr, STRING(m_TeamData[3].iszPreviousPoint[i]), 1024, COPY_ALL_CHARACTERS );
+ Q_strncat( tempstr, ", ", 1024, COPY_ALL_CHARACTERS );
+ }
+ }
+ EntityText(text_offset,tempstr,0);
+ text_offset++;
+
+ for ( int i = 0; i < MAX_CONTROL_POINT_TEAMS; i++ )
+ {
+ if ( ObjectiveResource()->GetBaseControlPointForTeam(i) == GetPointIndex() )
+ {
+ Q_snprintf(tempstr, sizeof(tempstr), "Base Control Point for Team %d", i );
+ EntityText(text_offset,tempstr,0);
+ text_offset++;
+ }
+ }
+ }
+
+ return text_offset;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: The specified player took part in capping this point.
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::PlayerCapped( CBaseMultiplayerPlayer *pPlayer )
+{
+ if ( pPlayer )
+ {
+ pPlayer->SpeakConceptIfAllowed( MP_CONCEPT_CAPTURED_POINT );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: The specified player blocked the enemy team from capping this point.
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::PlayerBlocked( CBaseMultiplayerPlayer *pPlayer )
+{
+ if ( pPlayer )
+ {
+ pPlayer->SpeakConceptIfAllowed( MP_CONCEPT_CAPTURE_BLOCKED );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::InputRoundActivate( inputdata_t &inputdata )
+{
+ switch ( m_iTeam - FIRST_GAME_TEAM+1 )
+ {
+ case 1:
+ m_OnRoundStartOwnedByTeam1.FireOutput( this, this );
+ break;
+ case 2:
+ m_OnRoundStartOwnedByTeam2.FireOutput( this, this );
+ break;
+ }
+
+ InternalSetLocked( m_bLocked );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::InputSetLocked( inputdata_t &inputdata )
+{
+ // never lock/unlock the point if we're in waiting for players
+ if ( TeamplayRoundBasedRules() && TeamplayRoundBasedRules()->IsInWaitingForPlayers() )
+ return;
+
+ bool bLocked = inputdata.value.Int() > 0;
+ InternalSetLocked( bLocked );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::InternalSetLocked( bool bLocked )
+{
+ if ( !bLocked && m_bLocked )
+ {
+ // unlocked this point
+ IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_point_unlocked" );
+ if ( event )
+ {
+ event->SetInt( "cp", m_iPointIndex );
+ event->SetString( "cpname", STRING( m_iszPrintName ) );
+ event->SetInt( "team", m_iTeam );
+ gameeventmanager->FireEvent( event );
+ }
+ }
+ else if ( bLocked && !m_bLocked )
+ {
+ // locked this point
+ IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_point_locked" );
+ if ( event )
+ {
+ event->SetInt( "cp", m_iPointIndex );
+ event->SetString( "cpname", STRING( m_iszPrintName ) );
+ event->SetInt( "team", m_iTeam );
+ gameeventmanager->FireEvent( event );
+ }
+ }
+
+ m_bLocked = bLocked;
+
+ if ( ObjectiveResource() && GetPointIndex() < ObjectiveResource()->GetNumControlPoints() )
+ {
+ ObjectiveResource()->SetCPLocked( GetPointIndex(), m_bLocked );
+ ObjectiveResource()->SetCPUnlockTime( GetPointIndex(), 0.0f );
+ }
+
+ if ( !m_bLocked )
+ {
+ m_flUnlockTime = -1;
+ m_OnUnlocked.FireOutput( this, this );
+ SetContextThink( NULL, 0, CONTROL_POINT_UNLOCK_THINK );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::InputSetUnlockTime( inputdata_t &inputdata )
+{
+ // never lock/unlock the point if we're in waiting for players
+ if ( TeamplayRoundBasedRules() && TeamplayRoundBasedRules()->IsInWaitingForPlayers() )
+ return;
+
+ int nTime = inputdata.value.Int();
+
+ if ( nTime <= 0 )
+ {
+ InternalSetLocked( false );
+ return;
+ }
+
+ m_flUnlockTime = gpGlobals->curtime + nTime;
+
+ if ( ObjectiveResource() )
+ {
+ ObjectiveResource()->SetCPUnlockTime( GetPointIndex(), m_flUnlockTime );
+ }
+
+ SetContextThink( &CTeamControlPoint::UnlockThink, gpGlobals->curtime + 0.1, CONTROL_POINT_UNLOCK_THINK );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPoint::UnlockThink( void )
+{
+ if ( m_flUnlockTime > 0 &&
+ m_flUnlockTime < gpGlobals->curtime &&
+ ( TeamplayRoundBasedRules() && TeamplayRoundBasedRules()->State_Get() == GR_STATE_RND_RUNNING ) )
+ {
+ InternalSetLocked( false );
+ return;
+ }
+
+ SetContextThink( &CTeamControlPoint::UnlockThink, gpGlobals->curtime + 0.1, CONTROL_POINT_UNLOCK_THINK );
+}