From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/server/team_control_point.cpp | 2154 ++++++++++++++--------------- 1 file changed, 1077 insertions(+), 1077 deletions(-) (limited to 'mp/src/game/server/team_control_point.cpp') 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( 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( 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( 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( 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( 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( 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 ); +} -- cgit v1.2.3