|
|
//========= 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"
#include "tf_gamerules.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; m_bBotsIgnore = false;
#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_bBotsIgnore = FBitSet( m_spawnflags, SF_CAP_POINT_BOTS_IGNORE ) > 0;
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" ); PrecacheScriptSound( "Announcer.ControlPointContested_Neutral" ); #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 );
CBaseMultiplayerPlayer *pPlayer = ToBaseMultiplayerPlayer( UTIL_PlayerByIndex( playerIndex ) ); PlayerCapped( pPlayer );
#ifdef TF_DLL
if ( TFGameRules() && TFGameRules()->IsHolidayActive( kHoliday_EOTL ) ) { TFGameRules()->DropBonusDuck( pPlayer->GetAbsOrigin(), ToTFPlayer( pPlayer ), NULL, NULL, false, true ); } #endif
}
// 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 ); }
#ifdef TF_DLL
if ( TFGameRules() && TFGameRules()->IsHolidayActive( kHoliday_Halloween ) ) { TFGameRules()->DropHalloweenSoulPackToTeam( 5, GetAbsOrigin(), m_iTeam, TEAM_SPECTATOR ); } #endif
}
// 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, CBaseMultiplayerPlayer *pVictim ) { 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 ); if ( pVictim ) { event->SetInt( "victim", pVictim->entindex() ); }
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 ); }
|