summaryrefslogtreecommitdiff
path: root/game/server/dod/dod_control_point.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/server/dod/dod_control_point.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/server/dod/dod_control_point.cpp')
-rw-r--r--game/server/dod/dod_control_point.cpp738
1 files changed, 738 insertions, 0 deletions
diff --git a/game/server/dod/dod_control_point.cpp b/game/server/dod/dod_control_point.cpp
new file mode 100644
index 0000000..5b74f8e
--- /dev/null
+++ b/game/server/dod/dod_control_point.cpp
@@ -0,0 +1,738 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "dod_shareddefs.h"
+#include "dod_control_point.h"
+#include "dod_player.h"
+#include "dod_gamerules.h"
+#include "dod_team.h"
+#include "dod_objective_resource.h"
+#include "dod_control_point_master.h"
+
+LINK_ENTITY_TO_CLASS( dod_control_point, CControlPoint );
+
+#define OBJ_ICON_NEUTRAL_FLAG 0
+#define OBJ_ICON_ALLIES_FLAG 1
+#define OBJ_ICON_AXIS_FLAG 2
+
+BEGIN_DATADESC(CControlPoint)
+
+ DEFINE_KEYFIELD( m_iszPrintName, FIELD_STRING, "point_printname" ),
+
+ DEFINE_KEYFIELD( m_iszAlliesCapSound, FIELD_STRING, "point_allies_capsound" ),
+ DEFINE_KEYFIELD( m_iszAxisCapSound, FIELD_STRING, "point_axis_capsound" ),
+ DEFINE_KEYFIELD( m_iszResetSound, FIELD_STRING, "point_resetsound" ),
+
+ DEFINE_KEYFIELD( m_iszAlliesModel, FIELD_STRING, "point_allies_model" ),
+ DEFINE_KEYFIELD( m_iszAxisModel, FIELD_STRING, "point_axis_model" ),
+ DEFINE_KEYFIELD( m_iszResetModel, FIELD_STRING, "point_reset_model" ),
+
+ DEFINE_KEYFIELD( m_iCPGroup, FIELD_INTEGER, "point_group" ),
+
+ DEFINE_KEYFIELD( m_iTimedPointsAllies, FIELD_INTEGER, "point_timedpoints_allies" ),
+ DEFINE_KEYFIELD( m_iTimedPointsAxis, FIELD_INTEGER, "point_timedpoints_axis" ),
+
+ DEFINE_KEYFIELD( m_iBombsRequired, FIELD_INTEGER, "point_num_bombs" ),
+
+ DEFINE_INPUTFUNC( FIELD_INTEGER, "SetOwner", InputSetOwner ),
+
+ DEFINE_INPUTFUNC( FIELD_VOID, "ShowModel", InputShowModel ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "HideModel", InputHideModel ),
+
+ DEFINE_OUTPUT( m_AlliesCapOutput, "OnAlliesCap" ), // these are fired whenever the point changes modes
+ DEFINE_OUTPUT( m_AxisCapOutput, "OnAxisCap" ),
+ DEFINE_OUTPUT( m_PointResetOutput, "OnCapReset" ),
+
+ DEFINE_OUTPUT( m_OwnerChangedToAllies, "AlliesCapturePoint" ), // these are fired when a team does the work to change the owner
+ DEFINE_OUTPUT( m_OwnerChangedToAxis, "AxisCapturePoint" ),
+
+END_DATADESC();
+
+
+CControlPoint::CControlPoint( )
+{
+ m_iPointIndex = -1;
+ m_bPointVisible = false;
+
+ m_iAlliesIcon = 0;
+ m_iAxisIcon = 0;
+ m_iNeutralIcon = 0;
+ m_iNeutralIcon = 0;
+
+ //default group is 0 for backwards compatibility
+ m_iAlliesModelBodygroup = 0;
+ m_iAxisModelBodygroup = 0;
+ m_iResetModelBodygroup = 0;
+
+ m_bBombPlanted = false;
+}
+
+void CControlPoint::Spawn( void )
+{
+ Precache();
+
+ SetTouch( NULL );
+
+ InternalSetOwner( m_iDefaultOwner, false ); //init the owner of this point
+
+ SetActive( !m_bStartDisabled );
+
+ BaseClass::Spawn();
+
+ UseClientSideAnimation();
+
+ SetPlaybackRate( 1.0 );
+
+ SetCycle( random->RandomFloat( 0, 1.0 ) );
+
+ m_iAlliesRequired = 0;
+ m_iAxisRequired = 0;
+
+ if ( FBitSet( m_spawnflags, CAP_POINT_HIDE_MODEL ) )
+ {
+ AddEffects( EF_NODRAW );
+ }
+
+ m_iBombsRemaining = m_iBombsRequired;
+}
+
+void CControlPoint::SetNumCappersRequired( int alliesRequired, int axisRequired )
+{
+ m_iAlliesRequired = alliesRequired;
+ m_iAxisRequired = axisRequired;
+}
+
+//================================
+// InputReset
+// Used by ControlMaster to this point to its default owner
+//================================
+void CControlPoint::InputReset( inputdata_t &input )
+{
+ InternalSetOwner( m_iDefaultOwner, false );
+ g_pObjectiveResource->SetOwningTeam( GetPointIndex(), m_iTeam );
+}
+
+//================================
+// InputReset
+// Used by Area caps to set the owner
+//================================
+void CControlPoint::InputSetOwner( inputdata_t &input )
+{
+ int team = input.value.Int();
+
+ Assert( team == TEAM_UNASSIGNED || team == TEAM_ALLIES || team == TEAM_AXIS );
+
+ Assert( input.pCaller );
+ Assert( input.pCaller->IsPlayer() );
+
+ CDODPlayer *pPlayer = ToDODPlayer( input.pCaller );
+
+ int iCappingPlayer = pPlayer->entindex();
+
+ // Only allow cp caps when round is running ( but not when in warmup )
+ if( DODGameRules()->State_Get() == STATE_RND_RUNNING &&
+ !DODGameRules()->IsInWarmup() )
+ {
+ InternalSetOwner( team, true, 1, &iCappingPlayer );
+ g_pObjectiveResource->SetOwningTeam( GetPointIndex(), m_iTeam );
+ }
+}
+
+void CControlPoint::SetOwner( int owner, bool bMakeSound, int iNumCappers, int *pCappingPlayers )
+{
+ // Only allow cp caps when round is running ( but not when in warmup )
+ if( DODGameRules()->State_Get() == STATE_RND_RUNNING &&
+ !DODGameRules()->IsInWarmup() )
+ {
+ InternalSetOwner( owner, bMakeSound, iNumCappers, pCappingPlayers );
+ g_pObjectiveResource->SetOwningTeam( GetPointIndex(), m_iTeam );
+ }
+}
+
+void CControlPoint::InputShowModel( inputdata_t &input )
+{
+ RemoveEffects( EF_NODRAW );
+}
+
+void CControlPoint::InputHideModel( inputdata_t &input )
+{
+ AddEffects( EF_NODRAW );
+}
+
+int CControlPoint::GetCurrentHudIconIndex( void )
+{
+ return GetHudIconIndexForTeam( GetOwner() );
+}
+
+int CControlPoint::GetHudIconIndexForTeam( int team )
+{
+ int icon = m_iNeutralIcon;
+
+ switch( team )
+ {
+ case TEAM_ALLIES:
+ icon = m_iAlliesIcon;
+ break;
+ case TEAM_AXIS:
+ icon = m_iAxisIcon;
+ break;
+ case TEAM_UNASSIGNED:
+ icon = m_iNeutralIcon;
+ break;
+ default:
+ Assert( !"Bad team in GetHudIconIndexForTeam()" );
+ break;
+ }
+
+ return icon;
+}
+
+int CControlPoint::GetTimerCapHudIcon( void )
+{
+ return m_iTimerCapIcon;
+}
+
+int CControlPoint::GetBombedHudIcon( void )
+{
+ return m_iBombedIcon;
+}
+
+// SetOwner
+// ========
+// Sets the new owner of the point
+// plays the appropriate sound
+// and shows the right model
+
+void CControlPoint::InternalSetOwner( int owner, bool bMakeSound, int iNumCappers, int *pCappingPlayers )
+{
+ m_iTeam = owner;
+
+ switch ( m_iTeam )
+ {
+ case TEAM_UNASSIGNED:
+ {
+ if( bMakeSound )
+ {
+ CBroadcastRecipientFilter filter;
+ EmitSound( filter, entindex(), STRING(m_iszResetSound) );
+ }
+
+ SetModel( STRING(m_iszResetModel) );
+ SetBodygroup( 0, m_iResetModelBodygroup );
+
+ m_PointResetOutput.FireOutput( this, this );
+ }
+ break;
+ case TEAM_ALLIES:
+ {
+ if( bMakeSound )
+ {
+ CBroadcastRecipientFilter filter;
+ EmitSound( filter, entindex(), STRING(m_iszAlliesCapSound) );
+ }
+
+ SetModel( STRING(m_iszAlliesModel) );
+ SetBodygroup( 0, m_iAlliesModelBodygroup );
+
+ m_AlliesCapOutput.FireOutput( this, this );
+ }
+ break;
+ case TEAM_AXIS:
+ {
+ if( bMakeSound )
+ {
+ CBroadcastRecipientFilter filter;
+ EmitSound( filter, entindex(), STRING(m_iszAxisCapSound) );
+ }
+
+ SetModel( STRING(m_iszAxisModel) );
+ SetBodygroup( 0, m_iAxisModelBodygroup );
+
+ m_AxisCapOutput.FireOutput( this, this );
+ }
+ break;
+ default:
+ Assert(0);
+ break;
+ }
+
+ if( bMakeSound ) //make sure this is a real cap and not a reset
+ {
+ for( int i=0;i<iNumCappers;i++ )
+ {
+ int playerIndex = pCappingPlayers[i];
+
+ Assert( playerIndex > 0 && playerIndex <= gpGlobals->maxClients );
+
+ CDODPlayer *pPlayer = ToDODPlayer( UTIL_PlayerByIndex( playerIndex ) );
+
+ Assert( pPlayer );
+
+ if ( pPlayer )
+ {
+ pPlayer->AddScore( PLAYER_POINTS_FOR_CAP );
+ pPlayer->Stats_AreaCaptured();
+ DODGameRules()->Stats_PlayerCap( pPlayer->GetTeamNumber(), pPlayer->m_Shared.DesiredPlayerClass() );
+
+ // count bomb plants as point capture
+ //if ( !m_bSetOwnerIsBombPlant )
+ {
+ pPlayer->StatEvent_PointCaptured();
+ }
+ }
+ }
+
+ if ( m_iTeam == TEAM_ALLIES )
+ {
+ m_OwnerChangedToAllies.FireOutput( this, this );
+ }
+ else if ( m_iTeam == TEAM_AXIS )
+ {
+ m_OwnerChangedToAxis.FireOutput( this, this );
+ }
+ }
+
+ if( bMakeSound && m_iTeam != TEAM_UNASSIGNED && iNumCappers > 0 ) //dont print message if its a reset
+ SendCapString( m_iTeam, iNumCappers, pCappingPlayers );
+
+ // have control point master check the win conditions now!
+ CBaseEntity *pEnt = gEntList.FindEntityByClassname( NULL, "dod_control_point_master" );
+
+ while( pEnt )
+ {
+ CControlPointMaster *pMaster = dynamic_cast<CControlPointMaster *>( pEnt );
+
+ if ( pMaster->IsActive() )
+ {
+ pMaster->CheckWinConditions();
+ }
+
+ pEnt = gEntList.FindEntityByClassname( pEnt, "dod_control_point_master" );
+ }
+
+ // Capping the last flag achievement
+ if ( ( DODGameRules()->State_Get() == STATE_ALLIES_WIN && m_iTeam == TEAM_ALLIES ) ||
+ ( DODGameRules()->State_Get() == STATE_AXIS_WIN && m_iTeam == TEAM_AXIS ) )
+ {
+ // limit to flag cap maps
+ if ( m_iBombsRequired == 0 )
+ {
+ for ( int i=0;i<iNumCappers;i++ )
+ {
+ CDODPlayer *pDODPlayer = ToDODPlayer( UTIL_PlayerByIndex( pCappingPlayers[i] ) );
+
+ if ( pDODPlayer )
+ {
+ pDODPlayer->AwardAchievement( ACHIEVEMENT_DOD_CAP_LAST_FLAG );
+ }
+ }
+ }
+ }
+}
+
+void CControlPoint::SendCapString( int team, int iNumCappers, int *pCappingPlayers )
+{
+ if( strlen( STRING(m_iszPrintName) ) <= 0 )
+ return;
+
+ IGameEvent * event = gameeventmanager->CreateEvent( "dod_point_captured" );
+
+ if ( event )
+ {
+ event->SetInt( "cp", m_iPointIndex );
+ event->SetString( "cpname", STRING(m_iszPrintName) );
+
+ char cappers[9]; // pCappingPlayers is 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 indeces
+ event->SetString( "cappers", cappers );
+ event->SetInt( "priority", 9 );
+
+ event->SetBool( "bomb", m_bSetOwnerIsBombPlant );
+
+ gameeventmanager->FireEvent( event );
+ }
+}
+
+void CControlPoint::CaptureBlocked( CDODPlayer *pPlayer )
+{
+ if( strlen( STRING(m_iszPrintName) ) <= 0 )
+ return;
+
+ IGameEvent *event = gameeventmanager->CreateEvent( "dod_capture_blocked" );
+
+ if ( event )
+ {
+ event->SetInt( "cp", m_iPointIndex );
+ event->SetString( "cpname", STRING(m_iszPrintName) );
+ event->SetInt( "blocker", pPlayer->entindex() );
+ event->SetInt( "priority", 9 );
+ event->SetBool( "bomb", GetBombsRemaining() > 0 );
+
+ gameeventmanager->FireEvent( event );
+ }
+
+ pPlayer->AddScore( PLAYER_POINTS_FOR_BLOCK );
+
+ if ( GetBombsRemaining() <= 0 ) // no bomb blocks ( kills planter or defuser )
+ {
+ pPlayer->StatEvent_CaptureBlocked();
+ }
+
+ pPlayer->Stats_AreaDefended();
+ DODGameRules()->Stats_PlayerDefended( pPlayer->GetTeamNumber(), pPlayer->m_Shared.DesiredPlayerClass() );
+}
+
+// GetOwner
+// ========
+// returns the current owner
+// 2 for allies
+// 3 for axis
+// 0 if noone owns it
+
+int CControlPoint::GetOwner( void ) const
+{
+ return m_iTeam;
+}
+
+int CControlPoint::GetDefaultOwner( void ) const
+{
+ return m_iDefaultOwner;
+}
+
+int CControlPoint::GetCPGroup( void )
+{
+ return m_iCPGroup;
+}
+
+// PointValue
+// ==========
+// returns the time-based point value of this control point
+int CControlPoint::PointValue( void )
+{
+ // teams earn 0 points for a flag they start with
+ // after that its 1 additional point for each flag closer to the spawn.
+
+ int value = 0;
+
+ if ( FBitSet( m_spawnflags, CAP_POINT_TICK_FOR_BOMBS_REMAINING ) )
+ {
+ value = m_iBombsRemaining;
+ }
+ else if ( GetOwner() == m_iDefaultOwner )
+ {
+ value = 0;
+ }
+ else
+ {
+ if ( GetOwner() == TEAM_ALLIES )
+ {
+ value = m_iTimedPointsAllies;
+ }
+ else if ( GetOwner() == TEAM_AXIS )
+ {
+ value = m_iTimedPointsAxis;
+ }
+ }
+
+ return value;
+}
+
+//precache the necessary models and sounds
+void CControlPoint::Precache( void )
+{
+ if ( m_iszAlliesCapSound != NULL_STRING )
+ {
+ PrecacheScriptSound( STRING(m_iszAlliesCapSound) );
+ }
+ if ( m_iszAxisCapSound != NULL_STRING )
+ {
+ PrecacheScriptSound( STRING(m_iszAxisCapSound) );
+ }
+ if ( m_iszResetSound != NULL_STRING )
+ {
+ PrecacheScriptSound( STRING(m_iszResetSound) );
+ }
+
+ PrecacheModel( STRING( m_iszAlliesModel ) );
+ PrecacheModel( STRING( m_iszAxisModel ) );
+ PrecacheModel( STRING( m_iszResetModel ) );
+
+ PrecacheMaterial( STRING( m_iszAlliesIcon ) );
+ m_iAlliesIcon = GetMaterialIndex( STRING( m_iszAlliesIcon ) );
+ Assert( m_iAlliesIcon != 0 );
+
+ PrecacheMaterial( STRING( m_iszAxisIcon ) );
+ m_iAxisIcon = GetMaterialIndex( STRING( m_iszAxisIcon ) );
+ Assert( m_iAxisIcon != 0 );
+
+ PrecacheMaterial( STRING( m_iszNeutralIcon ) );
+ m_iNeutralIcon = GetMaterialIndex( STRING( m_iszNeutralIcon ) );
+ Assert( m_iNeutralIcon != 0 );
+
+ if ( strlen( STRING( m_iszTimerCapIcon ) ) > 0 )
+ {
+ PrecacheMaterial( STRING( m_iszTimerCapIcon ) );
+ m_iTimerCapIcon = GetMaterialIndex( STRING( m_iszTimerCapIcon ) );
+ }
+
+ if ( strlen( STRING( m_iszBombedIcon ) ) > 0 )
+ {
+ PrecacheMaterial( STRING( m_iszBombedIcon ) );
+ m_iBombedIcon = GetMaterialIndex( STRING( m_iszBombedIcon ) );
+ }
+
+ if( !m_iNeutralIcon || !m_iAxisIcon || !m_iAlliesIcon )
+ {
+ Warning( "Invalid hud icon material in control point ( point index %d )\n", GetPointIndex() );
+ }
+}
+
+// Keyvalue
+// ========
+// this function interfaces with the keyvalues set by the mapper
+//
+// Values:
+// point_name - the name of the point displayed in the capture string ( and ControlStatus command )
+// point_reset_time - time after which the point spontaneously resets - currently not used
+// point_default_owner - the owner of this point at the start and after resets
+
+// point_allies_capsound |
+// point_axis_capsound | the sounds that are made when the points are capped by each team
+// point_resetsound |
+//
+// point_allies_model |
+// point_axis_model | the models that the ent is set to after each team caps it
+// point_reset_model |
+
+//point_team_points - number of team points to give to the capper's team for capping
+
+bool CControlPoint::KeyValue( const char *szKeyName, const char *szValue )
+{
+ if (FStrEq(szKeyName, "point_default_owner"))
+ {
+ m_iDefaultOwner = atoi(szValue);
+
+ Assert( m_iDefaultOwner == TEAM_ALLIES ||
+ m_iDefaultOwner == TEAM_AXIS ||
+ m_iDefaultOwner == TEAM_UNASSIGNED );
+
+ if( m_iDefaultOwner != TEAM_ALLIES &&
+ m_iDefaultOwner != TEAM_AXIS &&
+ m_iDefaultOwner != TEAM_UNASSIGNED )
+ {
+ Warning( "dod_control_point with bad point_default_owner - probably '1'\n" );
+ m_iDefaultOwner = TEAM_UNASSIGNED;
+ }
+ }
+ else if (FStrEq(szKeyName, "point_allies_model_bodygroup"))
+ {
+ m_iAlliesModelBodygroup = atoi(szValue);
+ }
+ else if (FStrEq(szKeyName, "point_axis_model_bodygroup"))
+ {
+ m_iAxisModelBodygroup = atoi(szValue);
+ }
+ else if (FStrEq(szKeyName, "point_reset_model_bodygroup"))
+ {
+ m_iResetModelBodygroup = atoi(szValue);
+ }
+ else if (FStrEq(szKeyName, "point_index"))
+ {
+ m_iPointIndex = atoi(szValue);
+ }
+ else if (FStrEq(szKeyName, "point_hud_icon_allies"))
+ {
+ m_iszAlliesIcon = AllocPooledString(szValue);
+ }
+ else if (FStrEq(szKeyName, "point_hud_icon_axis"))
+ {
+ m_iszAxisIcon = AllocPooledString(szValue);
+ }
+ else if (FStrEq(szKeyName, "point_hud_icon_neutral"))
+ {
+ m_iszNeutralIcon = AllocPooledString(szValue);
+ }
+ else if (FStrEq(szKeyName, "point_hud_icon_timercap"))
+ {
+ m_iszTimerCapIcon = AllocPooledString(szValue);
+ }
+ else if (FStrEq(szKeyName, "point_hud_icon_bombed"))
+ {
+ m_iszBombedIcon = AllocPooledString(szValue);
+ }
+ else
+ return CBaseEntity::KeyValue( szKeyName, szValue );
+
+ return true;
+}
+
+void CControlPoint::SetActive( bool active )
+{
+ m_bActive = active;
+
+ if( active )
+ {
+ RemoveEffects( EF_NODRAW );
+ }
+ else
+ {
+ AddEffects( EF_NODRAW );
+ }
+}
+
+void CControlPoint::BombPlanted( float flTimerLength, CDODPlayer *pPlantingPlayer )
+{
+ if ( m_bBombPlanted == true )
+ {
+ Warning( "ERROR - dod_control_point only supports one bomb being planted at once\n" );
+ return;
+ }
+
+ //send it to everyone
+ IGameEvent *event = gameeventmanager->CreateEvent( "dod_bomb_planted" );
+ if ( event )
+ {
+ int iOppositeTeam = ( pPlantingPlayer->GetTeamNumber() == TEAM_ALLIES ) ? TEAM_AXIS : TEAM_ALLIES;
+
+ event->SetInt( "team", iOppositeTeam );
+
+ event->SetInt( "cp", m_iPointIndex );
+ event->SetString( "cpname", STRING(m_iszPrintName) );
+ event->SetInt( "userid", pPlantingPlayer->GetUserID() );
+
+ gameeventmanager->FireEvent( event );
+ }
+
+ m_bBombPlanted = true;
+ m_flBombExplodeTime = gpGlobals->curtime + flTimerLength;
+
+ // give the planter a point
+ pPlantingPlayer->AddScore( PLAYER_POINTS_FOR_BOMB_PLANT );
+
+ pPlantingPlayer->StatEvent_BombPlanted();
+
+ // set hud display
+ // this triggers the countdown ( using a shared, constant bomb timer )
+ g_pObjectiveResource->SetBombPlanted( GetPointIndex(), true );
+}
+
+void CControlPoint::BombExploded( CDODPlayer *pPlantingPlayer /* = NULL */, int iPlantingTeam /* = TEAM_UNASSIGNED */ )
+{
+ m_bBombPlanted = false;
+
+ m_iBombsRemaining -= 1;
+ g_pObjectiveResource->SetBombsRemaining( GetPointIndex(), m_iBombsRemaining );
+
+ if ( pPlantingPlayer )
+ {
+ IGameEvent *event = gameeventmanager->CreateEvent( "dod_bomb_exploded" );
+ if ( event )
+ {
+ event->SetInt( "cp", m_iPointIndex );
+ event->SetString( "cpname", STRING(m_iszPrintName) );
+ event->SetInt( "userid", pPlantingPlayer->GetUserID() );
+
+ gameeventmanager->FireEvent( event );
+ }
+
+ pPlantingPlayer->Stats_BombDetonated();
+
+ int iCappingPlayer = pPlantingPlayer->entindex();
+
+ DODGameRules()->CapEvent( CAP_EVENT_BOMB, iPlantingTeam );
+
+ if ( m_iBombsRemaining <= 0 )
+ {
+ m_bSetOwnerIsBombPlant = true;
+
+ InternalSetOwner( iPlantingTeam, true, 1, &iCappingPlayer );
+ g_pObjectiveResource->SetOwningTeam( GetPointIndex(), GetOwner() );
+
+ m_bSetOwnerIsBombPlant = false;
+
+ // top up points so it equals PLAYER_POINTS_FOR_BOMB_EXPLODED
+ pPlantingPlayer->AddScore( PLAYER_POINTS_FOR_BOMB_EXPLODED - PLAYER_POINTS_FOR_CAP );
+ }
+ else
+ {
+ // give that bomber a point!
+ pPlantingPlayer->AddScore( PLAYER_POINTS_FOR_BOMB_EXPLODED );
+
+ pPlantingPlayer->Stats_AreaCaptured();
+
+ pPlantingPlayer->StatEvent_PointCaptured();
+
+ // send something to death notices to show that something was accomplished
+
+ IGameEvent * event = gameeventmanager->CreateEvent( "dod_point_captured" );
+
+ if ( event )
+ {
+ event->SetInt( "cp", m_iPointIndex );
+ event->SetString( "cpname", STRING(m_iszPrintName) );
+
+ char cappers[3];
+ cappers[0] = iCappingPlayer;
+ cappers[1] = '\0';
+
+ // pCappingPlayers is a null terminated list of player indeces
+ event->SetString( "cappers", cappers );
+ event->SetInt( "priority", 9 );
+
+ event->SetBool( "bomb", true );
+
+ gameeventmanager->FireEvent( event );
+ }
+ }
+ }
+ else
+ {
+ if ( m_iBombsRemaining <= 0 )
+ {
+ // get the opposite team
+ int team = ( GetOwner() == TEAM_ALLIES ) ? TEAM_AXIS : TEAM_ALLIES;
+
+ InternalSetOwner( team, true );
+ g_pObjectiveResource->SetOwningTeam( GetPointIndex(), GetOwner() );
+ }
+ }
+
+ g_pObjectiveResource->SetBombPlanted( GetPointIndex(), false );
+}
+
+void CControlPoint::BombDisarmed( CDODPlayer *pDisarmingPlayer )
+{
+ CancelBombPlanted();
+
+ CaptureBlocked( pDisarmingPlayer );
+
+ IGameEvent *event = gameeventmanager->CreateEvent( "dod_bomb_defused" );
+ if ( event )
+ {
+ event->SetInt( "cp", m_iPointIndex );
+ event->SetString( "cpname", STRING(m_iszPrintName) );
+ event->SetInt( "userid", pDisarmingPlayer->GetUserID() );
+ event->SetInt( "team", pDisarmingPlayer->GetTeamNumber() );
+ gameeventmanager->FireEvent( event );
+ }
+}
+
+void CControlPoint::CancelBombPlanted( void )
+{
+ m_bBombPlanted = false;
+
+ // reset hud display
+ g_pObjectiveResource->SetBombPlanted( GetPointIndex(), false );
+} \ No newline at end of file