mirror of
https://github.com/celisej567/source-engine.git
synced 2026-01-04 18:09:53 +03:00
add hl1,portal,dod source code
This commit is contained in:
141
game/server/dod/dod_ammo_box.cpp
Normal file
141
game/server/dod/dod_ammo_box.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_ammo_box.h"
|
||||
#include "dod_player.h"
|
||||
#include "dod_gamerules.h"
|
||||
|
||||
BEGIN_DATADESC( CAmmoBox )
|
||||
DEFINE_THINKFUNC( FlyThink ),
|
||||
DEFINE_ENTITYFUNC( BoxTouch ),
|
||||
END_DATADESC();
|
||||
|
||||
LINK_ENTITY_TO_CLASS( dod_ammo_box, CAmmoBox );
|
||||
|
||||
void CAmmoBox::Spawn( void )
|
||||
{
|
||||
Precache( );
|
||||
SetModel( "models/ammo/ammo_us.mdl" );
|
||||
BaseClass::Spawn();
|
||||
|
||||
SetNextThink( gpGlobals->curtime + 0.75f );
|
||||
SetThink( &CAmmoBox::FlyThink );
|
||||
|
||||
SetTouch( &CAmmoBox::BoxTouch );
|
||||
|
||||
m_hOldOwner = GetOwnerEntity();
|
||||
}
|
||||
|
||||
void CAmmoBox::Precache( void )
|
||||
{
|
||||
PrecacheModel( "models/ammo/ammo_axis.mdl" );
|
||||
PrecacheModel( "models/ammo/ammo_us.mdl" );
|
||||
}
|
||||
|
||||
CAmmoBox *CAmmoBox::Create( const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner, int team )
|
||||
{
|
||||
CAmmoBox *p = static_cast<CAmmoBox *> ( CBaseAnimating::Create( "dod_ammo_box", vecOrigin, vecAngles, pOwner ) );
|
||||
|
||||
p->SetAmmoTeam( team );
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void CAmmoBox::SetAmmoTeam( int team )
|
||||
{
|
||||
switch( team )
|
||||
{
|
||||
case TEAM_ALLIES:
|
||||
{
|
||||
SetModel( "models/ammo/ammo_us.mdl" );
|
||||
}
|
||||
break;
|
||||
case TEAM_AXIS:
|
||||
{
|
||||
SetModel( "models/ammo/ammo_axis.mdl" );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
m_iAmmoTeam = team;
|
||||
}
|
||||
|
||||
void CAmmoBox::FlyThink( void )
|
||||
{
|
||||
SetOwnerEntity( NULL ); //so our owner can pick it back up
|
||||
}
|
||||
|
||||
void CAmmoBox::BoxTouch( CBaseEntity *pOther )
|
||||
{
|
||||
Assert( pOther );
|
||||
|
||||
if( !pOther->IsPlayer() )
|
||||
return;
|
||||
|
||||
if( !pOther->IsAlive() )
|
||||
return;
|
||||
|
||||
//Don't let the person who threw this ammo pick it up until it hits the ground.
|
||||
//This way we can throw ammo to people, but not touch it as soon as we throw it ourselves
|
||||
if( GetOwnerEntity() == pOther )
|
||||
return;
|
||||
|
||||
CDODPlayer *pPlayer = ToDODPlayer( pOther );
|
||||
|
||||
Assert( pPlayer );
|
||||
|
||||
if( pPlayer->GetTeamNumber() != m_iAmmoTeam )
|
||||
return;
|
||||
|
||||
if( pPlayer == m_hOldOwner )
|
||||
{
|
||||
//don't give ammo, just give him his drop again
|
||||
pPlayer->ReturnGenericAmmo();
|
||||
UTIL_Remove(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
//See if they can use some ammo, if so, remove the box
|
||||
if( pPlayer->GiveGenericAmmo() )
|
||||
UTIL_Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool CAmmoBox::MyTouch( CBasePlayer *pBasePlayer )
|
||||
{
|
||||
if ( !pBasePlayer )
|
||||
{
|
||||
Assert( false );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !pBasePlayer->IsAlive() )
|
||||
return false;
|
||||
|
||||
if( pBasePlayer->GetTeamNumber() != m_iAmmoTeam )
|
||||
return false;
|
||||
|
||||
CDODPlayer *pPlayer = ToDODPlayer( pBasePlayer );
|
||||
|
||||
if( pPlayer == m_hOldOwner )
|
||||
{
|
||||
//don't give ammo, just give him his drop again
|
||||
pPlayer->ReturnGenericAmmo();
|
||||
UTIL_Remove(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
//See if they can use some ammo, if so, remove the box
|
||||
if( pPlayer->GiveGenericAmmo() )
|
||||
UTIL_Remove(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
43
game/server/dod/dod_ammo_box.h
Normal file
43
game/server/dod/dod_ammo_box.h
Normal file
@@ -0,0 +1,43 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef AMMO_BOX_H
|
||||
#define AMMO_BOX_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "items.h"
|
||||
|
||||
class CAmmoBox : public CItem
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CAmmoBox, CItem );
|
||||
|
||||
CAmmoBox() {}
|
||||
|
||||
virtual void Spawn();
|
||||
virtual void Precache();
|
||||
|
||||
void EXPORT FlyThink( void );
|
||||
void EXPORT BoxTouch( CBaseEntity *pOther );
|
||||
bool MyTouch( CBasePlayer *pBasePlayer );
|
||||
|
||||
static CAmmoBox *Create( const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner, int team );
|
||||
|
||||
void SetAmmoTeam( int team );
|
||||
|
||||
private:
|
||||
EHANDLE m_hOldOwner;
|
||||
int m_iAmmoTeam;
|
||||
|
||||
private:
|
||||
CAmmoBox( const CAmmoBox & );
|
||||
|
||||
DECLARE_DATADESC();
|
||||
};
|
||||
|
||||
#endif //GENERIC_AMMO_H
|
||||
590
game/server/dod/dod_area_capture.cpp
Normal file
590
game/server/dod/dod_area_capture.cpp
Normal file
@@ -0,0 +1,590 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_area_capture.h"
|
||||
#include "dod_player.h"
|
||||
#include "dod_gamerules.h"
|
||||
#include "dod_control_point.h"
|
||||
#include "dod_team.h"
|
||||
#include "dod_objective_resource.h"
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// CAreaCapture
|
||||
// An area entity that players must remain in in order to active another entity
|
||||
// Triggers are fired on start of capture, on end of capture and on broken capture
|
||||
// Can either be capped by both teams at once, or just by one
|
||||
// Time to capture and number of people required to capture are both passed by the mapper
|
||||
|
||||
|
||||
|
||||
BEGIN_DATADESC(CAreaCapture)
|
||||
|
||||
// Touch functions
|
||||
DEFINE_FUNCTION( AreaTouch ),
|
||||
|
||||
// Think functions
|
||||
DEFINE_THINKFUNC( Think ),
|
||||
|
||||
// Keyfields
|
||||
DEFINE_KEYFIELD( m_iszCapPointName, FIELD_STRING, "area_cap_point" ),
|
||||
|
||||
DEFINE_KEYFIELD( m_nAlliesNumCap, FIELD_INTEGER, "area_allies_numcap" ),
|
||||
DEFINE_KEYFIELD( m_nAxisNumCap, FIELD_INTEGER, "area_axis_numcap" ),
|
||||
DEFINE_KEYFIELD( m_flCapTime, FIELD_FLOAT, "area_time_to_cap" ),
|
||||
|
||||
DEFINE_KEYFIELD( m_bAlliesCanCap, FIELD_BOOLEAN, "area_allies_cancap" ),
|
||||
DEFINE_KEYFIELD( m_bAxisCanCap, FIELD_BOOLEAN, "area_axis_cancap" ),
|
||||
|
||||
DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ),
|
||||
|
||||
// Inputs
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "RoundInit", InputRoundInit ),
|
||||
|
||||
// Outputs
|
||||
DEFINE_OUTPUT( m_AlliesStartOutput, "OnAlliesStartCap" ),
|
||||
DEFINE_OUTPUT( m_AlliesBreakOutput, "OnAlliesBreakCap" ),
|
||||
DEFINE_OUTPUT( m_AlliesCapOutput, "OnAlliesEndCap" ),
|
||||
|
||||
DEFINE_OUTPUT( m_AxisStartOutput, "OnAxisStartCap" ),
|
||||
DEFINE_OUTPUT( m_AxisBreakOutput, "OnAxisBreakCap" ),
|
||||
DEFINE_OUTPUT( m_AxisCapOutput, "OnAxisEndCap" ),
|
||||
|
||||
DEFINE_OUTPUT( m_StartOutput, "OnStartCap" ),
|
||||
DEFINE_OUTPUT( m_BreakOutput, "OnBreakCap" ),
|
||||
DEFINE_OUTPUT( m_CapOutput, "OnEndCap" ),
|
||||
|
||||
// DEFINE_OUTPUT( m_OnStartCap, "OnStartCap" );
|
||||
// DEFINE_OUTPUT( m_OnBreakCap,
|
||||
|
||||
// DEFINE_OUTPUT( m_OnEnterNoObj, "OnEnterNoObj" );
|
||||
|
||||
END_DATADESC();
|
||||
|
||||
LINK_ENTITY_TO_CLASS( dod_capture_area, CAreaCapture );
|
||||
|
||||
void CAreaCapture::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
InitTrigger();
|
||||
|
||||
Precache();
|
||||
|
||||
m_iAreaIndex = -1;
|
||||
|
||||
SetTouch ( &CAreaCapture::AreaTouch );
|
||||
|
||||
m_bCapturing = false;
|
||||
m_nCapturingTeam = TEAM_UNASSIGNED;
|
||||
m_nOwningTeam = TEAM_UNASSIGNED;
|
||||
m_fTimeRemaining = 0.0f;
|
||||
|
||||
SetNextThink( gpGlobals->curtime + AREA_THINK_TIME );
|
||||
|
||||
if( m_nAlliesNumCap < 1 )
|
||||
m_nAlliesNumCap = 1;
|
||||
|
||||
if( m_nAxisNumCap < 1 )
|
||||
m_nAxisNumCap = 1;
|
||||
|
||||
m_bDisabled = false;
|
||||
|
||||
m_iCapAttemptNumber = 0;
|
||||
}
|
||||
|
||||
void CAreaCapture::Precache( void )
|
||||
{
|
||||
}
|
||||
|
||||
bool CAreaCapture::KeyValue( const char *szKeyName, const char *szValue )
|
||||
{
|
||||
return BaseClass::KeyValue( szKeyName, szValue );
|
||||
}
|
||||
|
||||
//sends to all players at the start of the round
|
||||
//needed?
|
||||
void CAreaCapture::area_SetIndex( int index )
|
||||
{
|
||||
m_iAreaIndex = index;
|
||||
}
|
||||
|
||||
bool CAreaCapture::IsActive( void )
|
||||
{
|
||||
return !m_bDisabled;
|
||||
}
|
||||
|
||||
void CAreaCapture::AreaTouch( CBaseEntity *pOther )
|
||||
{
|
||||
//if they are touching, set their SIGNAL flag on, and their m_iCapAreaNum to ours
|
||||
//then in think do all the scoring
|
||||
|
||||
if( !IsActive() )
|
||||
return;
|
||||
|
||||
//Don't cap areas unless the round is running
|
||||
if( DODGameRules()->State_Get() != STATE_RND_RUNNING || DODGameRules()->IsInWarmup() )
|
||||
return;
|
||||
|
||||
Assert( m_iAreaIndex != -1 );
|
||||
|
||||
if( m_pPoint )
|
||||
{
|
||||
m_nOwningTeam = m_pPoint->GetOwner();
|
||||
}
|
||||
|
||||
//dont touch for non-alive or non-players
|
||||
if( !pOther->IsPlayer() )
|
||||
return;
|
||||
|
||||
if( !pOther->IsAlive() )
|
||||
return;
|
||||
|
||||
CDODPlayer *pPlayer = ToDODPlayer(pOther);
|
||||
|
||||
ASSERT( pPlayer );
|
||||
|
||||
if ( pPlayer->GetTeamNumber() != m_nOwningTeam )
|
||||
{
|
||||
bool bAbleToCap = ( pPlayer->GetTeamNumber() == TEAM_ALLIES && m_bAlliesCanCap ) ||
|
||||
( pPlayer->GetTeamNumber() == TEAM_AXIS && m_bAxisCanCap );
|
||||
|
||||
if ( bAbleToCap )
|
||||
pPlayer->HintMessage( HINT_IN_AREA_CAP );
|
||||
}
|
||||
|
||||
pPlayer->m_signals.Signal( SIGNAL_CAPTUREAREA );
|
||||
|
||||
//add them to this area
|
||||
pPlayer->SetCapAreaIndex( m_iAreaIndex );
|
||||
|
||||
if ( m_pPoint )
|
||||
{
|
||||
pPlayer->SetCPIndex( m_pPoint->GetPointIndex() );
|
||||
}
|
||||
}
|
||||
|
||||
/* three ways to be capturing a cap area
|
||||
* 1) have the required number of people in the area
|
||||
* 2) have less than the required number on your team, new required num is everyone
|
||||
* 3) have less than the required number alive, new required is numAlive, but time is lengthened
|
||||
*/
|
||||
|
||||
ConVar dod_simulatemultiplecappers( "dod_simulatemultiplecappers", "1", FCVAR_CHEAT );
|
||||
|
||||
void CAreaCapture::Think( void )
|
||||
{
|
||||
SetNextThink( gpGlobals->curtime + AREA_THINK_TIME );
|
||||
|
||||
if( DODGameRules()->State_Get() != STATE_RND_RUNNING )
|
||||
{
|
||||
// If we were being capped, cancel it
|
||||
if( m_nNumAllies > 0 || m_nNumAxis > 0 )
|
||||
{
|
||||
m_nNumAllies = 0;
|
||||
m_nNumAxis = 0;
|
||||
SendNumPlayers();
|
||||
|
||||
if( m_pPoint )
|
||||
{
|
||||
g_pObjectiveResource->SetCappingTeam( m_pPoint->GetPointIndex(), TEAM_UNASSIGNED );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// go through our list of players
|
||||
|
||||
int iNumAllies = 0;
|
||||
int iNumAxis = 0;
|
||||
|
||||
CDODPlayer *pFirstAlliedTouching = NULL;
|
||||
CDODPlayer *pFirstAxisTouching = NULL;
|
||||
|
||||
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
|
||||
{
|
||||
CBaseEntity *ent = UTIL_PlayerByIndex( i );
|
||||
if ( ent )
|
||||
{
|
||||
CDODPlayer *pPlayer = ToDODPlayer(ent);
|
||||
|
||||
//First check if the player is in fact in this area
|
||||
if ( ( pPlayer->m_signals.GetState() & SIGNAL_CAPTUREAREA ) &&
|
||||
pPlayer->GetCapAreaIndex() == m_iAreaIndex &&
|
||||
pPlayer->IsAlive() ) // alive check is kinda unnecessary, but there is some
|
||||
// case where non-present people are messing up this count
|
||||
{
|
||||
if ( pPlayer->GetTeamNumber() == TEAM_ALLIES )
|
||||
{
|
||||
if ( iNumAllies == 0 )
|
||||
pFirstAlliedTouching = pPlayer;
|
||||
|
||||
iNumAllies++;
|
||||
}
|
||||
else if ( pPlayer->GetTeamNumber() == TEAM_AXIS )
|
||||
{
|
||||
if ( iNumAxis == 0 )
|
||||
pFirstAxisTouching = pPlayer;
|
||||
|
||||
iNumAxis++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iNumAllies *= dod_simulatemultiplecappers.GetInt();
|
||||
iNumAxis *= dod_simulatemultiplecappers.GetInt();
|
||||
|
||||
if( iNumAllies != m_nNumAllies || iNumAxis != m_nNumAxis )
|
||||
{
|
||||
m_nNumAllies = iNumAllies;
|
||||
m_nNumAxis = iNumAxis;
|
||||
SendNumPlayers();
|
||||
}
|
||||
|
||||
// when a player blocks, tell them the cap index and attempt number
|
||||
// only give successive blocks to them if the attempt number is different
|
||||
|
||||
if( m_bCapturing )
|
||||
{
|
||||
//its a regular cap
|
||||
//Subtract some time from the cap
|
||||
m_fTimeRemaining -= AREA_THINK_TIME;
|
||||
|
||||
//if both teams are in the area
|
||||
if( iNumAllies > 0 && iNumAxis > 0 )
|
||||
{
|
||||
// See if anyone gets credit for the block
|
||||
float flPercentToGo = m_fTimeRemaining / m_flCapTime;
|
||||
if ( flPercentToGo <= 0.5 && m_pPoint )
|
||||
{
|
||||
// find the first player that is not on the capturing team
|
||||
// they have just broken a cap and should be rewarded
|
||||
// tell the player the capture attempt number, for checking later
|
||||
CDODPlayer *pBlockingPlayer = ( m_nCapturingTeam == TEAM_ALLIES ) ? pFirstAxisTouching : pFirstAlliedTouching;
|
||||
|
||||
if ( pBlockingPlayer )
|
||||
{
|
||||
if ( pBlockingPlayer->GetCapAreaIndex() == m_iAreaIndex &&
|
||||
pBlockingPlayer->GetLastBlockCapAttempt() == m_iCapAttemptNumber )
|
||||
{
|
||||
// this is a repeat block on the same cap, ignore it
|
||||
NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pPoint->CaptureBlocked( pBlockingPlayer );
|
||||
pBlockingPlayer->StoreCaptureBlock( m_iAreaIndex, m_iCapAttemptNumber );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BreakCapture( false );
|
||||
return;
|
||||
}
|
||||
|
||||
//if no-one is in the area
|
||||
if( iNumAllies == 0 && iNumAxis == 0 )
|
||||
{
|
||||
BreakCapture( true );
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_nCapturingTeam == TEAM_ALLIES )
|
||||
{
|
||||
if( iNumAllies < m_nAlliesNumCap )
|
||||
{
|
||||
BreakCapture( true );
|
||||
}
|
||||
}
|
||||
else if( m_nCapturingTeam == TEAM_AXIS )
|
||||
{
|
||||
if( iNumAxis < m_nAxisNumCap )
|
||||
{
|
||||
BreakCapture( true );
|
||||
}
|
||||
}
|
||||
|
||||
//if the cap is done
|
||||
if( m_fTimeRemaining <= 0 )
|
||||
{
|
||||
EndCapture( m_nCapturingTeam );
|
||||
return; //we're done
|
||||
}
|
||||
}
|
||||
else //not capturing yet
|
||||
{
|
||||
bool bStarted = false;
|
||||
|
||||
if( iNumAllies > 0 && iNumAxis <= 0 && m_bAlliesCanCap && m_nOwningTeam != TEAM_ALLIES )
|
||||
{
|
||||
if( iNumAllies >= m_nAlliesNumCap )
|
||||
{
|
||||
m_iCappingRequired = m_nAlliesNumCap;
|
||||
m_iCappingPlayers = iNumAllies;
|
||||
StartCapture( TEAM_ALLIES, CAPTURE_NORMAL );
|
||||
bStarted = true;
|
||||
}
|
||||
}
|
||||
else if( iNumAxis > 0 && iNumAllies <= 0 && m_bAxisCanCap && m_nOwningTeam != TEAM_AXIS )
|
||||
{
|
||||
if( iNumAxis >= m_nAxisNumCap )
|
||||
{
|
||||
m_iCappingRequired = m_nAxisNumCap;
|
||||
m_iCappingPlayers = iNumAxis;
|
||||
StartCapture( TEAM_AXIS, CAPTURE_NORMAL );
|
||||
bStarted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CAreaCapture::SetOwner( int team )
|
||||
{
|
||||
//break any current capturing
|
||||
BreakCapture( false );
|
||||
|
||||
//set the owner to the passed value
|
||||
m_nOwningTeam = team;
|
||||
g_pObjectiveResource->SetOwningTeam( m_pPoint->GetPointIndex(), m_nOwningTeam );
|
||||
}
|
||||
|
||||
void CAreaCapture::SendNumPlayers( CBasePlayer *pPlayer )
|
||||
{
|
||||
if( !m_pPoint )
|
||||
return;
|
||||
|
||||
int index = m_pPoint->GetPointIndex();
|
||||
|
||||
g_pObjectiveResource->SetNumPlayers( index, TEAM_ALLIES, m_nNumAllies );
|
||||
g_pObjectiveResource->SetNumPlayers( index, TEAM_AXIS, m_nNumAxis );
|
||||
}
|
||||
|
||||
void CAreaCapture::StartCapture( int team, int capmode )
|
||||
{
|
||||
int iNumCappers = 0;
|
||||
|
||||
//trigger start
|
||||
if( team == TEAM_ALLIES )
|
||||
{
|
||||
m_AlliesStartOutput.FireOutput(this,this);
|
||||
iNumCappers = m_nAlliesNumCap;
|
||||
}
|
||||
else if( team == TEAM_AXIS )
|
||||
{
|
||||
m_AxisStartOutput.FireOutput(this,this);
|
||||
iNumCappers = m_nAxisNumCap;
|
||||
}
|
||||
|
||||
m_StartOutput.FireOutput(this,this);
|
||||
|
||||
m_nCapturingTeam = team;
|
||||
m_fTimeRemaining = m_flCapTime;
|
||||
m_bCapturing = true;
|
||||
m_iCapMode = capmode;
|
||||
|
||||
if( m_pPoint )
|
||||
{
|
||||
//send a message that we're starting to cap this area
|
||||
g_pObjectiveResource->SetCappingTeam( m_pPoint->GetPointIndex(), m_nCapturingTeam );
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_AREA_CAPPERS 9
|
||||
|
||||
void CAreaCapture::EndCapture( int team )
|
||||
{
|
||||
m_iCapAttemptNumber++;
|
||||
|
||||
//do the triggering
|
||||
if( team == TEAM_ALLIES )
|
||||
{
|
||||
m_AlliesCapOutput.FireOutput(this,this);
|
||||
}
|
||||
else if( team == TEAM_AXIS )
|
||||
{
|
||||
m_AxisCapOutput.FireOutput(this,this);
|
||||
}
|
||||
|
||||
m_CapOutput.FireOutput(this,this);
|
||||
|
||||
m_iCappingRequired = 0;
|
||||
m_iCappingPlayers = 0;
|
||||
|
||||
int numcappers = 0;
|
||||
int cappingplayers[MAX_AREA_CAPPERS];
|
||||
|
||||
CDODPlayer *pCappingPlayer = NULL;
|
||||
|
||||
CDODTeam *pTeam = GetGlobalDODTeam(team);
|
||||
if ( pTeam )
|
||||
{
|
||||
int iCount = pTeam->GetNumPlayers();
|
||||
|
||||
for ( int i=0;i<iCount;i++ )
|
||||
{
|
||||
CDODPlayer *pPlayer = ToDODPlayer( pTeam->GetPlayer(i) );
|
||||
if ( pPlayer )
|
||||
{
|
||||
if( ( pPlayer->m_signals.GetState() & SIGNAL_CAPTUREAREA ) &&
|
||||
pPlayer->GetCapAreaIndex() == m_iAreaIndex &&
|
||||
pPlayer->IsAlive() )
|
||||
{
|
||||
if( pCappingPlayer == NULL )
|
||||
pCappingPlayer = pPlayer;
|
||||
|
||||
if ( numcappers < MAX_AREA_CAPPERS-1 )
|
||||
{
|
||||
cappingplayers[numcappers] = pPlayer->entindex();
|
||||
numcappers++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( numcappers < MAX_AREA_CAPPERS )
|
||||
{
|
||||
cappingplayers[numcappers] = 0; //null terminate :)
|
||||
}
|
||||
|
||||
m_nOwningTeam = team;
|
||||
m_bCapturing = false;
|
||||
m_fTimeRemaining = 0.0f;
|
||||
|
||||
//there may have been more than one capper, but only report this one.
|
||||
//he hasnt gotten points yet, and his name will go in the cap string if its needed
|
||||
//first capper gets name sent and points given by flag.
|
||||
//other cappers get points manually above, no name in message
|
||||
|
||||
//send the player in the cap string
|
||||
if( m_pPoint )
|
||||
{
|
||||
DODGameRules()->CapEvent( CAP_EVENT_FLAG, m_nOwningTeam );
|
||||
|
||||
g_pObjectiveResource->SetOwningTeam( m_pPoint->GetPointIndex(), m_nOwningTeam );
|
||||
m_pPoint->SetOwner( m_nOwningTeam, true, numcappers, cappingplayers );
|
||||
}
|
||||
}
|
||||
|
||||
void CAreaCapture::BreakCapture( bool bNotEnoughPlayers )
|
||||
{
|
||||
if( m_bCapturing )
|
||||
{
|
||||
m_iCappingRequired = 0;
|
||||
m_iCappingPlayers = 0;
|
||||
|
||||
if( m_nCapturingTeam == TEAM_ALLIES )
|
||||
m_AlliesBreakOutput.FireOutput(this,this);
|
||||
|
||||
else if( m_nCapturingTeam == TEAM_AXIS )
|
||||
m_AxisBreakOutput.FireOutput(this,this);
|
||||
|
||||
m_BreakOutput.FireOutput(this,this);
|
||||
|
||||
m_bCapturing = false;
|
||||
|
||||
if( m_pPoint )
|
||||
{
|
||||
g_pObjectiveResource->SetCappingTeam( m_pPoint->GetPointIndex(), TEAM_UNASSIGNED );
|
||||
}
|
||||
|
||||
if ( bNotEnoughPlayers )
|
||||
{
|
||||
m_iCapAttemptNumber++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAreaCapture::InputDisable( inputdata_t &inputdata )
|
||||
{
|
||||
m_bDisabled = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAreaCapture::InputEnable( inputdata_t &inputdata )
|
||||
{
|
||||
m_bDisabled = false;
|
||||
}
|
||||
|
||||
void CAreaCapture::InputRoundInit( inputdata_t &inputdata )
|
||||
{
|
||||
// find the flag we're linked to
|
||||
if( !m_pPoint )
|
||||
{
|
||||
m_pPoint = dynamic_cast<CControlPoint*>( gEntList.FindEntityByName(NULL, STRING(m_iszCapPointName) ) );
|
||||
|
||||
if ( m_pPoint )
|
||||
{
|
||||
m_pPoint->SetNumCappersRequired( m_nAlliesNumCap, m_nAxisNumCap );
|
||||
g_pObjectiveResource->SetCPRequiredCappers( m_pPoint->GetPointIndex(), m_nAlliesNumCap, m_nAxisNumCap );
|
||||
g_pObjectiveResource->SetCPCapTime( m_pPoint->GetPointIndex(), m_flCapTime, m_flCapTime );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check if this player's death causes a block
|
||||
// return FALSE if the player is not in this area
|
||||
// return TRUE otherwise ( eg player is in area, but his death does not cause break )
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAreaCapture::CheckIfDeathCausesBlock( CDODPlayer *pVictim, CDODPlayer *pKiller )
|
||||
{
|
||||
// This shouldn't happen
|
||||
if ( !pVictim || !pKiller )
|
||||
{
|
||||
Assert( !"Why are null players getting here?" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure this player is in this area
|
||||
if ( pVictim->GetCapAreaIndex() != m_iAreaIndex )
|
||||
return false;
|
||||
|
||||
// Teamkills shouldn't give a block reward
|
||||
if ( pVictim->GetTeamNumber() == pKiller->GetTeamNumber() )
|
||||
return true;
|
||||
|
||||
// return if the area is not being capped
|
||||
if ( !m_bCapturing )
|
||||
return true;
|
||||
|
||||
int iTeam = pVictim->GetTeamNumber();
|
||||
|
||||
// return if this player's team is not capping the area
|
||||
if ( iTeam != m_nCapturingTeam )
|
||||
return true;
|
||||
|
||||
bool bBlocked = false;
|
||||
|
||||
if ( m_nCapturingTeam == TEAM_ALLIES )
|
||||
{
|
||||
if ( m_nNumAllies-1 < m_nAlliesNumCap )
|
||||
bBlocked = true;
|
||||
}
|
||||
else if ( m_nCapturingTeam == TEAM_AXIS )
|
||||
{
|
||||
if ( m_nNumAxis-1 < m_nAxisNumCap )
|
||||
bBlocked = true;
|
||||
}
|
||||
|
||||
// break early incase we kill multiple people in the same frame
|
||||
if ( bBlocked )
|
||||
{
|
||||
m_pPoint->CaptureBlocked( pKiller );
|
||||
BreakCapture( false );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
104
game/server/dod/dod_area_capture.h
Normal file
104
game/server/dod/dod_area_capture.h
Normal file
@@ -0,0 +1,104 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_AREA_CAPTURE_H
|
||||
#define DOD_AREA_CAPTURE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "triggers.h"
|
||||
#include "dod_control_point.h"
|
||||
|
||||
#define AREA_ATTEND_TIME 0.7f
|
||||
|
||||
#define AREA_THINK_TIME 0.1f
|
||||
|
||||
#define CAPTURE_NORMAL 0
|
||||
#define CAPTURE_CATCHUP_ALIVEPLAYERS 1
|
||||
|
||||
#define MAX_CLIENT_AREAS 128
|
||||
|
||||
class CAreaCapture : public CBaseTrigger
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CAreaCapture, CBaseTrigger );
|
||||
|
||||
virtual void Spawn( void );
|
||||
virtual void Precache( void );
|
||||
virtual bool KeyValue( const char *szKeyName, const char *szValue );
|
||||
|
||||
void area_SetIndex( int index );
|
||||
|
||||
bool IsActive( void );
|
||||
|
||||
bool CheckIfDeathCausesBlock( CDODPlayer *pVictim, CDODPlayer *pKiller );
|
||||
|
||||
private:
|
||||
void EXPORT AreaTouch( CBaseEntity *pOther );
|
||||
void Think( void );
|
||||
|
||||
void StartCapture( int team, int capmode );
|
||||
void EndCapture( int team );
|
||||
void BreakCapture( bool bNotEnoughPlayers );
|
||||
void SwitchCapture( int team );
|
||||
void SendNumPlayers( CBasePlayer *pPlayer = NULL );
|
||||
|
||||
void SetOwner( int team ); //sets the owner of this point - useful for resetting all to -1
|
||||
|
||||
void InputEnable( inputdata_t &inputdata );
|
||||
void InputDisable( inputdata_t &inputdata );
|
||||
void InputRoundInit( inputdata_t &inputdata );
|
||||
|
||||
private:
|
||||
int m_iCapMode; //which capture mode we're in
|
||||
int m_bCapturing;
|
||||
int m_nCapturingTeam; //the team that is capturing this point
|
||||
int m_nOwningTeam; //the team that has captured this point
|
||||
float m_flCapTime; //the total time it takes to capture the area, in seconds
|
||||
float m_fTimeRemaining; //the time left in the capture
|
||||
|
||||
int m_nAlliesNumCap; //number of allies required to cap
|
||||
int m_nAxisNumCap; //number of axis required to cap
|
||||
|
||||
int m_nNumAllies;
|
||||
int m_nNumAxis;
|
||||
|
||||
bool m_bAlliesCanCap;
|
||||
bool m_bAxisCanCap;
|
||||
|
||||
//used for catchup capping
|
||||
int m_iCappingRequired; //how many players are currently capping
|
||||
int m_iCappingPlayers; //how many are required?
|
||||
|
||||
bool m_bActive;
|
||||
|
||||
COutputEvent m_AlliesStartOutput;
|
||||
COutputEvent m_AlliesBreakOutput;
|
||||
COutputEvent m_AlliesCapOutput;
|
||||
|
||||
COutputEvent m_AxisStartOutput;
|
||||
COutputEvent m_AxisBreakOutput;
|
||||
COutputEvent m_AxisCapOutput;
|
||||
|
||||
COutputEvent m_StartOutput;
|
||||
COutputEvent m_BreakOutput;
|
||||
COutputEvent m_CapOutput;
|
||||
|
||||
int m_iAreaIndex; //index of this area among all other areas
|
||||
|
||||
CControlPoint *m_pPoint; //the capture point that we are linked to!
|
||||
|
||||
bool m_bRequiresObject;
|
||||
|
||||
string_t m_iszCapPointName; //name of the cap point that we're linked to
|
||||
|
||||
int m_iCapAttemptNumber; // number used to keep track of discrete cap attempts, for block tracking
|
||||
|
||||
DECLARE_DATADESC();
|
||||
};
|
||||
|
||||
#endif //DOD_AREA_CAPTURE_H
|
||||
526
game/server/dod/dod_basegrenade.cpp
Normal file
526
game/server/dod/dod_basegrenade.cpp
Normal file
@@ -0,0 +1,526 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_basegrenade.h"
|
||||
#include "dod_player.h"
|
||||
#include "dod_gamerules.h"
|
||||
#include "func_break.h"
|
||||
#include "physics_saverestore.h"
|
||||
#include "grenadetrail.h"
|
||||
#include "fx_dod_shared.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
float GetCurrentGravity( void );
|
||||
|
||||
ConVar dod_grenadegravity( "dod_grenadegravity", "-420", FCVAR_CHEAT, "gravity applied to grenades", true, -2000, true, -300 );
|
||||
extern ConVar dod_bonusround;
|
||||
|
||||
IMotionEvent::simresult_e CGrenadeController::Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular )
|
||||
{
|
||||
linear.x = linear.y = 0;
|
||||
linear.z = dod_grenadegravity.GetFloat();
|
||||
|
||||
angular.x = angular.y = angular.z = 0;
|
||||
|
||||
return SIM_GLOBAL_ACCELERATION;
|
||||
}
|
||||
|
||||
BEGIN_SIMPLE_DATADESC( CGrenadeController )
|
||||
END_DATADESC()
|
||||
|
||||
BEGIN_DATADESC( CDODBaseGrenade )
|
||||
|
||||
DEFINE_THINKFUNC( DetonateThink ),
|
||||
|
||||
DEFINE_EMBEDDED( m_GrenadeController ),
|
||||
DEFINE_PHYSPTR( m_pMotionController ), // probably not necessary
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST( CDODBaseGrenade, DT_DODBaseGrenade )
|
||||
SendPropVector( SENDINFO( m_vInitialVelocity ),
|
||||
20, // nbits
|
||||
0, // flags
|
||||
-3000, // low value
|
||||
3000 // high value
|
||||
)
|
||||
END_SEND_TABLE()
|
||||
|
||||
CDODBaseGrenade::CDODBaseGrenade()
|
||||
{
|
||||
}
|
||||
|
||||
CDODBaseGrenade::~CDODBaseGrenade( void )
|
||||
{
|
||||
if ( m_pMotionController != NULL )
|
||||
{
|
||||
physenv->DestroyMotionController( m_pMotionController );
|
||||
m_pMotionController = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CDODBaseGrenade::Spawn( void )
|
||||
{
|
||||
m_bUseVPhysics = true;
|
||||
|
||||
BaseClass::Spawn();
|
||||
|
||||
SetSolid( SOLID_BBOX ); // So it will collide with physics props!
|
||||
|
||||
UTIL_SetSize( this, Vector(-4,-4,-4), Vector(4,4,4) );
|
||||
|
||||
if( m_bUseVPhysics )
|
||||
{
|
||||
SetCollisionGroup( COLLISION_GROUP_WEAPON );
|
||||
IPhysicsObject *pPhysicsObject = VPhysicsInitNormal( SOLID_BBOX, 0, false );
|
||||
|
||||
if ( pPhysicsObject )
|
||||
{
|
||||
m_pMotionController = physenv->CreateMotionController( &m_GrenadeController );
|
||||
m_pMotionController->AttachObject( pPhysicsObject, true );
|
||||
|
||||
pPhysicsObject->EnableGravity( false );
|
||||
}
|
||||
|
||||
m_takedamage = DAMAGE_EVENTS_ONLY;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_CUSTOM );
|
||||
m_takedamage = DAMAGE_NO;
|
||||
}
|
||||
|
||||
AddSolidFlags( FSOLID_NOT_STANDABLE );
|
||||
|
||||
m_iHealth = 1;
|
||||
|
||||
SetFriction( GetGrenadeFriction() );
|
||||
SetElasticity( GetGrenadeElasticity() );
|
||||
|
||||
// Remember our owner's team
|
||||
ChangeTeam( GetThrower()->GetTeamNumber() );
|
||||
|
||||
m_flDamage = 150;
|
||||
m_DmgRadius = m_flDamage * 2.5f;
|
||||
|
||||
// Don't collide with players on the owner's team for the first bit of our life
|
||||
m_flCollideWithTeammatesTime = gpGlobals->curtime + 0.25;
|
||||
m_bCollideWithTeammates = false;
|
||||
|
||||
SetThink( &CDODBaseGrenade::DetonateThink );
|
||||
SetNextThink( gpGlobals->curtime + 0.1 );
|
||||
}
|
||||
|
||||
void CDODBaseGrenade::Precache( void )
|
||||
{
|
||||
BaseClass::Precache();
|
||||
|
||||
PrecacheParticleSystem( "grenadetrail" );
|
||||
PrecacheParticleSystem( "riflegrenadetrail" );
|
||||
PrecacheParticleSystem( "explosioncore_midair" );
|
||||
PrecacheParticleSystem( "explosioncore_floor" );
|
||||
}
|
||||
|
||||
void CDODBaseGrenade::DetonateThink( void )
|
||||
{
|
||||
if (!IsInWorld())
|
||||
{
|
||||
Remove( );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( gpGlobals->curtime > m_flCollideWithTeammatesTime && m_bCollideWithTeammates == false )
|
||||
{
|
||||
m_bCollideWithTeammates = true;
|
||||
}
|
||||
|
||||
Vector foo;
|
||||
AngularImpulse a;
|
||||
|
||||
VPhysicsGetObject()->GetVelocity( &foo, &a );
|
||||
|
||||
if( gpGlobals->curtime > m_flDetonateTime )
|
||||
{
|
||||
Detonate();
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetWaterLevel() != 0)
|
||||
{
|
||||
SetAbsVelocity( GetAbsVelocity() * 0.5 );
|
||||
}
|
||||
|
||||
SetNextThink( gpGlobals->curtime + 0.2 );
|
||||
}
|
||||
|
||||
//Sets the time at which the grenade will explode
|
||||
void CDODBaseGrenade::SetDetonateTimerLength( float timer )
|
||||
{
|
||||
m_flDetonateTime = gpGlobals->curtime + timer;
|
||||
}
|
||||
|
||||
void CDODBaseGrenade::ResolveFlyCollisionCustom( trace_t &trace, Vector &vecVelocity )
|
||||
{
|
||||
//Assume all surfaces have the same elasticity
|
||||
float flSurfaceElasticity = 1.0;
|
||||
|
||||
//Don't bounce off of players with perfect elasticity
|
||||
if( trace.m_pEnt && trace.m_pEnt->IsPlayer() )
|
||||
{
|
||||
flSurfaceElasticity = 0.3;
|
||||
}
|
||||
|
||||
float flTotalElasticity = GetElasticity() * flSurfaceElasticity;
|
||||
flTotalElasticity = clamp( flTotalElasticity, 0.0f, 0.9f );
|
||||
|
||||
// NOTE: A backoff of 2.0f is a reflection
|
||||
Vector vecAbsVelocity;
|
||||
PhysicsClipVelocity( GetAbsVelocity(), trace.plane.normal, vecAbsVelocity, 2.0f );
|
||||
vecAbsVelocity *= flTotalElasticity;
|
||||
|
||||
// Get the total velocity (player + conveyors, etc.)
|
||||
VectorAdd( vecAbsVelocity, GetBaseVelocity(), vecVelocity );
|
||||
float flSpeedSqr = DotProduct( vecVelocity, vecVelocity );
|
||||
|
||||
// Stop if on ground.
|
||||
if ( trace.plane.normal.z > 0.7f ) // Floor
|
||||
{
|
||||
// Verify that we have an entity.
|
||||
CBaseEntity *pEntity = trace.m_pEnt;
|
||||
Assert( pEntity );
|
||||
|
||||
// Are we on the ground?
|
||||
if ( vecVelocity.z < ( GetCurrentGravity() * gpGlobals->frametime ) )
|
||||
{
|
||||
if ( pEntity->IsStandable() )
|
||||
{
|
||||
SetGroundEntity( pEntity );
|
||||
}
|
||||
|
||||
vecAbsVelocity.z = 0.0f;
|
||||
}
|
||||
SetAbsVelocity( vecAbsVelocity );
|
||||
|
||||
if ( flSpeedSqr < ( 30 * 30 ) )
|
||||
{
|
||||
if ( pEntity->IsStandable() )
|
||||
{
|
||||
SetGroundEntity( pEntity );
|
||||
}
|
||||
|
||||
// Reset velocities.
|
||||
SetAbsVelocity( vec3_origin );
|
||||
SetLocalAngularVelocity( vec3_angle );
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector vecDelta = GetBaseVelocity() - vecAbsVelocity;
|
||||
Vector vecBaseDir = GetBaseVelocity();
|
||||
VectorNormalize( vecBaseDir );
|
||||
float flScale = vecDelta.Dot( vecBaseDir );
|
||||
|
||||
VectorScale( vecAbsVelocity, ( 1.0f - trace.fraction ) * gpGlobals->frametime, vecVelocity );
|
||||
VectorMA( vecVelocity, ( 1.0f - trace.fraction ) * gpGlobals->frametime, GetBaseVelocity() * flScale, vecVelocity );
|
||||
PhysicsPushEntity( vecVelocity, &trace );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we get *too* slow, we'll stick without ever coming to rest because
|
||||
// we'll get pushed down by gravity faster than we can escape from the wall.
|
||||
if ( flSpeedSqr < ( 30 * 30 ) )
|
||||
{
|
||||
// Reset velocities.
|
||||
SetAbsVelocity( vec3_origin );
|
||||
SetLocalAngularVelocity( vec3_angle );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetAbsVelocity( vecAbsVelocity );
|
||||
}
|
||||
}
|
||||
|
||||
BounceSound();
|
||||
}
|
||||
|
||||
char *CDODBaseGrenade::GetExplodingClassname( void )
|
||||
{
|
||||
Assert( !"Baseclass must implement this" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CDODBaseGrenade::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
if ( !CanBePickedUp() )
|
||||
return;
|
||||
|
||||
if ( !pActivator->IsPlayer() )
|
||||
return;
|
||||
|
||||
CDODPlayer *pPlayer = ToDODPlayer( pActivator );
|
||||
|
||||
//Don't pick up grenades while deployed
|
||||
CBaseCombatWeapon *pWpn = pPlayer->GetActiveWeapon();
|
||||
if ( pWpn && !pWpn->CanHolster() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DODRoundState state = DODGameRules()->State_Get();
|
||||
|
||||
if ( dod_bonusround.GetBool() )
|
||||
{
|
||||
int team = pPlayer->GetTeamNumber();
|
||||
|
||||
// if its after the round and bonus round is on, we can only pick it up if we are winners
|
||||
|
||||
if ( team == TEAM_ALLIES && state == STATE_AXIS_WIN )
|
||||
return;
|
||||
|
||||
if ( team == TEAM_AXIS && state == STATE_ALLIES_WIN )
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if its after the round, and bonus round is off, don't allow anyone to pick it up
|
||||
if ( state != STATE_RND_RUNNING )
|
||||
return;
|
||||
}
|
||||
|
||||
OnPickedUp();
|
||||
|
||||
char *szClsName = GetExplodingClassname();
|
||||
|
||||
Assert( szClsName );
|
||||
|
||||
CBaseCombatWeapon *pWeapon = dynamic_cast<CBaseCombatWeapon *>( pPlayer->GiveNamedItem( szClsName ) );
|
||||
|
||||
Assert( pWeapon && "Wpn pointer has to be valid for us to pick up this grenade" );
|
||||
|
||||
if( pWeapon )
|
||||
{
|
||||
variant_t flDetTime;
|
||||
flDetTime.SetFloat( m_flDetonateTime );
|
||||
pWeapon->AcceptInput( "DetonateTime", this, this, flDetTime, 0 );
|
||||
|
||||
#ifdef DBGFLAG_ASSERT
|
||||
bool bSuccess =
|
||||
#endif
|
||||
pPlayer->Weapon_Switch( pWeapon );
|
||||
|
||||
Assert( bSuccess );
|
||||
|
||||
//Remove the one we picked up
|
||||
SetThink( NULL );
|
||||
UTIL_Remove( this );
|
||||
}
|
||||
}
|
||||
|
||||
int CDODBaseGrenade::OnTakeDamage( const CTakeDamageInfo &info )
|
||||
{
|
||||
if( info.GetDamageType() & DMG_BULLET )
|
||||
{
|
||||
// Don't allow players to shoot grenades
|
||||
return 0;
|
||||
}
|
||||
else if( info.GetDamageType() & DMG_BLAST )
|
||||
{
|
||||
// Don't allow explosion force to move grenades
|
||||
return 0;
|
||||
}
|
||||
|
||||
VPhysicsTakeDamage( info );
|
||||
|
||||
return BaseClass::OnTakeDamage( info );
|
||||
}
|
||||
|
||||
void CDODBaseGrenade::Detonate()
|
||||
{
|
||||
// Don't explode after the round has ended
|
||||
if ( dod_bonusround.GetBool() == false && DODGameRules()->State_Get() != STATE_RND_RUNNING )
|
||||
{
|
||||
SetDamage( 0 );
|
||||
}
|
||||
|
||||
// stun players in a radius
|
||||
const float flStunDamage = 100;
|
||||
|
||||
CTakeDamageInfo info( this, GetThrower(), GetBlastForce(), GetAbsOrigin(), flStunDamage, DMG_STUN );
|
||||
DODGameRules()->RadiusStun( info, GetAbsOrigin(), m_DmgRadius );
|
||||
|
||||
BaseClass::Detonate();
|
||||
}
|
||||
|
||||
bool CDODBaseGrenade::CreateVPhysics()
|
||||
{
|
||||
// Create the object in the physics system
|
||||
VPhysicsInitNormal( SOLID_BBOX, 0, false );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDODBaseGrenade::Explode( trace_t *pTrace, int bitsDamageType )
|
||||
{
|
||||
SetModelName( NULL_STRING );//invisible
|
||||
AddSolidFlags( FSOLID_NOT_SOLID );
|
||||
|
||||
m_takedamage = DAMAGE_NO;
|
||||
|
||||
// Pull out of the wall a bit
|
||||
if ( pTrace->fraction != 1.0 )
|
||||
{
|
||||
SetAbsOrigin( pTrace->endpos + (pTrace->plane.normal * 0.6) );
|
||||
}
|
||||
|
||||
// Explosion effect on client
|
||||
Vector vecOrigin = GetAbsOrigin();
|
||||
CPVSFilter filter( vecOrigin );
|
||||
TE_DODExplosion( filter, 0.0f, vecOrigin, pTrace->plane.normal );
|
||||
|
||||
// Use the thrower's position as the reported position
|
||||
Vector vecReported = GetThrower() ? GetThrower()->GetAbsOrigin() : vec3_origin;
|
||||
|
||||
CTakeDamageInfo info( this, GetThrower(), GetBlastForce(), GetAbsOrigin(), m_flDamage, bitsDamageType, 0, &vecReported );
|
||||
|
||||
RadiusDamage( info, vecOrigin, GetDamageRadius(), CLASS_NONE, NULL );
|
||||
|
||||
// Don't decal players with scorch.
|
||||
if ( pTrace->m_pEnt && !pTrace->m_pEnt->IsPlayer() )
|
||||
{
|
||||
UTIL_DecalTrace( pTrace, "Scorch" );
|
||||
}
|
||||
|
||||
SetThink( &CBaseGrenade::SUB_Remove );
|
||||
SetTouch( NULL );
|
||||
|
||||
AddEffects( EF_NODRAW );
|
||||
SetAbsVelocity( vec3_origin );
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
}
|
||||
|
||||
// this will hit only things that are in newCollisionGroup, but NOT in collisionGroupAlreadyChecked
|
||||
class CTraceFilterCollisionGroupDelta : public CTraceFilterEntitiesOnly
|
||||
{
|
||||
public:
|
||||
// It does have a base, but we'll never network anything below here..
|
||||
DECLARE_CLASS_NOBASE( CTraceFilterCollisionGroupDelta );
|
||||
|
||||
CTraceFilterCollisionGroupDelta( const IHandleEntity *passentity, int collisionGroupAlreadyChecked, int newCollisionGroup )
|
||||
: m_pPassEnt(passentity), m_collisionGroupAlreadyChecked( collisionGroupAlreadyChecked ), m_newCollisionGroup( newCollisionGroup )
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask )
|
||||
{
|
||||
if ( !PassServerEntityFilter( pHandleEntity, m_pPassEnt ) )
|
||||
return false;
|
||||
CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity );
|
||||
|
||||
if ( pEntity )
|
||||
{
|
||||
if ( g_pGameRules->ShouldCollide( m_collisionGroupAlreadyChecked, pEntity->GetCollisionGroup() ) )
|
||||
return false;
|
||||
if ( g_pGameRules->ShouldCollide( m_newCollisionGroup, pEntity->GetCollisionGroup() ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
const IHandleEntity *m_pPassEnt;
|
||||
int m_collisionGroupAlreadyChecked;
|
||||
int m_newCollisionGroup;
|
||||
};
|
||||
|
||||
|
||||
const float GRENADE_COEFFICIENT_OF_RESTITUTION = 0.2f;
|
||||
|
||||
void CDODBaseGrenade::VPhysicsUpdate( IPhysicsObject *pPhysics )
|
||||
{
|
||||
BaseClass::VPhysicsUpdate( pPhysics );
|
||||
Vector vel;
|
||||
AngularImpulse angVel;
|
||||
pPhysics->GetVelocity( &vel, &angVel );
|
||||
|
||||
Vector start = GetAbsOrigin();
|
||||
// find all entities that my collision group wouldn't hit, but COLLISION_GROUP_NONE would and bounce off of them as a ray cast
|
||||
CTraceFilterCollisionGroupDelta filter( this, GetCollisionGroup(), COLLISION_GROUP_NONE );
|
||||
trace_t tr;
|
||||
|
||||
UTIL_TraceLine( start, start + vel * gpGlobals->frametime, CONTENTS_HITBOX|CONTENTS_MONSTER|CONTENTS_SOLID, &filter, &tr );
|
||||
|
||||
bool bHitTeammate = false;
|
||||
|
||||
if ( m_bCollideWithTeammates == false && tr.m_pEnt && tr.m_pEnt->IsPlayer() && tr.m_pEnt->GetTeamNumber() == GetTeamNumber() )
|
||||
{
|
||||
bHitTeammate = true;
|
||||
}
|
||||
|
||||
if ( tr.startsolid )
|
||||
{
|
||||
if ( m_bInSolid == false && bHitTeammate == false )
|
||||
{
|
||||
// UNDONE: Do a better contact solution that uses relative velocity?
|
||||
vel *= -GRENADE_COEFFICIENT_OF_RESTITUTION; // bounce backwards
|
||||
pPhysics->SetVelocity( &vel, NULL );
|
||||
}
|
||||
m_bInSolid = true;
|
||||
return;
|
||||
}
|
||||
m_bInSolid = false;
|
||||
if ( tr.DidHit() && bHitTeammate == false )
|
||||
{
|
||||
Vector dir = vel;
|
||||
VectorNormalize(dir);
|
||||
|
||||
float flPercent = vel.Length() / 2000;
|
||||
float flDmg = 5 * flPercent;
|
||||
|
||||
// send a tiny amount of damage so the character will react to getting bonked
|
||||
CTakeDamageInfo info( this, GetThrower(), pPhysics->GetMass() * vel, GetAbsOrigin(), flDmg, DMG_CRUSH );
|
||||
tr.m_pEnt->DispatchTraceAttack( info, dir, &tr );
|
||||
ApplyMultiDamage();
|
||||
|
||||
if ( vel.Length() > 1000 )
|
||||
{
|
||||
CTakeDamageInfo stunInfo( this, GetThrower(), vec3_origin, GetAbsOrigin(), flDmg, DMG_STUN );
|
||||
tr.m_pEnt->TakeDamage( stunInfo );
|
||||
}
|
||||
|
||||
// reflect velocity around normal
|
||||
vel = -2.0f * tr.plane.normal * DotProduct(vel,tr.plane.normal) + vel;
|
||||
|
||||
// absorb 80% in impact
|
||||
vel *= GetElasticity();
|
||||
angVel *= -0.5f;
|
||||
pPhysics->SetVelocity( &vel, &angVel );
|
||||
}
|
||||
}
|
||||
|
||||
float CDODBaseGrenade::GetElasticity( void )
|
||||
{
|
||||
return GRENADE_COEFFICIENT_OF_RESTITUTION;
|
||||
}
|
||||
|
||||
const float DOD_GRENADE_WINDOW_BREAK_DAMPING_AMOUNT = 0.5f;
|
||||
|
||||
// If we hit a window, let it break and continue on our way
|
||||
// with a damped speed
|
||||
void CDODBaseGrenade::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent )
|
||||
{
|
||||
CBreakable *pBreakable = dynamic_cast<CBreakable*>( pEvent->pEntities[!index] );
|
||||
if ( pBreakable && pBreakable->GetMaterialType() == matGlass && VPhysicsGetObject() )
|
||||
{
|
||||
// don't stop, go through this entity after breaking it
|
||||
Vector dampedVelocity = DOD_GRENADE_WINDOW_BREAK_DAMPING_AMOUNT * pEvent->preVelocity[index];
|
||||
VPhysicsGetObject()->SetVelocity( &dampedVelocity, &pEvent->preAngularVelocity[index] );
|
||||
}
|
||||
else
|
||||
BaseClass::VPhysicsCollision( index, pEvent );
|
||||
}
|
||||
106
game/server/dod/dod_basegrenade.h
Normal file
106
game/server/dod/dod_basegrenade.h
Normal file
@@ -0,0 +1,106 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_BASEGRENADE_H
|
||||
#define DOD_BASEGRENADE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "weapon_dodbase.h"
|
||||
#include "basegrenade_shared.h"
|
||||
|
||||
class CGrenadeTrail;
|
||||
|
||||
class CGrenadeController : public IMotionEvent
|
||||
{
|
||||
DECLARE_SIMPLE_DATADESC();
|
||||
public:
|
||||
virtual simresult_e Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular );
|
||||
};
|
||||
|
||||
class CDODBaseGrenade : public CBaseGrenade
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODBaseGrenade, CBaseGrenade );
|
||||
|
||||
DECLARE_DATADESC();
|
||||
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
CDODBaseGrenade();
|
||||
virtual ~CDODBaseGrenade();
|
||||
|
||||
virtual void Spawn();
|
||||
virtual void Precache( void );
|
||||
|
||||
static inline float GetGrenadeGravity() { return 0.4f; }
|
||||
static inline const float GetGrenadeFriction() { return 0.5f; }
|
||||
static inline const float GetGrenadeElasticity() { return 0.2f; }
|
||||
|
||||
void DetonateThink( void );
|
||||
|
||||
virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
|
||||
virtual char *GetExplodingClassname( void );
|
||||
|
||||
virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() | FCAP_IMPULSE_USE | FCAP_USE_IN_RADIUS; }
|
||||
|
||||
virtual int OnTakeDamage( const CTakeDamageInfo &info );
|
||||
|
||||
virtual void Detonate();
|
||||
|
||||
bool CreateVPhysics();
|
||||
virtual void VPhysicsUpdate( IPhysicsObject *pPhysics );
|
||||
virtual void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent );
|
||||
|
||||
virtual void Explode( trace_t *pTrace, int bitsDamageType );
|
||||
|
||||
void SetupInitialTransmittedGrenadeVelocity( const Vector &velocity )
|
||||
{
|
||||
m_vInitialVelocity = velocity;
|
||||
}
|
||||
|
||||
CGrenadeController m_GrenadeController;
|
||||
IPhysicsMotionController *m_pMotionController;
|
||||
|
||||
virtual bool CanBePickedUp( void ) { return true; }
|
||||
|
||||
virtual void OnPickedUp( void ) {}
|
||||
|
||||
virtual float GetElasticity();
|
||||
|
||||
virtual DODWeaponID GetEmitterWeaponID() { return m_EmitterWeaponID; }
|
||||
|
||||
protected:
|
||||
|
||||
//Set the time to detonate ( now + timer )
|
||||
virtual void SetDetonateTimerLength( float timer );
|
||||
float m_flDetonateTime;
|
||||
|
||||
//Custom collision to allow for constant elasticity on hit surfaces
|
||||
virtual void ResolveFlyCollisionCustom( trace_t &trace, Vector &vecVelocity );
|
||||
|
||||
bool m_bUseVPhysics;
|
||||
|
||||
DODWeaponID m_EmitterWeaponID;
|
||||
|
||||
private:
|
||||
|
||||
CDODBaseGrenade( const CDODBaseGrenade & );
|
||||
|
||||
bool m_bInSolid;
|
||||
|
||||
// This gets sent to the client and placed in the client's interpolation history
|
||||
// so the projectile starts out moving right off the bat.
|
||||
CNetworkVector( m_vInitialVelocity );
|
||||
|
||||
float m_flCollideWithTeammatesTime;
|
||||
bool m_bCollideWithTeammates;
|
||||
};
|
||||
|
||||
|
||||
#endif // DOD_BASEGRENADE_H
|
||||
294
game/server/dod/dod_baserocket.cpp
Normal file
294
game/server/dod/dod_baserocket.cpp
Normal file
@@ -0,0 +1,294 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_baserocket.h"
|
||||
#include "explode.h"
|
||||
#include "dod_shareddefs.h"
|
||||
#include "dod_gamerules.h"
|
||||
#include "fx_dod_shared.h"
|
||||
|
||||
|
||||
BEGIN_DATADESC( CDODBaseRocket )
|
||||
|
||||
// Function Pointers
|
||||
DEFINE_FUNCTION( RocketTouch ),
|
||||
|
||||
DEFINE_THINKFUNC( FlyThink ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST( CDODBaseRocket, DT_DODBaseRocket )
|
||||
SendPropVector( SENDINFO( m_vInitialVelocity ),
|
||||
20, // nbits
|
||||
0, // flags
|
||||
-3000, // low value
|
||||
3000 // high value
|
||||
)
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS( base_rocket, CDODBaseRocket );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDODBaseRocket::CDODBaseRocket()
|
||||
{
|
||||
}
|
||||
|
||||
CDODBaseRocket::~CDODBaseRocket()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBaseRocket::Precache( void )
|
||||
{
|
||||
PrecacheScriptSound( "Weapon_Bazooka.Shoot" );
|
||||
PrecacheParticleSystem( "rockettrail" );
|
||||
}
|
||||
|
||||
ConVar mp_rocketdamage( "mp_rocketdamage", "150", FCVAR_GAMEDLL | FCVAR_CHEAT );
|
||||
ConVar mp_rocketradius( "mp_rocketradius", "200", FCVAR_GAMEDLL | FCVAR_CHEAT );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBaseRocket::Spawn( void )
|
||||
{
|
||||
Precache();
|
||||
|
||||
SetSolid( SOLID_BBOX );
|
||||
|
||||
Assert( GetModel() ); //derived classes must have set model
|
||||
|
||||
UTIL_SetSize( this, -Vector(2,2,2), Vector(2,2,2) );
|
||||
|
||||
SetTouch( &CDODBaseRocket::RocketTouch );
|
||||
|
||||
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_CUSTOM );
|
||||
|
||||
m_takedamage = DAMAGE_NO;
|
||||
SetGravity( 0.1 );
|
||||
SetDamage( mp_rocketdamage.GetFloat() );
|
||||
|
||||
AddFlag( FL_OBJECT );
|
||||
|
||||
SetCollisionGroup( COLLISION_GROUP_PROJECTILE );
|
||||
|
||||
EmitSound( "Weapon_Bazooka.Shoot" );
|
||||
|
||||
m_flCollideWithTeammatesTime = gpGlobals->curtime + 0.25;
|
||||
m_bCollideWithTeammates = false;
|
||||
|
||||
SetThink( &CDODBaseRocket::FlyThink );
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
}
|
||||
|
||||
unsigned int CDODBaseRocket::PhysicsSolidMaskForEntity( void ) const
|
||||
{
|
||||
int teamContents = 0;
|
||||
|
||||
if ( m_bCollideWithTeammates == false )
|
||||
{
|
||||
// Only collide with the other team
|
||||
teamContents = ( GetTeamNumber() == TEAM_ALLIES ) ? CONTENTS_TEAM1 : CONTENTS_TEAM2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Collide with both teams
|
||||
teamContents = CONTENTS_TEAM1 | CONTENTS_TEAM2;
|
||||
}
|
||||
|
||||
return BaseClass::PhysicsSolidMaskForEntity() | CONTENTS_HITBOX | teamContents;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Stops any kind of tracking and shoots dumb
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBaseRocket::Fire( void )
|
||||
{
|
||||
SetThink( NULL );
|
||||
SetMoveType( MOVETYPE_FLY );
|
||||
|
||||
SetModel("models/weapons/w_missile.mdl");
|
||||
UTIL_SetSize( this, vec3_origin, vec3_origin );
|
||||
|
||||
EmitSound( "Weapon_Bazooka.Shoot" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The actual explosion
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBaseRocket::DoExplosion( trace_t *pTrace )
|
||||
{
|
||||
/*
|
||||
// Explode
|
||||
ExplosionCreate(
|
||||
GetAbsOrigin(), //DMG_ROCKET
|
||||
GetAbsAngles(),
|
||||
GetOwnerEntity(),
|
||||
GetDamage(), //magnitude
|
||||
mp_rocketradius.GetFloat(), //radius
|
||||
SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE,
|
||||
0.0f, //explosion force
|
||||
this); //inflictor
|
||||
*/
|
||||
|
||||
// Pull out of the wall a bit
|
||||
if ( pTrace->fraction != 1.0 )
|
||||
{
|
||||
SetAbsOrigin( pTrace->endpos + (pTrace->plane.normal * 0.6) );
|
||||
}
|
||||
|
||||
// Explosion effect on client
|
||||
Vector vecOrigin = GetAbsOrigin();
|
||||
CPVSFilter filter( vecOrigin );
|
||||
TE_DODExplosion( filter, 0.0f, vecOrigin, pTrace->plane.normal );
|
||||
|
||||
CTakeDamageInfo info( this, GetOwnerEntity(), vec3_origin, GetAbsOrigin(), GetDamage(), DMG_BLAST, 0 );
|
||||
RadiusDamage( info, vecOrigin, mp_rocketradius.GetFloat() /* GetDamageRadius() */, CLASS_NONE, NULL );
|
||||
|
||||
// stun players in a radius
|
||||
const float flStunDamage = 75;
|
||||
const float flRadius = 150;
|
||||
|
||||
CTakeDamageInfo stunInfo( this, GetOwnerEntity(), vec3_origin, GetAbsOrigin(), flStunDamage, DMG_STUN );
|
||||
DODGameRules()->RadiusStun( stunInfo, GetAbsOrigin(), flRadius );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBaseRocket::Explode( void )
|
||||
{
|
||||
// Don't explode against the skybox. Just pretend that
|
||||
// the missile flies off into the distance.
|
||||
const trace_t &tr = CBaseEntity::GetTouchTrace();
|
||||
const trace_t *p = &tr;
|
||||
trace_t *newTrace = const_cast<trace_t*>(p);
|
||||
|
||||
DoExplosion( newTrace );
|
||||
|
||||
if ( newTrace->m_pEnt && !newTrace->m_pEnt->IsPlayer() )
|
||||
UTIL_DecalTrace( newTrace, "Scorch" );
|
||||
|
||||
StopSound( "Weapon_Bazooka.Shoot" );
|
||||
UTIL_Remove( this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pOther -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBaseRocket::RocketTouch( CBaseEntity *pOther )
|
||||
{
|
||||
Assert( pOther );
|
||||
if ( !pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS) )
|
||||
return;
|
||||
|
||||
if ( pOther->GetCollisionGroup() == COLLISION_GROUP_WEAPON )
|
||||
return;
|
||||
|
||||
// if we hit the skybox, just disappear
|
||||
const trace_t &tr = CBaseEntity::GetTouchTrace();
|
||||
|
||||
const trace_t *p = &tr;
|
||||
trace_t *newTrace = const_cast<trace_t*>(p);
|
||||
|
||||
if( tr.surface.flags & SURF_SKY )
|
||||
{
|
||||
UTIL_Remove( this );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !pOther->IsPlayer() && pOther->m_takedamage == DAMAGE_YES )
|
||||
{
|
||||
CTakeDamageInfo info;
|
||||
info.SetAttacker( this );
|
||||
info.SetInflictor( this );
|
||||
info.SetDamage( 50 );
|
||||
info.SetDamageForce( vec3_origin ); // don't worry about this not having a damage force.
|
||||
// It will explode on touch and impart its own forces
|
||||
info.SetDamageType( DMG_CLUB );
|
||||
|
||||
Vector dir;
|
||||
AngleVectors( GetAbsAngles(), &dir );
|
||||
|
||||
pOther->DispatchTraceAttack( info, dir, newTrace );
|
||||
ApplyMultiDamage();
|
||||
|
||||
if( pOther->IsAlive() )
|
||||
{
|
||||
Explode();
|
||||
}
|
||||
|
||||
// if it's not alive, continue flying
|
||||
}
|
||||
else
|
||||
{
|
||||
Explode();
|
||||
}
|
||||
}
|
||||
|
||||
void CDODBaseRocket::FlyThink( void )
|
||||
{
|
||||
QAngle angles;
|
||||
|
||||
VectorAngles( GetAbsVelocity(), angles );
|
||||
|
||||
SetAbsAngles( angles );
|
||||
|
||||
if ( gpGlobals->curtime > m_flCollideWithTeammatesTime && m_bCollideWithTeammates == false )
|
||||
{
|
||||
m_bCollideWithTeammates = true;
|
||||
}
|
||||
|
||||
SetNextThink( gpGlobals->curtime + 0.1f );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//
|
||||
// Input : &vecOrigin -
|
||||
// &vecAngles -
|
||||
// NULL -
|
||||
//
|
||||
// Output : CDODBaseRocket
|
||||
//-----------------------------------------------------------------------------
|
||||
CDODBaseRocket *CDODBaseRocket::Create( const char *szClassname, const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner = NULL )
|
||||
{
|
||||
CDODBaseRocket *pMissile = (CDODBaseRocket *) CBaseEntity::Create( szClassname, vecOrigin, vecAngles, pOwner );
|
||||
pMissile->SetOwnerEntity( pOwner );
|
||||
pMissile->Spawn();
|
||||
|
||||
Vector vecForward;
|
||||
AngleVectors( vecAngles, &vecForward );
|
||||
|
||||
Vector vRocket = vecForward * 1300;
|
||||
|
||||
pMissile->SetAbsVelocity( vRocket );
|
||||
pMissile->SetupInitialTransmittedGrenadeVelocity( vRocket );
|
||||
|
||||
pMissile->SetAbsAngles( vecAngles );
|
||||
|
||||
// remember what team we should be on
|
||||
pMissile->ChangeTeam( pOwner->GetTeamNumber() );
|
||||
|
||||
return pMissile;
|
||||
}
|
||||
|
||||
void CDODBaseRocket::SetupInitialTransmittedGrenadeVelocity( const Vector &velocity )
|
||||
{
|
||||
m_vInitialVelocity = velocity;
|
||||
}
|
||||
67
game/server/dod/dod_baserocket.h
Normal file
67
game/server/dod/dod_baserocket.h
Normal file
@@ -0,0 +1,67 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_BASEROCKET_H
|
||||
#define DOD_BASEROCKET_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "cbase.h"
|
||||
#include "baseanimating.h"
|
||||
#include "smoke_trail.h"
|
||||
#include "weapon_dodbase.h"
|
||||
|
||||
class RocketTrail;
|
||||
|
||||
//================================================
|
||||
// CDODBaseRocket
|
||||
//================================================
|
||||
class CDODBaseRocket : public CBaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( CDODBaseRocket, CBaseAnimating );
|
||||
|
||||
public:
|
||||
CDODBaseRocket();
|
||||
~CDODBaseRocket();
|
||||
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void RocketTouch( CBaseEntity *pOther );
|
||||
void Explode( void );
|
||||
void Fire( void );
|
||||
|
||||
virtual float GetDamage() { return m_flDamage; }
|
||||
virtual void SetDamage(float flDamage) { m_flDamage = flDamage; }
|
||||
|
||||
unsigned int PhysicsSolidMaskForEntity( void ) const;
|
||||
|
||||
static CDODBaseRocket *Create( const char *szClassname, const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner );
|
||||
|
||||
void SetupInitialTransmittedGrenadeVelocity( const Vector &velocity );
|
||||
|
||||
virtual DODWeaponID GetEmitterWeaponID() { return WEAPON_NONE; Assert(0); }
|
||||
|
||||
protected:
|
||||
virtual void DoExplosion( trace_t *pTrace );
|
||||
|
||||
void FlyThink( void );
|
||||
|
||||
float m_flDamage;
|
||||
|
||||
CNetworkVector( m_vInitialVelocity );
|
||||
|
||||
private:
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
float m_flCollideWithTeammatesTime;
|
||||
bool m_bCollideWithTeammates;
|
||||
};
|
||||
|
||||
#endif // DOD_BASEROCKET_H
|
||||
144
game/server/dod/dod_bombdispenser.cpp
Normal file
144
game/server/dod/dod_bombdispenser.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_player.h"
|
||||
#include "dod_bombtarget.h"
|
||||
#include "triggers.h"
|
||||
|
||||
class CDODBombDispenserMapIcon;
|
||||
|
||||
class CDODBombDispenser : public CBaseTrigger
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODBombDispenser, CBaseTrigger );
|
||||
DECLARE_DATADESC();
|
||||
|
||||
virtual void Spawn( void );
|
||||
void EXPORT Touch( CBaseEntity *pOther );
|
||||
|
||||
bool IsActive( void ) { return !m_bDisabled; }
|
||||
|
||||
private:
|
||||
|
||||
void InputEnable( inputdata_t &inputdata );
|
||||
void InputDisable( inputdata_t &inputdata );
|
||||
|
||||
// Which team to give bombs to. TEAM_UNASSIGNED gives to both
|
||||
int m_iDispenseToTeam;
|
||||
|
||||
// Is this area giving out bombs?
|
||||
bool m_bActive;
|
||||
};
|
||||
|
||||
BEGIN_DATADESC(CDODBombDispenser)
|
||||
|
||||
// Touch functions
|
||||
DEFINE_FUNCTION( Touch ),
|
||||
|
||||
// Inputs
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
|
||||
|
||||
DEFINE_KEYFIELD( m_iDispenseToTeam, FIELD_INTEGER, "dispense_team" ),
|
||||
DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ),
|
||||
|
||||
END_DATADESC();
|
||||
|
||||
LINK_ENTITY_TO_CLASS( dod_bomb_dispenser, CDODBombDispenser );
|
||||
|
||||
|
||||
void CDODBombDispenser::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
InitTrigger();
|
||||
|
||||
SetTouch( &CDODBombDispenser::Touch );
|
||||
|
||||
m_bDisabled = false;
|
||||
|
||||
// make our map icon entity
|
||||
#ifdef DBGFLAG_ASSERT
|
||||
CBaseEntity *pIcon =
|
||||
#endif
|
||||
CBaseEntity::Create( "dod_bomb_dispenser_icon", WorldSpaceCenter(), GetAbsAngles(), this );
|
||||
|
||||
Assert( pIcon );
|
||||
}
|
||||
|
||||
void CDODBombDispenser::Touch( CBaseEntity *pOther )
|
||||
{
|
||||
if ( m_bDisabled )
|
||||
return;
|
||||
|
||||
if( !pOther->IsPlayer() )
|
||||
return;
|
||||
|
||||
if( !pOther->IsAlive() )
|
||||
return;
|
||||
|
||||
if ( m_iDispenseToTeam != TEAM_UNASSIGNED && pOther->GetTeamNumber() != m_iDispenseToTeam )
|
||||
return;
|
||||
|
||||
CDODPlayer *pPlayer = ToDODPlayer( pOther );
|
||||
|
||||
pPlayer->HintMessage( HINT_BOMB_PICKUP );
|
||||
|
||||
switch( pPlayer->GetTeamNumber() )
|
||||
{
|
||||
case TEAM_ALLIES:
|
||||
case TEAM_AXIS:
|
||||
{
|
||||
if ( pPlayer->Weapon_OwnsThisType( "weapon_basebomb" ) == NULL )
|
||||
{
|
||||
pPlayer->GiveNamedItem( "weapon_basebomb" );
|
||||
|
||||
CPASFilter filter( pPlayer->WorldSpaceCenter() );
|
||||
pPlayer->EmitSound( filter, pPlayer->entindex(), "Weapon_C4.PickUp" );
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CDODBombDispenser::InputEnable( inputdata_t &inputdata )
|
||||
{
|
||||
m_bDisabled = false;
|
||||
}
|
||||
|
||||
void CDODBombDispenser::InputDisable( inputdata_t &inputdata )
|
||||
{
|
||||
m_bDisabled = true;
|
||||
}
|
||||
|
||||
class CDODBombDispenserMapIcon : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODBombDispenserMapIcon, CBaseEntity );
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
|
||||
virtual int UpdateTransmitState( void )
|
||||
{
|
||||
if ( (( CDODBombDispenser * )GetOwnerEntity())->IsActive() )
|
||||
{
|
||||
return SetTransmitState( FL_EDICT_ALWAYS );
|
||||
}
|
||||
else
|
||||
{
|
||||
return SetTransmitState( FL_EDICT_DONTSEND );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST(CDODBombDispenserMapIcon, DT_DODBombDispenserMapIcon)
|
||||
END_SEND_TABLE()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( dod_bomb_dispenser_icon, CDODBombDispenserMapIcon );
|
||||
767
game/server/dod/dod_bombtarget.cpp
Normal file
767
game/server/dod/dod_bombtarget.cpp
Normal file
@@ -0,0 +1,767 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_player.h"
|
||||
#include "dod_gamerules.h"
|
||||
#include "dod_shareddefs.h"
|
||||
#include "dod_bombtarget.h"
|
||||
#include "basecombatweapon.h"
|
||||
#include "weapon_dodbasebomb.h"
|
||||
#include "dod_team.h"
|
||||
#include "dod_shareddefs.h"
|
||||
#include "dod_objective_resource.h"
|
||||
|
||||
BEGIN_DATADESC(CDODBombTarget)
|
||||
|
||||
DEFINE_KEYFIELD( m_iszCapPointName, FIELD_STRING, "target_control_point" ),
|
||||
|
||||
DEFINE_KEYFIELD( m_iBombingTeam, FIELD_INTEGER, "bombing_team" ),
|
||||
|
||||
DEFINE_KEYFIELD( m_iTimerAddSeconds, FIELD_INTEGER, "add_timer_seconds" ),
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
|
||||
|
||||
DEFINE_OUTPUT( m_OnBecomeActive, "OnBombTargetActivated" ),
|
||||
DEFINE_OUTPUT( m_OnBecomeInactive, "OnBombTargetDeactivated" ),
|
||||
DEFINE_OUTPUT( m_OnBombPlanted, "OnBombPlanted" ),
|
||||
DEFINE_OUTPUT( m_OnBombExploded, "OnBombExploded" ),
|
||||
DEFINE_OUTPUT( m_OnBombDisarmed, "OnBombDefused" ),
|
||||
|
||||
DEFINE_KEYFIELD( m_bStartDisabled, FIELD_INTEGER, "StartDisabled" ),
|
||||
|
||||
DEFINE_USEFUNC( State_Use ),
|
||||
DEFINE_THINKFUNC( State_Think ),
|
||||
|
||||
END_DATADESC();
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST(CDODBombTarget, DT_DODBombTarget)
|
||||
SendPropInt( SENDINFO(m_iState), 3 ),
|
||||
SendPropInt( SENDINFO(m_iBombingTeam), 3 ),
|
||||
|
||||
SendPropModelIndex( SENDINFO(m_iTargetModel) ),
|
||||
SendPropModelIndex( SENDINFO(m_iUnavailableModel) ),
|
||||
END_SEND_TABLE()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( dod_bomb_target, CDODBombTarget );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::Spawn( void )
|
||||
{
|
||||
m_pControlPoint = NULL;
|
||||
|
||||
Precache();
|
||||
|
||||
SetTouch( NULL );
|
||||
SetUse( &CDODBombTarget::State_Use );
|
||||
SetThink( &CDODBombTarget::State_Think );
|
||||
SetNextThink( gpGlobals->curtime + 0.1 );
|
||||
|
||||
m_pCurStateInfo = NULL;
|
||||
if ( m_bStartDisabled )
|
||||
State_Transition( BOMB_TARGET_INACTIVE );
|
||||
else
|
||||
State_Transition( BOMB_TARGET_ACTIVE );
|
||||
|
||||
BaseClass::Spawn();
|
||||
|
||||
// incase we have any animating bomb models
|
||||
SetPlaybackRate( 1.0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::Precache( void )
|
||||
{
|
||||
BaseClass::Precache();
|
||||
|
||||
PrecacheModel( DOD_BOMB_TARGET_MODEL_ARMED );
|
||||
m_iTargetModel = PrecacheModel( DOD_BOMB_TARGET_MODEL_TARGET );
|
||||
m_iUnavailableModel = PrecacheModel( DOD_BOMB_TARGET_MODEL_UNAVAILABLE );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: change use flags based on state
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDODBombTarget::ObjectCaps()
|
||||
{
|
||||
int caps = BaseClass::ObjectCaps();
|
||||
|
||||
if ( State_Get() != BOMB_TARGET_INACTIVE )
|
||||
{
|
||||
caps |= (FCAP_CONTINUOUS_USE | FCAP_USE_IN_RADIUS);
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: timer length accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
float CDODBombTarget::GetBombTimerLength( void )
|
||||
{
|
||||
return DOD_BOMB_TIMER_LENGTH;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::State_Transition( BombTargetState newState )
|
||||
{
|
||||
State_Leave();
|
||||
State_Enter( newState );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::State_Enter( BombTargetState newState )
|
||||
{
|
||||
m_pCurStateInfo = State_LookupInfo( newState );
|
||||
|
||||
if ( 0 )
|
||||
{
|
||||
if ( m_pCurStateInfo )
|
||||
Msg( "DODRoundState: entering '%s'\n", m_pCurStateInfo->m_pStateName );
|
||||
else
|
||||
Msg( "DODRoundState: entering #%d\n", newState );
|
||||
}
|
||||
|
||||
// Initialize the new state.
|
||||
if ( m_pCurStateInfo && m_pCurStateInfo->pfnEnterState )
|
||||
(this->*m_pCurStateInfo->pfnEnterState)();
|
||||
|
||||
m_iState = (int)newState;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::State_Leave()
|
||||
{
|
||||
if ( m_pCurStateInfo && m_pCurStateInfo->pfnLeaveState )
|
||||
{
|
||||
(this->*m_pCurStateInfo->pfnLeaveState)();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::State_Think()
|
||||
{
|
||||
if ( m_pCurStateInfo && m_pCurStateInfo->pfnThink )
|
||||
{
|
||||
(this->*m_pCurStateInfo->pfnThink)();
|
||||
}
|
||||
|
||||
SetNextThink( gpGlobals->curtime + 0.1 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::State_Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
if ( m_pCurStateInfo && m_pCurStateInfo->pfnUse )
|
||||
{
|
||||
(this->*m_pCurStateInfo->pfnUse)( pActivator, pCaller, useType, value );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CDODBombTargetStateInfo* CDODBombTarget::State_LookupInfo( BombTargetState state )
|
||||
{
|
||||
static CDODBombTargetStateInfo bombTargetStateInfos[] =
|
||||
{
|
||||
{ BOMB_TARGET_INACTIVE, "BOMB_TARGET_INACTIVE", &CDODBombTarget::State_Enter_INACTIVE, NULL, NULL, NULL },
|
||||
{ BOMB_TARGET_ACTIVE, "BOMB_TARGET_ACTIVE", &CDODBombTarget::State_Enter_ACTIVE, NULL, NULL, &CDODBombTarget::State_Use_ACTIVE },
|
||||
{ BOMB_TARGET_ARMED, "BOMB_TARGET_ARMED", &CDODBombTarget::State_Enter_ARMED, &CDODBombTarget::State_Leave_Armed, &CDODBombTarget::State_Think_ARMED, &CDODBombTarget::State_Use_ARMED }
|
||||
};
|
||||
|
||||
for ( int i=0; i < ARRAYSIZE( bombTargetStateInfos ); i++ )
|
||||
{
|
||||
if ( bombTargetStateInfos[i].m_iState == state )
|
||||
return &bombTargetStateInfos[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::State_Enter_INACTIVE( void )
|
||||
{
|
||||
// go invisible
|
||||
AddEffects( EF_NODRAW );
|
||||
|
||||
m_OnBecomeInactive.FireOutput( this, this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::State_Enter_ACTIVE( void )
|
||||
{
|
||||
RemoveEffects( EF_NODRAW );
|
||||
|
||||
// set transparent model
|
||||
SetModel( DOD_BOMB_TARGET_MODEL_TARGET );
|
||||
|
||||
m_OnBecomeActive.FireOutput( this, this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::State_Enter_ARMED( void )
|
||||
{
|
||||
RemoveEffects( EF_NODRAW );
|
||||
|
||||
// set solid model
|
||||
SetModel( DOD_BOMB_TARGET_MODEL_ARMED );
|
||||
|
||||
// start count down
|
||||
m_flExplodeTime = gpGlobals->curtime + GetBombTimerLength();
|
||||
|
||||
m_OnBombPlanted.FireOutput( this, this );
|
||||
|
||||
// tell CP our time until detonation
|
||||
CControlPoint *pCP = GetControlPoint();
|
||||
if ( pCP )
|
||||
{
|
||||
pCP->BombPlanted( GetBombTimerLength(), m_pPlantingPlayer );
|
||||
}
|
||||
|
||||
EmitSound( "Weapon_C4.Fuse" );
|
||||
|
||||
static int iWickSeq = LookupSequence( "w_tnt_wick" );
|
||||
ResetSequence( iWickSeq );
|
||||
}
|
||||
|
||||
void CDODBombTarget::State_Leave_Armed( void )
|
||||
{
|
||||
StopSound( "Weapon_C4.Fuse" );
|
||||
}
|
||||
|
||||
void CDODBombTarget::ResetDefuse( int index )
|
||||
{
|
||||
DefusingPlayer *pRec = &m_DefusingPlayers[index];
|
||||
|
||||
Assert( pRec );
|
||||
|
||||
if ( pRec && pRec->m_pPlayer )
|
||||
{
|
||||
pRec->m_pPlayer->SetDefusing( NULL );
|
||||
|
||||
//cancel the progress bar
|
||||
pRec->m_pPlayer->SetProgressBarTime( 0 );
|
||||
}
|
||||
|
||||
m_DefusingPlayers.Remove( index );
|
||||
|
||||
// if noone else is defusing, set objective resource to not be defusing
|
||||
if ( m_DefusingPlayers.Count() <= 0 )
|
||||
{
|
||||
CControlPoint *pCP = GetControlPoint();
|
||||
if ( pCP )
|
||||
{
|
||||
g_pObjectiveResource->SetBombBeingDefused( pCP->GetPointIndex(), false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "IEffects.h"
|
||||
void TE_Sparks( IRecipientFilter& filter, float delay,
|
||||
const Vector *pos, int nMagnitude, int nTrailLength, const Vector *pDir );
|
||||
|
||||
extern short g_sModelIndexFireball;
|
||||
|
||||
void CDODBombTarget::Explode( void )
|
||||
{
|
||||
// output the explosion
|
||||
EmitSound( "Weapon_C4.Explode" );
|
||||
|
||||
Vector origin = GetAbsOrigin();
|
||||
|
||||
CPASFilter filter( origin );
|
||||
|
||||
te->Explosion( filter, -1.0, // don't apply cl_interp delay
|
||||
&origin,
|
||||
g_sModelIndexFireball,
|
||||
20, //scale
|
||||
25,
|
||||
TE_EXPLFLAG_NONE,
|
||||
0,
|
||||
0 );
|
||||
|
||||
float flDamage = 200;
|
||||
float flDmgRadius = flDamage * 2.5;
|
||||
// do a separate radius damage that ignores the world for added damage!
|
||||
CTakeDamageInfo dmgInfo( this, m_pPlantingPlayer, vec3_origin, origin, flDamage, DMG_BLAST | DMG_BOMB );
|
||||
DODGameRules()->RadiusDamage( dmgInfo, origin, flDmgRadius, CLASS_NONE, NULL, true );
|
||||
|
||||
// stun players in a radius
|
||||
const float flStunDamage = 100;
|
||||
|
||||
CTakeDamageInfo stunInfo( this, this, vec3_origin, GetAbsOrigin(), flStunDamage, DMG_STUN );
|
||||
DODGameRules()->RadiusStun( stunInfo, GetAbsOrigin(), flDmgRadius );
|
||||
|
||||
State_Transition( BOMB_TARGET_INACTIVE );
|
||||
|
||||
m_OnBombExploded.FireOutput( this, this );
|
||||
|
||||
// tell CP bomb is no longer active
|
||||
CControlPoint *pCP = GetControlPoint();
|
||||
if ( pCP )
|
||||
{
|
||||
CDODPlayer *pPlayer = m_pPlantingPlayer;
|
||||
|
||||
if ( !pPlayer || !pPlayer->IsConnected() )
|
||||
{
|
||||
// pick a random player from the bombing team
|
||||
|
||||
// hax - if we are debug and team is 0, use allies
|
||||
if ( m_iBombingTeam == TEAM_UNASSIGNED )
|
||||
m_iBombingTeam = TEAM_ALLIES;
|
||||
|
||||
CDODTeam *pTeam = GetGlobalDODTeam( m_iBombingTeam );
|
||||
|
||||
pPlayer = NULL;
|
||||
|
||||
if ( pTeam->GetNumPlayers() > 0 )
|
||||
{
|
||||
pPlayer = ToDODPlayer( pTeam->GetPlayer( 0 ) );
|
||||
|
||||
if ( !pPlayer || !pPlayer->IsConnected() )
|
||||
{
|
||||
// bad situation, abandon here
|
||||
pPlayer = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pCP->BombExploded( pPlayer, m_iBombingTeam );
|
||||
|
||||
g_pObjectiveResource->SetBombBeingDefused( pCP->GetPointIndex(), false );
|
||||
}
|
||||
|
||||
// If we add time to the round timer, tell Gamerules
|
||||
// Don't do this if this bomb ended the game
|
||||
if ( m_iTimerAddSeconds > 0 )
|
||||
{
|
||||
if ( m_pPlantingPlayer && FStrEq( STRING(gpGlobals->mapname), "dod_jagd" ) )
|
||||
{
|
||||
// if the timer is 0:00 or less, achievement time
|
||||
if ( DODGameRules()->GetTimerSeconds() <= 0 )
|
||||
{
|
||||
m_pPlantingPlayer->AwardAchievement( ACHIEVEMENT_DOD_JAGD_OVERTIME_CAP );
|
||||
}
|
||||
}
|
||||
|
||||
if ( DODGameRules()->State_Get() == STATE_RND_RUNNING )
|
||||
{
|
||||
DODGameRules()->AddTimerSeconds( m_iTimerAddSeconds );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDODBombTarget::BombDefused( CDODPlayer *pDefuser )
|
||||
{
|
||||
// tell CP bomb is no longer active
|
||||
CControlPoint *pCP = GetControlPoint();
|
||||
if ( pCP )
|
||||
{
|
||||
pCP->BombDisarmed( pDefuser );
|
||||
}
|
||||
|
||||
if ( pDefuser )
|
||||
{
|
||||
pDefuser->StatEvent_BombDefused();
|
||||
}
|
||||
|
||||
State_Transition( BOMB_TARGET_ACTIVE );
|
||||
|
||||
m_OnBombDisarmed.FireOutput( this, this );
|
||||
}
|
||||
|
||||
bool CDODBombTarget::CanPlayerStartDefuse( CDODPlayer *pPlayer )
|
||||
{
|
||||
if ( !pPlayer || !pPlayer->IsAlive() || !pPlayer->IsConnected() )
|
||||
{
|
||||
// if the defuser is not alive or has disconnected, reset
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !FBitSet( pPlayer->GetFlags(), FL_ONGROUND ) )
|
||||
{
|
||||
// they are not on the ground, remove them
|
||||
pPlayer->HintMessage( HINT_BOMB_DEFUSE_ONGROUND );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector vecDist = ( pPlayer->GetAbsOrigin() - GetAbsOrigin() );
|
||||
float flDist = vecDist.Length();
|
||||
|
||||
if ( flDist > DOD_BOMB_DEFUSE_MAXDIST ) // PLAYER_USE_RADIUS is not actually used by the playerUse code!!
|
||||
{
|
||||
// they are too far away to continue ( or start ) defusing
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDODBombTarget::CanPlayerContinueDefusing( CDODPlayer *pPlayer, DefusingPlayer *pDefuseRecord )
|
||||
{
|
||||
if ( !pDefuseRecord || pDefuseRecord->m_flDefuseTimeoutTime < gpGlobals->curtime )
|
||||
{
|
||||
// they have not updated their +use in a while, assume they stopped
|
||||
return false;
|
||||
}
|
||||
|
||||
return CanPlayerStartDefuse( pPlayer );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::State_Think_ARMED( void )
|
||||
{
|
||||
// count down
|
||||
|
||||
if ( DODGameRules()->State_Get() != STATE_RND_RUNNING )
|
||||
{
|
||||
State_Transition( BOMB_TARGET_ACTIVE );
|
||||
|
||||
// reset the timer
|
||||
CControlPoint *pCP = GetControlPoint();
|
||||
if ( pCP )
|
||||
{
|
||||
pCP->CancelBombPlanted();
|
||||
}
|
||||
}
|
||||
|
||||
// manually advance frame so that it matches bomb timer length.
|
||||
float flTimerLength = GetBombTimerLength();
|
||||
float flTimeLeft = m_flExplodeTime - gpGlobals->curtime;
|
||||
SetCycle( clamp( 1.0 - ( flTimeLeft / flTimerLength ), 0.0, 1.0 ) );
|
||||
|
||||
static int iAttachment = LookupAttachment( "wick" );//ed awesome
|
||||
|
||||
Vector pos;
|
||||
QAngle ang;
|
||||
GetAttachment( iAttachment, pos, ang );
|
||||
|
||||
Vector forward;
|
||||
AngleVectors( ang, &forward );
|
||||
|
||||
CPVSFilter filter( pos );
|
||||
TE_Sparks( filter, 0.0, &pos, 1, 1, &forward );
|
||||
|
||||
// So long as we have valid defusers, we will not explode
|
||||
|
||||
if ( m_DefusingPlayers.Count() > 0 )
|
||||
{
|
||||
// remove the undesirables
|
||||
// make sure they are on ground still
|
||||
// see if they have completed the defuse
|
||||
|
||||
for ( int i=m_DefusingPlayers.Count()-1;i>=0;i-- )
|
||||
{
|
||||
DefusingPlayer *pDefuseRecord = &m_DefusingPlayers[i];
|
||||
|
||||
CDODPlayer *pPlayer = pDefuseRecord->m_pPlayer;
|
||||
|
||||
if ( !CanPlayerContinueDefusing( pPlayer, pDefuseRecord ) )
|
||||
{
|
||||
ResetDefuse( i );
|
||||
}
|
||||
else
|
||||
{
|
||||
// they are still a valid defuser
|
||||
|
||||
// if their defuse complete time has passed
|
||||
if ( pDefuseRecord->m_flDefuseCompleteTime < gpGlobals->curtime )
|
||||
{
|
||||
// Defuse Complete
|
||||
BombDefused( pPlayer );
|
||||
|
||||
// remove everyone from the list
|
||||
for ( int j=m_DefusingPlayers.Count()-1;j>=0;j-- )
|
||||
{
|
||||
ResetDefuse( j );
|
||||
}
|
||||
|
||||
// break out of this loop
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( gpGlobals->curtime > m_flExplodeTime )
|
||||
{
|
||||
// no defusers, time is up
|
||||
Explode();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::State_Use_ACTIVE( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
CDODPlayer *pPlayer = ToDODPlayer( pActivator );
|
||||
|
||||
if ( !CanPlantHere( pPlayer ) )
|
||||
return;
|
||||
|
||||
Vector pos = pPlayer->WorldSpaceCenter();
|
||||
|
||||
float flDist = ( pos - GetAbsOrigin() ).Length();
|
||||
|
||||
if ( flDist > DOD_BOMB_PLANT_RADIUS )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !FBitSet( pPlayer->GetFlags(), FL_ONGROUND ) )
|
||||
{
|
||||
pPlayer->HintMessage( HINT_BOMB_DEFUSE_ONGROUND, true );
|
||||
return;
|
||||
}
|
||||
|
||||
CBaseCombatWeapon *pWeapon = NULL;
|
||||
|
||||
if ( ( pWeapon = pPlayer->Weapon_OwnsThisType( "weapon_basebomb" ) ) != NULL )
|
||||
{
|
||||
CDODBaseBombWeapon *pBomb = dynamic_cast<CDODBaseBombWeapon *>( pWeapon );
|
||||
|
||||
if ( pBomb )
|
||||
{
|
||||
// switch to their bomb, they will have to hit primary attack
|
||||
pPlayer->Weapon_Switch( pBomb );
|
||||
|
||||
if ( pBomb == pPlayer->GetActiveWeapon() )
|
||||
{
|
||||
pBomb->PrimaryAttack();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// they don't have a bomb - play hint message
|
||||
pPlayer->HintMessage( HINT_NEED_BOMB );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::CompletePlanting( CDODPlayer *pPlantingPlayer )
|
||||
{
|
||||
if ( pPlantingPlayer && ( pPlantingPlayer->GetTeamNumber() == m_iBombingTeam || m_iBombingTeam == TEAM_UNASSIGNED ) )
|
||||
{
|
||||
m_pPlantingPlayer = pPlantingPlayer;
|
||||
|
||||
State_Transition( BOMB_TARGET_ARMED );
|
||||
}
|
||||
}
|
||||
|
||||
DefusingPlayer *CDODBombTarget::FindDefusingPlayer( CDODPlayer *pPlayer )
|
||||
{
|
||||
DefusingPlayer *pRec = NULL;
|
||||
|
||||
for ( int i=0;i<m_DefusingPlayers.Count();i++ )
|
||||
{
|
||||
if ( m_DefusingPlayers[i].m_pPlayer == pPlayer )
|
||||
{
|
||||
pRec = &m_DefusingPlayers[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pRec;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::State_Use_ARMED( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
// check for people disarming
|
||||
CDODPlayer *pPlayer = ToDODPlayer( pActivator );
|
||||
|
||||
if ( !pPlayer || pPlayer->GetTeamNumber() == m_iBombingTeam || pPlayer->GetTeamNumber() == TEAM_SPECTATOR )
|
||||
return;
|
||||
|
||||
// check for distance, offground etc
|
||||
if ( CanPlayerStartDefuse( pPlayer ) == false )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DefusingPlayer *pDefusingPlayerRecord = FindDefusingPlayer( pPlayer );
|
||||
|
||||
// See if we already added this player to the defusing list
|
||||
if ( pDefusingPlayerRecord )
|
||||
{
|
||||
// They are still defusing for the next 0.2 seconds
|
||||
pDefusingPlayerRecord->m_flDefuseTimeoutTime = gpGlobals->curtime + 0.2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// add player to the list
|
||||
DefusingPlayer defusingPlayer;
|
||||
|
||||
defusingPlayer.m_pPlayer = pPlayer;
|
||||
defusingPlayer.m_flDefuseCompleteTime = gpGlobals->curtime + DOD_BOMB_DEFUSE_TIME;
|
||||
defusingPlayer.m_flDefuseTimeoutTime = gpGlobals->curtime + 0.2;
|
||||
|
||||
m_DefusingPlayers.AddToTail( defusingPlayer );
|
||||
|
||||
// tell the player they are defusing
|
||||
pPlayer->SetDefusing( this );
|
||||
pPlayer->SetProgressBarTime( DOD_BOMB_DEFUSE_TIME );
|
||||
|
||||
CControlPoint *pCP = GetControlPoint();
|
||||
if ( pCP )
|
||||
{
|
||||
g_pObjectiveResource->SetBombBeingDefused( pCP->GetPointIndex(), true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::InputEnable( inputdata_t &inputdata )
|
||||
{
|
||||
if ( m_pCurStateInfo && m_pCurStateInfo->m_iState == BOMB_TARGET_INACTIVE )
|
||||
{
|
||||
State_Transition( BOMB_TARGET_ACTIVE );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::InputDisable( inputdata_t &inputdata )
|
||||
{
|
||||
if ( m_pCurStateInfo && m_pCurStateInfo->m_iState != BOMB_TARGET_INACTIVE )
|
||||
{
|
||||
if ( m_pCurStateInfo->m_iState == BOMB_TARGET_ARMED )
|
||||
{
|
||||
// if planting, tell our cp we're not planting anymore
|
||||
CControlPoint *pCP = GetControlPoint();
|
||||
if ( pCP )
|
||||
{
|
||||
pCP->CancelBombPlanted();
|
||||
}
|
||||
}
|
||||
|
||||
State_Transition( BOMB_TARGET_INACTIVE );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CControlPoint *CDODBombTarget::GetControlPoint( void )
|
||||
{
|
||||
if ( !m_pControlPoint )
|
||||
{
|
||||
if ( m_iszCapPointName == NULL_STRING )
|
||||
return NULL;
|
||||
|
||||
// try to find it
|
||||
m_pControlPoint = dynamic_cast<CControlPoint *>( gEntList.FindEntityByName( NULL, STRING(m_iszCapPointName) ) );
|
||||
|
||||
if ( !m_pControlPoint )
|
||||
Warning( "Could not find dod_control_point named \"%s\" for dod_bomb_target \"%s\"\n", STRING(m_iszCapPointName), STRING( GetEntityName() ) );
|
||||
}
|
||||
|
||||
return m_pControlPoint;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDODBombTarget::CanPlantHere( CDODPlayer *pPlayer )
|
||||
{
|
||||
if ( !m_pCurStateInfo )
|
||||
return false;
|
||||
|
||||
if ( m_pCurStateInfo->m_iState != BOMB_TARGET_ACTIVE )
|
||||
return false;
|
||||
|
||||
if ( pPlayer->GetTeamNumber() != m_iBombingTeam && m_iBombingTeam != TEAM_UNASSIGNED )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODBombTarget::DefuseBlocked( CDODPlayer *pAttacker )
|
||||
{
|
||||
CControlPoint *pPoint = GetControlPoint();
|
||||
|
||||
if ( !pPoint )
|
||||
return;
|
||||
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "dod_capture_blocked" );
|
||||
|
||||
if ( event )
|
||||
{
|
||||
event->SetInt( "cp", pPoint->GetPointIndex() );
|
||||
event->SetString( "cpname", pPoint->GetName() );
|
||||
event->SetInt( "blocker", pAttacker->entindex() );
|
||||
event->SetInt( "priority", 9 );
|
||||
event->SetBool( "bomb", true );
|
||||
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
|
||||
pAttacker->AddScore( PLAYER_POINTS_FOR_BLOCK );
|
||||
|
||||
pAttacker->Stats_AreaDefended();
|
||||
|
||||
}
|
||||
|
||||
void CDODBombTarget::PlantBlocked( CDODPlayer *pAttacker )
|
||||
{
|
||||
CControlPoint *pPoint = GetControlPoint();
|
||||
|
||||
if ( !pPoint )
|
||||
return;
|
||||
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "dod_capture_blocked" );
|
||||
|
||||
if ( event )
|
||||
{
|
||||
event->SetInt( "cp", pPoint->GetPointIndex() );
|
||||
event->SetString( "cpname", pPoint->GetName() );
|
||||
event->SetInt( "blocker", pAttacker->entindex() );
|
||||
event->SetInt( "priority", 9 );
|
||||
event->SetBool( "bomb", true );
|
||||
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
|
||||
pAttacker->AddScore( PLAYER_POINTS_FOR_BLOCK );
|
||||
|
||||
pAttacker->Stats_AreaDefended();
|
||||
}
|
||||
154
game/server/dod/dod_bombtarget.h
Normal file
154
game/server/dod/dod_bombtarget.h
Normal file
@@ -0,0 +1,154 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_BOMBTARGET_H
|
||||
#define DOD_BOMBTARGET_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "baseanimating.h"
|
||||
#include "dod_control_point.h"
|
||||
|
||||
#define DOD_BOMB_TARGET_MODEL_ARMED "models/weapons/w_tnt.mdl"
|
||||
#define DOD_BOMB_TARGET_MODEL_TARGET "models/weapons/w_tnt_red.mdl"
|
||||
#define DOD_BOMB_TARGET_MODEL_UNAVAILABLE "models/weapons/w_tnt_grey.mdl"
|
||||
|
||||
class CDODBombTarget;
|
||||
|
||||
class CDODBombTargetStateInfo
|
||||
{
|
||||
public:
|
||||
BombTargetState m_iState;
|
||||
const char *m_pStateName;
|
||||
|
||||
void (CDODBombTarget::*pfnEnterState)(); // Init and deinit the state.
|
||||
void (CDODBombTarget::*pfnLeaveState)();
|
||||
void (CDODBombTarget::*pfnThink)(); // Do a PreThink() in this state.
|
||||
void (CDODBombTarget::*pfnUse)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
};
|
||||
|
||||
|
||||
struct DefusingPlayer
|
||||
{
|
||||
CHandle<CDODPlayer> m_pPlayer;
|
||||
|
||||
float m_flDefuseTimeoutTime;
|
||||
float m_flDefuseCompleteTime;
|
||||
};
|
||||
|
||||
class CDODBombTarget : public CBaseAnimating
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODBombTarget, CBaseAnimating );
|
||||
DECLARE_DATADESC();
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
|
||||
CDODBombTarget() {}
|
||||
|
||||
virtual void Spawn( void );
|
||||
virtual void Precache( void );
|
||||
|
||||
// Set these flags so players can use the bomb target ( for planting or defusing )
|
||||
virtual int ObjectCaps( void );
|
||||
|
||||
// Inputs
|
||||
void InputEnable( inputdata_t &inputdata );
|
||||
void InputDisable( inputdata_t &inputdata );
|
||||
|
||||
// State Functions
|
||||
void State_Transition( BombTargetState newState );
|
||||
void State_Enter( BombTargetState newState );
|
||||
void State_Leave();
|
||||
void State_Think();
|
||||
void State_Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
|
||||
int State_Get( void ) { return m_iState; }
|
||||
|
||||
CDODBombTargetStateInfo* State_LookupInfo( BombTargetState state );
|
||||
|
||||
// Enter
|
||||
void State_Enter_INACTIVE( void );
|
||||
void State_Enter_ACTIVE( void );
|
||||
void State_Enter_ARMED( void );
|
||||
|
||||
// Leave
|
||||
void State_Leave_Armed( void );
|
||||
|
||||
// Think
|
||||
void State_Think_ARMED( void );
|
||||
|
||||
// Use
|
||||
void State_Use_ACTIVE( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void State_Use_ARMED( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
|
||||
float GetBombTimerLength( void );
|
||||
|
||||
// Get the dod_control_point that we're linked to
|
||||
CControlPoint *GetControlPoint( void );
|
||||
|
||||
bool CanPlantHere( CDODPlayer *pPlayer );
|
||||
void CompletePlanting( CDODPlayer *pPlantingPlayer );
|
||||
|
||||
void DefuseBlocked( CDODPlayer *pAttacker );
|
||||
void PlantBlocked( CDODPlayer *pAttacker );
|
||||
|
||||
int GetTimerAddSeconds( void ) { return m_iTimerAddSeconds; }
|
||||
|
||||
int GetBombingTeam( void ) { return m_iBombingTeam; }
|
||||
|
||||
DefusingPlayer *FindDefusingPlayer( CDODPlayer *pPlayer );
|
||||
void Explode( void );
|
||||
void BombDefused( CDODPlayer *pDefuser );
|
||||
void ResetDefuse( int index );
|
||||
|
||||
bool CanPlayerStartDefuse( CDODPlayer *pPlayer );
|
||||
bool CanPlayerContinueDefusing( CDODPlayer *pPlayer, DefusingPlayer *pDefuseRecord );
|
||||
private:
|
||||
|
||||
// Control Point we're linked to
|
||||
string_t m_iszCapPointName;
|
||||
CControlPoint *m_pControlPoint;
|
||||
|
||||
// Outputs
|
||||
COutputEvent m_OnBecomeActive;
|
||||
COutputEvent m_OnBecomeInactive;
|
||||
COutputEvent m_OnBombPlanted;
|
||||
COutputEvent m_OnBombExploded;
|
||||
COutputEvent m_OnBombDisarmed;
|
||||
|
||||
// state
|
||||
CNetworkVar( int, m_iState );
|
||||
CDODBombTargetStateInfo *m_pCurStateInfo;
|
||||
bool m_bStartDisabled;
|
||||
|
||||
// timers for armed state
|
||||
float m_flExplodeTime;
|
||||
float m_flNextAnnounce;
|
||||
|
||||
// player that planted this bomb
|
||||
CHandle<CDODPlayer> m_pPlantingPlayer;
|
||||
|
||||
// The team that is allowed to plant bombs here
|
||||
CNetworkVar( int, m_iBombingTeam );
|
||||
|
||||
// network the model indices of active bomb so we can change per-team
|
||||
CNetworkVar( int, m_iTargetModel );
|
||||
CNetworkVar( int, m_iUnavailableModel );
|
||||
|
||||
int m_iTimerAddSeconds;
|
||||
|
||||
// List of defusing players and time until completion
|
||||
CUtlVector< DefusingPlayer > m_DefusingPlayers;
|
||||
|
||||
private:
|
||||
CDODBombTarget( const CDODBombTarget & );
|
||||
};
|
||||
|
||||
#endif //DOD_BOMBTARGET_H
|
||||
453
game/server/dod/dod_bot_temp.cpp
Normal file
453
game/server/dod/dod_bot_temp.cpp
Normal file
@@ -0,0 +1,453 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Basic BOT handling.
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "player.h"
|
||||
#include "dod_player.h"
|
||||
#include "in_buttons.h"
|
||||
#include "movehelper_server.h"
|
||||
|
||||
void ClientPutInServer( edict_t *pEdict, const char *playername );
|
||||
void Bot_Think( CDODPlayer *pBot );
|
||||
|
||||
ConVar bot_forcefireweapon( "bot_forcefireweapon", "", 0, "Force bots with the specified weapon to fire." );
|
||||
ConVar bot_forceattack2( "bot_forceattack2", "0", 0, "When firing, use attack2." );
|
||||
ConVar bot_forceattackon( "bot_forceattackon", "0", 0, "When firing, don't tap fire, hold it down." );
|
||||
ConVar bot_flipout( "bot_flipout", "0", 0, "When on, all bots fire their guns." );
|
||||
ConVar bot_defend( "bot_defend", "0", 0, "Set to a team number, and that team will all keep their combat shields raised." );
|
||||
ConVar bot_changeclass( "bot_changeclass", "0", 0, "Force all bots to change to the specified class." );
|
||||
ConVar bot_zombie( "bot_zombie", "0", 0, "Brraaaaaiiiins." );
|
||||
static ConVar bot_mimic( "bot_mimic", "0", 0, "Bot uses usercmd of player by index." );
|
||||
static ConVar bot_mimic_yaw_offset( "bot_mimic_yaw_offset", "0", 0, "Offsets the bot yaw." );
|
||||
ConVar bot_attack( "bot_attack", "0", 0, "Shoot!" );
|
||||
|
||||
ConVar bot_sendcmd( "bot_sendcmd", "", 0, "Forces bots to send the specified command." );
|
||||
|
||||
ConVar bot_crouch( "bot_crouch", "0", 0, "Bot crouches" );
|
||||
|
||||
static int BotNumber = 1;
|
||||
static int g_iNextBotTeam = -1;
|
||||
static int g_iNextBotClass = -1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool backwards;
|
||||
|
||||
float nextturntime;
|
||||
bool lastturntoright;
|
||||
|
||||
float nextstrafetime;
|
||||
float sidemove;
|
||||
|
||||
QAngle forwardAngle;
|
||||
QAngle lastAngles;
|
||||
|
||||
float m_flJoinTeamTime;
|
||||
int m_WantedTeam;
|
||||
int m_WantedClass;
|
||||
} botdata_t;
|
||||
|
||||
static botdata_t g_BotData[ MAX_PLAYERS ];
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Create a new Bot and put it in the game.
|
||||
// Output : Pointer to the new Bot, or NULL if there's no free clients.
|
||||
//-----------------------------------------------------------------------------
|
||||
CBasePlayer *BotPutInServer( bool bFrozen, int iTeam, int iClass )
|
||||
{
|
||||
g_iNextBotTeam = iTeam;
|
||||
g_iNextBotClass = iClass;
|
||||
|
||||
char botname[ 64 ];
|
||||
Q_snprintf( botname, sizeof( botname ), "Bot%02i", BotNumber );
|
||||
|
||||
// This is an evil hack, but we use it to prevent sv_autojointeam from kicking in.
|
||||
edict_t *pEdict = engine->CreateFakeClient( botname );
|
||||
|
||||
if (!pEdict)
|
||||
{
|
||||
Msg( "Failed to create Bot.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allocate a CBasePlayer for the bot, and call spawn
|
||||
//ClientPutInServer( pEdict, botname );
|
||||
CDODPlayer *pPlayer = ((CDODPlayer *)CBaseEntity::Instance( pEdict ));
|
||||
pPlayer->ClearFlags();
|
||||
pPlayer->AddFlag( FL_CLIENT | FL_FAKECLIENT );
|
||||
|
||||
if ( bFrozen )
|
||||
pPlayer->AddEFlags( EFL_BOT_FROZEN );
|
||||
|
||||
BotNumber++;
|
||||
|
||||
g_BotData[pPlayer->entindex()-1].m_WantedTeam = iTeam;
|
||||
g_BotData[pPlayer->entindex()-1].m_WantedClass = iClass;
|
||||
g_BotData[pPlayer->entindex()-1].m_flJoinTeamTime = gpGlobals->curtime + 0.3;
|
||||
|
||||
return pPlayer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run through all the Bots in the game and let them think.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bot_RunAll( void )
|
||||
{
|
||||
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
|
||||
{
|
||||
CDODPlayer *pPlayer = ToDODPlayer( UTIL_PlayerByIndex( i ) );
|
||||
|
||||
if ( pPlayer && (pPlayer->GetFlags() & FL_FAKECLIENT) )
|
||||
{
|
||||
Bot_Think( pPlayer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RunMimicCommand( CUserCmd& cmd )
|
||||
{
|
||||
if ( bot_mimic.GetInt() <= 0 )
|
||||
return false;
|
||||
|
||||
if ( bot_mimic.GetInt() > gpGlobals->maxClients )
|
||||
return false;
|
||||
|
||||
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( bot_mimic.GetInt() );
|
||||
if ( !pPlayer )
|
||||
return false;
|
||||
|
||||
if ( !pPlayer->GetLastUserCommand() )
|
||||
return false;
|
||||
|
||||
cmd = *pPlayer->GetLastUserCommand();
|
||||
cmd.viewangles[YAW] += bot_mimic_yaw_offset.GetFloat();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Simulates a single frame of movement for a player
|
||||
// Input : *fakeclient -
|
||||
// *viewangles -
|
||||
// forwardmove -
|
||||
// sidemove -
|
||||
// upmove -
|
||||
// buttons -
|
||||
// impulse -
|
||||
// msec -
|
||||
// Output : virtual void
|
||||
//-----------------------------------------------------------------------------
|
||||
static void RunPlayerMove( CDODPlayer *fakeclient, const QAngle& viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, float frametime )
|
||||
{
|
||||
if ( !fakeclient )
|
||||
return;
|
||||
|
||||
CUserCmd cmd;
|
||||
|
||||
// Store off the globals.. they're gonna get whacked
|
||||
float flOldFrametime = gpGlobals->frametime;
|
||||
float flOldCurtime = gpGlobals->curtime;
|
||||
|
||||
float flTimeBase = gpGlobals->curtime + gpGlobals->frametime - frametime;
|
||||
fakeclient->SetTimeBase( flTimeBase );
|
||||
|
||||
Q_memset( &cmd, 0, sizeof( cmd ) );
|
||||
|
||||
if ( !RunMimicCommand( cmd ) && !bot_zombie.GetBool() )
|
||||
{
|
||||
VectorCopy( viewangles, cmd.viewangles );
|
||||
cmd.forwardmove = forwardmove;
|
||||
cmd.sidemove = sidemove;
|
||||
cmd.upmove = upmove;
|
||||
cmd.buttons = buttons;
|
||||
cmd.impulse = impulse;
|
||||
cmd.random_seed = random->RandomInt( 0, 0x7fffffff );
|
||||
}
|
||||
|
||||
if( bot_crouch.GetInt() )
|
||||
cmd.buttons |= IN_DUCK;
|
||||
|
||||
if ( bot_attack.GetBool() )
|
||||
cmd.buttons |= IN_ATTACK;
|
||||
|
||||
MoveHelperServer()->SetHost( fakeclient );
|
||||
fakeclient->PlayerRunCommand( &cmd, MoveHelperServer() );
|
||||
|
||||
// save off the last good usercmd
|
||||
fakeclient->SetLastUserCommand( cmd );
|
||||
|
||||
// Clear out any fixangle that has been set
|
||||
fakeclient->pl.fixangle = FIXANGLE_NONE;
|
||||
|
||||
// Restore the globals..
|
||||
gpGlobals->frametime = flOldFrametime;
|
||||
gpGlobals->curtime = flOldCurtime;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run this Bot's AI for one frame.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bot_Think( CDODPlayer *pBot )
|
||||
{
|
||||
// Make sure we stay being a bot
|
||||
pBot->AddFlag( FL_FAKECLIENT );
|
||||
|
||||
botdata_t *botdata = &g_BotData[ ENTINDEX( pBot->edict() ) - 1 ];
|
||||
|
||||
QAngle vecViewAngles;
|
||||
float forwardmove = 0.0;
|
||||
float sidemove = botdata->sidemove;
|
||||
float upmove = 0.0;
|
||||
unsigned short buttons = 0;
|
||||
byte impulse = 0;
|
||||
float frametime = gpGlobals->frametime;
|
||||
|
||||
vecViewAngles = pBot->GetLocalAngles();
|
||||
|
||||
|
||||
// Create some random values
|
||||
if ( pBot->GetTeamNumber() == TEAM_UNASSIGNED && gpGlobals->curtime > botdata->m_flJoinTeamTime )
|
||||
{
|
||||
pBot->HandleCommand_JoinTeam( botdata->m_WantedTeam );
|
||||
}
|
||||
else if ( pBot->GetTeamNumber() != TEAM_UNASSIGNED && pBot->m_Shared.PlayerClass() == PLAYERCLASS_UNDEFINED )
|
||||
{
|
||||
// If they're on a team but haven't picked a class, choose a random class..
|
||||
pBot->HandleCommand_JoinClass( botdata->m_WantedClass );
|
||||
pBot->DODRespawn();
|
||||
}
|
||||
else if ( pBot->IsAlive() && (pBot->GetSolid() == SOLID_BBOX) )
|
||||
{
|
||||
trace_t trace;
|
||||
|
||||
// Stop when shot
|
||||
if ( !pBot->IsEFlagSet(EFL_BOT_FROZEN) )
|
||||
{
|
||||
if ( pBot->m_iHealth == 100 )
|
||||
{
|
||||
forwardmove = 600 * ( botdata->backwards ? -1 : 1 );
|
||||
if ( botdata->sidemove != 0.0f )
|
||||
{
|
||||
forwardmove *= random->RandomFloat( 0.1, 1.0f );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forwardmove = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Only turn if I haven't been hurt
|
||||
if ( !pBot->IsEFlagSet(EFL_BOT_FROZEN) && pBot->m_iHealth == 100 )
|
||||
{
|
||||
Vector vecEnd;
|
||||
Vector forward;
|
||||
|
||||
QAngle angle;
|
||||
float angledelta = 15.0;
|
||||
|
||||
int maxtries = (int)360.0/angledelta;
|
||||
|
||||
if ( botdata->lastturntoright )
|
||||
{
|
||||
angledelta = -angledelta;
|
||||
}
|
||||
|
||||
angle = pBot->GetLocalAngles();
|
||||
|
||||
Vector vecSrc;
|
||||
while ( --maxtries >= 0 )
|
||||
{
|
||||
AngleVectors( angle, &forward );
|
||||
|
||||
vecSrc = pBot->GetLocalOrigin() + Vector( 0, 0, 36 );
|
||||
|
||||
vecEnd = vecSrc + forward * 10;
|
||||
|
||||
UTIL_TraceHull( vecSrc, vecEnd, VEC_HULL_MIN_SCALED( pBot ), VEC_HULL_MAX_SCALED( pBot ),
|
||||
MASK_PLAYERSOLID, pBot, COLLISION_GROUP_NONE, &trace );
|
||||
|
||||
if ( trace.fraction == 1.0 )
|
||||
{
|
||||
if ( gpGlobals->curtime < botdata->nextturntime )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
angle.y += angledelta;
|
||||
|
||||
if ( angle.y > 180 )
|
||||
angle.y -= 360;
|
||||
else if ( angle.y < -180 )
|
||||
angle.y += 360;
|
||||
|
||||
botdata->nextturntime = gpGlobals->curtime + 2.0;
|
||||
botdata->lastturntoright = random->RandomInt( 0, 1 ) == 0 ? true : false;
|
||||
|
||||
botdata->forwardAngle = angle;
|
||||
botdata->lastAngles = angle;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ( gpGlobals->curtime >= botdata->nextstrafetime )
|
||||
{
|
||||
botdata->nextstrafetime = gpGlobals->curtime + 1.0f;
|
||||
|
||||
if ( random->RandomInt( 0, 5 ) == 0 )
|
||||
{
|
||||
botdata->sidemove = -600.0f + 1200.0f * random->RandomFloat( 0, 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
botdata->sidemove = 0;
|
||||
}
|
||||
sidemove = botdata->sidemove;
|
||||
|
||||
if ( random->RandomInt( 0, 20 ) == 0 )
|
||||
{
|
||||
botdata->backwards = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
botdata->backwards = false;
|
||||
}
|
||||
}
|
||||
|
||||
pBot->SetLocalAngles( angle );
|
||||
vecViewAngles = angle;
|
||||
}
|
||||
|
||||
// Is my team being forced to defend?
|
||||
if ( bot_defend.GetInt() == pBot->GetTeamNumber() )
|
||||
{
|
||||
buttons |= IN_ATTACK2;
|
||||
}
|
||||
// If bots are being forced to fire a weapon, see if I have it
|
||||
else if ( bot_forcefireweapon.GetString() )
|
||||
{
|
||||
CBaseCombatWeapon *pWeapon = pBot->Weapon_OwnsThisType( bot_forcefireweapon.GetString() );
|
||||
if ( pWeapon )
|
||||
{
|
||||
// Switch to it if we don't have it out
|
||||
CBaseCombatWeapon *pActiveWeapon = pBot->GetActiveWeapon();
|
||||
|
||||
// Switch?
|
||||
if ( pActiveWeapon != pWeapon )
|
||||
{
|
||||
pBot->Weapon_Switch( pWeapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start firing
|
||||
// Some weapons require releases, so randomise firing
|
||||
if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
|
||||
{
|
||||
buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( bot_flipout.GetInt() )
|
||||
{
|
||||
if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
|
||||
{
|
||||
buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
|
||||
}
|
||||
|
||||
if ( RandomFloat(0.0,1.0) > 0.9 )
|
||||
buttons |= IN_RELOAD;
|
||||
}
|
||||
|
||||
if ( Q_strlen( bot_sendcmd.GetString() ) > 0 )
|
||||
{
|
||||
//send the cmd from this bot
|
||||
CCommand args;
|
||||
args.Tokenize( bot_sendcmd.GetString() );
|
||||
pBot->ClientCommand( args );
|
||||
|
||||
bot_sendcmd.SetValue("");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait for Reinforcement wave
|
||||
if ( !pBot->IsAlive() )
|
||||
{
|
||||
// Try hitting my buttons occasionally
|
||||
if ( random->RandomInt( 0, 100 ) > 80 )
|
||||
{
|
||||
// Respawn the bot
|
||||
if ( random->RandomInt( 0, 1 ) == 0 )
|
||||
{
|
||||
buttons |= IN_JUMP;
|
||||
}
|
||||
else
|
||||
{
|
||||
buttons = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( bot_flipout.GetInt() >= 2 )
|
||||
{
|
||||
botdata->lastAngles.x = sin( gpGlobals->curtime + pBot->entindex() ) * 90;
|
||||
botdata->lastAngles.y = AngleNormalize( ( gpGlobals->curtime * 1.7 + pBot->entindex() ) * 45 );
|
||||
botdata->lastAngles.z = 0.0;
|
||||
|
||||
// botdata->lastAngles = QAngle( 0, 0, 0 );
|
||||
|
||||
/*
|
||||
QAngle angOffset = RandomAngle( -1, 1 );
|
||||
for ( int i = 0 ; i < 2; i++ )
|
||||
{
|
||||
if ( fabs( botdata->lastAngles[ i ] - botdata->forwardAngle[ i ] ) > 15.0f )
|
||||
{
|
||||
if ( botdata->lastAngles[ i ] > botdata->forwardAngle[ i ] )
|
||||
{
|
||||
botdata->lastAngles[ i ] = botdata->forwardAngle[ i ] + 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
botdata->lastAngles[ i ] = botdata->forwardAngle[ i ] - 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
botdata->lastAngles[ 2 ] = 0;
|
||||
*/
|
||||
|
||||
float speed = 300; // sin( gpGlobals->curtime / 1.7 + pBot->entindex() ) * 600;
|
||||
forwardmove = sin( gpGlobals->curtime + pBot->entindex() ) * speed;
|
||||
sidemove = cos( gpGlobals->curtime * 2.3 + pBot->entindex() ) * speed;
|
||||
|
||||
if (sin(gpGlobals->curtime ) < -0.5)
|
||||
{
|
||||
buttons |= IN_DUCK;
|
||||
}
|
||||
else if (sin(gpGlobals->curtime ) < 0.5)
|
||||
{
|
||||
buttons |= IN_WALK;
|
||||
}
|
||||
|
||||
pBot->SetLocalAngles( botdata->lastAngles );
|
||||
}
|
||||
|
||||
RunPlayerMove( pBot, pBot->GetLocalAngles(), forwardmove, sidemove, upmove, buttons, impulse, frametime );
|
||||
}
|
||||
|
||||
|
||||
19
game/server/dod/dod_bot_temp.h
Normal file
19
game/server/dod/dod_bot_temp.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef BOT_BASE_H
|
||||
#define BOT_BASE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// If iTeam or iClass is -1, then a team or class is randomly chosen.
|
||||
CBasePlayer *BotPutInServer( bool bFrozen, int iTeam, int iClass );
|
||||
|
||||
|
||||
#endif // BOT_BASE_H
|
||||
236
game/server/dod/dod_client.cpp
Normal file
236
game/server/dod/dod_client.cpp
Normal file
@@ -0,0 +1,236 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
/*
|
||||
|
||||
===== tf_client.cpp ========================================================
|
||||
|
||||
HL2 client/server game specific stuff
|
||||
|
||||
*/
|
||||
|
||||
#include "cbase.h"
|
||||
#include "player.h"
|
||||
#include "gamerules.h"
|
||||
#include "entitylist.h"
|
||||
#include "physics.h"
|
||||
#include "game.h"
|
||||
#include "ai_network.h"
|
||||
#include "ai_node.h"
|
||||
#include "ai_hull.h"
|
||||
#include "shake.h"
|
||||
#include "player_resource.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "dod_player.h"
|
||||
#include "dod_gamerules.h"
|
||||
#include "tier0/vprof.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
extern CBaseEntity *FindPickerEntity( CBasePlayer *pPlayer );
|
||||
|
||||
extern bool g_fGameOver;
|
||||
|
||||
void FinishClientPutInServer( CDODPlayer *pPlayer )
|
||||
{
|
||||
pPlayer->InitialSpawn();
|
||||
pPlayer->Spawn();
|
||||
|
||||
if (!pPlayer->IsBot())
|
||||
{
|
||||
// When the player first joins the server, they
|
||||
pPlayer->m_takedamage = DAMAGE_NO;
|
||||
pPlayer->pl.deadflag = true;
|
||||
pPlayer->m_lifeState = LIFE_DEAD;
|
||||
pPlayer->AddEffects( EF_NODRAW );
|
||||
pPlayer->SetThink( NULL );
|
||||
|
||||
if ( 1 )
|
||||
{
|
||||
pPlayer->ChangeTeam( TEAM_UNASSIGNED );
|
||||
|
||||
// Move them to the first intro camera.
|
||||
pPlayer->MoveToNextIntroCamera();
|
||||
pPlayer->SetMoveType( MOVETYPE_NONE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char sName[128];
|
||||
Q_strncpy( sName, pPlayer->GetPlayerName(), sizeof( sName ) );
|
||||
|
||||
// First parse the name and remove any %'s
|
||||
for ( char *pApersand = sName; pApersand != NULL && *pApersand != 0; pApersand++ )
|
||||
{
|
||||
// Replace it with a space
|
||||
if ( *pApersand == '%' )
|
||||
*pApersand = ' ';
|
||||
}
|
||||
|
||||
// notify other clients of player joining the game
|
||||
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "#Game_connected", sName[0] != 0 ? sName : "<unconnected>" );
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
ClientPutInServer
|
||||
|
||||
called each time a player is spawned into the game
|
||||
============
|
||||
*/
|
||||
void ClientPutInServer( edict_t *pEdict, const char *playername )
|
||||
{
|
||||
// Allocate a CBaseTFPlayer for pev, and call spawn
|
||||
CDODPlayer *pPlayer = CDODPlayer::CreatePlayer( "player", pEdict );
|
||||
|
||||
pPlayer->SetPlayerName( playername );
|
||||
}
|
||||
|
||||
|
||||
void ClientActive( edict_t *pEdict, bool bLoadGame )
|
||||
{
|
||||
// Can't load games in CS!
|
||||
Assert( !bLoadGame );
|
||||
|
||||
CDODPlayer *pPlayer = ToDODPlayer( CBaseEntity::Instance( pEdict ) );
|
||||
FinishClientPutInServer( pPlayer );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
const char *GetGameDescription()
|
||||
|
||||
Returns the descriptive name of this .dll. E.g., Half-Life, or Team Fortress 2
|
||||
===============
|
||||
*/
|
||||
const char *GetGameDescription()
|
||||
{
|
||||
if ( g_pGameRules ) // this function may be called before the world has spawned, and the game rules initialized
|
||||
return g_pGameRules->GetGameDescription();
|
||||
else
|
||||
return "Day of Defeat";
|
||||
}
|
||||
|
||||
int g_iHelmetModels[NUM_HELMETS];
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Precache game-specific models & sounds
|
||||
//-----------------------------------------------------------------------------
|
||||
void ClientGamePrecache( void )
|
||||
{
|
||||
// Materials used by the client effects
|
||||
CBaseEntity::PrecacheModel( "sprites/white.vmt" );
|
||||
CBaseEntity::PrecacheModel( "sprites/physbeam.vmt" );
|
||||
|
||||
for( int i=0;i<NUM_HELMETS;i++ )
|
||||
{
|
||||
g_iHelmetModels[i] = CBaseEntity::PrecacheModel( m_pszHelmetModels[i] );
|
||||
}
|
||||
|
||||
// Moved to pure_server_minimal.txt
|
||||
// // Sniper scope
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_spring_ul.vmt" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_spring_ul.vtf" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_spring_ur.vmt" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_spring_ur.vtf" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_spring_ll.vmt" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_spring_ll.vtf" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_spring_lr.vmt" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_spring_lr.vtf" );
|
||||
//
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_k43_ul.vmt" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_k43_ul.vtf" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_k43_ur.vmt" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_k43_ur.vtf" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_k43_ll.vmt" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_k43_ll.vtf" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_k43_lr.vmt" );
|
||||
// engine->ForceExactFile( "sprites/scopes/scope_k43_lr.vtf" );
|
||||
//
|
||||
// // Smoke grenade-related files
|
||||
// engine->ForceExactFile( "particle/particle_smokegrenade1.vmt" );
|
||||
// engine->ForceExactFile( "particle/particle_smokegrenade.vtf" );
|
||||
// engine->ForceExactFile( "effects/stun.vmt" );
|
||||
//
|
||||
// // DSP presets - don't want people avoiding the deafening + ear ring
|
||||
// engine->ForceExactFile( "scripts/dsp_presets.txt" );
|
||||
//
|
||||
// // force weapon scripts because people are dirty cheaters
|
||||
// engine->ForceExactFile( "scripts/weapon_30cal.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_amerknife.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_bar.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_bazooka.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_c96.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_colt.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_frag_ger.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_frag_ger_live.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_frag_us.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_frag_us_live.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_garand.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_k98.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_k98_scoped.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_m1carbine.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_mg42.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_mp40.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_mp44.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_p38.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_pschreck.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_riflegren_ger.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_riflegren_ger_live.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_riflegren_us.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_riflegren_us_live.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_smoke_ger.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_smoke_us.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_spade.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_spring.ctx");
|
||||
// engine->ForceExactFile( "scripts/weapon_thompson.ctx");
|
||||
}
|
||||
|
||||
|
||||
// called by ClientKill and DeadThink
|
||||
void respawn( CBaseEntity *pEdict, bool fCopyCorpse )
|
||||
{
|
||||
if (gpGlobals->coop || gpGlobals->deathmatch)
|
||||
{
|
||||
if ( fCopyCorpse )
|
||||
{
|
||||
// make a copy of the dead body for appearances sake
|
||||
dynamic_cast< CBasePlayer* >( pEdict )->CreateCorpse();
|
||||
}
|
||||
|
||||
// respawn player
|
||||
pEdict->Spawn();
|
||||
}
|
||||
else
|
||||
{ // restart the entire server
|
||||
engine->ServerCommand("reload\n");
|
||||
}
|
||||
}
|
||||
|
||||
void GameStartFrame( void )
|
||||
{
|
||||
VPROF( "GameStartFrame" );
|
||||
|
||||
if ( g_fGameOver )
|
||||
return;
|
||||
|
||||
gpGlobals->teamplay = teamplay.GetInt() ? true : false;
|
||||
|
||||
extern void Bot_RunAll();
|
||||
Bot_RunAll();
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// instantiate the proper game rules object
|
||||
//=========================================================
|
||||
void InstallGameRules()
|
||||
{
|
||||
CreateGameRulesObject( "CDODGameRules" );
|
||||
}
|
||||
738
game/server/dod/dod_control_point.cpp
Normal file
738
game/server/dod/dod_control_point.cpp
Normal file
@@ -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 );
|
||||
}
|
||||
164
game/server/dod/dod_control_point.h
Normal file
164
game/server/dod/dod_control_point.h
Normal file
@@ -0,0 +1,164 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_CONTROL_POINT_H
|
||||
#define DOD_CONTROL_POINT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "dod_player.h"
|
||||
|
||||
#define CAP_ICON_ALLIES_FLAG 1
|
||||
#define CAP_ICON_BRIT_FLAG 27 //from dod_objectives.cpp
|
||||
|
||||
#define CAP_POINT_HIDEFLAG (1<<0)
|
||||
#define CAP_POINT_HIDE_MODEL (1<<1)
|
||||
#define CAP_POINT_TICK_FOR_BOMBS_REMAINING (1<<2)
|
||||
|
||||
#define PLAYER_POINTS_FOR_CAP 1
|
||||
#define PLAYER_POINTS_FOR_BLOCK 1
|
||||
#define PLAYER_POINTS_FOR_BOMB_PLANT 1
|
||||
#define PLAYER_POINTS_FOR_BOMB_EXPLODED 3
|
||||
|
||||
|
||||
class CControlPoint : public CBaseAnimating
|
||||
{
|
||||
|
||||
public:
|
||||
DECLARE_CLASS( CControlPoint, CBaseAnimating );
|
||||
DECLARE_DATADESC();
|
||||
|
||||
CControlPoint();
|
||||
|
||||
virtual void Spawn( void );
|
||||
virtual bool KeyValue( const char *szKeyName, const char *szValue );
|
||||
virtual void Precache( void );
|
||||
|
||||
void Reset( void );
|
||||
|
||||
//Inputs
|
||||
inline void Enable( inputdata_t &input ) { SetActive( false ); }
|
||||
inline void Disable( inputdata_t &input ) { SetActive( true ); }
|
||||
void InputReset( inputdata_t &input );
|
||||
void InputSetOwner( inputdata_t &input );
|
||||
|
||||
void InputShowModel( inputdata_t &input );
|
||||
void InputHideModel( inputdata_t &input );
|
||||
|
||||
int PointValue( void );
|
||||
|
||||
void RoundRespawn( void ); //Mugsy - resetting
|
||||
void TriggerTargets( void );
|
||||
|
||||
void SetActive( bool active );
|
||||
|
||||
bool PointIsVisible( void ) { return !( FBitSet( m_spawnflags, CAP_POINT_HIDEFLAG ) ); }
|
||||
|
||||
void SendCapString( int team, int iNumCappers, int *pCappingPlayers );
|
||||
|
||||
void SetOwner( int team, bool bMakeSound = true, int iNumCappers = 0, int *iCappingPlayers = NULL );
|
||||
int GetOwner( void ) const;
|
||||
|
||||
int GetDefaultOwner( void ) const;
|
||||
|
||||
inline const char *GetName( void ) { return STRING(m_iszPrintName); }
|
||||
int GetCPGroup( void );
|
||||
int GetPointIndex( void ) { return m_iPointIndex; } //the mapper set index
|
||||
void SetPointIndex( int index ) { m_iPointIndex = index; }
|
||||
int GetAlliesIcon( void ) { return m_iAlliesIcon; }
|
||||
int GetAxisIcon( void ) { return m_iAxisIcon; }
|
||||
int GetNeutralIcon( void ) { return m_iNeutralIcon; }
|
||||
|
||||
int GetCurrentHudIconIndex( void );
|
||||
int GetHudIconIndexForTeam( int team );
|
||||
int GetTimerCapHudIcon( void );
|
||||
int GetBombedHudIcon( void );
|
||||
|
||||
inline bool IsActive( void ) { return m_bActive; }
|
||||
|
||||
void SetNumCappersRequired( int alliesRequired, int axisRequired );
|
||||
|
||||
void CaptureBlocked( CDODPlayer *pPlayer );
|
||||
|
||||
// Bomb interface
|
||||
void BombPlanted( float flTimerLength, CDODPlayer *pPlantingPlayer );
|
||||
void BombExploded( CDODPlayer *pPlantingPlayer = NULL, int iPlantingTeam = TEAM_UNASSIGNED );
|
||||
void BombDisarmed( CDODPlayer *pDisarmingPlayer );
|
||||
void CancelBombPlanted( void );
|
||||
|
||||
int GetBombsRemaining( void ) { return m_iBombsRemaining; } // total bombs required
|
||||
int GetBombsRequired( void ) { return m_iBombsRequired; } // number of bombs remaining
|
||||
|
||||
private:
|
||||
void InternalSetOwner( int team, bool bMakeSound = true, int iNumCappers = 0, int *iCappingPlayers = NULL );
|
||||
|
||||
int m_iTeam; //0 - clear, 2 - allies, 3 - axis
|
||||
int m_iDefaultOwner; //team that initially owns the cap point
|
||||
int m_iIndex; //the index of this point in the controlpointArray
|
||||
|
||||
string_t m_iszPrintName;
|
||||
|
||||
string_t m_iszAlliesCapSound; //the sound to play on cap
|
||||
string_t m_iszAxisCapSound;
|
||||
string_t m_iszResetSound;
|
||||
|
||||
string_t m_iszAlliesModel; //models to set the ent to on capture
|
||||
string_t m_iszAxisModel;
|
||||
string_t m_iszResetModel;
|
||||
|
||||
int m_iAlliesModelBodygroup;//which bodygroup to use in the model
|
||||
int m_iAxisModelBodygroup;
|
||||
int m_iResetModelBodygroup;
|
||||
|
||||
COutputEvent m_AlliesCapOutput; //outputs to fire when capped
|
||||
COutputEvent m_AxisCapOutput;
|
||||
COutputEvent m_PointResetOutput;
|
||||
|
||||
COutputEvent m_OwnerChangedToAllies;
|
||||
COutputEvent m_OwnerChangedToAxis;
|
||||
|
||||
int m_iAlliesIcon; //custom hud sprites for cap point
|
||||
int m_iAxisIcon;
|
||||
int m_iNeutralIcon;
|
||||
int m_iTimerCapIcon;
|
||||
int m_iBombedIcon;
|
||||
|
||||
string_t m_iszAlliesIcon;
|
||||
string_t m_iszAxisIcon;
|
||||
string_t m_iszNeutralIcon;
|
||||
string_t m_iszTimerCapIcon;
|
||||
string_t m_iszBombedIcon;
|
||||
|
||||
int m_bPointVisible; //should this capture point be visible on the hud?
|
||||
int m_iPointIndex; //the mapper set index value of this control point
|
||||
|
||||
int m_iCPGroup; //the group that this control point belongs to
|
||||
bool m_bActive; //
|
||||
|
||||
string_t m_iszName; //Name used in cap messages
|
||||
|
||||
bool m_bStartDisabled;
|
||||
|
||||
int m_iAlliesRequired; // if we're controlled by an area cap,
|
||||
int m_iAxisRequired; // these hold the number of cappers required. Used to calc point value
|
||||
|
||||
int m_iTimedPointsAllies; // timed points value of this flag, per team
|
||||
int m_iTimedPointsAxis;
|
||||
|
||||
bool m_bBombPlanted;
|
||||
float m_flBombExplodeTime;
|
||||
|
||||
int m_iBombsRemaining;
|
||||
int m_iBombsRequired; // number of bombs required to flip this control point
|
||||
|
||||
bool m_bSetOwnerIsBombPlant; // temp flag to indicate if the set owner we're doing is the result of a bomb
|
||||
|
||||
private:
|
||||
CControlPoint( const CControlPoint & );
|
||||
};
|
||||
|
||||
#endif //DOD_CONTROL_POINT_H
|
||||
587
game/server/dod/dod_control_point_master.cpp
Normal file
587
game/server/dod/dod_control_point_master.cpp
Normal file
@@ -0,0 +1,587 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_control_point_master.h"
|
||||
|
||||
BEGIN_DATADESC( CControlPointMaster )
|
||||
DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ),
|
||||
|
||||
DEFINE_KEYFIELD( m_iTimerLength, FIELD_INTEGER, "cpm_timer_length" ),
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "RoundInit", InputRoundInit ),
|
||||
|
||||
DEFINE_FUNCTION( CPMThink ),
|
||||
|
||||
DEFINE_OUTPUT( m_AlliesWinOutput, "OnAlliesWin" ),
|
||||
DEFINE_OUTPUT( m_AxisWinOutput, "OnAxisWin" ),
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_INTEGER, "AddTimerSeconds", InputAddTimerSeconds ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( dod_control_point_master, CControlPointMaster );
|
||||
|
||||
CControlPointMaster::CControlPointMaster()
|
||||
{
|
||||
m_bUseTimer = false;
|
||||
m_iTimerTeam = TEAM_UNASSIGNED;
|
||||
|
||||
SetDefLessFunc( m_ControlPoints );
|
||||
}
|
||||
|
||||
void CControlPointMaster::Spawn( void )
|
||||
{
|
||||
SetTouch( NULL );
|
||||
m_bFoundPoints = false;
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
|
||||
ConVar mp_tickpointinterval( "mp_tickpointinterval", "30", FCVAR_GAMEDLL, "Delay between point gives.", true, 1, false, 0 );
|
||||
|
||||
void CControlPointMaster::RoundRespawn( void )
|
||||
{
|
||||
m_fGivePointsTime = gpGlobals->curtime + mp_tickpointinterval.GetInt();
|
||||
}
|
||||
|
||||
|
||||
// KeyValue
|
||||
// ========
|
||||
// this function interfaces with the keyvalues set by the mapper
|
||||
//
|
||||
// Values
|
||||
// point_give_delay_time - how often to give time based points ( seconds )
|
||||
// allies_capture_target - target to fire on allies complete capture
|
||||
// axis_capture_target - target to fire on axis complete capture
|
||||
|
||||
bool CControlPointMaster::KeyValue( const char *szKeyName, const char *szValue )
|
||||
{
|
||||
if (FStrEq(szKeyName, "cpm_use_timer"))
|
||||
{
|
||||
m_bUseTimer = ( atoi(szValue) > 0 );
|
||||
}
|
||||
else if (FStrEq(szKeyName, "cpm_timer_team"))
|
||||
{
|
||||
m_iTimerTeam = atoi(szValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CBaseEntity::KeyValue( szKeyName, szValue );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CControlPointMaster::Reset( void )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CControlPointMaster::FindControlPoints( void )
|
||||
{
|
||||
//go through all the points
|
||||
CBaseEntity *pEnt = gEntList.FindEntityByClassname( NULL, "dod_control_point" );
|
||||
|
||||
int numFound = 0;
|
||||
|
||||
while( pEnt )
|
||||
{
|
||||
CControlPoint *pPoint = (CControlPoint *)pEnt;
|
||||
|
||||
if( pPoint->IsActive() )
|
||||
{
|
||||
int index = pPoint->GetPointIndex();
|
||||
|
||||
Assert( index >= 0 );
|
||||
|
||||
if( m_ControlPoints.Find( index ) == m_ControlPoints.InvalidIndex())
|
||||
{
|
||||
DevMsg( 2, "Adding control point %s with index %d\n", pPoint->GetName(), index );
|
||||
m_ControlPoints.Insert( index, pPoint );
|
||||
numFound++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "!!!!\nMultiple control points with the same index, duplicates ignored\n!!!!\n" );
|
||||
UTIL_Remove( pPoint );
|
||||
}
|
||||
}
|
||||
|
||||
pEnt = gEntList.FindEntityByClassname( pEnt, "dod_control_point" );
|
||||
}
|
||||
|
||||
if( numFound > MAX_CONTROL_POINTS )
|
||||
{
|
||||
Warning( "Too many control points! Max is %d\n", MAX_CONTROL_POINTS );
|
||||
}
|
||||
|
||||
//Remap the indeces of the control points so they are 0-based
|
||||
//======================
|
||||
unsigned int j;
|
||||
|
||||
bool bHandled[MAX_CONTROL_POINTS];
|
||||
memset( bHandled, 0, sizeof(bHandled) );
|
||||
|
||||
unsigned int numPoints = m_ControlPoints.Count();
|
||||
unsigned int newIndex = 0;
|
||||
|
||||
while( newIndex < numPoints )
|
||||
{
|
||||
//Find the lowest numbered, unhandled point
|
||||
int lowestIndex = -1;
|
||||
int lowestValue = 999;
|
||||
|
||||
//find the lowest unhandled index
|
||||
for( j=0; j<numPoints; j++ )
|
||||
{
|
||||
if( !bHandled[j] && m_ControlPoints[j]->GetPointIndex() < lowestValue )
|
||||
{
|
||||
lowestIndex = j;
|
||||
lowestValue = m_ControlPoints[j]->GetPointIndex();
|
||||
}
|
||||
}
|
||||
|
||||
//Don't examine this point again
|
||||
Assert( lowestIndex >= 0 );
|
||||
bHandled[lowestIndex] = true;
|
||||
|
||||
//Give it its new index
|
||||
m_ControlPoints[lowestIndex]->SetPointIndex( newIndex );
|
||||
newIndex++;
|
||||
}
|
||||
|
||||
if( m_ControlPoints.Count() == 0 )
|
||||
{
|
||||
Warning( "Error! No control points found in map!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
g_pObjectiveResource->SetNumControlPoints( m_ControlPoints.Count() );
|
||||
|
||||
unsigned int i;
|
||||
for( i=0;i<m_ControlPoints.Count();i++ )
|
||||
{
|
||||
CControlPoint *pPoint = m_ControlPoints[i];
|
||||
|
||||
int iPointIndex = m_ControlPoints[i]->GetPointIndex();
|
||||
|
||||
g_pObjectiveResource->SetOwningTeam( iPointIndex, pPoint->GetOwner() );
|
||||
g_pObjectiveResource->SetCPVisible( iPointIndex, pPoint->PointIsVisible() );
|
||||
g_pObjectiveResource->SetCPPosition( iPointIndex, pPoint->GetAbsOrigin() );
|
||||
|
||||
g_pObjectiveResource->SetBombsRequired( iPointIndex, pPoint->GetBombsRequired() );
|
||||
g_pObjectiveResource->SetBombsRemaining( iPointIndex, pPoint->GetBombsRemaining() );
|
||||
|
||||
g_pObjectiveResource->SetCPIcons( iPointIndex,
|
||||
pPoint->GetHudIconIndexForTeam(TEAM_ALLIES),
|
||||
pPoint->GetHudIconIndexForTeam(TEAM_AXIS),
|
||||
pPoint->GetHudIconIndexForTeam(TEAM_UNASSIGNED),
|
||||
pPoint->GetTimerCapHudIcon(),
|
||||
pPoint->GetBombedHudIcon() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Think
|
||||
// =====
|
||||
// Think is called every 0.1 seconds and checks the status of all the control points
|
||||
// if one team owns them all, it gives points and resets
|
||||
// Think also gives the time based points at the specified time intervals
|
||||
//
|
||||
// I moved the search for spawn points to the initial think - sometimes the points spawned
|
||||
// after the master and it wasnt finding them.
|
||||
|
||||
void CControlPointMaster::CPMThink( void )
|
||||
{
|
||||
// search for all "dod_control_point" entities in the map
|
||||
// and put them in the array
|
||||
// only done the first Think
|
||||
|
||||
//try to establish if any dod_area_capture ents are linked to our flags
|
||||
//via dod_point_relay
|
||||
|
||||
//if there exists a point relay that has this as the target,
|
||||
//AND there exists a capture area that has that relay as a target
|
||||
//then we have our area!
|
||||
|
||||
//every think
|
||||
|
||||
//go through all the control points and make sure theyre the same as the last think
|
||||
//check masters
|
||||
|
||||
//if they are, do nothing
|
||||
//else
|
||||
//
|
||||
|
||||
//Note! Only one cpm should ever be active at the same time
|
||||
//funny things may happen if there are two of em!
|
||||
//if we are recently mastered on or off, touch the cps
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//below here we shouldn't execute unless we are an active control point master
|
||||
|
||||
//if the round has been decided, don't do any more thinking
|
||||
//if this cpm is not active, dont' do any thinking
|
||||
|
||||
int iRoundState = DODGameRules()->State_Get();
|
||||
|
||||
// No points or triggering new wins if we are not active
|
||||
if( m_bDisabled || iRoundState != STATE_RND_RUNNING )
|
||||
{
|
||||
SetContextThink( &CControlPointMaster::CPMThink, gpGlobals->curtime + 0.2, FLAGS_CONTEXT );
|
||||
return;
|
||||
}
|
||||
|
||||
// is it time to give time-based points yet?
|
||||
if( gpGlobals->curtime > m_fGivePointsTime )
|
||||
{
|
||||
int AlliesPoints = 0;
|
||||
int AxisPoints = 0;
|
||||
|
||||
//give points based on who owns what
|
||||
unsigned int i;
|
||||
for( i=0;i<m_ControlPoints.Count();i++ )
|
||||
{
|
||||
switch( m_ControlPoints[i]->GetOwner() )
|
||||
{
|
||||
case TEAM_ALLIES:
|
||||
AlliesPoints += m_ControlPoints[i]->PointValue();
|
||||
break;
|
||||
case TEAM_AXIS:
|
||||
AxisPoints += m_ControlPoints[i]->PointValue();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//================
|
||||
//give team points
|
||||
//================
|
||||
// See if there are players active on these teams
|
||||
|
||||
bool bFoundAllies = ( GetGlobalTeam(TEAM_ALLIES)->GetNumPlayers() > 0 );
|
||||
bool bFoundAxis = ( GetGlobalTeam(TEAM_AXIS)->GetNumPlayers() > 0 );
|
||||
|
||||
bool bReportScore = true;
|
||||
|
||||
// don't give team points to a team with no-one on it!
|
||||
if( AlliesPoints > 0 && bFoundAllies && DODGameRules()->State_Get() == STATE_RND_RUNNING )
|
||||
{
|
||||
if( bReportScore )
|
||||
{
|
||||
if (AlliesPoints == 1)
|
||||
UTIL_ClientPrintAll( HUD_PRINTTALK, "#game_score_allie_point" );
|
||||
else
|
||||
{
|
||||
char buf[8];
|
||||
Q_snprintf( buf, sizeof(buf), "%d", AlliesPoints );
|
||||
UTIL_ClientPrintAll( HUD_PRINTTALK, "#game_score_allie_points", buf );
|
||||
}
|
||||
|
||||
}
|
||||
GetGlobalTeam(TEAM_ALLIES)->AddScore( AlliesPoints );
|
||||
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "dod_tick_points" );
|
||||
|
||||
if ( event )
|
||||
{
|
||||
event->SetInt( "team", TEAM_ALLIES );
|
||||
event->SetInt( "score", AlliesPoints );
|
||||
event->SetInt( "totalscore", GetGlobalTeam(TEAM_ALLIES)->GetScore() );
|
||||
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
}
|
||||
|
||||
if( AxisPoints > 0 && bFoundAxis && DODGameRules()->State_Get() == STATE_RND_RUNNING )
|
||||
{
|
||||
if( bReportScore )
|
||||
{
|
||||
if (AxisPoints == 1)
|
||||
UTIL_ClientPrintAll( HUD_PRINTTALK, "#game_score_axis_point" );
|
||||
else
|
||||
{
|
||||
char buf[8];
|
||||
Q_snprintf( buf, sizeof(buf), "%d", AxisPoints );
|
||||
UTIL_ClientPrintAll( HUD_PRINTTALK, "#game_score_axis_points", buf );
|
||||
}
|
||||
}
|
||||
GetGlobalTeam(TEAM_AXIS)->AddScore( AxisPoints );
|
||||
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "dod_tick_points" );
|
||||
|
||||
if ( event )
|
||||
{
|
||||
event->SetInt( "team", TEAM_AXIS );
|
||||
event->SetInt( "score", AxisPoints );
|
||||
event->SetInt( "totalscore", GetGlobalTeam(TEAM_AXIS)->GetScore() );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
}
|
||||
|
||||
// the next time we'll give points
|
||||
m_fGivePointsTime = gpGlobals->curtime + mp_tickpointinterval.GetInt();
|
||||
}
|
||||
|
||||
// If we call this from dod_control_point, this function should never
|
||||
// trigger a win. but we'll leave it here just incase.
|
||||
CheckWinConditions();
|
||||
|
||||
// the next time we 'think'
|
||||
SetContextThink( &CControlPointMaster::CPMThink, gpGlobals->curtime + 0.2, FLAGS_CONTEXT );
|
||||
}
|
||||
|
||||
void CControlPointMaster::CheckWinConditions( void )
|
||||
{
|
||||
// ============
|
||||
// Check that the points aren't all held by one team
|
||||
// if they are this will reset the round
|
||||
// and will reset all the points
|
||||
// ============
|
||||
switch( TeamOwnsAllPoints() )
|
||||
{
|
||||
case TEAM_ALLIES: //allies own all
|
||||
{
|
||||
TeamWins( TEAM_ALLIES );
|
||||
}
|
||||
break;
|
||||
case TEAM_AXIS: //axis owns all
|
||||
{
|
||||
TeamWins( TEAM_AXIS );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CControlPointMaster::InputRoundInit( inputdata_t &input )
|
||||
{
|
||||
//clear out old control points
|
||||
m_ControlPoints.RemoveAll();
|
||||
|
||||
//find the control points
|
||||
|
||||
//if successful, do CPMThink
|
||||
if( FindControlPoints() )
|
||||
{
|
||||
SetContextThink( &CControlPointMaster::CPMThink, gpGlobals->curtime + 0.1, FLAGS_CONTEXT );
|
||||
}
|
||||
|
||||
//init the ClientAreas
|
||||
int index = 0;
|
||||
|
||||
CBaseEntity *pEnt = gEntList.FindEntityByClassname( NULL, "dod_capture_area" );
|
||||
while( pEnt )
|
||||
{
|
||||
CAreaCapture *pArea = (CAreaCapture *)pEnt;
|
||||
Assert( pArea );
|
||||
pArea->area_SetIndex( index );
|
||||
index++;
|
||||
|
||||
pEnt = gEntList.FindEntityByClassname( pEnt, "dod_capture_area" );
|
||||
}
|
||||
|
||||
g_pObjectiveResource->ResetControlPoints();
|
||||
}
|
||||
|
||||
void CControlPointMaster::FireTeamWinOutput( int iWinningTeam )
|
||||
{
|
||||
switch( iWinningTeam )
|
||||
{
|
||||
case TEAM_ALLIES:
|
||||
m_AlliesWinOutput.FireOutput(this,this);
|
||||
break;
|
||||
case TEAM_AXIS:
|
||||
m_AxisWinOutput.FireOutput(this,this);
|
||||
break;
|
||||
default:
|
||||
Assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CControlPointMaster::TeamWins( int iWinningTeam )
|
||||
{
|
||||
DODGameRules()->SetWinningTeam( iWinningTeam );
|
||||
|
||||
FireTeamWinOutput( iWinningTeam );
|
||||
}
|
||||
|
||||
void CControlPointMaster::BecomeActive( void )
|
||||
{
|
||||
Assert( m_bDisabled );
|
||||
m_bDisabled = false;
|
||||
}
|
||||
|
||||
void CControlPointMaster::BecomeInactive( void )
|
||||
{
|
||||
Assert( !m_bDisabled );
|
||||
m_bDisabled = true;
|
||||
}
|
||||
|
||||
int CControlPointMaster::GetPointOwner( int point )
|
||||
{
|
||||
Assert( point >= 0 );
|
||||
Assert( point < MAX_CONTROL_POINTS );
|
||||
|
||||
CControlPoint *pPoint = m_ControlPoints[point];
|
||||
|
||||
if( pPoint )
|
||||
{
|
||||
return pPoint->GetOwner();
|
||||
}
|
||||
else
|
||||
return TEAM_UNASSIGNED;
|
||||
}
|
||||
|
||||
// TeamOwnsAllPoints
|
||||
// =================
|
||||
// This function returns the team that owns all
|
||||
// the cap points. if its not the case that one
|
||||
// team owns them all, it returns 0
|
||||
|
||||
// New - cps are now broken into groups.
|
||||
// A team can win by owning all flags within a single group.
|
||||
|
||||
// Can be passed an overriding team. If this is not null, the passed team
|
||||
// number will be used for that cp. Used to predict if that CP changing would
|
||||
// win the game.
|
||||
|
||||
int CControlPointMaster::TeamOwnsAllPoints( CControlPoint *pOverridePoint /* = NULL */, int iOverrideNewTeam /* = TEAM_UNASSIGNED */ )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
int iWinningTeam[MAX_CONTROL_POINT_GROUPS];
|
||||
|
||||
for( i=0;i<MAX_CONTROL_POINT_GROUPS;i++ )
|
||||
{
|
||||
iWinningTeam[i] = TEAM_INVALID;
|
||||
}
|
||||
|
||||
// if TEAM_INVALID, haven't found a flag for this group yet
|
||||
// if TEAM_UNASSIGNED, the group is still being contested
|
||||
|
||||
// for each control point
|
||||
for( i=0;i<m_ControlPoints.Count();i++ )
|
||||
{
|
||||
int group = m_ControlPoints[i]->GetCPGroup();
|
||||
int owner = m_ControlPoints[i]->GetOwner();
|
||||
|
||||
if ( pOverridePoint == m_ControlPoints[i] )
|
||||
{
|
||||
owner = iOverrideNewTeam;
|
||||
}
|
||||
|
||||
// the first one we find in this group, set the win to true
|
||||
if ( iWinningTeam[group] == TEAM_INVALID )
|
||||
{
|
||||
iWinningTeam[group] = owner;
|
||||
}
|
||||
// unassigned means this group is already contested, move on
|
||||
else if ( iWinningTeam[group] == TEAM_UNASSIGNED )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// if we find another one in the group that isn't the same owner, set the win to false
|
||||
else if ( owner != iWinningTeam[group] )
|
||||
{
|
||||
iWinningTeam[group] = TEAM_UNASSIGNED;
|
||||
}
|
||||
}
|
||||
|
||||
// report the first win we find as the winner
|
||||
for ( i=0;i<MAX_CONTROL_POINT_GROUPS;i++ )
|
||||
{
|
||||
if ( iWinningTeam[i] == TEAM_ALLIES || iWinningTeam[i] == TEAM_AXIS )
|
||||
return iWinningTeam[i];
|
||||
}
|
||||
|
||||
// no wins yet
|
||||
return TEAM_UNASSIGNED;
|
||||
}
|
||||
|
||||
// an advantage flag is a flag that we've taken that didn't initially
|
||||
// belong to our team
|
||||
int CControlPointMaster::CountAdvantageFlags( int team )
|
||||
{
|
||||
int numFlags = 0;
|
||||
|
||||
unsigned int i;
|
||||
for( i = 0;i<m_ControlPoints.Count();i++ )
|
||||
{
|
||||
CControlPoint *pPoint = m_ControlPoints[i];
|
||||
|
||||
if ( pPoint->GetOwner() != pPoint->GetDefaultOwner() )
|
||||
{
|
||||
if ( pPoint->GetOwner() == team )
|
||||
{
|
||||
// we own a flag we didn't initially
|
||||
numFlags++;
|
||||
}
|
||||
else //
|
||||
{
|
||||
// the enemy owns one of our flags
|
||||
numFlags--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return numFlags;
|
||||
}
|
||||
|
||||
void CControlPointMaster::InputAddTimerSeconds( inputdata_t &inputdata )
|
||||
{
|
||||
DODGameRules()->AddTimerSeconds( inputdata.value.Int() );
|
||||
}
|
||||
|
||||
void CControlPointMaster::GetTimerData( int &iTimerSeconds, int &iTimerWinTeam )
|
||||
{
|
||||
iTimerSeconds = m_iTimerLength;
|
||||
iTimerWinTeam = m_iTimerTeam;
|
||||
}
|
||||
|
||||
bool CControlPointMaster::WouldNewCPOwnerWinGame( CControlPoint *pPoint, int iNewOwner )
|
||||
{
|
||||
return ( TeamOwnsAllPoints( pPoint, iNewOwner ) == iNewOwner );
|
||||
}
|
||||
|
||||
int CControlPointMaster::GetNumPoints( void )
|
||||
{
|
||||
return m_ControlPoints.Count();
|
||||
}
|
||||
|
||||
CControlPoint *CControlPointMaster::GetCPByIndex( int index )
|
||||
{
|
||||
CControlPoint *pPoint = NULL;
|
||||
|
||||
if ( index >= 0 && index < (int)m_ControlPoints.Count() )
|
||||
{
|
||||
pPoint = m_ControlPoints[index];
|
||||
}
|
||||
|
||||
return pPoint;
|
||||
}
|
||||
|
||||
// custom scoring entity
|
||||
BEGIN_DATADESC( CDODCustomScoring )
|
||||
DEFINE_INPUTFUNC( FIELD_INTEGER, "GiveTickPoints", InputGivePoints ),
|
||||
|
||||
DEFINE_KEYFIELD( m_iPointTeam, FIELD_INTEGER, "TeamNum" ),
|
||||
DEFINE_KEYFIELD( m_iTickLength, FIELD_INTEGER, "point_give_delay" ),
|
||||
DEFINE_KEYFIELD( m_iPointsToGive, FIELD_INTEGER, "point_give_amount" ),
|
||||
DEFINE_KEYFIELD( m_iNumPointGives, FIELD_INTEGER, "point_give_max_times" ),
|
||||
|
||||
DEFINE_THINKFUNC( PointsThink ),
|
||||
END_DATADESC()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( dod_scoring, CDODCustomScoring );
|
||||
222
game/server/dod/dod_control_point_master.h
Normal file
222
game/server/dod/dod_control_point_master.h
Normal file
@@ -0,0 +1,222 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_CONTROL_POINT_MASTER_H
|
||||
#define DOD_CONTROL_POINT_MASTER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "utlmap.h"
|
||||
#include "dod_shareddefs.h"
|
||||
#include "dod_team.h"
|
||||
#include "dod_gamerules.h"
|
||||
#include "dod_control_point.h"
|
||||
#include "dod_area_capture.h"
|
||||
#include "dod_objective_resource.h"
|
||||
#include "GameEventListener.h"
|
||||
|
||||
// ====================
|
||||
// Control Point Master
|
||||
// ====================
|
||||
// One ControlPointMaster is spawned per level. Shortly after spawning it detects all the Control
|
||||
// points in the map and puts them into the m_ControlPoints. From there it detects the state
|
||||
// where all points are captured and resets them if necessary It gives points every time interval to
|
||||
// the owners of the points
|
||||
// ====================
|
||||
|
||||
#define TIMER_CONTEXT "TIMER_CONTEXT"
|
||||
#define FLAGS_CONTEXT "FLAGS_CONTEXT"
|
||||
|
||||
class CControlPointMaster : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CControlPointMaster, CBaseEntity );
|
||||
|
||||
CControlPointMaster();
|
||||
|
||||
virtual void Spawn( void );
|
||||
virtual bool KeyValue( const char *szKeyName, const char *szValue );
|
||||
|
||||
int GetNumPoints( void );
|
||||
int GetPointOwner( int point );
|
||||
void Reset( void );
|
||||
|
||||
void RoundRespawn( void );
|
||||
|
||||
int CountAdvantageFlags( int team );
|
||||
|
||||
bool IsActive( void ) { return ( m_bDisabled == false ); }
|
||||
|
||||
bool IsUsingRoundTimer( void ) { return m_bUseTimer; }
|
||||
void GetTimerData( int &iTimerSeconds, int &iTimerWinTeam );
|
||||
|
||||
void FireTeamWinOutput( int iWinningTeam );
|
||||
|
||||
void CheckWinConditions( void );
|
||||
|
||||
bool WouldNewCPOwnerWinGame( CControlPoint *pPoint, int iNewOwner );
|
||||
|
||||
CControlPoint *GetCPByIndex( int index );
|
||||
|
||||
private:
|
||||
void BecomeActive( void );
|
||||
void BecomeInactive( void );
|
||||
|
||||
void EXPORT CPMThink( void );
|
||||
|
||||
int TeamOwnsAllPoints( CControlPoint *pOverridePoint = NULL, int iOverrideNewTeam = TEAM_UNASSIGNED );
|
||||
|
||||
void TeamWins( int team );
|
||||
|
||||
bool FindControlPoints( void ); //look in the map to find active control points
|
||||
|
||||
void InputAddTimerSeconds( inputdata_t &inputdata );
|
||||
|
||||
CUtlMap<int, CControlPoint *> m_ControlPoints;
|
||||
|
||||
bool m_bFoundPoints; //true when the control points have been found and the array is initialized
|
||||
|
||||
float m_fGivePointsTime; //the time at which we give points for holding control points
|
||||
|
||||
DECLARE_DATADESC();
|
||||
|
||||
bool m_bDisabled; //is this CPM active or not
|
||||
void InputEnable( inputdata_t &inputdata ) { BecomeInactive(); }
|
||||
void InputDisable( inputdata_t &inputdata ) { BecomeActive(); }
|
||||
|
||||
void InputRoundInit( inputdata_t &inputdata );
|
||||
void InputRoundStart( inputdata_t &inputdata );
|
||||
|
||||
bool m_bUseTimer;
|
||||
int m_iTimerTeam;
|
||||
int m_iTimerLength;
|
||||
|
||||
COutputEvent m_AlliesWinOutput;
|
||||
COutputEvent m_AxisWinOutput;
|
||||
};
|
||||
|
||||
class CDODCustomScoring : public CBaseEntity, public CGameEventListener
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODCustomScoring, CBaseEntity );
|
||||
|
||||
DECLARE_DATADESC();
|
||||
|
||||
CDODCustomScoring()
|
||||
{
|
||||
ListenForGameEvent( "dod_round_win" );
|
||||
ListenForGameEvent( "dod_round_active" );
|
||||
}
|
||||
|
||||
virtual void Spawn( void )
|
||||
{
|
||||
Assert( m_iPointTeam == TEAM_ALLIES || m_iPointTeam == TEAM_AXIS );
|
||||
}
|
||||
|
||||
virtual void FireGameEvent( IGameEvent *event )
|
||||
{
|
||||
const char *eventName = event->GetName();
|
||||
|
||||
if ( !Q_strcmp( eventName, "dod_round_win" ) )
|
||||
{
|
||||
int team = event->GetInt( "team" );
|
||||
if ( team == m_iPointTeam )
|
||||
{
|
||||
GiveRemainingPoints();
|
||||
}
|
||||
|
||||
// stop giving points, round is over
|
||||
SetThink( NULL ); // think no more!
|
||||
}
|
||||
else if ( !Q_strcmp( eventName, "dod_round_active" ) )
|
||||
{
|
||||
StartGivingPoints();
|
||||
}
|
||||
}
|
||||
|
||||
// Needs to be activated by gamerules
|
||||
void StartGivingPoints( void )
|
||||
{
|
||||
if ( m_iNumPointGives <= 0 )
|
||||
return;
|
||||
|
||||
if ( m_iPointsToGive <= 0 )
|
||||
return;
|
||||
|
||||
m_iRemainingPoints = m_iNumPointGives * m_iPointsToGive;
|
||||
|
||||
SetThink( &CDODCustomScoring::PointsThink );
|
||||
SetNextThink( gpGlobals->curtime + m_iTickLength );
|
||||
}
|
||||
|
||||
// Give this team all the points that they would have gotten had we continued
|
||||
void GiveRemainingPoints( void )
|
||||
{
|
||||
GivePoints( m_iRemainingPoints );
|
||||
}
|
||||
|
||||
// input to give tick points to our team
|
||||
void InputGivePoints( inputdata_t &inputdata )
|
||||
{
|
||||
int iPoints = inputdata.value.Int();
|
||||
GetGlobalTeam(m_iPointTeam)->AddScore( MAX( iPoints, 0 ) );
|
||||
}
|
||||
|
||||
// accessor for our point team
|
||||
int GetPointTeam( void )
|
||||
{
|
||||
return m_iPointTeam;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void GivePoints( int points )
|
||||
{
|
||||
GetGlobalTeam(m_iPointTeam)->AddScore( MAX( points, 0 ) );
|
||||
m_iRemainingPoints -= points;
|
||||
|
||||
if ( points > 0 )
|
||||
{
|
||||
if ( points == 1 )
|
||||
{
|
||||
UTIL_ClientPrintAll( HUD_PRINTTALK, "#game_score_allie_point" );
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[8];
|
||||
Q_snprintf( buf, sizeof(buf), "%d", points );
|
||||
UTIL_ClientPrintAll( HUD_PRINTTALK, "#game_score_allie_points", buf );
|
||||
}
|
||||
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "dod_tick_points" );
|
||||
|
||||
if ( event )
|
||||
{
|
||||
event->SetInt( "team", m_iPointTeam );
|
||||
event->SetInt( "score", points );
|
||||
event->SetInt( "totalscore", GetGlobalTeam(m_iPointTeam)->GetScore() );
|
||||
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointsThink( void )
|
||||
{
|
||||
GivePoints( m_iPointsToGive );
|
||||
|
||||
SetNextThink( gpGlobals->curtime + m_iTickLength );
|
||||
}
|
||||
|
||||
int m_iPointTeam; // team to give points to
|
||||
int m_iPointsToGive; // points to give per tick
|
||||
int m_iRemainingPoints; // total number of points we have left to give
|
||||
int m_iTickLength; // time between point gives
|
||||
int m_iNumPointGives; // number of times we're planning on giving out points
|
||||
};
|
||||
|
||||
#endif //DOD_CONTROL_POINT_MASTER_H
|
||||
90
game/server/dod/dod_cvars.cpp
Normal file
90
game/server/dod/dod_cvars.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_cvars.h"
|
||||
|
||||
|
||||
/*
|
||||
// Gameplay
|
||||
cvar_t cvar_forcechasecam = {"mp_forcechasecam", "1", FCVAR_SERVER };
|
||||
cvar_t cvar_forcecamera = {"mp_forcecamera", "1", FCVAR_SERVER };
|
||||
|
||||
|
||||
// Clan cvars
|
||||
cvar_t cvar_waveTime = {"mp_clan_respawntime", "0", FCVAR_SERVER };
|
||||
cvar_t cvar_clanRestartRound = {"mp_clan_restartround", "0", FCVAR_SERVER };
|
||||
cvar_t cvar_clanReadyRestart = {"mp_clan_readyrestart", "0", FCVAR_SERVER };
|
||||
cvar_t cvar_clanMatchWarmup = {"mp_clan_match_warmup", "0", FCVAR_SERVER };
|
||||
cvar_t cvar_clanMatch = {"mp_clan_match", "0", FCVAR_SERVER };
|
||||
cvar_t cvar_clanTimer = {"mp_clan_timer", "20", FCVAR_SERVER };
|
||||
cvar_t cvar_clanScoring = {"mp_clan_scoring", "0", FCVAR_SERVER };
|
||||
cvar_t cvar_clanScoringValuesAllies = {"mp_clan_scoring_values_allies", "111111", FCVAR_SERVER };
|
||||
cvar_t cvar_clanScoringValuesAxis = {"mp_clan_scoring_values_axis", "111111", FCVAR_SERVER };
|
||||
cvar_t cvar_clanScoringDelay = {"mp_clan_scoring_delay", "60", FCVAR_SERVER };
|
||||
cvar_t cvar_clanReadyString = {"mp_clan_ready_signal", "ready", FCVAR_SERVER };
|
||||
cvar_t cvar_clanScoringBonusAllies = {"mp_clan_scoring_bonus_allies", "-1", FCVAR_SERVER };
|
||||
cvar_t cvar_clanScoringBonusAxis = {"mp_clan_scoring_bonus_axis", "-1", FCVAR_SERVER };
|
||||
|
||||
|
||||
// Other Server Cvars ( Not FCVAR_SERVER! )
|
||||
//===================
|
||||
cvar_t cvar_nummapmarkers = {"mp_nummapmarkers", "1" };
|
||||
cvar_t cvar_markerstaytime = {"mp_markerstaytime", "30"};
|
||||
|
||||
cvar_t cvar_teamSpectators = {"mp_allowspectators", "1" };
|
||||
cvar_t cvar_logScores = {"mp_log_scores", "0" };
|
||||
cvar_t cvar_logScoresDelay = {"mp_log_scores_delay", "60"};
|
||||
cvar_t cvar_tkPenalty = {"mp_tkpenalty", "6" };
|
||||
* now mp_limitteams * cvar_t cvar_teamOver = {"mp_teamlimit", "2" };
|
||||
cvar_t cvar_deathMsg = {"mp_deathmsg", "1" };
|
||||
cvar_t cvar_chatMsg = {"mp_chatmsg", "1" };
|
||||
cvar_t cvar_alliesclasses = {"mp_alliesclasses", "-1"};
|
||||
cvar_t cvar_axisclasses = {"mp_axisclasses", "-1"};
|
||||
*/
|
||||
|
||||
ConVar mp_winlimit( "mp_winlimit", "0", FCVAR_REPLICATED | FCVAR_NOTIFY, "Max score one team can reach before server changes maps", true, 0, false, 0 );
|
||||
|
||||
ConVar mp_clan_restartround( "mp_clan_restartround", "0", FCVAR_GAMEDLL, "If non-zero, the round will restart in the specified number of seconds" );
|
||||
|
||||
ConVar mp_limitteams(
|
||||
"mp_limitteams",
|
||||
"2",
|
||||
FCVAR_REPLICATED,
|
||||
"Max # of players 1 team can have over another",
|
||||
true, 1, // min value
|
||||
true, 20 // max value
|
||||
);
|
||||
|
||||
ConVar mp_autokick(
|
||||
"mp_autokick",
|
||||
"0",
|
||||
FCVAR_REPLICATED,
|
||||
"Kick idle/team-killing players" );
|
||||
|
||||
ConVar mp_combinemglimits(
|
||||
"mp_combinemglimits",
|
||||
"0",
|
||||
FCVAR_REPLICATED,
|
||||
"Set to 1 to combine the class limit cvars for mg34 and mg42. New limit is sum of two" );
|
||||
|
||||
// Class limit cvars
|
||||
// welcome to ugly-town
|
||||
|
||||
ConVar mp_limitAlliesRifleman( "mp_limit_allies_rifleman", "-1", FCVAR_REPLICATED, "Class limit for team: Allies class: Rifleman" );
|
||||
ConVar mp_limitAlliesAssault( "mp_limit_allies_assault", "-1", FCVAR_REPLICATED, "Class limit for team: Allies class: Assault" );
|
||||
ConVar mp_limitAlliesSupport( "mp_limit_allies_support", "-1", FCVAR_REPLICATED, "Class limit for team: Allies class: Support" );
|
||||
ConVar mp_limitAlliesSniper( "mp_limit_allies_sniper", "-1", FCVAR_REPLICATED, "Class limit for team: Allies class: Sniper" );
|
||||
ConVar mp_limitAlliesMachinegun( "mp_limit_allies_mg", "-1", FCVAR_REPLICATED, "Class limit for team: Allies class: Machinegunner" );
|
||||
ConVar mp_limitAlliesRocket( "mp_limit_allies_rocket", "-1", FCVAR_REPLICATED, "Class limit for team: Allies class: Rocket" );
|
||||
|
||||
ConVar mp_limitAxisRifleman( "mp_limit_axis_rifleman", "-1", FCVAR_REPLICATED, "Class limit for team: Axis class: Rifleman" );
|
||||
ConVar mp_limitAxisAssault( "mp_limit_axis_assault", "-1", FCVAR_REPLICATED, "Class limit for team: Axis class: Assault" );
|
||||
ConVar mp_limitAxisSupport( "mp_limit_axis_support", "-1", FCVAR_REPLICATED, "Class limit for team: Axis class: Support" );
|
||||
ConVar mp_limitAxisSniper( "mp_limit_axis_sniper", "-1", FCVAR_REPLICATED, "Class limit for team: Axis class: Sniper" );
|
||||
ConVar mp_limitAxisMachinegun( "mp_limit_axis_mg", "-1", FCVAR_REPLICATED, "Class limit for team: Axis class: Machinegunner" );
|
||||
ConVar mp_limitAxisRocket( "mp_limit_axis_rocket", "-1", FCVAR_REPLICATED, "Class limit for team: Axis class: Rocket" );
|
||||
42
game/server/dod/dod_cvars.h
Normal file
42
game/server/dod/dod_cvars.h
Normal file
@@ -0,0 +1,42 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_CVARS_H
|
||||
#define DOD_CVARS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define MAX_INTERMISSION_TIME 120
|
||||
|
||||
extern ConVar mp_limitteams;
|
||||
extern ConVar mp_autokick;
|
||||
|
||||
extern ConVar mp_clan_restartround;
|
||||
extern ConVar mp_clan_readyrestart;
|
||||
extern ConVar mp_clan_ready_signal;
|
||||
extern ConVar mp_warmup_time;
|
||||
extern ConVar mp_combinemglimits;
|
||||
extern ConVar mp_restartwarmup;
|
||||
extern ConVar mp_cancelwarmup;
|
||||
extern ConVar mp_winlimit;
|
||||
|
||||
extern ConVar mp_limitAlliesRifleman;
|
||||
extern ConVar mp_limitAlliesAssault;
|
||||
extern ConVar mp_limitAlliesSupport;
|
||||
extern ConVar mp_limitAlliesSniper;
|
||||
extern ConVar mp_limitAlliesMachinegun;
|
||||
extern ConVar mp_limitAlliesRocket;
|
||||
|
||||
extern ConVar mp_limitAxisRifleman;
|
||||
extern ConVar mp_limitAxisAssault;
|
||||
extern ConVar mp_limitAxisSupport;
|
||||
extern ConVar mp_limitAxisSniper;
|
||||
extern ConVar mp_limitAxisMachinegun;
|
||||
extern ConVar mp_limitAxisRocket;
|
||||
|
||||
#endif //DOD_CVARS_H
|
||||
547
game/server/dod/dod_eventlog.cpp
Normal file
547
game/server/dod/dod_eventlog.cpp
Normal file
@@ -0,0 +1,547 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "../EventLog.h"
|
||||
#include "team.h"
|
||||
#include "KeyValues.h"
|
||||
#include "dod_shareddefs.h"
|
||||
#include "dod_team.h"
|
||||
|
||||
#define LOG_DETAIL_ENEMY_ATTACKS 1
|
||||
#define LOG_DETAIL_TEAMMATE_ATTACKS 2
|
||||
|
||||
ConVar mp_logdetail( "mp_logdetail", "0", FCVAR_NONE, "Logs attacks. Values are: 0=off, 1=enemy, 2=teammate, 3=both)", true, 0.0f, true, 3.0f );
|
||||
|
||||
class CDODEventLog : public CEventLog
|
||||
{
|
||||
private:
|
||||
typedef CEventLog BaseClass;
|
||||
|
||||
public:
|
||||
bool PrintEvent( IGameEvent * event ) // override virtual function
|
||||
{
|
||||
if ( !PrintDodEvent( event ) ) // allow DOD to override logging
|
||||
{
|
||||
return BaseClass::PrintEvent( event );
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Init()
|
||||
{
|
||||
BaseClass::Init();
|
||||
|
||||
ListenForGameEvent( "player_death" );
|
||||
ListenForGameEvent( "player_hurt" );
|
||||
ListenForGameEvent( "player_changeclass" );
|
||||
ListenForGameEvent( "dod_warmup_begins" );
|
||||
ListenForGameEvent( "dod_warmup_ends" );
|
||||
ListenForGameEvent( "dod_round_start" );
|
||||
ListenForGameEvent( "dod_restart_round" );
|
||||
ListenForGameEvent( "dod_ready_restart" );
|
||||
ListenForGameEvent( "dod_allies_ready" );
|
||||
ListenForGameEvent( "dod_axis_ready" );
|
||||
ListenForGameEvent( "dod_round_restart_seconds" );
|
||||
ListenForGameEvent( "dod_team_scores" );
|
||||
ListenForGameEvent( "dod_round_win" );
|
||||
ListenForGameEvent( "dod_tick_points" );
|
||||
ListenForGameEvent( "dod_game_over" );
|
||||
ListenForGameEvent( "dod_point_captured" );
|
||||
ListenForGameEvent( "dod_capture_blocked" );
|
||||
ListenForGameEvent( "dod_bomb_planted" );
|
||||
ListenForGameEvent( "dod_bomb_exploded" );
|
||||
ListenForGameEvent( "dod_bomb_defused" );
|
||||
ListenForGameEvent( "dod_kill_planter" );
|
||||
ListenForGameEvent( "dod_kill_defuser" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
bool PrintDodEvent( IGameEvent * event ) // print Mod specific logs
|
||||
{
|
||||
const char *eventName = event->GetName();
|
||||
|
||||
if ( !Q_strncmp( eventName, "server_", strlen("server_")) )
|
||||
{
|
||||
return false; // ignore server_ messages
|
||||
}
|
||||
|
||||
if ( FStrEq( eventName, "player_death" ) )
|
||||
{
|
||||
const int userid = event->GetInt( "userid" );
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
|
||||
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const int attackerid = event->GetInt("attacker" );
|
||||
const char *weapon = event->GetString( "weapon" );
|
||||
CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
|
||||
|
||||
if ( pPlayer == pAttacker )
|
||||
{
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\"\n",
|
||||
pPlayer->GetPlayerName(),
|
||||
userid,
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pPlayer->GetTeam()->GetName(),
|
||||
weapon
|
||||
);
|
||||
}
|
||||
else if ( pAttacker )
|
||||
{
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\"\n",
|
||||
pAttacker->GetPlayerName(),
|
||||
attackerid,
|
||||
pAttacker->GetNetworkIDString(),
|
||||
pAttacker->GetTeam()->GetName(),
|
||||
pPlayer->GetPlayerName(),
|
||||
userid,
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pPlayer->GetTeam()->GetName(),
|
||||
weapon
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// killed by the world
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"world\"\n",
|
||||
pPlayer->GetPlayerName(),
|
||||
userid,
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pPlayer->GetTeam()->GetName()
|
||||
);
|
||||
}
|
||||
|
||||
// Domination and Revenge
|
||||
// pAttacker //int attackerid = engine->GetPlayerForUserID( event->GetInt( "attacker" ) );
|
||||
// pPlayer //int userid = engine->GetPlayerForUserID( event->GetInt( "userid" ) );
|
||||
|
||||
if ( event->GetInt( "dominated" ) > 0 && pAttacker )
|
||||
{
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"domination\" against \"%s<%i><%s><%s>\"\n",
|
||||
pAttacker->GetPlayerName(),
|
||||
attackerid,
|
||||
pAttacker->GetNetworkIDString(),
|
||||
pAttacker->GetTeam()->GetName(),
|
||||
pPlayer->GetPlayerName(),
|
||||
userid,
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pPlayer->GetTeam()->GetName()
|
||||
);
|
||||
}
|
||||
if ( event->GetInt( "revenge" ) > 0 && pAttacker )
|
||||
{
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"revenge\" against \"%s<%i><%s><%s>\"\n",
|
||||
pAttacker->GetPlayerName(),
|
||||
attackerid,
|
||||
pAttacker->GetNetworkIDString(),
|
||||
pAttacker->GetTeam()->GetName(),
|
||||
pPlayer->GetPlayerName(),
|
||||
userid,
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pPlayer->GetTeam()->GetName()
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "player_hurt" ) )
|
||||
{
|
||||
const int userid = event->GetInt( "userid" );
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
|
||||
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const int attackerid = event->GetInt("attacker" );
|
||||
const char *weapon = event->GetString( "weapon" );
|
||||
CBasePlayer *pAttacker = UTIL_PlayerByUserId( attackerid );
|
||||
if ( !pAttacker )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isTeamAttack = ( (pPlayer->GetTeamNumber() == pAttacker->GetTeamNumber() ) && (pPlayer != pAttacker) );
|
||||
int detail = mp_logdetail.GetInt();
|
||||
if ( ( isTeamAttack && ( detail & LOG_DETAIL_TEAMMATE_ATTACKS ) ) ||
|
||||
( !isTeamAttack && ( detail & LOG_DETAIL_ENEMY_ATTACKS ) ) )
|
||||
{
|
||||
int hitgroup = event->GetInt( "hitgroup" );
|
||||
const char *hitgroupStr = "GENERIC";
|
||||
switch ( hitgroup )
|
||||
{
|
||||
case HITGROUP_GENERIC:
|
||||
hitgroupStr = "generic";
|
||||
break;
|
||||
case HITGROUP_HEAD:
|
||||
hitgroupStr = "head";
|
||||
break;
|
||||
case HITGROUP_CHEST:
|
||||
hitgroupStr = "chest";
|
||||
break;
|
||||
case HITGROUP_STOMACH:
|
||||
hitgroupStr = "stomach";
|
||||
break;
|
||||
case HITGROUP_LEFTARM:
|
||||
hitgroupStr = "left arm";
|
||||
break;
|
||||
case HITGROUP_RIGHTARM:
|
||||
hitgroupStr = "right arm";
|
||||
break;
|
||||
case HITGROUP_LEFTLEG:
|
||||
hitgroupStr = "left leg";
|
||||
break;
|
||||
case HITGROUP_RIGHTLEG:
|
||||
hitgroupStr = "right leg";
|
||||
break;
|
||||
}
|
||||
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" attacked \"%s<%i><%s><%s>\" with \"%s\" (damage \"%d\") (health \"%d\") (hitgroup \"%s\")\n",
|
||||
pAttacker->GetPlayerName(),
|
||||
attackerid,
|
||||
pAttacker->GetNetworkIDString(),
|
||||
pAttacker->GetTeam()->GetName(),
|
||||
pPlayer->GetPlayerName(),
|
||||
userid,
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pPlayer->GetTeam()->GetName(),
|
||||
weapon,
|
||||
event->GetInt( "damage" ),
|
||||
event->GetInt( "health" ),
|
||||
hitgroupStr );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "player_changeclass" ) )
|
||||
{
|
||||
const int userid = event->GetInt( "userid" );
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByUserId( userid );
|
||||
|
||||
if ( !pPlayer )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int iClass = event->GetInt("class");
|
||||
int iTeam = pPlayer->GetTeamNumber();
|
||||
|
||||
if ( iTeam != TEAM_ALLIES && iTeam != TEAM_AXIS )
|
||||
return true;
|
||||
|
||||
CDODTeam *pTeam = GetGlobalDODTeam( iTeam );
|
||||
|
||||
if ( iClass == PLAYERCLASS_RANDOM )
|
||||
{
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed role to \"Random\"\n",
|
||||
pPlayer->GetPlayerName(),
|
||||
userid,
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pTeam->GetName()
|
||||
);
|
||||
}
|
||||
else if ( iClass < GetGlobalDODTeam(iTeam)->GetNumPlayerClasses() )
|
||||
{
|
||||
const CDODPlayerClassInfo &pInfo = GetGlobalDODTeam(iTeam)->GetPlayerClassInfo( iClass );
|
||||
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed role to \"%s\"\n",
|
||||
pPlayer->GetPlayerName(),
|
||||
userid,
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pTeam->GetName(),
|
||||
pInfo.m_szPrintName
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_warmup_begins" ) )
|
||||
{
|
||||
UTIL_LogPrintf( "World triggered \"Warmup_Begin\"\n" );
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_warmup_ends" ) )
|
||||
{
|
||||
UTIL_LogPrintf( "World triggered \"Warmup_Ends\"\n" );
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_round_start" ) )
|
||||
{
|
||||
UTIL_LogPrintf("World triggered \"Round_Start\"\n");
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_restart_round" ) )
|
||||
{
|
||||
UTIL_LogPrintf("World triggered \"Round_Restart\"\n");
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_ready_restart" ) )
|
||||
{
|
||||
UTIL_LogPrintf( "World triggered \"Ready_Restart_Begin\"\n" );
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_allies_ready" ) )
|
||||
{
|
||||
UTIL_LogPrintf("World triggered \"Allies Ready\"\n");
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_axis_ready" ) )
|
||||
{
|
||||
UTIL_LogPrintf("World triggered \"Axis Ready\"\n");
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_round_restart_seconds" ) )
|
||||
{
|
||||
UTIL_LogPrintf( "World triggered \"Round_Restart_In\" (delay \"%d\")\n", event->GetInt("seconds") );
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_team_scores" ) )
|
||||
{
|
||||
int iAlliesRoundsWon = event->GetInt( "allies_caps" );
|
||||
int iAlliesTickPoints = event->GetInt( "allies_tick" );
|
||||
int iNumAllies = event->GetInt( "allies_players" );
|
||||
int iAxisRoundsWon = event->GetInt( "axis_caps" );
|
||||
int iAxisTickPoints = event->GetInt( "axis_tick" );
|
||||
int iNumAxis = event->GetInt( "axis_players" );
|
||||
|
||||
UTIL_LogPrintf( "Team \"Allies\" triggered \"team_scores\" (roundswon \"%d\") (tickpoints \"%d\") (numplayers \"%d\")\n", iAlliesRoundsWon, iAlliesTickPoints, iNumAllies );
|
||||
UTIL_LogPrintf( "Team \"Allies\" triggered \"team_scores\" (roundswon \"%d\") (tickpoints \"%d\") (numplayers \"%d\")\n", iAxisRoundsWon, iAxisTickPoints, iNumAxis );
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_round_win" ) )
|
||||
{
|
||||
CDODTeam *pTeam = GetGlobalDODTeam( event->GetInt( "team" ) );
|
||||
|
||||
UTIL_LogPrintf( "Team \"%s\" triggered \"round_win\" (rounds_won \"%d\") (numplayers \"%d\")\n",
|
||||
pTeam->GetName(),
|
||||
pTeam->GetRoundsWon(),
|
||||
pTeam->GetNumPlayers() );
|
||||
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_tick_points" ) )
|
||||
{
|
||||
CDODTeam *pTeam = GetGlobalDODTeam( event->GetInt( "team" ) );
|
||||
|
||||
int iScore = event->GetInt( "score" );
|
||||
int iTotalScore = event->GetInt( "totalscore" );
|
||||
|
||||
UTIL_LogPrintf( "Team \"%s\" triggered \"tick_score\" (score \"%i\") (totalscore \"%d\") (numplayers \"%d\")\n",
|
||||
pTeam->GetName(),
|
||||
iScore,
|
||||
iTotalScore,
|
||||
pTeam->GetNumPlayers() );
|
||||
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_game_over" ) )
|
||||
{
|
||||
UTIL_LogPrintf( "World triggered \"Game_Over\" reason \"%s\"\n", event->GetString( "reason" ) );
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_point_captured" ) )
|
||||
{
|
||||
// identifier of the area "cp" "cpname"
|
||||
int iPointIndex = event->GetInt( "cp" );
|
||||
const char *szPointName = event->GetString( "cpname" );
|
||||
|
||||
const char *szCappers = event->GetString( "cappers" );
|
||||
|
||||
int iNumCappers = Q_strlen( szCappers );
|
||||
|
||||
if ( iNumCappers <= 0 )
|
||||
return true;
|
||||
|
||||
//"Team "Allies" captured location "<3><#map_flag_2nd_axis>" with "2"
|
||||
// players (1 "Matt<UID><STEAMID><TEAM>") (2 "Player2<2><STEAMID><TEAM>")
|
||||
|
||||
char buf[512];
|
||||
|
||||
for ( int i=0;i<iNumCappers;i++ )
|
||||
{
|
||||
int iPlayerIndex = szCappers[i];
|
||||
|
||||
Assert( iPlayerIndex != '\0' && iPlayerIndex > 0 && iPlayerIndex < MAX_PLAYERS );
|
||||
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( iPlayerIndex );
|
||||
|
||||
if ( i == 0 )
|
||||
{
|
||||
Q_snprintf( buf, sizeof(buf), "Team \"%s\" triggered \"captured_loc\" (flagindex \"%d\") (flagname \"%s\") (numplayers \"%d\") ",
|
||||
pPlayer->GetTeam()->GetName(),
|
||||
iPointIndex,
|
||||
szPointName,
|
||||
iNumCappers );
|
||||
}
|
||||
|
||||
char playerBuf[256];
|
||||
Q_snprintf( playerBuf, sizeof(playerBuf), "(player \"%s<%i><%s><%s>\") ",
|
||||
pPlayer->GetPlayerName(),
|
||||
pPlayer->GetUserID(),
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pPlayer->GetTeam()->GetName() );
|
||||
|
||||
Q_strncat( buf, playerBuf, sizeof(buf), COPY_ALL_CHARACTERS );
|
||||
}
|
||||
|
||||
UTIL_LogPrintf( "%s\n", buf );
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_capture_blocked" ) )
|
||||
{
|
||||
int iPointIndex = event->GetInt( "cp" );
|
||||
const char *szPointName = event->GetString( "cpname" );
|
||||
|
||||
int iBlocker = event->GetInt( "blocker" );
|
||||
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( iBlocker );
|
||||
|
||||
if ( !pPlayer )
|
||||
return false;
|
||||
|
||||
// "Matt<2><UNKNOWN><Allies>" triggered "capblock" (flagindex "2") (flagname "#map_flag_2nd_axis")
|
||||
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"capblock\" (flagindex \"%d\") (flagname \"%s\")\n",
|
||||
pPlayer->GetPlayerName(),
|
||||
pPlayer->GetUserID(),
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pPlayer->GetTeam()->GetName(),
|
||||
iPointIndex,
|
||||
szPointName );
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_bomb_planted" ) )
|
||||
{
|
||||
int iPointIndex = event->GetInt( "cp" );
|
||||
const char *szPointName = event->GetString( "cpname" );
|
||||
|
||||
int iPlanter = event->GetInt( "userid" );
|
||||
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByUserId( iPlanter );
|
||||
|
||||
if ( !pPlayer )
|
||||
return false;
|
||||
|
||||
// "Matt<2><UNKNOWN><Allies>" triggered "bomb_plant" (flagindex "2") (flagname "#map_flag_2nd_axis")
|
||||
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"bomb_plant\" (flagindex \"%d\") (flagname \"%s\")\n",
|
||||
pPlayer->GetPlayerName(),
|
||||
pPlayer->GetUserID(),
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pPlayer->GetTeam()->GetName(),
|
||||
iPointIndex,
|
||||
szPointName );
|
||||
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_bomb_defused" ) )
|
||||
{
|
||||
int iPointIndex = event->GetInt( "cp" );
|
||||
const char *szPointName = event->GetString( "cpname" );
|
||||
|
||||
int iDefuser = event->GetInt( "userid" );
|
||||
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByUserId( iDefuser );
|
||||
|
||||
if ( !pPlayer )
|
||||
return false;
|
||||
|
||||
// "Matt<2><UNKNOWN><Allies>" triggered "bomb_defuse" (flagindex "2") (flagname "#map_flag_2nd_axis")
|
||||
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"bomb_defuse\" (flagindex \"%d\") (flagname \"%s\")\n",
|
||||
pPlayer->GetPlayerName(),
|
||||
pPlayer->GetUserID(),
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pPlayer->GetTeam()->GetName(),
|
||||
iPointIndex,
|
||||
szPointName );
|
||||
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_kill_planter" ) )
|
||||
{
|
||||
int iKiller = event->GetInt( "userid" );
|
||||
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByUserId( iKiller );
|
||||
|
||||
if ( !pPlayer )
|
||||
return false;
|
||||
|
||||
int iVictim = event->GetInt( "victimid" );
|
||||
|
||||
CBasePlayer *pVictim = UTIL_PlayerByUserId( iVictim );
|
||||
|
||||
if ( !pVictim )
|
||||
return false;
|
||||
|
||||
// "Matt<2><UNKNOWN><Allies>" triggered "kill_planter" against "Fred<3><UNKNOWN><Axis>"
|
||||
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"kill_planter\" against \"%s<%i><%s><%s>\"\n",
|
||||
pPlayer->GetPlayerName(),
|
||||
pPlayer->GetUserID(),
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pPlayer->GetTeam()->GetName(),
|
||||
pVictim->GetPlayerName(),
|
||||
pVictim->GetUserID(),
|
||||
pVictim->GetNetworkIDString(),
|
||||
pVictim->GetTeam()->GetName() );
|
||||
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_kill_defuser" ) )
|
||||
{
|
||||
int iKiller = event->GetInt( "userid" );
|
||||
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByUserId( iKiller );
|
||||
|
||||
if ( !pPlayer )
|
||||
return false;
|
||||
|
||||
int iVictim = event->GetInt( "victimid" );
|
||||
|
||||
CBasePlayer *pVictim = UTIL_PlayerByUserId( iVictim );
|
||||
|
||||
if ( !pVictim )
|
||||
return false;
|
||||
|
||||
// "Matt<2><UNKNOWN><Allies>" triggered "kill_defuser" against "Fred<3><UNKNOWN><Axis>"
|
||||
|
||||
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"kill_defuser\" against \"%s<%i><%s><%s>\"\n",
|
||||
pPlayer->GetPlayerName(),
|
||||
pPlayer->GetUserID(),
|
||||
pPlayer->GetNetworkIDString(),
|
||||
pPlayer->GetTeam()->GetName(),
|
||||
pVictim->GetPlayerName(),
|
||||
pVictim->GetUserID(),
|
||||
pVictim->GetNetworkIDString(),
|
||||
pVictim->GetTeam()->GetName() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CDODEventLog g_DODEventLog;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton access
|
||||
//-----------------------------------------------------------------------------
|
||||
IGameSystem* GameLogSystem()
|
||||
{
|
||||
return &g_DODEventLog;
|
||||
}
|
||||
|
||||
30
game/server/dod/dod_gameinterface.cpp
Normal file
30
game/server/dod/dod_gameinterface.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "gameinterface.h"
|
||||
#include "mapentities.h"
|
||||
#include "dod_gameinterface.h"
|
||||
|
||||
// -------------------------------------------------------------------------------------------- //
|
||||
// Mod-specific CServerGameClients implementation.
|
||||
// -------------------------------------------------------------------------------------------- //
|
||||
|
||||
void CServerGameClients::GetPlayerLimits( int& minplayers, int& maxplayers, int &defaultMaxPlayers ) const
|
||||
{
|
||||
minplayers = 2; // Force multiplayer.
|
||||
maxplayers = MAX_PLAYERS;
|
||||
defaultMaxPlayers = 32;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------- //
|
||||
// Mod-specific CServerGameDLL implementation.
|
||||
// -------------------------------------------------------------------------------------------- //
|
||||
|
||||
void CServerGameDLL::LevelInit_ParseAllEntities( const char *pMapEntities )
|
||||
{
|
||||
}
|
||||
|
||||
15
game/server/dod/dod_gameinterface.h
Normal file
15
game/server/dod/dod_gameinterface.h
Normal file
@@ -0,0 +1,15 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_GAMEINTERFACE_H
|
||||
#define DOD_GAMEINTERFACE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "gameinterface.h"
|
||||
|
||||
#endif // DOD_GAMEINTERFACE_H
|
||||
150
game/server/dod/dod_gamestats.cpp
Normal file
150
game/server/dod/dod_gamestats.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: dod game stats
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
// Some tricky business here - we don't want to include the precompiled header for the statreader
|
||||
// and trying to #ifdef it out does funky things like ignoring the #endif. Define our header file
|
||||
// separately and include it based on the switch
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#ifdef GAME_DLL
|
||||
#include "weapon_dodbase.h"
|
||||
#endif
|
||||
|
||||
#include <tier0/platform.h>
|
||||
#include "dod_gamestats.h"
|
||||
|
||||
int iDistanceStatWeapons[DOD_NUM_DISTANCE_STAT_WEAPONS] =
|
||||
{
|
||||
WEAPON_COLT,
|
||||
WEAPON_P38,
|
||||
WEAPON_C96,
|
||||
WEAPON_GARAND,
|
||||
WEAPON_GARAND_ZOOMED,
|
||||
WEAPON_M1CARBINE,
|
||||
WEAPON_K98,
|
||||
WEAPON_K98_ZOOMED,
|
||||
WEAPON_SPRING,
|
||||
WEAPON_SPRING_ZOOMED,
|
||||
WEAPON_K98_SCOPED,
|
||||
WEAPON_K98_SCOPED_ZOOMED,
|
||||
WEAPON_THOMPSON,
|
||||
WEAPON_MP40,
|
||||
WEAPON_MP44,
|
||||
WEAPON_MP44_SEMIAUTO,
|
||||
WEAPON_BAR,
|
||||
WEAPON_BAR_SEMIAUTO,
|
||||
WEAPON_30CAL,
|
||||
WEAPON_30CAL_UNDEPLOYED,
|
||||
WEAPON_MG42,
|
||||
WEAPON_MG42_UNDEPLOYED,
|
||||
};
|
||||
|
||||
// Send hit/shots only for the following weapons
|
||||
int iNoDistStatWeapons[DOD_NUM_NODIST_STAT_WEAPONS] =
|
||||
{
|
||||
WEAPON_AMERKNIFE,
|
||||
WEAPON_SPADE,
|
||||
WEAPON_BAZOOKA,
|
||||
WEAPON_PSCHRECK,
|
||||
WEAPON_FRAG_US,
|
||||
WEAPON_FRAG_GER,
|
||||
WEAPON_FRAG_US_LIVE,
|
||||
WEAPON_FRAG_GER_LIVE,
|
||||
WEAPON_RIFLEGREN_US,
|
||||
WEAPON_RIFLEGREN_GER,
|
||||
WEAPON_RIFLEGREN_US_LIVE,
|
||||
WEAPON_RIFLEGREN_GER_LIVE,
|
||||
WEAPON_THOMPSON_PUNCH,
|
||||
WEAPON_MP40_PUNCH,
|
||||
};
|
||||
|
||||
int iWeaponBucketDistances[DOD_NUM_WEAPON_DISTANCE_BUCKETS-1] =
|
||||
{
|
||||
50,
|
||||
150,
|
||||
300,
|
||||
450,
|
||||
700,
|
||||
1000,
|
||||
1300,
|
||||
1600,
|
||||
2000
|
||||
};
|
||||
|
||||
#ifndef GAME_DLL
|
||||
|
||||
const char * s_WeaponAliasInfo[] =
|
||||
{
|
||||
"none", // WEAPON_NONE = 0,
|
||||
|
||||
//Melee
|
||||
"amerknife", //WEAPON_AMERKNIFE,
|
||||
"spade", //WEAPON_SPADE,
|
||||
|
||||
//Pistols
|
||||
"colt", //WEAPON_COLT,
|
||||
"p38", //WEAPON_P38,
|
||||
"c96", //WEAPON_C96
|
||||
|
||||
//Rifles
|
||||
"garand", //WEAPON_GARAND,
|
||||
"m1carbine", //WEAPON_M1CARBINE,
|
||||
"k98", //WEAPON_K98,
|
||||
|
||||
//Sniper Rifles
|
||||
"spring", //WEAPON_SPRING,
|
||||
"k98_scoped", //WEAPON_K98_SCOPED,
|
||||
|
||||
//SMG
|
||||
"thompson", //WEAPON_THOMPSON,
|
||||
"mp40", //WEAPON_MP40,
|
||||
"mp44", //WEAPON_MP44,
|
||||
"bar", //WEAPON_BAR,
|
||||
|
||||
//Machine guns
|
||||
"30cal", //WEAPON_30CAL,
|
||||
"mg42", //WEAPON_MG42,
|
||||
|
||||
//Rocket weapons
|
||||
"bazooka", //WEAPON_BAZOOKA,
|
||||
"pschreck", //WEAPON_PSCHRECK,
|
||||
|
||||
//Grenades
|
||||
"frag_us", //WEAPON_FRAG_US,
|
||||
"frag_ger", //WEAPON_FRAG_GER,
|
||||
|
||||
"frag_us_live", //WEAPON_FRAG_US_LIVE
|
||||
"frag_ger_live", //WEAPON_FRAG_GER_LIVE
|
||||
|
||||
"smoke_us", //WEAPON_SMOKE_US
|
||||
"smoke_ger", //WEAPON_SMOKE_GER
|
||||
|
||||
"riflegren_us", //WEAPON_RIFLEGREN_US
|
||||
"riflegren_ger", //WEAPON_RIFLEGREN_GER
|
||||
|
||||
"riflegren_us_live", //WEAPON_RIFLEGREN_US_LIVE
|
||||
"riflegren_ger_live", //WEAPON_RIFLEGREN_GER_LIVE
|
||||
|
||||
// not actually separate weapons, but defines used in stats recording
|
||||
"thompson_punch", //WEAPON_THOMPSON_PUNCH
|
||||
"mp40_punch", //WEAPON_MP40_PUNCH
|
||||
"garand_zoomed", //WEAPON_GARAND_ZOOMED,
|
||||
|
||||
"k98_zoomed", //WEAPON_K98_ZOOMED
|
||||
"spring_zoomed", //WEAPON_SPRING_ZOOMED
|
||||
"k98_scoped_zoomed", //WEAPON_K98_SCOPED_ZOOMED
|
||||
|
||||
"30cal_undeployed", //WEAPON_30CAL_UNDEPLOYED,
|
||||
"mg42_undeployed", //WEAPON_MG42_UNDEPLOYED,
|
||||
|
||||
"bar_semiauto", //WEAPON_BAR_SEMIAUTO,
|
||||
"mp44_semiauto", //WEAPON_MP44_SEMIAUTO,
|
||||
|
||||
0, // end of list marker
|
||||
};
|
||||
#endif
|
||||
175
game/server/dod/dod_gamestats.h
Normal file
175
game/server/dod/dod_gamestats.h
Normal file
@@ -0,0 +1,175 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: The dod game stats header
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_GAMESTATS_H
|
||||
#define DOD_GAMESTATS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// Redefine some things for the stat reader so it doesn't have to include weapon_dodbase.h
|
||||
#ifndef GAME_DLL
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WEAPON_NONE = 0,
|
||||
|
||||
//Melee
|
||||
WEAPON_AMERKNIFE,
|
||||
WEAPON_SPADE,
|
||||
|
||||
//Pistols
|
||||
WEAPON_COLT,
|
||||
WEAPON_P38,
|
||||
WEAPON_C96,
|
||||
|
||||
//Rifles
|
||||
WEAPON_GARAND,
|
||||
WEAPON_M1CARBINE,
|
||||
WEAPON_K98,
|
||||
|
||||
//Sniper Rifles
|
||||
WEAPON_SPRING,
|
||||
WEAPON_K98_SCOPED,
|
||||
|
||||
//SMG
|
||||
WEAPON_THOMPSON,
|
||||
WEAPON_MP40,
|
||||
WEAPON_MP44,
|
||||
WEAPON_BAR,
|
||||
|
||||
//Machine guns
|
||||
WEAPON_30CAL,
|
||||
WEAPON_MG42,
|
||||
|
||||
//Rocket weapons
|
||||
WEAPON_BAZOOKA,
|
||||
WEAPON_PSCHRECK,
|
||||
|
||||
//Grenades
|
||||
WEAPON_FRAG_US,
|
||||
WEAPON_FRAG_GER,
|
||||
|
||||
WEAPON_FRAG_US_LIVE,
|
||||
WEAPON_FRAG_GER_LIVE,
|
||||
|
||||
WEAPON_SMOKE_US,
|
||||
WEAPON_SMOKE_GER,
|
||||
|
||||
WEAPON_RIFLEGREN_US,
|
||||
WEAPON_RIFLEGREN_GER,
|
||||
|
||||
WEAPON_RIFLEGREN_US_LIVE,
|
||||
WEAPON_RIFLEGREN_GER_LIVE,
|
||||
|
||||
// not actually separate weapons, but defines used in stats recording
|
||||
// find a better way to do this without polluting the list of actual weapons.
|
||||
WEAPON_THOMPSON_PUNCH,
|
||||
WEAPON_MP40_PUNCH,
|
||||
|
||||
WEAPON_GARAND_ZOOMED,
|
||||
WEAPON_K98_ZOOMED,
|
||||
WEAPON_SPRING_ZOOMED,
|
||||
WEAPON_K98_SCOPED_ZOOMED,
|
||||
|
||||
WEAPON_30CAL_UNDEPLOYED,
|
||||
WEAPON_MG42_UNDEPLOYED,
|
||||
|
||||
WEAPON_BAR_SEMIAUTO,
|
||||
WEAPON_MP44_SEMIAUTO,
|
||||
|
||||
WEAPON_MAX, // number of weapons weapon index
|
||||
|
||||
} DODWeaponID;
|
||||
|
||||
#endif // ndef WEAPON_NONE
|
||||
|
||||
#define DOD_STATS_BLOB_VERSION 2 // changed to 2 for the orange box beta
|
||||
|
||||
#define DOD_NUM_DISTANCE_STAT_WEAPONS 22
|
||||
#define DOD_NUM_NODIST_STAT_WEAPONS 14
|
||||
#define DOD_NUM_WEAPON_DISTANCE_BUCKETS 10
|
||||
|
||||
extern int iDistanceStatWeapons[DOD_NUM_DISTANCE_STAT_WEAPONS];
|
||||
extern int iNoDistStatWeapons[DOD_NUM_NODIST_STAT_WEAPONS];
|
||||
extern int iWeaponBucketDistances[DOD_NUM_WEAPON_DISTANCE_BUCKETS-1];
|
||||
|
||||
#ifndef GAME_DLL
|
||||
extern const char * s_WeaponAliasInfo[];
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char szGameName[8];
|
||||
byte iVersion;
|
||||
char szMapName[32];
|
||||
char ipAddr[4];
|
||||
short port;
|
||||
int serverid;
|
||||
} gamestats_header_t;
|
||||
|
||||
// Stats for bullet weapons - includes distance of hits
|
||||
typedef struct
|
||||
{
|
||||
short iNumAttacks; // times fired
|
||||
short iNumHits; // times hit
|
||||
|
||||
// distance buckets - distances are defined per-weapon ( 0 is closest, buckets-1 farthest )
|
||||
short iDistanceBuckets[DOD_NUM_WEAPON_DISTANCE_BUCKETS];
|
||||
|
||||
} dod_gamestats_weapon_distance_t;
|
||||
|
||||
// Stats for non-bullet weapons
|
||||
typedef struct
|
||||
{
|
||||
short iNumAttacks; // times fired
|
||||
short iNumHits; // times hit
|
||||
} dod_gamestats_weapon_nodist_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gamestats_header_t header;
|
||||
|
||||
// Team Scores
|
||||
byte iNumAlliesWins;
|
||||
byte iNumAxisWins;
|
||||
|
||||
short iAlliesTickPoints;
|
||||
short iAxisTickPoints;
|
||||
|
||||
short iMinutesPlayed; // time spent on the map rotation
|
||||
|
||||
// Player Data
|
||||
short iMinutesPlayedPerClass_Allies[7]; // includes random
|
||||
short iMinutesPlayedPerClass_Axis[7]; // includes random
|
||||
|
||||
short iKillsPerClass_Allies[6];
|
||||
short iKillsPerClass_Axis[6];
|
||||
|
||||
short iSpawnsPerClass_Allies[6];
|
||||
short iSpawnsPerClass_Axis[6];
|
||||
|
||||
short iCapsPerClass_Allies[6];
|
||||
short iCapsPerClass_Axis[6];
|
||||
|
||||
byte iDefensesPerClass_Allies[6];
|
||||
byte iDefensesPerClass_Axis[6];
|
||||
|
||||
// Server Settings
|
||||
// assume these class limits don't change through the course of the map
|
||||
byte iClassLimits_Allies[6];
|
||||
byte iClassLimits_Axis[6];
|
||||
|
||||
// Weapon Data
|
||||
dod_gamestats_weapon_distance_t weaponStatsDistance[DOD_NUM_DISTANCE_STAT_WEAPONS]; // 14 * 22 = 308 bytes
|
||||
dod_gamestats_weapon_nodist_t weaponStats[DOD_NUM_NODIST_STAT_WEAPONS]; // 4 * 14 = 56 bytes
|
||||
|
||||
// how many times a weapon was picked up ?
|
||||
|
||||
} dod_gamestats_t;
|
||||
|
||||
#endif // DOD_GAMESTATS_H
|
||||
76
game/server/dod/dod_handgrenade.cpp
Normal file
76
game/server/dod/dod_handgrenade.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_handgrenade.h"
|
||||
#include "dod_shareddefs.h"
|
||||
|
||||
#define GRENADE_MODEL "models/Weapons/w_frag.mdl"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( grenade_frag_us, CDODHandGrenade );
|
||||
PRECACHE_WEAPON_REGISTER( grenade_frag_us );
|
||||
|
||||
CDODHandGrenade* CDODHandGrenade::Create(
|
||||
const Vector &position,
|
||||
const QAngle &angles,
|
||||
const Vector &velocity,
|
||||
const AngularImpulse &angVelocity,
|
||||
CBaseCombatCharacter *pOwner,
|
||||
float timer,
|
||||
DODWeaponID weaponID )
|
||||
{
|
||||
CDODHandGrenade *pGrenade = (CDODHandGrenade*)CBaseEntity::Create( "grenade_frag_us", position, angles, pOwner );
|
||||
|
||||
Assert( pGrenade );
|
||||
|
||||
if( !pGrenade )
|
||||
return NULL;
|
||||
|
||||
IPhysicsObject *pPhysicsObject = pGrenade->VPhysicsGetObject();
|
||||
if ( pPhysicsObject )
|
||||
{
|
||||
pPhysicsObject->AddVelocity( &velocity, &angVelocity );
|
||||
}
|
||||
|
||||
// Who threw this grenade
|
||||
pGrenade->SetThrower( pOwner );
|
||||
|
||||
pGrenade->ChangeTeam( pOwner->GetTeamNumber() );
|
||||
|
||||
// How long until we explode
|
||||
pGrenade->SetDetonateTimerLength( timer );
|
||||
|
||||
// Save the weapon id for stats purposes
|
||||
pGrenade->m_EmitterWeaponID = weaponID;
|
||||
|
||||
return pGrenade;
|
||||
}
|
||||
|
||||
void CDODHandGrenade::Spawn()
|
||||
{
|
||||
SetModel( GRENADE_MODEL );
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
|
||||
void CDODHandGrenade::Precache()
|
||||
{
|
||||
PrecacheModel( GRENADE_MODEL );
|
||||
|
||||
PrecacheScriptSound( "HEGrenade.Bounce" );
|
||||
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
void CDODHandGrenade::BounceSound( void )
|
||||
{
|
||||
EmitSound( "HEGrenade.Bounce" );
|
||||
}
|
||||
|
||||
//Pass the classname of the exploding version of this grenade.
|
||||
char *CDODHandGrenade::GetExplodingClassname()
|
||||
{
|
||||
return "weapon_frag_us_live";
|
||||
}
|
||||
48
game/server/dod/dod_handgrenade.h
Normal file
48
game/server/dod/dod_handgrenade.h
Normal file
@@ -0,0 +1,48 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_HANDGRENADE_H
|
||||
#define DOD_HANDGRENADE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "dod_basegrenade.h"
|
||||
|
||||
class CDODHandGrenade : public CDODBaseGrenade
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODHandGrenade, CDODBaseGrenade );
|
||||
|
||||
// Overrides.
|
||||
public:
|
||||
CDODHandGrenade() {}
|
||||
virtual void Spawn();
|
||||
virtual void Precache();
|
||||
virtual void BounceSound( void );
|
||||
|
||||
// Grenade stuff.
|
||||
public:
|
||||
|
||||
static CDODHandGrenade* Create(
|
||||
const Vector &position,
|
||||
const QAngle &angles,
|
||||
const Vector &velocity,
|
||||
const AngularImpulse &angVelocity,
|
||||
CBaseCombatCharacter *pOwner,
|
||||
float timer,
|
||||
DODWeaponID weaponID );
|
||||
|
||||
void SetTimer( float timer );
|
||||
|
||||
virtual char *GetExplodingClassname();
|
||||
|
||||
private:
|
||||
float m_flDetonateTime;
|
||||
};
|
||||
|
||||
|
||||
#endif // DOD_HANDGRENADE_H
|
||||
140
game/server/dod/dod_hltvdirector.cpp
Normal file
140
game/server/dod/dod_hltvdirector.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hltvdirector.h"
|
||||
|
||||
class CDODHLTVDirector : public CHLTVDirector
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODHLTVDirector, CHLTVDirector );
|
||||
|
||||
const char** GetModEvents();
|
||||
void SetHLTVServer( IHLTVServer *hltv );
|
||||
void CreateShotFromEvent( CHLTVGameEvent *event );
|
||||
};
|
||||
|
||||
void CDODHLTVDirector::SetHLTVServer( IHLTVServer *hltv )
|
||||
{
|
||||
BaseClass::SetHLTVServer( hltv );
|
||||
|
||||
if ( m_pHLTVServer )
|
||||
{
|
||||
// mod specific events the director uses to find interesting shots
|
||||
ListenForGameEvent( "dod_point_captured" );
|
||||
ListenForGameEvent( "dod_capture_blocked" );
|
||||
}
|
||||
}
|
||||
|
||||
void CDODHLTVDirector::CreateShotFromEvent( CHLTVGameEvent *event )
|
||||
{
|
||||
// show event at least for 2 more seconds after it occured
|
||||
const char *name = event->m_Event->GetName();
|
||||
IGameEvent *shot = NULL;
|
||||
|
||||
if ( !Q_strcmp( "dod_point_captured", name ) ||
|
||||
!Q_strcmp( "dod_capture_blocked", name ) )
|
||||
{
|
||||
// try to find a capper or blocker
|
||||
const char *text = event->m_Event->GetString("blocker");
|
||||
int playerIndex = text[0];
|
||||
|
||||
if ( playerIndex < 1 )
|
||||
{
|
||||
// maybe its a capper ?
|
||||
text = event->m_Event->GetString("cappers");
|
||||
playerIndex = text[0];
|
||||
}
|
||||
|
||||
// if we found one, show him
|
||||
if ( playerIndex > 0 )
|
||||
{
|
||||
// shot player as primary, hostage as secondary target
|
||||
shot = gameeventmanager->CreateEvent( "hltv_chase", true );
|
||||
shot->SetInt( "target1", playerIndex );
|
||||
shot->SetInt( "target2", 0 );
|
||||
shot->SetFloat( "distance", 96.0f );
|
||||
shot->SetInt( "theta", 0 );
|
||||
shot->SetInt( "phi", 20 );
|
||||
|
||||
// shot 2 seconds after event
|
||||
m_nNextShotTick = MIN( m_nNextShotTick, (event->m_Tick+TIME_TO_TICKS(2.0)) );
|
||||
m_iPVSEntity = playerIndex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// let baseclass create a shot
|
||||
BaseClass::CreateShotFromEvent( event );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( shot )
|
||||
{
|
||||
m_pHLTVServer->BroadcastEvent( shot );
|
||||
gameeventmanager->FreeEvent( shot );
|
||||
DevMsg("DrcCmd: %s\n", name );
|
||||
}
|
||||
}
|
||||
|
||||
const char** CDODHLTVDirector::GetModEvents()
|
||||
{
|
||||
// game events relayed to spectator clients
|
||||
static const char *s_modevents[] =
|
||||
{
|
||||
"hltv_status",
|
||||
"hltv_chat",
|
||||
"player_connect",
|
||||
"player_disconnect",
|
||||
"player_team",
|
||||
"player_info",
|
||||
"server_cvar",
|
||||
"player_death",
|
||||
"player_chat",
|
||||
"round_start",
|
||||
"round_end",
|
||||
// additional DoD:S events:
|
||||
"player_changeclass",
|
||||
"dod_warmup_begins",
|
||||
"dod_warmup_ends",
|
||||
"dod_round_start",
|
||||
"dod_restart_round",
|
||||
"dod_ready_restart",
|
||||
"dod_allies_ready",
|
||||
"dod_axis_ready",
|
||||
"dod_round_restart_seconds",
|
||||
"dod_team_scores",
|
||||
"dod_round_win",
|
||||
"dod_tick_points",
|
||||
"dod_game_over",
|
||||
"dod_broadcast_audio",
|
||||
"dod_point_captured",
|
||||
"dod_capture_blocked",
|
||||
"dod_top_cappers",
|
||||
"dod_timer_flash",
|
||||
"dod_bomb_planted",
|
||||
NULL
|
||||
};
|
||||
|
||||
return s_modevents;
|
||||
}
|
||||
|
||||
static CDODHLTVDirector s_HLTVDirector; // singleton
|
||||
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CHLTVDirector, IHLTVDirector, INTERFACEVERSION_HLTVDIRECTOR, s_HLTVDirector );
|
||||
|
||||
CHLTVDirector* HLTVDirector()
|
||||
{
|
||||
return &s_HLTVDirector;
|
||||
}
|
||||
|
||||
IGameSystem* HLTVDirectorSystem()
|
||||
{
|
||||
return &s_HLTVDirector;
|
||||
}
|
||||
29
game/server/dod/dod_location.cpp
Normal file
29
game/server/dod/dod_location.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_location.h"
|
||||
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( dod_location, CDODLocation );
|
||||
|
||||
void CDODLocation::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
|
||||
bool CDODLocation::KeyValue( const char *szKeyName, const char *szValue )
|
||||
{
|
||||
if (FStrEq(szKeyName, "location_name")) //name of this location
|
||||
{
|
||||
Q_strncpy( m_szLocationName, szValue, sizeof(m_szLocationName) );
|
||||
}
|
||||
else
|
||||
return CBaseEntity::KeyValue( szKeyName, szValue );
|
||||
|
||||
return true;
|
||||
}
|
||||
38
game/server/dod/dod_location.h
Normal file
38
game/server/dod/dod_location.h
Normal file
@@ -0,0 +1,38 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DOD_LOCATION_H
|
||||
#define DOD_LOCATION_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "baseentity.h"
|
||||
|
||||
//a location on the map that players can refernce in their say messages
|
||||
//with the %l escape sequence
|
||||
class CDODLocation : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODLocation, CBaseEntity );
|
||||
CDODLocation()
|
||||
{
|
||||
m_szLocationName[0] = '\0';
|
||||
}
|
||||
|
||||
virtual void Spawn( void );
|
||||
virtual bool KeyValue( const char *szKeyName, const char *szValue );
|
||||
|
||||
inline const char *GetName( void ) { return m_szLocationName; }
|
||||
|
||||
private:
|
||||
char m_szLocationName[64];
|
||||
|
||||
private:
|
||||
CDODLocation( const CDODLocation & );
|
||||
};
|
||||
|
||||
#endif //DOD_LOCATION_H
|
||||
226
game/server/dod/dod_objective_resource.cpp
Normal file
226
game/server/dod/dod_objective_resource.cpp
Normal file
@@ -0,0 +1,226 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Entity that propagates general data needed by clients for every player.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "dod_objective_resource.h"
|
||||
#include "shareddefs.h"
|
||||
#include <coordsize.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// Datatable
|
||||
IMPLEMENT_SERVERCLASS_ST_NOBASE(CDODObjectiveResource, DT_DODObjectiveResource)
|
||||
|
||||
SendPropInt( SENDINFO(m_iNumControlPoints), 4, SPROP_UNSIGNED ),
|
||||
|
||||
// data variables
|
||||
SendPropArray( SendPropVector( SENDINFO_ARRAY(m_vCPPositions), -1, SPROP_COORD), m_vCPPositions ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_bCPIsVisible), SendPropInt( SENDINFO_ARRAY(m_bCPIsVisible), 1, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iAlliesIcons), SendPropInt( SENDINFO_ARRAY(m_iAlliesIcons), 8, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iAxisIcons), SendPropInt( SENDINFO_ARRAY(m_iAxisIcons), 8, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iNeutralIcons), SendPropInt( SENDINFO_ARRAY(m_iNeutralIcons), 8, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iTimerCapIcons), SendPropInt( SENDINFO_ARRAY(m_iTimerCapIcons), 8, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iBombedIcons), SendPropInt( SENDINFO_ARRAY(m_iBombedIcons), 8, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iAlliesReqCappers), SendPropInt( SENDINFO_ARRAY(m_iAlliesReqCappers), 4, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iAxisReqCappers), SendPropInt( SENDINFO_ARRAY(m_iAxisReqCappers), 4, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_flAlliesCapTime), SendPropTime( SENDINFO_ARRAY(m_flAlliesCapTime) ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_flAxisCapTime), SendPropTime( SENDINFO_ARRAY(m_flAxisCapTime) ) ),
|
||||
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_bBombPlanted), SendPropInt( SENDINFO_ARRAY(m_bBombPlanted), 1, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iBombsRequired), SendPropInt( SENDINFO_ARRAY(m_iBombsRequired), 2, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iBombsRemaining), SendPropInt( SENDINFO_ARRAY(m_iBombsRemaining), 2, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_bBombBeingDefused), SendPropInt( SENDINFO_ARRAY(m_bBombBeingDefused), 1, SPROP_UNSIGNED ) ),
|
||||
|
||||
// state variables
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iNumAllies), SendPropInt( SENDINFO_ARRAY(m_iNumAllies), 4, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iNumAxis), SendPropInt( SENDINFO_ARRAY(m_iNumAxis), 4, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iCappingTeam), SendPropInt( SENDINFO_ARRAY(m_iCappingTeam), 4, SPROP_UNSIGNED ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iOwner), SendPropInt( SENDINFO_ARRAY(m_iOwner), 4, SPROP_UNSIGNED ) ),
|
||||
|
||||
END_SEND_TABLE()
|
||||
|
||||
|
||||
BEGIN_DATADESC( CDODObjectiveResource )
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS( dod_objective_resource, CDODObjectiveResource );
|
||||
|
||||
CDODObjectiveResource *g_pObjectiveResource;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODObjectiveResource::Spawn( void )
|
||||
{
|
||||
m_iNumControlPoints = 0;
|
||||
|
||||
for ( int i=0; i < MAX_CONTROL_POINTS; i++ )
|
||||
{
|
||||
// data variables
|
||||
m_vCPPositions.Set( i, vec3_origin );
|
||||
m_bCPIsVisible.Set( i, true );
|
||||
m_iAlliesIcons.Set( i, 0 );
|
||||
m_iAxisIcons.Set( i, 0 );
|
||||
m_iNeutralIcons.Set( i, 0 );
|
||||
m_iTimerCapIcons.Set( i, 0 );
|
||||
m_iBombedIcons.Set( i, 0 );
|
||||
m_iAlliesReqCappers.Set( i, 0 );
|
||||
m_iAxisReqCappers.Set( i, 0 );
|
||||
m_flAlliesCapTime.Set( i, 0.0f );
|
||||
m_flAxisCapTime.Set( i, 0.0f );
|
||||
m_bBombPlanted.Set( i, 0 );
|
||||
m_iBombsRequired.Set( i, 0 );
|
||||
m_iBombsRemaining.Set( i, 0 );
|
||||
m_bBombBeingDefused.Set( i, 0 );
|
||||
|
||||
// state variables
|
||||
m_iNumAllies.Set( i, 0 );
|
||||
m_iNumAxis.Set( i, 0 );
|
||||
m_iCappingTeam.Set( i, TEAM_UNASSIGNED );
|
||||
m_iOwner.Set( i, TEAM_UNASSIGNED );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The objective resource is always transmitted to clients
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDODObjectiveResource::UpdateTransmitState()
|
||||
{
|
||||
// ALWAYS transmit to all clients.
|
||||
return SetTransmitState( FL_EDICT_ALWAYS );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Round is starting, reset state
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODObjectiveResource::ResetControlPoints( void )
|
||||
{
|
||||
for ( int i=0; i < MAX_CONTROL_POINTS; i++ )
|
||||
{
|
||||
m_iNumAllies.Set( i, 0 );
|
||||
m_iNumAxis.Set( i, 0 );
|
||||
m_iCappingTeam.Set( i, TEAM_UNASSIGNED );
|
||||
|
||||
m_bBombPlanted.Set( i, 0 );
|
||||
m_bBombBeingDefused.Set( i, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Data setting functions
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODObjectiveResource::SetNumControlPoints( int num )
|
||||
{
|
||||
Assert( num <= MAX_CONTROL_POINTS );
|
||||
m_iNumControlPoints = num;
|
||||
}
|
||||
|
||||
void CDODObjectiveResource::SetCPIcons( int index, int iAlliesIcon, int iAxisIcon, int iNeutralIcon, int iTimerCapIcon, int iBombedIcon )
|
||||
{
|
||||
AssertValidIndex(index);
|
||||
m_iAlliesIcons.Set( index, iAlliesIcon);
|
||||
m_iAxisIcons.Set( index, iAxisIcon );
|
||||
m_iNeutralIcons.Set( index, iNeutralIcon );
|
||||
m_iTimerCapIcons.Set( index, iTimerCapIcon );
|
||||
m_iBombedIcons.Set( index, iBombedIcon );
|
||||
}
|
||||
|
||||
void CDODObjectiveResource::SetCPPosition( int index, const Vector& vPosition )
|
||||
{
|
||||
AssertValidIndex(index);
|
||||
m_vCPPositions.Set( index, vPosition );
|
||||
}
|
||||
|
||||
void CDODObjectiveResource::SetCPVisible( int index, bool bVisible )
|
||||
{
|
||||
AssertValidIndex(index);
|
||||
m_bCPIsVisible.Set( index, bVisible );
|
||||
}
|
||||
|
||||
void CDODObjectiveResource::SetCPRequiredCappers( int index, int iReqAllies, int iReqAxis )
|
||||
{
|
||||
AssertValidIndex(index);
|
||||
m_iAlliesReqCappers.Set( index, iReqAllies );
|
||||
m_iAxisReqCappers.Set( index, iReqAxis );
|
||||
}
|
||||
|
||||
void CDODObjectiveResource::SetCPCapTime( int index, float flAlliesCapTime, float flAxisCapTime )
|
||||
{
|
||||
AssertValidIndex(index);
|
||||
m_flAlliesCapTime.Set( index, flAlliesCapTime );
|
||||
m_flAxisCapTime.Set( index, flAxisCapTime );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Data setting functions
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODObjectiveResource::SetNumPlayers( int index, int team, int iNumPlayers )
|
||||
{
|
||||
AssertValidIndex(index);
|
||||
|
||||
switch( team )
|
||||
{
|
||||
case TEAM_ALLIES:
|
||||
m_iNumAllies.Set( index, iNumPlayers );
|
||||
break;
|
||||
|
||||
case TEAM_AXIS:
|
||||
m_iNumAxis.Set( index, iNumPlayers );
|
||||
break;
|
||||
|
||||
default:
|
||||
Assert( 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CDODObjectiveResource::StartCap( int index, int team )
|
||||
{
|
||||
AssertValidIndex(index);
|
||||
m_iCappingTeam.Set( index, team );
|
||||
}
|
||||
|
||||
void CDODObjectiveResource::SetOwningTeam( int index, int team )
|
||||
{
|
||||
AssertValidIndex(index);
|
||||
m_iOwner.Set( index, team );
|
||||
|
||||
// clear the capper
|
||||
m_iCappingTeam.Set( index, TEAM_UNASSIGNED );
|
||||
}
|
||||
|
||||
void CDODObjectiveResource::SetCappingTeam( int index, int team )
|
||||
{
|
||||
AssertValidIndex(index);
|
||||
m_iCappingTeam.Set( index, team );
|
||||
}
|
||||
|
||||
void CDODObjectiveResource::SetBombPlanted( int index, bool bPlanted )
|
||||
{
|
||||
AssertValidIndex(index);
|
||||
m_bBombPlanted.Set( index, bPlanted );
|
||||
}
|
||||
|
||||
void CDODObjectiveResource::SetBombBeingDefused( int index, bool bBeingDefused )
|
||||
{
|
||||
AssertValidIndex(index);
|
||||
m_bBombBeingDefused.Set( index, bBeingDefused );
|
||||
}
|
||||
|
||||
void CDODObjectiveResource::SetBombsRequired( int index, int iBombsRequired )
|
||||
{
|
||||
AssertValidIndex(index);
|
||||
m_iBombsRequired.Set( index, iBombsRequired );
|
||||
}
|
||||
|
||||
void CDODObjectiveResource::SetBombsRemaining( int index, int iBombsRemaining )
|
||||
{
|
||||
AssertValidIndex(index);
|
||||
m_iBombsRemaining.Set( index, iBombsRemaining );
|
||||
}
|
||||
86
game/server/dod/dod_objective_resource.h
Normal file
86
game/server/dod/dod_objective_resource.h
Normal file
@@ -0,0 +1,86 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: DOD's objective resource, transmits all objective states to players
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_OBJECTIVE_RESOURCE_H
|
||||
#define DOD_OBJECTIVE_RESOURCE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "dod_shareddefs.h"
|
||||
|
||||
class CDODObjectiveResource : public CBaseEntity
|
||||
{
|
||||
DECLARE_CLASS( CDODObjectiveResource, CBaseEntity );
|
||||
public:
|
||||
DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
virtual void Spawn( void );
|
||||
virtual int UpdateTransmitState(void);
|
||||
|
||||
void ResetControlPoints( void );
|
||||
|
||||
// Data functions, called to set up the state at the beginning of a round
|
||||
void SetNumControlPoints( int num );
|
||||
void SetCPIcons( int index, int iAlliesIcon, int iAxisIcon, int iNeutralIcon, int iTimerCapIcon, int iBombedIcon );
|
||||
void SetCPPosition( int index, const Vector& vPosition );
|
||||
void SetCPVisible( int index, bool bVisible );
|
||||
void SetCPRequiredCappers( int index, int iReqAllies, int iReqAxis );
|
||||
void SetCPCapTime( int index, float flAlliesCapTime, float flAxisCapTime );
|
||||
|
||||
// State functions, called many times
|
||||
void SetNumPlayers( int index, int team, int iNumPlayers );
|
||||
void StartCap( int index, int team );
|
||||
void SetOwningTeam( int index, int team );
|
||||
void SetCappingTeam( int index, int team );
|
||||
void SetBombPlanted( int index, bool bPlanted );
|
||||
void SetBombsRequired( int index, int iBombsRequired );
|
||||
void SetBombsRemaining( int index, int iBombsRemaining );
|
||||
void SetBombBeingDefused( int index, bool bBeingDefused );
|
||||
|
||||
void AssertValidIndex( int index )
|
||||
{
|
||||
Assert( 0 <= index && index <= MAX_CONTROL_POINTS && index < m_iNumControlPoints );
|
||||
}
|
||||
|
||||
private:
|
||||
CNetworkVar( int, m_iNumControlPoints );
|
||||
|
||||
// data variables
|
||||
CNetworkArray( Vector, m_vCPPositions, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( int, m_bCPIsVisible, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( int, m_iAlliesIcons, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( int, m_iAxisIcons, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( int, m_iNeutralIcons, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( int, m_iTimerCapIcons, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( int, m_iBombedIcons, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( int, m_iAlliesReqCappers,MAX_CONTROL_POINTS );
|
||||
CNetworkArray( int, m_iAxisReqCappers, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( float, m_flAlliesCapTime, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( float, m_flAxisCapTime, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( int, m_bBombPlanted, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( int, m_iBombsRequired, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( int, m_iBombsRemaining, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( int, m_bBombBeingDefused,MAX_CONTROL_POINTS );
|
||||
|
||||
// state variables
|
||||
|
||||
// change when players enter/exit an area
|
||||
CNetworkArray( int, m_iNumAllies, MAX_CONTROL_POINTS );
|
||||
CNetworkArray( int, m_iNumAxis, MAX_CONTROL_POINTS );
|
||||
|
||||
// changes when a cap starts. start and end times are calculated on client
|
||||
CNetworkArray( int, m_iCappingTeam, MAX_CONTROL_POINTS );
|
||||
|
||||
// changes when a point is successfully captured
|
||||
CNetworkArray( int, m_iOwner, MAX_CONTROL_POINTS );
|
||||
};
|
||||
|
||||
extern CDODObjectiveResource *g_pObjectiveResource;
|
||||
|
||||
#endif //DOD_OBJECTIVE_RESOURCE_H
|
||||
4936
game/server/dod/dod_player.cpp
Normal file
4936
game/server/dod/dod_player.cpp
Normal file
File diff suppressed because it is too large
Load Diff
661
game/server/dod/dod_player.h
Normal file
661
game/server/dod/dod_player.h
Normal file
@@ -0,0 +1,661 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Player for HL1.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_PLAYER_H
|
||||
#define DOD_PLAYER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "basemultiplayerplayer.h"
|
||||
#include "server_class.h"
|
||||
#include "dod_playeranimstate.h"
|
||||
#include "dod_shareddefs.h"
|
||||
#include "dod_player_shared.h"
|
||||
#include "unisignals.h"
|
||||
#include "dod_statmgr.h"
|
||||
#include "utlmap.h"
|
||||
#include "steam/steam_gameserver.h"
|
||||
#include "hintsystem.h"
|
||||
|
||||
// Function table for each player state.
|
||||
class CDODPlayerStateInfo
|
||||
{
|
||||
public:
|
||||
DODPlayerState m_iPlayerState;
|
||||
const char *m_pStateName;
|
||||
|
||||
void (CDODPlayer::*pfnEnterState)(); // Init and deinit the state.
|
||||
void (CDODPlayer::*pfnLeaveState)();
|
||||
void (CDODPlayer::*pfnPreThink)(); // Do a PreThink() in this state.
|
||||
};
|
||||
|
||||
class CDODPlayer;
|
||||
|
||||
//=======================================
|
||||
//Record of either damage taken or given.
|
||||
//Contains the player name that we hurt or that hurt us,
|
||||
//and the total damage
|
||||
//=======================================
|
||||
class CDamageRecord
|
||||
{
|
||||
public:
|
||||
CDamageRecord( const char *pszName, int iLifeID, int iDamage )
|
||||
{
|
||||
Q_strncpy( m_szPlayerName, pszName, MAX_PLAYER_NAME_LENGTH );
|
||||
m_iDamage = iDamage;
|
||||
m_iNumHits = 1;
|
||||
m_iLifeID = iLifeID;
|
||||
}
|
||||
|
||||
void AddDamage( int iDamage )
|
||||
{
|
||||
m_iDamage += iDamage;
|
||||
m_iNumHits++;
|
||||
}
|
||||
|
||||
char *GetPlayerName( void ) { return m_szPlayerName; }
|
||||
int GetDamage( void ) { return m_iDamage; }
|
||||
int GetNumHits( void ) { return m_iNumHits; }
|
||||
int GetLifeID( void ) { return m_iLifeID; }
|
||||
|
||||
private:
|
||||
char m_szPlayerName[MAX_PLAYER_NAME_LENGTH];
|
||||
int m_iLifeID; // life ID of the player when this damage was done
|
||||
int m_iDamage; //how much damage was done
|
||||
int m_iNumHits; //how many hits
|
||||
};
|
||||
|
||||
#define SIGNAL_CAPTUREAREA (1<<0)
|
||||
|
||||
class CDODBombTarget;
|
||||
|
||||
class CDODPlayerStatProperty
|
||||
{
|
||||
DECLARE_CLASS_NOBASE( CDODPlayerStatProperty );
|
||||
|
||||
public:
|
||||
CDODPlayerStatProperty()
|
||||
{
|
||||
m_iCurrentLifePlayerClass = -1;
|
||||
m_bRecordingStats = false;
|
||||
ResetPerLifeStats();
|
||||
}
|
||||
|
||||
~CDODPlayerStatProperty() {}
|
||||
|
||||
void SetClassAndTeamForThisLife( int iPlayerClass, int iTeam );
|
||||
|
||||
void IncrementPlayerClassStat( DODStatType_t statType, int iValue = 1 );
|
||||
|
||||
void IncrementWeaponStat( DODWeaponID iWeaponID, DODStatType_t statType, int iValue = 1 );
|
||||
|
||||
// reset per life stats
|
||||
void ResetPerLifeStats( void );
|
||||
|
||||
// send this life's worth of data to the client
|
||||
void SendStatsToPlayer( CDODPlayer *pPlayer );
|
||||
|
||||
private:
|
||||
|
||||
bool m_bRecordingStats; // not recording until we get a valid class. stop recording when we join spectator
|
||||
|
||||
int m_iCurrentLifePlayerClass;
|
||||
int m_iCurrentLifePlayerTeam;
|
||||
|
||||
// single life's worth of player stats
|
||||
dod_stat_accumulator_t m_PlayerStatsPerLife;
|
||||
|
||||
// single life's worth of weapon stats
|
||||
dod_stat_accumulator_t m_WeaponStatsPerLife[WEAPON_MAX];
|
||||
bool m_bWeaponStatsDirty[WEAPON_MAX];
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// >> Day of Defeat player
|
||||
//=============================================================================
|
||||
class CDODPlayer : public CBaseMultiplayerPlayer
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODPlayer, CBaseMultiplayerPlayer );
|
||||
DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
CDODPlayer();
|
||||
~CDODPlayer();
|
||||
|
||||
static CDODPlayer *CreatePlayer( const char *className, edict_t *ed );
|
||||
static CDODPlayer* Instance( int iEnt );
|
||||
|
||||
// This passes the event to the client's and server's CPlayerAnimState.
|
||||
void DoAnimationEvent( PlayerAnimEvent_t event, int nData = 0 );
|
||||
void SetupBones( matrix3x4_t *pBoneToWorld, int boneMask );
|
||||
|
||||
virtual void Precache();
|
||||
void PrecachePlayerModel( const char *szPlayerModel );
|
||||
virtual void Spawn();
|
||||
virtual void InitialSpawn( void );
|
||||
|
||||
virtual void CheatImpulseCommands( int iImpulse );
|
||||
virtual void PlayerRunCommand( CUserCmd *ucmd, IMoveHelper *moveHelper );
|
||||
|
||||
virtual void PreThink();
|
||||
virtual void PostThink();
|
||||
|
||||
virtual int OnTakeDamage( const CTakeDamageInfo &inputInfo );
|
||||
virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info );
|
||||
|
||||
virtual void Event_Killed( const CTakeDamageInfo &info );
|
||||
virtual void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
|
||||
void Pain( void );
|
||||
void OnDamagedByExplosion( const CTakeDamageInfo &info );
|
||||
void OnDamageByStun( const CTakeDamageInfo &info );
|
||||
void DeafenThink( void );
|
||||
|
||||
virtual void UpdateGeigerCounter( void ) {}
|
||||
virtual void CheckTrainUpdate( void ) {}
|
||||
|
||||
virtual void CreateViewModel( int viewmodelindex = 0 );
|
||||
|
||||
virtual bool SetObserverMode(int mode); // sets new observer mode, returns true if successful
|
||||
virtual bool ModeWantsSpectatorGUI( int iMode ) { return ( iMode != OBS_MODE_DEATHCAM && iMode != OBS_MODE_FREEZECAM ); }
|
||||
|
||||
|
||||
// from CBasePlayer
|
||||
void SetupVisibility( CBaseEntity *pViewEntity, unsigned char *pvs, int pvssize );
|
||||
|
||||
CBaseEntity* EntSelectSpawnPoint();
|
||||
|
||||
void ChangeTeam( int iTeamNum );
|
||||
|
||||
bool CanMove( void ) const;
|
||||
|
||||
virtual void SharedSpawn();
|
||||
|
||||
void CheckProneMoveSound( int groundspeed, bool onground );
|
||||
virtual void UpdateStepSound( surfacedata_t *psurface, const Vector &vecOrigin, const Vector &vecVelocity );
|
||||
virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force );
|
||||
|
||||
virtual const Vector GetPlayerMins( void ) const; // uses local player
|
||||
virtual const Vector GetPlayerMaxs( void ) const; // uses local player
|
||||
|
||||
void DODRespawn( void );
|
||||
|
||||
virtual void SetAnimation( PLAYER_ANIM playerAnim );
|
||||
|
||||
CBaseEntity * GiveNamedItem( const char *pszName, int iSubType = 0 );
|
||||
|
||||
bool Weapon_CanSwitchTo( CBaseCombatWeapon *pWeapon );
|
||||
|
||||
void SetScore( int score );
|
||||
void AddScore( int num );
|
||||
int GetScore( void ) { return m_iScore; }
|
||||
int m_iScore;
|
||||
|
||||
// Simulates a single frame of movement for a player
|
||||
void RunPlayerMove( const QAngle& viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, float frametime );
|
||||
|
||||
|
||||
//Damage record functions
|
||||
void RecordDamageTaken( CDODPlayer *pAttacker, int iDamageTaken );
|
||||
void RecordWorldDamageTaken( int iDamageTaken );
|
||||
void RecordDamageGiven( CDODPlayer *pVictim, int iDamageGiven );
|
||||
void ResetDamageCounters(); //Reset all lists
|
||||
|
||||
void OutputDamageTaken( void );
|
||||
void OutputDamageGiven( void );
|
||||
|
||||
// Voice Commands
|
||||
//============
|
||||
void HandleCommand_Voice( const char *pcmd ); // player submitted a raw voice_ command
|
||||
void HandleCommand_HandSignal( const char *pcmd ); // player wants to show a hand signal
|
||||
void VoiceCommand( int iVoiceCommand ); // internal voice command function
|
||||
void HandSignal( int iSignal ); // same for hand signals
|
||||
|
||||
float m_flNextVoice;
|
||||
float m_flNextHandSignal;
|
||||
|
||||
void PopHelmet( Vector vecDir, Vector vecForceOrigin );
|
||||
|
||||
bool DropActiveWeapon( void );
|
||||
bool DropPrimaryWeapon( void );
|
||||
bool DODWeaponDrop( CBaseCombatWeapon *pWeapon, bool bThrowForward );
|
||||
bool BumpWeapon( CBaseCombatWeapon *pBaseWeapon );
|
||||
|
||||
CWeaponDODBase* GetActiveDODWeapon() const;
|
||||
|
||||
virtual void AttemptToExitFreezeCam( void );
|
||||
|
||||
//Generic Ammo
|
||||
//============
|
||||
void DropGenericAmmo( void );
|
||||
void ReturnGenericAmmo( void );
|
||||
bool GiveGenericAmmo( void );
|
||||
bool m_bHasGenericAmmo;
|
||||
|
||||
void ResetBleeding( void );
|
||||
void Bandage( void ); // stops the bleeding
|
||||
void SetBandager( CDODPlayer *pPlayer );
|
||||
bool IsBeingBandaged( void );
|
||||
EHANDLE m_hBandager;
|
||||
|
||||
//Area Signals
|
||||
//============
|
||||
//to determine if the player is in a sandbag trigger
|
||||
CUnifiedSignals m_signals; // Player signals (buy zone, bomb zone, etc.)
|
||||
|
||||
int m_iCapAreaIconIndex; //which area's icon to show - we are not necessarily capping it.
|
||||
int m_iObjectAreaIndex; //if the player is in an object cap area, which one?
|
||||
|
||||
void SetCapAreaIndex( int index );
|
||||
int GetCapAreaIndex( void );
|
||||
void ClearCapAreaIndex() { SetCapAreaIndex(-1); }
|
||||
|
||||
void SetCPIndex( int index );
|
||||
|
||||
float m_fHandleSignalsTime; //time to next check the area signals
|
||||
void HandleSignals( void ); //check if signals need to do anything, like turn icons on or off
|
||||
|
||||
bool ShouldAutoReload( void ) { return m_bAutoReload; }
|
||||
void SetAutoReload( bool bAutoReload ) { m_bAutoReload = bAutoReload; }
|
||||
|
||||
bool ShouldAutoRezoom( void ) { return m_bAutoRezoom; }
|
||||
void SetAutoRezoom( bool bAutoRezoom ) { m_bAutoRezoom = bAutoRezoom; }
|
||||
|
||||
// Hints
|
||||
virtual CHintSystem *Hints( void ) { return &m_Hints; }
|
||||
|
||||
// Reset all scores
|
||||
void ResetScores( void );
|
||||
|
||||
int GetHealthAsString( char *pDest, int iDestSize );
|
||||
int GetLastPlayerIDAsString( char *pDest, int iDestSize );
|
||||
int GetClosestPlayerHealthAsString( char *pDest, int iDestSize );
|
||||
int GetPlayerClassAsString( char *pDest, int iDestSize );
|
||||
int GetNearestLocationAsString( char *pDest, int iDestSize );
|
||||
int GetTimeleftAsString( char *pDest, int iDestSize );
|
||||
int GetStringForEscapeSequence( char c, char *pDest, int iDestSize );
|
||||
virtual void CheckChatText( char *p, int bufsize );
|
||||
|
||||
void PushawayThink();
|
||||
|
||||
void DestroyRagdoll( void );
|
||||
|
||||
virtual bool CanHearChatFrom( CBasePlayer *pPlayer );
|
||||
|
||||
virtual void CommitSuicide( bool bExplode = false, bool bForce = false );
|
||||
virtual void CommitSuicide( const Vector &vecForce, bool bExplode = false, bool bForce = false );
|
||||
|
||||
virtual bool StartReplayMode( float fDelay, float fDuration, int iEntity );
|
||||
virtual void StopReplayMode();
|
||||
|
||||
void PickUpWeapon( CWeaponDODBase *pWeapon );
|
||||
|
||||
int GetPriorityForPickUpEnt( CBaseEntity *pEnt );
|
||||
virtual CBaseEntity *FindUseEntity();
|
||||
|
||||
virtual void ComputeWorldSpaceSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs );
|
||||
|
||||
bool ShouldCollide( int collisionGroup, int contentsMask ) const;
|
||||
|
||||
void SetDeathFlags( int iDeathFlags ) { m_iDeathFlags = iDeathFlags; }
|
||||
int GetDeathFlags() { return m_iDeathFlags; }
|
||||
|
||||
void RemoveNemesisRelationships();
|
||||
|
||||
virtual void OnAchievementEarned( int iAchievement );
|
||||
void RecalculateAchievementAwardsMask();
|
||||
|
||||
bool ShouldInstantRespawn( void );
|
||||
|
||||
void StatEvent_UploadStats( void );
|
||||
void StatEvent_KilledPlayer( DODWeaponID iKillingWeapon );
|
||||
void StatEvent_WasKilled( void );
|
||||
void StatEvent_RoundWin( void );
|
||||
void StatEvent_RoundLoss( void );
|
||||
void StatEvent_PointCaptured( void );
|
||||
void StatEvent_CaptureBlocked( void );
|
||||
void StatEvent_BombPlanted( void );
|
||||
void StatEvent_BombDefused( void );
|
||||
void StatEvent_ScoredDomination( void );
|
||||
void StatEvent_ScoredRevenge( void );
|
||||
void StatEvent_WeaponFired( DODWeaponID iWeaponID );
|
||||
void StatEvent_WeaponHit( DODWeaponID iWeaponID, bool bWasHeadshot );
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
// Player state management.
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
public:
|
||||
|
||||
void State_Transition( DODPlayerState newState );
|
||||
DODPlayerState State_Get() const; // Get the current state.
|
||||
|
||||
void MoveToNextIntroCamera(); //Cycle view through available intro cameras
|
||||
|
||||
bool ClientCommand( const CCommand &args );
|
||||
|
||||
virtual bool IsReadyToPlay( void );
|
||||
|
||||
void FireBullets( const FireBulletsInfo_t &info );
|
||||
|
||||
bool CanAttack( void );
|
||||
|
||||
void SetBazookaDeployed( bool bDeployed ) { m_bBazookaDeployed = bDeployed; }
|
||||
|
||||
// from cbasecombatcharacter
|
||||
virtual void InitVCollision( const Vector &vecAbsOrigin, const Vector &vecAbsVelocity );
|
||||
virtual void VPhysicsShadowUpdate( IPhysicsObject *pPhysics );
|
||||
|
||||
void DeathSound( const CTakeDamageInfo &info );
|
||||
|
||||
Activity TranslateActivity( Activity baseAct, bool *pRequired = NULL );
|
||||
|
||||
CNetworkVar( float, m_flStunDuration );
|
||||
CNetworkVar( float, m_flStunMaxAlpha );
|
||||
|
||||
// Stats Functions
|
||||
|
||||
void Stats_WeaponFired( int weaponID );
|
||||
void Stats_WeaponHit( CDODPlayer *pVictim, int weaponID, int iDamage, int iDamageGiven, int hitgroup, float flHitDistance );
|
||||
void Stats_HitByWeapon( CDODPlayer *pAttacker, int weaponID, int iDamage, int iDamageGiven, int hitgroup );
|
||||
void Stats_KilledPlayer( CDODPlayer *pVictim, int weaponID );
|
||||
void Stats_KilledByPlayer( CDODPlayer *pAttacker, int weaponID );
|
||||
void Stats_AreaDefended( void );
|
||||
void Stats_AreaCaptured( void );
|
||||
void Stats_BonusRoundKill( void );
|
||||
void Stats_BombDetonated( void );
|
||||
|
||||
void PrintLifetimeStats( void );
|
||||
|
||||
// Called whenever this player fires a shot.
|
||||
void NoteWeaponFired();
|
||||
virtual bool WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const;
|
||||
|
||||
void TallyLatestTimePlayedPerClass( int iOldTeam, int iOldClass );
|
||||
|
||||
void ResetProgressBar( void );
|
||||
void SetProgressBarTime( int barTime );
|
||||
|
||||
void StoreCaptureBlock( int iAreaIndex, int iCapAttempt );
|
||||
int GetLastBlockCapAttempt( void );
|
||||
int GetLastBlockAreaIndex( void );
|
||||
|
||||
public:
|
||||
|
||||
CNetworkVarEmbedded( CDODPlayerShared, m_Shared );
|
||||
|
||||
int m_flNextTimeCheck; // Next time the player can execute a "timeleft" command
|
||||
|
||||
Vector m_lastStandingPos; // used by the gamemovement code for finding ladders
|
||||
|
||||
void SetSprinting( bool bIsSprinting );
|
||||
|
||||
void SetDefusing( CDODBombTarget *pTarget );
|
||||
bool m_bIsDefusing;
|
||||
CHandle<CDODBombTarget> m_pDefuseTarget;
|
||||
|
||||
void SetPlanting( CDODBombTarget *pTarget );
|
||||
bool m_bIsPlanting;
|
||||
CHandle<CDODBombTarget> m_pPlantTarget;
|
||||
|
||||
// Achievements
|
||||
void HandleHeadshotAchievement( int iNumHeadshots );
|
||||
void HandleDeployedMGKillCount( int iNumDeployedKills );
|
||||
int GetDeployedKillStreak( void );
|
||||
void HandleEnemyWeaponsAchievement( int iNumEnemyWpnKills );
|
||||
|
||||
void ResetComboWeaponKill( void );
|
||||
void HandleComboWeaponKill( int iWeaponType );
|
||||
|
||||
virtual void PlayUseDenySound();
|
||||
|
||||
int iNumKilledByUnanswered[MAX_PLAYERS+1]; // how many unanswered kills this player has been dealt by every other player
|
||||
|
||||
#if !defined(NO_STEAM)
|
||||
STEAM_GAMESERVER_CALLBACK( CDODPlayer, OnGSStatsReceived, GSStatsReceived_t, m_CallbackGSStatsReceived );
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool SelectSpawnSpot( const char *pEntClassName, CBaseEntity* &pSpot );
|
||||
|
||||
CBaseEntity *SelectSpawnSpot( CUtlVector<EHANDLE> *pSpawnPoints, int &iLastSpawnIndex );
|
||||
|
||||
// Copyed from EyeAngles() so we can send it to the client.
|
||||
CNetworkQAngle( m_angEyeAngles );
|
||||
|
||||
IDODPlayerAnimState *m_PlayerAnimState;
|
||||
|
||||
int FlashlightIsOn( void );
|
||||
void FlashlightTurnOn( void );
|
||||
void FlashlightTurnOff( void );
|
||||
|
||||
void ShowClassSelectMenu();
|
||||
|
||||
void CheckRotateIntroCam( void );
|
||||
|
||||
void State_Enter( DODPlayerState newState ); // Initialize the new state.
|
||||
void State_Leave(); // Cleanup the previous state.
|
||||
void State_PreThink(); // Update the current state.
|
||||
|
||||
// Specific state handler functions.
|
||||
void State_Enter_WELCOME();
|
||||
void State_PreThink_WELCOME();
|
||||
|
||||
void State_Enter_PICKINGTEAM();
|
||||
void State_Enter_PICKINGCLASS();
|
||||
|
||||
void State_PreThink_PICKING();
|
||||
|
||||
void State_Enter_ACTIVE();
|
||||
void State_PreThink_ACTIVE();
|
||||
|
||||
void State_Enter_OBSERVER_MODE();
|
||||
void State_PreThink_OBSERVER_MODE();
|
||||
|
||||
void State_Enter_DEATH_ANIM();
|
||||
void State_PreThink_DEATH_ANIM();
|
||||
|
||||
virtual void PlayerDeathThink();
|
||||
|
||||
// When the player joins, it cycles their view between trigger_camera entities.
|
||||
// This is the current camera, and the time that we'll switch to the next one.
|
||||
EHANDLE m_pIntroCamera;
|
||||
float m_fIntroCamTime;
|
||||
|
||||
// Find the state info for the specified state.
|
||||
static CDODPlayerStateInfo* State_LookupInfo( DODPlayerState state );
|
||||
|
||||
// This tells us which state the player is currently in (joining, observer, dying, etc).
|
||||
// Each state has a well-defined set of parameters that go with it (ie: observer is movetype_noclip, non-solid,
|
||||
// invisible, etc).
|
||||
CNetworkVar( DODPlayerState, m_iPlayerState );
|
||||
// Tracks our ragdoll entity.
|
||||
CNetworkHandle( CBaseEntity, m_hRagdoll ); // networked entity handle
|
||||
|
||||
float m_flLastMovement; // Time the player last moved, used for mp_autokick
|
||||
|
||||
void InitProne( void );
|
||||
|
||||
void InitSprinting( void );
|
||||
bool IsSprinting( void );
|
||||
bool CanSprint( void );
|
||||
|
||||
int m_iDeathFlags; // death notice flags related to domination/revenge
|
||||
|
||||
CNetworkVar( int, m_iAchievementAwardsMask );
|
||||
|
||||
protected:
|
||||
|
||||
void CreateRagdollEntity();
|
||||
|
||||
|
||||
void PhysObjectSleep();
|
||||
void PhysObjectWake();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
friend void Bot_Think( CDODPlayer *pBot ); // needs to use the HandleCommand_ stuff.
|
||||
bool HandleCommand_JoinTeam( int iTeam );
|
||||
bool HandleCommand_JoinClass( int iClass );
|
||||
|
||||
CDODPlayerStateInfo *m_pCurStateInfo; // This can be NULL if no state info is defined for m_iPlayerState.
|
||||
|
||||
bool m_bTeamChanged; //have we changed teams this spawn? Used to enforce one team switch per death rule
|
||||
|
||||
float m_flNextStaminaThink; //time to do next stamina gain
|
||||
CNetworkVar( float, m_flStamina ); //stamina for sprinting, jumping etc
|
||||
|
||||
Vector m_vecTotalBulletForce; //Accumulator for bullet force in a single frame
|
||||
|
||||
bool m_bBazookaDeployed;
|
||||
|
||||
//A list of damage given
|
||||
CUtlLinkedList< CDamageRecord *, int > m_DamageGivenList;
|
||||
|
||||
//A list of damage taken
|
||||
CUtlLinkedList< CDamageRecord *, int > m_DamageTakenList;
|
||||
|
||||
bool m_bSlowedByHit;
|
||||
float m_flUnslowTime;
|
||||
int m_iPlayerSpeed; //last updated player max speed
|
||||
|
||||
bool SetSpeed( int speed );
|
||||
|
||||
bool m_bAutoReload; // does the player want to autoreload their weapon when empty
|
||||
|
||||
bool m_bAutoRezoom; // does the player want to re-zoom after each shot for sniper rifles and bazookas
|
||||
|
||||
float m_flIdleTime; // next time we should do a deep idle
|
||||
|
||||
bool m_bIsSprinting;
|
||||
|
||||
CNetworkVar( bool, m_bSpawnInterpCounter );
|
||||
|
||||
CHintSystem m_Hints;
|
||||
|
||||
float m_flMinNextStepSoundTime;
|
||||
|
||||
int m_LastHitGroup; // the last body region that took damage
|
||||
int m_LastDamageType; // the type of damage we last took
|
||||
|
||||
bool m_bPlayingProneMoveSound;
|
||||
|
||||
int m_iCapAreaIndex;
|
||||
|
||||
// Last usercmd we shot a bullet on.
|
||||
int m_iLastWeaponFireUsercmd;
|
||||
|
||||
CNetworkVar( float, m_flProgressBarStartTime );
|
||||
CNetworkVar( int, m_iProgressBarDuration );
|
||||
|
||||
// blocking abuse protection
|
||||
int m_iLastBlockAreaIndex;
|
||||
int m_iLastBlockCapAttempt;
|
||||
|
||||
// Achievements Data
|
||||
int m_iComboWeaponKillMask;
|
||||
|
||||
bool m_bAbortFreezeCam;
|
||||
bool m_bPlayedFreezeCamSound;
|
||||
|
||||
CDODPlayerStatProperty m_StatProperty;
|
||||
|
||||
EHANDLE m_hLastDroppedWeapon;
|
||||
EHANDLE m_hLastDroppedAmmoBox;
|
||||
|
||||
float m_flTimeAsClassAccumulator;
|
||||
|
||||
public:
|
||||
|
||||
// LifeID is a unique int assigned to a player each time they spawn
|
||||
int GetLifeID() { return m_iLifeID; }
|
||||
int m_iLifeID;
|
||||
|
||||
// Stats variables
|
||||
//==================
|
||||
|
||||
// stats related to each weapon ( shots taken and given )
|
||||
weaponstat_t m_WeaponStats[MAX_WEAPONS];
|
||||
|
||||
// a list of players I have killed ( by userid )
|
||||
CUtlMap<int, playerstat_t, int> m_KilledPlayers;
|
||||
|
||||
// a list of players that have killed me ( by userid )
|
||||
CUtlMap<int, playerstat_t, int> m_KilledByPlayers;
|
||||
|
||||
// start time - used to calc total time played
|
||||
|
||||
// time played per class
|
||||
float m_flTimePlayedPerClass_Allies[7]; //0-5, 6 is random
|
||||
float m_flTimePlayedPerClass_Axis[7]; //0-5, 6 is random
|
||||
float m_flLastClassChangeTime;
|
||||
|
||||
// area cap stats
|
||||
int m_iNumAreaDefenses;
|
||||
int m_iNumAreaCaptures;
|
||||
int m_iNumBonusRoundKills;
|
||||
|
||||
|
||||
// Per-Round Stats
|
||||
//================
|
||||
|
||||
virtual void ResetPerRoundStats( void )
|
||||
{
|
||||
m_iPerRoundCaptures = 0;
|
||||
m_iPerRoundDefenses = 0;
|
||||
m_iPerRoundBombsDetonated = 0;
|
||||
m_iPerRoundKills = 0;
|
||||
}
|
||||
|
||||
int GetPerRoundCaps( void )
|
||||
{
|
||||
return m_iPerRoundCaptures;
|
||||
}
|
||||
|
||||
int GetPerRoundDefenses( void )
|
||||
{
|
||||
return m_iPerRoundDefenses;
|
||||
}
|
||||
|
||||
int GetPerRoundBombsDetonated( void )
|
||||
{
|
||||
return m_iPerRoundBombsDetonated;
|
||||
}
|
||||
|
||||
int GetPerRoundKills( void )
|
||||
{
|
||||
return m_iPerRoundKills;
|
||||
}
|
||||
|
||||
int m_iPerRoundCaptures; // how many caps this round
|
||||
int m_iPerRoundDefenses; // how many defenses this round
|
||||
int m_iPerRoundBombsDetonated;
|
||||
int m_iPerRoundKills;
|
||||
};
|
||||
|
||||
|
||||
inline CDODPlayer *ToDODPlayer( CBaseEntity *pEntity )
|
||||
{
|
||||
if ( !pEntity || !pEntity->IsPlayer() )
|
||||
return NULL;
|
||||
|
||||
#ifdef _DEBUG
|
||||
Assert( dynamic_cast<CDODPlayer*>( pEntity ) != 0 );
|
||||
#endif
|
||||
return static_cast< CDODPlayer* >( pEntity );
|
||||
}
|
||||
|
||||
inline DODPlayerState CDODPlayer::State_Get() const
|
||||
{
|
||||
return m_iPlayerState;
|
||||
}
|
||||
|
||||
#endif //DOD_PLAYER_H
|
||||
63
game/server/dod/dod_player_resource.cpp
Normal file
63
game/server/dod/dod_player_resource.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: DOD's custom CPlayerResource
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "dod_player.h"
|
||||
#include "player_resource.h"
|
||||
#include "dod_player_resource.h"
|
||||
#include <coordsize.h>
|
||||
|
||||
// Datatable
|
||||
IMPLEMENT_SERVERCLASS_ST(CDODPlayerResource, DT_DODPlayerResource)
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iObjScore), SendPropInt( SENDINFO_ARRAY(m_iObjScore), 12 ) ),
|
||||
SendPropArray3( SENDINFO_ARRAY3(m_iPlayerClass), SendPropInt( SENDINFO_ARRAY(m_iPlayerClass), 4 ) ),
|
||||
END_SEND_TABLE()
|
||||
|
||||
BEGIN_DATADESC( CDODPlayerResource )
|
||||
// DEFINE_ARRAY( m_iObjScore, FIELD_INTEGER, MAX_PLAYERS+1 ),
|
||||
// DEFINE_ARRAY( m_iPlayerClass, FIELD_INTEGER, MAX_PLAYERS+1 ),
|
||||
END_DATADESC()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( dod_player_manager, CDODPlayerResource );
|
||||
|
||||
CDODPlayerResource::CDODPlayerResource( void )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODPlayerResource::UpdatePlayerData( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 1; i <= gpGlobals->maxClients; i++ )
|
||||
{
|
||||
CDODPlayer *pPlayer = (CDODPlayer*)UTIL_PlayerByIndex( i );
|
||||
|
||||
if ( pPlayer && pPlayer->IsConnected() )
|
||||
{
|
||||
m_iObjScore.Set( i, pPlayer->GetScore() );
|
||||
m_iPlayerClass.Set( i, pPlayer->m_Shared.PlayerClass() );
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::UpdatePlayerData();
|
||||
}
|
||||
|
||||
void CDODPlayerResource::Spawn( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i=0; i < MAX_PLAYERS+1; i++ )
|
||||
{
|
||||
m_iObjScore.Set( i, 0 );
|
||||
m_iPlayerClass.Set( i, PLAYERCLASS_UNDEFINED );
|
||||
}
|
||||
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
32
game/server/dod/dod_player_resource.h
Normal file
32
game/server/dod/dod_player_resource.h
Normal file
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: DOD's custom CPlayerResource
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_PLAYER_RESOURCE_H
|
||||
#define DOD_PLAYER_RESOURCE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class CDODPlayerResource : public CPlayerResource
|
||||
{
|
||||
DECLARE_CLASS( CDODPlayerResource, CPlayerResource );
|
||||
|
||||
public:
|
||||
DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
CDODPlayerResource();
|
||||
|
||||
virtual void UpdatePlayerData( void );
|
||||
virtual void Spawn( void );
|
||||
|
||||
protected:
|
||||
CNetworkArray( int, m_iObjScore, MAX_PLAYERS+1 );
|
||||
CNetworkArray( int, m_iPlayerClass, MAX_PLAYERS+1 );
|
||||
};
|
||||
|
||||
#endif // DOD_PLAYER_RESOURCE_H
|
||||
80
game/server/dod/dod_playermove.cpp
Normal file
80
game/server/dod/dod_playermove.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "player_command.h"
|
||||
#include "igamemovement.h"
|
||||
#include "in_buttons.h"
|
||||
#include "ipredictionsystem.h"
|
||||
#include "dod_player.h"
|
||||
|
||||
|
||||
static CMoveData g_MoveData;
|
||||
CMoveData *g_pMoveData = &g_MoveData;
|
||||
|
||||
IPredictionSystem *IPredictionSystem::g_pPredictionSystems = NULL;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets up the move data for TF2
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDODPlayerMove : public CPlayerMove
|
||||
{
|
||||
DECLARE_CLASS( CDODPlayerMove, CPlayerMove );
|
||||
|
||||
public:
|
||||
//virtual void StartCommand( CBasePlayer *player, CUserCmd *cmd );
|
||||
virtual void SetupMove( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move );
|
||||
virtual void FinishMove( CBasePlayer *player, CUserCmd *ucmd, CMoveData *move );
|
||||
};
|
||||
|
||||
// PlayerMove Interface
|
||||
static CDODPlayerMove g_PlayerMove;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
CPlayerMove *PlayerMove()
|
||||
{
|
||||
return &g_PlayerMove;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main setup, finish
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
void CDODPlayerMove::StartCommand( CBasePlayer *player, CUserCmd *cmd )
|
||||
{
|
||||
BaseClass::StartCommand( player, cmd );
|
||||
}
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is called pre player movement and copies all the data necessary
|
||||
// from the player for movement. (Server-side, the client-side version
|
||||
// of this code can be found in prediction.cpp.)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODPlayerMove::SetupMove( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move )
|
||||
{
|
||||
player->AvoidPhysicsProps( ucmd );
|
||||
|
||||
BaseClass::SetupMove( player, ucmd, pHelper, move );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is called post player movement to copy back all data that
|
||||
// movement could have modified and that is necessary for future
|
||||
// movement. (Server-side, the client-side version of this code can
|
||||
// be found in prediction.cpp.)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODPlayerMove::FinishMove( CBasePlayer *player, CUserCmd *ucmd, CMoveData *move )
|
||||
{
|
||||
// Call the default FinishMove code.
|
||||
BaseClass::FinishMove( player, ucmd, move );
|
||||
}
|
||||
72
game/server/dod/dod_riflegrenade_ger.cpp
Normal file
72
game/server/dod/dod_riflegrenade_ger.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_riflegrenade_ger.h"
|
||||
#include "dod_shareddefs.h"
|
||||
|
||||
#define GRENADE_MODEL "models/Weapons/w_k98_rg_grenade.mdl"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( grenade_riflegren_ger, CDODRifleGrenadeGER );
|
||||
PRECACHE_WEAPON_REGISTER( grenade_riflegren_ger );
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST( CDODRifleGrenadeGER, DT_DODRifleGrenadeGER )
|
||||
END_SEND_TABLE()
|
||||
|
||||
CDODRifleGrenadeGER* CDODRifleGrenadeGER::Create(
|
||||
const Vector &position,
|
||||
const QAngle &angles,
|
||||
const Vector &velocity,
|
||||
const AngularImpulse &angVelocity,
|
||||
CBaseCombatCharacter *pOwner,
|
||||
float timer,
|
||||
DODWeaponID weaponID )
|
||||
{
|
||||
CDODRifleGrenadeGER *pGrenade = (CDODRifleGrenadeGER*)CBaseEntity::Create( "grenade_riflegren_ger", position, angles, pOwner );
|
||||
|
||||
Assert( pGrenade );
|
||||
|
||||
if( !pGrenade )
|
||||
return NULL;
|
||||
|
||||
IPhysicsObject *pPhysicsObject = pGrenade->VPhysicsGetObject();
|
||||
if ( pPhysicsObject )
|
||||
{
|
||||
pPhysicsObject->AddVelocity( &velocity, &angVelocity );
|
||||
}
|
||||
|
||||
// Who threw this grenade
|
||||
pGrenade->SetThrower( pOwner );
|
||||
|
||||
pGrenade->ChangeTeam( pOwner->GetTeamNumber() );
|
||||
|
||||
// How long until we explode
|
||||
pGrenade->SetDetonateTimerLength( timer );
|
||||
|
||||
// Save the weapon id for stats purposes
|
||||
pGrenade->m_EmitterWeaponID = weaponID;
|
||||
|
||||
return pGrenade;
|
||||
}
|
||||
|
||||
void CDODRifleGrenadeGER::Spawn()
|
||||
{
|
||||
SetModel( GRENADE_MODEL );
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
|
||||
void CDODRifleGrenadeGER::Precache()
|
||||
{
|
||||
PrecacheModel( GRENADE_MODEL );
|
||||
PrecacheScriptSound( "HEGrenade.Bounce" );
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
//Pass the classname of the exploding version of this grenade.
|
||||
char *CDODRifleGrenadeGER::GetExplodingClassname()
|
||||
{
|
||||
return "weapon_riflegren_ger_live";
|
||||
}
|
||||
49
game/server/dod/dod_riflegrenade_ger.h
Normal file
49
game/server/dod/dod_riflegrenade_ger.h
Normal file
@@ -0,0 +1,49 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_RIFLEGRENADE_GER_H
|
||||
#define DOD_RIFLEGRENADE_GER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "dod_basegrenade.h"
|
||||
|
||||
class CDODRifleGrenadeGER : public CDODBaseGrenade
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODRifleGrenadeGER, CDODBaseGrenade );
|
||||
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
// Overrides
|
||||
public:
|
||||
CDODRifleGrenadeGER() {}
|
||||
virtual void Spawn();
|
||||
virtual void Precache();
|
||||
|
||||
// Grenade stuff.
|
||||
public:
|
||||
|
||||
static CDODRifleGrenadeGER* Create(
|
||||
const Vector &position,
|
||||
const QAngle &angles,
|
||||
const Vector &velocity,
|
||||
const AngularImpulse &angVelocity,
|
||||
CBaseCombatCharacter *pOwner,
|
||||
float timer,
|
||||
DODWeaponID weaponID );
|
||||
|
||||
virtual char *GetExplodingClassname();
|
||||
|
||||
virtual float GetElasticity() { return 0.05; }
|
||||
|
||||
private:
|
||||
float m_flDetonateTime;
|
||||
};
|
||||
|
||||
|
||||
#endif // DOD_RIFLEGRENADE_GER_H
|
||||
72
game/server/dod/dod_riflegrenade_us.cpp
Normal file
72
game/server/dod/dod_riflegrenade_us.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_riflegrenade_us.h"
|
||||
#include "dod_shareddefs.h"
|
||||
|
||||
#define GRENADE_MODEL "models/Weapons/w_garand_rg_grenade.mdl"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( grenade_riflegren_us, CDODRifleGrenadeUS );
|
||||
PRECACHE_WEAPON_REGISTER( grenade_riflegren_us );
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST( CDODRifleGrenadeUS, DT_DODRifleGrenadeUS )
|
||||
END_SEND_TABLE()
|
||||
|
||||
CDODRifleGrenadeUS* CDODRifleGrenadeUS::Create(
|
||||
const Vector &position,
|
||||
const QAngle &angles,
|
||||
const Vector &velocity,
|
||||
const AngularImpulse &angVelocity,
|
||||
CBaseCombatCharacter *pOwner,
|
||||
float timer,
|
||||
DODWeaponID weaponID )
|
||||
{
|
||||
CDODRifleGrenadeUS *pGrenade = (CDODRifleGrenadeUS*)CBaseEntity::Create( "grenade_riflegren_us", position, angles, pOwner );
|
||||
|
||||
Assert( pGrenade );
|
||||
|
||||
if( !pGrenade )
|
||||
return NULL;
|
||||
|
||||
IPhysicsObject *pPhysicsObject = pGrenade->VPhysicsGetObject();
|
||||
if ( pPhysicsObject )
|
||||
{
|
||||
pPhysicsObject->AddVelocity( &velocity, &angVelocity );
|
||||
}
|
||||
|
||||
// Who threw this grenade
|
||||
pGrenade->SetThrower( pOwner );
|
||||
|
||||
pGrenade->ChangeTeam( pOwner->GetTeamNumber() );
|
||||
|
||||
// How long until we explode
|
||||
pGrenade->SetDetonateTimerLength( timer );
|
||||
|
||||
// Save the weapon id for stats purposes
|
||||
pGrenade->m_EmitterWeaponID = weaponID;
|
||||
|
||||
return pGrenade;
|
||||
}
|
||||
|
||||
void CDODRifleGrenadeUS::Spawn()
|
||||
{
|
||||
SetModel( GRENADE_MODEL );
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
|
||||
void CDODRifleGrenadeUS::Precache()
|
||||
{
|
||||
PrecacheModel( GRENADE_MODEL );
|
||||
PrecacheScriptSound( "HEGrenade.Bounce" );
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
//Pass the classname of the exploding version of this grenade.
|
||||
char *CDODRifleGrenadeUS::GetExplodingClassname()
|
||||
{
|
||||
return "weapon_riflegren_us_live";
|
||||
}
|
||||
49
game/server/dod/dod_riflegrenade_us.h
Normal file
49
game/server/dod/dod_riflegrenade_us.h
Normal file
@@ -0,0 +1,49 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_RIFLEGRENADE_US_H
|
||||
#define DOD_RIFLEGRENADE_US_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "dod_basegrenade.h"
|
||||
|
||||
class CDODRifleGrenadeUS : public CDODBaseGrenade
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODRifleGrenadeUS, CDODBaseGrenade );
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
|
||||
// Overrides.
|
||||
public:
|
||||
CDODRifleGrenadeUS() {}
|
||||
virtual void Spawn();
|
||||
virtual void Precache();
|
||||
|
||||
// Grenade stuff.
|
||||
public:
|
||||
|
||||
static CDODRifleGrenadeUS* Create(
|
||||
const Vector &position,
|
||||
const QAngle &angles,
|
||||
const Vector &velocity,
|
||||
const AngularImpulse &angVelocity,
|
||||
CBaseCombatCharacter *pOwner,
|
||||
float timer,
|
||||
DODWeaponID weaponID );
|
||||
|
||||
virtual char *GetExplodingClassname();
|
||||
|
||||
virtual float GetElasticity() { return 0.05; }
|
||||
|
||||
private:
|
||||
float m_flDetonateTime;
|
||||
};
|
||||
|
||||
|
||||
#endif // DOD_RIFLEGRENADE_US_H
|
||||
121
game/server/dod/dod_smokegrenade.cpp
Normal file
121
game/server/dod/dod_smokegrenade.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_smokegrenade.h"
|
||||
#include "particle_parse.h"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( grenade_smoke, CDODSmokeGrenade );
|
||||
PRECACHE_WEAPON_REGISTER( grenade_smoke );
|
||||
|
||||
BEGIN_DATADESC( CDODSmokeGrenade )
|
||||
DEFINE_THINKFUNC( Think_Emit ),
|
||||
DEFINE_THINKFUNC( Think_Fade ),
|
||||
DEFINE_THINKFUNC( Think_Remove )
|
||||
END_DATADESC()
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST( CDODSmokeGrenade, DT_DODSmokeGrenade )
|
||||
SendPropTime(SENDINFO(m_flSmokeSpawnTime) ),
|
||||
END_SEND_TABLE()
|
||||
|
||||
void CDODSmokeGrenade::Spawn()
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
SetThink( &CDODSmokeGrenade::Think_Emit );
|
||||
SetNextThink( gpGlobals->curtime + 0.5 );
|
||||
|
||||
m_bInitialSmoke = false;
|
||||
m_flRemoveTime = -1;
|
||||
m_flSmokeSpawnTime = 0;
|
||||
}
|
||||
|
||||
void CDODSmokeGrenade::Precache()
|
||||
{
|
||||
PrecacheScriptSound( "SmokeGrenade.Bounce" );
|
||||
PrecacheParticleSystem( "smokegrenade" );
|
||||
PrecacheParticleSystem( "smokegrenade_jet" );
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
void CDODSmokeGrenade::BounceSound( void )
|
||||
{
|
||||
EmitSound( "SmokeGrenade.Bounce" );
|
||||
}
|
||||
|
||||
void CDODSmokeGrenade::Think_Emit( void )
|
||||
{
|
||||
// if we're stationary and have not yet created smoke, do so now
|
||||
Vector vel;
|
||||
AngularImpulse a;
|
||||
VPhysicsGetObject()->GetVelocity( &vel, &a );
|
||||
|
||||
if ( vel.Length() < 15.0 && !m_bInitialSmoke )
|
||||
{
|
||||
VPhysicsGetObject()->EnableMotion( false );
|
||||
|
||||
// Smoke Cloud
|
||||
DispatchParticleEffect( "smokegrenade", GetAbsOrigin(), vec3_angle );
|
||||
|
||||
// Smoke Jet
|
||||
DispatchParticleEffect( "smokegrenade_jet", PATTACH_POINT, this, "jet" );
|
||||
|
||||
EmitSound( "BaseSmokeEffect.Sound" );
|
||||
|
||||
m_flRemoveTime = gpGlobals->curtime + 10;
|
||||
|
||||
m_bInitialSmoke = true;
|
||||
|
||||
m_flSmokeSpawnTime = gpGlobals->curtime;
|
||||
}
|
||||
|
||||
// if its past our bedtime, fade out
|
||||
if ( m_flRemoveTime > 0 && gpGlobals->curtime > m_flRemoveTime )
|
||||
{
|
||||
m_nRenderMode = kRenderTransColor;
|
||||
SetThink( &CDODSmokeGrenade::Think_Fade );
|
||||
}
|
||||
|
||||
SetNextThink( gpGlobals->curtime + 0.1 );
|
||||
}
|
||||
|
||||
// Fade the projectile out over time before making it disappear
|
||||
void CDODSmokeGrenade::Think_Fade()
|
||||
{
|
||||
m_bFading = true;
|
||||
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
|
||||
color32 c = GetRenderColor();
|
||||
c.a -= 1;
|
||||
SetRenderColor( c.r, c.b, c.g, c.a );
|
||||
|
||||
if ( !c.a )
|
||||
{
|
||||
SetModelName( NULL_STRING );//invisible
|
||||
SetNextThink( gpGlobals->curtime + 10 );
|
||||
SetThink( &CDODSmokeGrenade::Think_Remove ); // Spit out smoke for 10 seconds.
|
||||
SetSolid( SOLID_NONE );
|
||||
}
|
||||
}
|
||||
|
||||
void CDODSmokeGrenade::Think_Remove()
|
||||
{
|
||||
// stop all effects
|
||||
StopParticleEffects( this );
|
||||
|
||||
SetModelName( NULL_STRING );//invisible
|
||||
SetSolid( SOLID_NONE );
|
||||
SetMoveType( MOVETYPE_NONE );
|
||||
|
||||
UTIL_Remove( this );
|
||||
}
|
||||
|
||||
|
||||
void CDODSmokeGrenade::Detonate( void )
|
||||
{
|
||||
// Intentionally blank - our detonate does nothing
|
||||
}
|
||||
42
game/server/dod/dod_smokegrenade.h
Normal file
42
game/server/dod/dod_smokegrenade.h
Normal file
@@ -0,0 +1,42 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_SMOKEGRENADE_H
|
||||
#define DOD_SMOKEGRENADE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "dod_basegrenade.h"
|
||||
|
||||
class CDODSmokeGrenade : public CDODBaseGrenade
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODSmokeGrenade, CDODBaseGrenade );
|
||||
DECLARE_DATADESC();
|
||||
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
virtual void Spawn();
|
||||
virtual void Precache();
|
||||
virtual void BounceSound( void );
|
||||
virtual void Detonate();
|
||||
|
||||
virtual bool CanBePickedUp( void ) { return false; }
|
||||
|
||||
void Think_Emit();
|
||||
void Think_Fade();
|
||||
void Think_Remove();
|
||||
|
||||
private:
|
||||
bool m_bFading;
|
||||
bool m_bInitialSmoke;
|
||||
float m_flRemoveTime;
|
||||
|
||||
CNetworkVar( float, m_flSmokeSpawnTime );
|
||||
};
|
||||
|
||||
#endif // DOD_SMOKEGRENADE_H
|
||||
53
game/server/dod/dod_smokegrenade_ger.cpp
Normal file
53
game/server/dod/dod_smokegrenade_ger.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_smokegrenade_ger.h"
|
||||
|
||||
#define GRENADE_MODEL "models/Weapons/w_smoke_ger.mdl"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( grenade_smoke_ger, CDODSmokeGrenadeGER );
|
||||
PRECACHE_WEAPON_REGISTER( grenade_smoke_ger );
|
||||
|
||||
CDODSmokeGrenadeGER* CDODSmokeGrenadeGER::Create(
|
||||
const Vector &position,
|
||||
const QAngle &angles,
|
||||
const Vector &velocity,
|
||||
const AngularImpulse &angVelocity,
|
||||
CBaseCombatCharacter *pOwner )
|
||||
{
|
||||
CDODSmokeGrenadeGER *pGrenade = (CDODSmokeGrenadeGER*)CBaseEntity::Create( "grenade_smoke_ger", position, angles, pOwner );
|
||||
|
||||
Assert( pGrenade );
|
||||
|
||||
if( !pGrenade )
|
||||
return NULL;
|
||||
|
||||
IPhysicsObject *pPhysicsObject = pGrenade->VPhysicsGetObject();
|
||||
if ( pPhysicsObject )
|
||||
{
|
||||
pPhysicsObject->AddVelocity( &velocity, &angVelocity );
|
||||
}
|
||||
|
||||
// Who threw this grenade
|
||||
pGrenade->SetThrower( pOwner );
|
||||
|
||||
pGrenade->ChangeTeam( pOwner->GetTeamNumber() );
|
||||
|
||||
return pGrenade;
|
||||
}
|
||||
|
||||
void CDODSmokeGrenadeGER::Spawn()
|
||||
{
|
||||
SetModel( GRENADE_MODEL );
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
|
||||
void CDODSmokeGrenadeGER::Precache()
|
||||
{
|
||||
PrecacheModel( GRENADE_MODEL );
|
||||
BaseClass::Precache();
|
||||
}
|
||||
38
game/server/dod/dod_smokegrenade_ger.h
Normal file
38
game/server/dod/dod_smokegrenade_ger.h
Normal file
@@ -0,0 +1,38 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_SMOKEGRENADE_GER_H
|
||||
#define DOD_SMOKEGRENADE_GER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "dod_smokegrenade.h"
|
||||
|
||||
class CDODSmokeGrenadeGER : public CDODSmokeGrenade
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODSmokeGrenadeGER, CDODSmokeGrenade );
|
||||
|
||||
// Overrides.
|
||||
public:
|
||||
CDODSmokeGrenadeGER() {}
|
||||
virtual void Spawn();
|
||||
virtual void Precache();
|
||||
|
||||
// Grenade stuff.
|
||||
public:
|
||||
static CDODSmokeGrenadeGER* Create(
|
||||
const Vector &position,
|
||||
const QAngle &angles,
|
||||
const Vector &velocity,
|
||||
const AngularImpulse &angVelocity,
|
||||
CBaseCombatCharacter *pOwner );
|
||||
|
||||
virtual DODWeaponID GetEmitterWeaponID() { return WEAPON_SMOKE_GER; }
|
||||
};
|
||||
|
||||
#endif // DOD_SMOKEGRENADE_GER_H
|
||||
53
game/server/dod/dod_smokegrenade_us.cpp
Normal file
53
game/server/dod/dod_smokegrenade_us.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_smokegrenade_us.h"
|
||||
|
||||
#define GRENADE_MODEL "models/Weapons/w_smoke_us.mdl"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( grenade_smoke_us, CDODSmokeGrenadeUS );
|
||||
PRECACHE_WEAPON_REGISTER( grenade_smoke_us );
|
||||
|
||||
CDODSmokeGrenadeUS* CDODSmokeGrenadeUS::Create(
|
||||
const Vector &position,
|
||||
const QAngle &angles,
|
||||
const Vector &velocity,
|
||||
const AngularImpulse &angVelocity,
|
||||
CBaseCombatCharacter *pOwner )
|
||||
{
|
||||
CDODSmokeGrenadeUS *pGrenade = (CDODSmokeGrenadeUS*)CBaseEntity::Create( "grenade_smoke_us", position, angles, pOwner );
|
||||
|
||||
Assert( pGrenade );
|
||||
|
||||
if( !pGrenade )
|
||||
return NULL;
|
||||
|
||||
IPhysicsObject *pPhysicsObject = pGrenade->VPhysicsGetObject();
|
||||
if ( pPhysicsObject )
|
||||
{
|
||||
pPhysicsObject->AddVelocity( &velocity, &angVelocity );
|
||||
}
|
||||
|
||||
// Who threw this grenade
|
||||
pGrenade->SetThrower( pOwner );
|
||||
|
||||
pGrenade->ChangeTeam( pOwner->GetTeamNumber() );
|
||||
|
||||
return pGrenade;
|
||||
}
|
||||
|
||||
void CDODSmokeGrenadeUS::Spawn()
|
||||
{
|
||||
SetModel( GRENADE_MODEL );
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
|
||||
void CDODSmokeGrenadeUS::Precache()
|
||||
{
|
||||
PrecacheModel( GRENADE_MODEL );
|
||||
BaseClass::Precache();
|
||||
}
|
||||
38
game/server/dod/dod_smokegrenade_us.h
Normal file
38
game/server/dod/dod_smokegrenade_us.h
Normal file
@@ -0,0 +1,38 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_SMOKEGRENADE_US_H
|
||||
#define DOD_SMOKEGRENADE_US_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "dod_smokegrenade.h"
|
||||
|
||||
class CDODSmokeGrenadeUS : public CDODSmokeGrenade
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODSmokeGrenadeUS, CDODSmokeGrenade );
|
||||
|
||||
// Overrides.
|
||||
public:
|
||||
CDODSmokeGrenadeUS() {}
|
||||
virtual void Spawn();
|
||||
virtual void Precache();
|
||||
|
||||
// Grenade stuff.
|
||||
public:
|
||||
static CDODSmokeGrenadeUS* Create(
|
||||
const Vector &position,
|
||||
const QAngle &angles,
|
||||
const Vector &velocity,
|
||||
const AngularImpulse &angVelocity,
|
||||
CBaseCombatCharacter *pOwner );
|
||||
|
||||
virtual DODWeaponID GetEmitterWeaponID() { return WEAPON_SMOKE_US; }
|
||||
};
|
||||
|
||||
#endif // DOD_SMOKEGRENADE_US_H
|
||||
82
game/server/dod/dod_statmgr.cpp
Normal file
82
game/server/dod/dod_statmgr.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Handle stats game events and route them to the appropriate place
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "KeyValues.h"
|
||||
#include "dod_statmgr.h"
|
||||
#include "dod_player.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
CDODStatManager::CDODStatManager()
|
||||
{
|
||||
}
|
||||
|
||||
bool CDODStatManager::Init()
|
||||
{
|
||||
ListenForGameEvent( "player_death" );
|
||||
ListenForGameEvent( "dod_stats_weapon_attack" );
|
||||
ListenForGameEvent( "dod_stats_player_damage" );
|
||||
ListenForGameEvent( "dod_stats_player_killed" );
|
||||
|
||||
return BaseClass::Init();
|
||||
}
|
||||
|
||||
void CDODStatManager::FireGameEvent( IGameEvent *event )
|
||||
{
|
||||
const char *eventName = event->GetName();
|
||||
|
||||
if ( FStrEq( eventName, "dod_stats_weapon_attack" ) )
|
||||
{
|
||||
CDODPlayer *pAttacker = ToDODPlayer( UTIL_PlayerByUserId( event->GetInt("attacker") ) );
|
||||
|
||||
Assert( pAttacker );
|
||||
|
||||
if ( pAttacker )
|
||||
pAttacker->Stats_WeaponFired( event->GetInt("weapon") );
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_stats_player_damage" ) )
|
||||
{
|
||||
CDODPlayer *pAttacker = ToDODPlayer( UTIL_PlayerByUserId( event->GetInt("attacker") ) );
|
||||
|
||||
int iVictimID = event->GetInt("victim");
|
||||
CDODPlayer *pVictim = ToDODPlayer( UTIL_PlayerByUserId( iVictimID ) );
|
||||
|
||||
// discard damage to teammates or to yourself
|
||||
if ( ( pAttacker == NULL ) || ( pVictim->GetTeamNumber() == pAttacker->GetTeamNumber() ) )
|
||||
return;
|
||||
|
||||
int weaponID = event->GetInt("weapon");
|
||||
int iDamage = event->GetInt("damage");
|
||||
int iDamageGiven = event->GetInt("damage_given");
|
||||
float flDistance = event->GetFloat("distance");
|
||||
int hitgroup = event->GetInt("hitgroup");
|
||||
|
||||
pAttacker->Stats_WeaponHit( pVictim, weaponID, iDamage, iDamageGiven, hitgroup, flDistance );
|
||||
pVictim->Stats_HitByWeapon( pAttacker, weaponID, iDamage, iDamageGiven, hitgroup );
|
||||
}
|
||||
else if ( FStrEq( eventName, "dod_stats_player_killed" ) )
|
||||
{
|
||||
int iVictimID = event->GetInt("victim");
|
||||
CDODPlayer *pVictim = ToDODPlayer( UTIL_PlayerByUserId( iVictimID ) );
|
||||
|
||||
CDODPlayer *pAttacker = ToDODPlayer( UTIL_PlayerByUserId( event->GetInt("attacker") ) );
|
||||
|
||||
// discard kills to teammates or to yourself
|
||||
if ( ( pAttacker == NULL ) || ( pVictim->GetTeamNumber() == pAttacker->GetTeamNumber() ) )
|
||||
return;
|
||||
|
||||
int weaponID = event->GetInt("weapon");
|
||||
|
||||
pAttacker->Stats_KilledPlayer( pVictim, weaponID );
|
||||
pVictim->Stats_KilledByPlayer( pAttacker, weaponID );
|
||||
}
|
||||
}
|
||||
|
||||
CDODStatManager g_DODStatMgr;
|
||||
78
game/server/dod/dod_statmgr.h
Normal file
78
game/server/dod/dod_statmgr.h
Normal file
@@ -0,0 +1,78 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_STATMGR_H
|
||||
#define DOD_STATMGR_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "GameEventListener.h"
|
||||
#include <igamesystem.h>
|
||||
|
||||
// Structure that holds all information related to how a player related to a
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
// shots taken
|
||||
int m_iNumShotsTaken;
|
||||
|
||||
// shots hit
|
||||
int m_iNumShotsHit;
|
||||
|
||||
// total damage given
|
||||
int m_iTotalDamageGiven;
|
||||
|
||||
// average distance of hit shots
|
||||
float m_flAverageHitDistance;
|
||||
|
||||
// total kills
|
||||
int m_iNumKills;
|
||||
|
||||
// times we hit each hitgroup
|
||||
int m_iBodygroupsHit[7];
|
||||
|
||||
// times hit by this weapon
|
||||
int m_iNumHitsTaken;
|
||||
|
||||
// total damage given to us
|
||||
int m_iTotalDamageTaken;
|
||||
|
||||
// times killed by this weapon
|
||||
int m_iTimesKilled;
|
||||
|
||||
// times we were hit in each hitgroup
|
||||
int m_iHitInBodygroups[8];
|
||||
} weaponstat_t;
|
||||
|
||||
// Can be used to represent a victim and how many times we killed him,
|
||||
// or as an attacker, how many times we were killed by this person
|
||||
typedef struct
|
||||
{
|
||||
char m_szPlayerName[MAX_PLAYER_NAME_LENGTH]; // when we add this player, store the player name
|
||||
int m_iUserID; // player that did the killing
|
||||
int m_iKills; // number of kills
|
||||
int m_iTotalDamage; // amount of damage
|
||||
} playerstat_t;
|
||||
|
||||
class CDODStatManager : public CGameEventListener, public CAutoGameSystem
|
||||
{
|
||||
private:
|
||||
typedef CBaseGameSystem BaseClass;
|
||||
|
||||
public:
|
||||
CDODStatManager();
|
||||
|
||||
public: // IGameEventListener Interface
|
||||
virtual void FireGameEvent( IGameEvent * event );
|
||||
|
||||
public: // CBaseGameSystem overrides
|
||||
virtual bool Init();
|
||||
//virtual void Shutdown() {}
|
||||
};
|
||||
|
||||
|
||||
#endif // DOD_STATMGR_H
|
||||
78
game/server/dod/dod_stickgrenade.cpp
Normal file
78
game/server/dod/dod_stickgrenade.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "dod_stickgrenade.h"
|
||||
#include "dod_shareddefs.h"
|
||||
|
||||
#define GRENADE_MODEL "models/Weapons/w_stick.mdl"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( grenade_frag_ger, CDODStickGrenade );
|
||||
PRECACHE_WEAPON_REGISTER( grenade_frag_ger );
|
||||
|
||||
CDODStickGrenade* CDODStickGrenade::Create(
|
||||
const Vector &position,
|
||||
const QAngle &angles,
|
||||
const Vector &velocity,
|
||||
const AngularImpulse &angVelocity,
|
||||
CBaseCombatCharacter *pOwner,
|
||||
float timer,
|
||||
DODWeaponID weaponID )
|
||||
{
|
||||
CDODStickGrenade *pGrenade = (CDODStickGrenade*)CBaseEntity::Create( "grenade_frag_ger", position, angles, pOwner );
|
||||
|
||||
Assert( pGrenade );
|
||||
|
||||
if( !pGrenade )
|
||||
return NULL;
|
||||
|
||||
IPhysicsObject *pPhysicsObject = pGrenade->VPhysicsGetObject();
|
||||
if ( pPhysicsObject )
|
||||
{
|
||||
pPhysicsObject->AddVelocity( &velocity, &angVelocity );
|
||||
}
|
||||
|
||||
pGrenade->SetupInitialTransmittedGrenadeVelocity( velocity );
|
||||
|
||||
// Who threw this grenade
|
||||
pGrenade->SetThrower( pOwner );
|
||||
|
||||
pGrenade->ChangeTeam( pOwner->GetTeamNumber() );
|
||||
|
||||
// How long until we explode
|
||||
pGrenade->SetDetonateTimerLength( timer );
|
||||
|
||||
// Save the weapon id for stats purposes
|
||||
pGrenade->m_EmitterWeaponID = weaponID;
|
||||
|
||||
return pGrenade;
|
||||
}
|
||||
|
||||
void CDODStickGrenade::Spawn()
|
||||
{
|
||||
SetModel( GRENADE_MODEL );
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
|
||||
void CDODStickGrenade::Precache()
|
||||
{
|
||||
PrecacheModel( GRENADE_MODEL );
|
||||
|
||||
PrecacheScriptSound( "HEGrenade.Bounce" );
|
||||
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
void CDODStickGrenade::BounceSound( void )
|
||||
{
|
||||
EmitSound( "HEGrenade.Bounce" );
|
||||
}
|
||||
|
||||
//Pass the classname of the exploding version of this grenade.
|
||||
char *CDODStickGrenade::GetExplodingClassname()
|
||||
{
|
||||
return "weapon_frag_ger_live";
|
||||
}
|
||||
50
game/server/dod/dod_stickgrenade.h
Normal file
50
game/server/dod/dod_stickgrenade.h
Normal file
@@ -0,0 +1,50 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_STICKGRENADE_H
|
||||
#define DOD_STICKGRENADE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "dod_basegrenade.h"
|
||||
|
||||
class CDODStickGrenade : public CDODBaseGrenade
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CDODStickGrenade, CDODBaseGrenade );
|
||||
|
||||
|
||||
// Overrides.
|
||||
public:
|
||||
CDODStickGrenade() {}
|
||||
virtual void Spawn();
|
||||
virtual void Precache();
|
||||
virtual void BounceSound( void );
|
||||
|
||||
// Grenade stuff.
|
||||
public:
|
||||
|
||||
static CDODStickGrenade* Create(
|
||||
const Vector &position,
|
||||
const QAngle &angles,
|
||||
const Vector &velocity,
|
||||
const AngularImpulse &angVelocity,
|
||||
CBaseCombatCharacter *pOwner,
|
||||
float timer,
|
||||
DODWeaponID weaponID );
|
||||
|
||||
void SetTimer( float timer );
|
||||
|
||||
virtual char *GetExplodingClassname();
|
||||
|
||||
private:
|
||||
float m_flDetonateTime;
|
||||
CDODStickGrenade( const CDODStickGrenade & );
|
||||
};
|
||||
|
||||
|
||||
#endif // DOD_STICKGRENADE_H
|
||||
168
game/server/dod/dod_team.cpp
Normal file
168
game/server/dod/dod_team.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Team management class. Contains all the details for a specific team
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "dod_team.h"
|
||||
#include "entitylist.h"
|
||||
#include "dod_shareddefs.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
// Datatable
|
||||
IMPLEMENT_SERVERCLASS_ST(CDODTeam, DT_DODTeam)
|
||||
END_SEND_TABLE()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( dod_team_manager, CDODTeam );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get a pointer to the specified TF team manager
|
||||
//-----------------------------------------------------------------------------
|
||||
CDODTeam *GetGlobalDODTeam( int iIndex )
|
||||
{
|
||||
return (CDODTeam*)GetGlobalTeam( iIndex );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Needed because this is an entity, but should never be used
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDODTeam::Init( const char *pName, int iNumber )
|
||||
{
|
||||
BaseClass::Init( pName, iNumber );
|
||||
|
||||
// Only detect changes every half-second.
|
||||
NetworkProp()->SetUpdateInterval( 0.75f );
|
||||
|
||||
m_hPlayerClassInfoHandles.Purge();
|
||||
}
|
||||
|
||||
void CDODTeam::AddPlayerClass( const char *szClassName )
|
||||
{
|
||||
PLAYERCLASS_FILE_INFO_HANDLE hPlayerClassInfo;
|
||||
|
||||
if ( ReadPlayerClassDataFromFileForSlot( filesystem, szClassName, &hPlayerClassInfo, GetEncryptionKey() ) )
|
||||
{
|
||||
m_hPlayerClassInfoHandles.AddToTail( hPlayerClassInfo );
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( !"missing playerclass script file" );
|
||||
Msg( "Missing playerclass script file for class: %s\n", szClassName );
|
||||
}
|
||||
}
|
||||
|
||||
const CDODPlayerClassInfo &CDODTeam::GetPlayerClassInfo( int iPlayerClass ) const
|
||||
{
|
||||
Assert( iPlayerClass >= 0 && iPlayerClass < m_hPlayerClassInfoHandles.Count() );
|
||||
|
||||
const FilePlayerClassInfo_t *pPlayerClassInfo = GetFilePlayerClassInfoFromHandle( m_hPlayerClassInfoHandles[iPlayerClass] );
|
||||
const CDODPlayerClassInfo *pDODInfo;
|
||||
|
||||
#ifdef _DEBUG
|
||||
pDODInfo = dynamic_cast< const CDODPlayerClassInfo* >( pPlayerClassInfo );
|
||||
Assert( pDODInfo );
|
||||
#else
|
||||
pDODInfo = static_cast< const CDODPlayerClassInfo* >( pPlayerClassInfo );
|
||||
#endif
|
||||
|
||||
return *pDODInfo;
|
||||
}
|
||||
|
||||
bool CDODTeam::IsClassOnTeam( const char *pszClassName, int &iClassNum ) const
|
||||
{
|
||||
iClassNum = PLAYERCLASS_UNDEFINED;
|
||||
|
||||
// Random is always on every team
|
||||
if( FStrEq( pszClassName, "cls_random" ) )
|
||||
{
|
||||
iClassNum = PLAYERCLASS_RANDOM;
|
||||
return true;
|
||||
}
|
||||
|
||||
for( int i=0;i<m_hPlayerClassInfoHandles.Count(); i++ )
|
||||
{
|
||||
FilePlayerClassInfo_t *pPlayerClassInfo = GetFilePlayerClassInfoFromHandle( m_hPlayerClassInfoHandles[i] );
|
||||
|
||||
if( stricmp( pszClassName, pPlayerClassInfo->m_szSelectCmd ) == 0 )
|
||||
{
|
||||
iClassNum = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CDODTeam::ResetScores( void )
|
||||
{
|
||||
SetRoundsWon(0);
|
||||
SetScore(0);
|
||||
}
|
||||
|
||||
//==================================
|
||||
// TEAMS!
|
||||
//==================================
|
||||
|
||||
// US REGULARS
|
||||
//==================
|
||||
|
||||
class CDODTeam_Allies : public CDODTeam
|
||||
{
|
||||
DECLARE_CLASS( CDODTeam_Allies, CDODTeam );
|
||||
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
virtual void Init( const char *pName, int iNumber )
|
||||
{
|
||||
BaseClass::Init( pName, iNumber );
|
||||
|
||||
int i = 0;
|
||||
while( pszTeamAlliesClasses[i] != NULL )
|
||||
{
|
||||
AddPlayerClass( pszTeamAlliesClasses[i] );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
virtual const char *GetTeamName( void ) { return "#Teamname_Allies"; }
|
||||
};
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST(CDODTeam_Allies, DT_DODTeam_Allies)
|
||||
END_SEND_TABLE()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( dod_team_allies, CDODTeam_Allies );
|
||||
|
||||
|
||||
// AXIS REGULAR
|
||||
//==================
|
||||
|
||||
class CDODTeam_Axis : public CDODTeam
|
||||
{
|
||||
DECLARE_CLASS( CDODTeam_Axis, CDODTeam );
|
||||
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
virtual void Init( const char *pName, int iNumber )
|
||||
{
|
||||
BaseClass::Init( pName, iNumber );
|
||||
|
||||
int i = 0;
|
||||
while( pszTeamAxisClasses[i] != NULL )
|
||||
{
|
||||
AddPlayerClass( pszTeamAxisClasses[i] );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
virtual const char *GetTeamName( void ) { return "#Teamname_Allies"; }
|
||||
};
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST(CDODTeam_Axis, DT_DODTeam_Axis)
|
||||
END_SEND_TABLE()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( dod_team_axis, CDODTeam_Axis );
|
||||
60
game/server/dod/dod_team.h
Normal file
60
game/server/dod/dod_team.h
Normal file
@@ -0,0 +1,60 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Team management class. Contains all the details for a specific team
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DOD_TEAM_H
|
||||
#define DOD_TEAM_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "utlvector.h"
|
||||
#include "team.h"
|
||||
#include "playerclass_info_parse.h"
|
||||
#include "dod_playerclass_info_parse.h"
|
||||
#include "dod_shareddefs.h"
|
||||
#include "dod_player.h"
|
||||
|
||||
typedef CUtlLinkedList< PLAYERCLASS_FILE_INFO_HANDLE, int > PlayerClassInfoList;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Team Manager
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDODTeam : public CTeam
|
||||
{
|
||||
DECLARE_CLASS( CDODTeam, CTeam );
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
public:
|
||||
|
||||
// Initialization
|
||||
virtual void Init( const char *pName, int iNumber );
|
||||
|
||||
CDODPlayerClassInfo const &GetPlayerClassInfo( int iPlayerClass ) const;
|
||||
const unsigned char *GetEncryptionKey( void ) { return g_pGameRules->GetEncryptionKey(); }
|
||||
|
||||
virtual void AddPlayerClass( const char *pszClassName );
|
||||
|
||||
bool IsClassOnTeam( const char *pszClassName, int &iClassNum ) const;
|
||||
int GetNumPlayerClasses( void ) { return m_hPlayerClassInfoHandles.Count(); }
|
||||
|
||||
void ResetScores( void );
|
||||
|
||||
virtual const char *GetTeamName( void ) { return "#Teamname_Spectators"; }
|
||||
|
||||
virtual CDODPlayer *GetDODPlayer( int iIndex ) { return ToDODPlayer(GetPlayer(iIndex)); }
|
||||
|
||||
private:
|
||||
CUtlVector < PLAYERCLASS_FILE_INFO_HANDLE > m_hPlayerClassInfoHandles;
|
||||
};
|
||||
|
||||
|
||||
extern CDODTeam *GetGlobalDODTeam( int iIndex );
|
||||
|
||||
|
||||
#endif // TF_TEAM_H
|
||||
109
game/server/dod/grenadetrail.cpp
Normal file
109
game/server/dod/grenadetrail.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "grenadetrail.h"
|
||||
#include "dt_send.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define GRENADETRAIL_ENTITYNAME "env_grenadetrail"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//Data table
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_SERVERCLASS_ST(CGrenadeTrail, DT_GrenadeTrail)
|
||||
SendPropFloat(SENDINFO(m_SpawnRate), 8, 0, 1, 1024),
|
||||
SendPropFloat(SENDINFO(m_ParticleLifetime), 16, SPROP_ROUNDUP, 0.1, 100),
|
||||
SendPropFloat(SENDINFO(m_StopEmitTime), 0, SPROP_NOSCALE),
|
||||
SendPropBool(SENDINFO(m_bEmit) ),
|
||||
SendPropInt(SENDINFO(m_nAttachment), 32 ),
|
||||
END_SEND_TABLE()
|
||||
|
||||
|
||||
BEGIN_DATADESC( CGrenadeTrail )
|
||||
|
||||
DEFINE_KEYFIELD( m_SpawnRate, FIELD_FLOAT, "spawnrate" ),
|
||||
DEFINE_KEYFIELD( m_ParticleLifetime, FIELD_FLOAT, "lifetime" ),
|
||||
DEFINE_FIELD( m_StopEmitTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_bEmit, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( m_nAttachment, FIELD_INTEGER ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS(env_grenadetrail, CGrenadeTrail);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
CGrenadeTrail::CGrenadeTrail()
|
||||
{
|
||||
m_SpawnRate = 10;
|
||||
m_ParticleLifetime = 5;
|
||||
m_StopEmitTime = 0; // Don't stop emitting particles
|
||||
m_bEmit = true;
|
||||
m_nAttachment = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGrenadeTrail::SetEmit(bool bVal)
|
||||
{
|
||||
m_bEmit = bVal;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : CGrenadeTrail*
|
||||
//-----------------------------------------------------------------------------
|
||||
CGrenadeTrail* CGrenadeTrail::CreateGrenadeTrail()
|
||||
{
|
||||
CBaseEntity *pEnt = CreateEntityByName(GRENADETRAIL_ENTITYNAME);
|
||||
if(pEnt)
|
||||
{
|
||||
CGrenadeTrail *pTrail = dynamic_cast<CGrenadeTrail*>(pEnt);
|
||||
if(pTrail)
|
||||
{
|
||||
pTrail->Activate();
|
||||
return pTrail;
|
||||
}
|
||||
else
|
||||
{
|
||||
UTIL_Remove(pEnt);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Attach the smoke trail to an entity or point
|
||||
// Input : index - entity that has the attachment
|
||||
// attachment - point to attach to
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGrenadeTrail::FollowEntity( CBaseEntity *pEntity, const char *pAttachmentName )
|
||||
{
|
||||
// For attachments
|
||||
if ( pAttachmentName && pEntity && pEntity->GetBaseAnimating() )
|
||||
{
|
||||
m_nAttachment = pEntity->GetBaseAnimating()->LookupAttachment( pAttachmentName );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nAttachment = 0;
|
||||
}
|
||||
|
||||
BaseClass::FollowEntity( pEntity );
|
||||
}
|
||||
31
game/server/dod/grenadetrail.h
Normal file
31
game/server/dod/grenadetrail.h
Normal file
@@ -0,0 +1,31 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#ifndef GRENADE_TRAIL_H
|
||||
#define GRENADE_TRAIL_H
|
||||
|
||||
#include "baseparticleentity.h"
|
||||
|
||||
//==================================================
|
||||
// SmokeTrail
|
||||
//==================================================
|
||||
|
||||
class CGrenadeTrail : public CBaseParticleEntity
|
||||
{
|
||||
DECLARE_DATADESC();
|
||||
public:
|
||||
DECLARE_CLASS( CGrenadeTrail, CBaseParticleEntity );
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
CGrenadeTrail();
|
||||
void SetEmit(bool bVal);
|
||||
void FollowEntity( CBaseEntity *pEntity, const char *pAttachmentName = NULL);
|
||||
static CGrenadeTrail* CreateGrenadeTrail();
|
||||
|
||||
public:
|
||||
CNetworkVar( float, m_SpawnRate ); // How many particles per second.
|
||||
CNetworkVar( float, m_ParticleLifetime ); // How long do the particles live?
|
||||
CNetworkVar( bool, m_bEmit );
|
||||
CNetworkVar( float, m_StopEmitTime ); // When do I stop emitting particles?
|
||||
CNetworkVar( int, m_nAttachment );
|
||||
};
|
||||
|
||||
#endif //GRENADE_TRAIL_H
|
||||
123
game/server/dod/holiday_gift.cpp
Normal file
123
game/server/dod/holiday_gift.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "holiday_gift.h"
|
||||
#include "dod_shareddefs.h"
|
||||
|
||||
#define CHRISTMAS_MODEL "models/items/dod_gift.mdl"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( holiday_gift, CHolidayGift );
|
||||
PRECACHE_WEAPON_REGISTER( holiday_gift );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
CHolidayGift* CHolidayGift::Create( const Vector &position, const QAngle &angles, const QAngle &eyeAngles, const Vector &velocity, CBaseCombatCharacter *pOwner )
|
||||
{
|
||||
CHolidayGift *pGift = (CHolidayGift*)CBaseEntity::Create( "holiday_gift", position, angles, pOwner );
|
||||
|
||||
if ( pGift )
|
||||
{
|
||||
pGift->AddSpawnFlags( SF_NORESPAWN );
|
||||
|
||||
Vector vecRight, vecUp;
|
||||
AngleVectors( eyeAngles, NULL, &vecRight, &vecUp );
|
||||
|
||||
// Calculate the initial impulse on the gift.
|
||||
Vector vecImpulse( 0.0f, 0.0f, 0.0f );
|
||||
vecImpulse += vecUp * random->RandomFloat( 0, 0.25 );
|
||||
vecImpulse += vecRight * random->RandomFloat( -0.25, 0.25 );
|
||||
VectorNormalize( vecImpulse );
|
||||
vecImpulse *= random->RandomFloat( 100.0, 150.0 );
|
||||
vecImpulse += velocity;
|
||||
|
||||
// Cap the impulse.
|
||||
float flSpeed = vecImpulse.Length();
|
||||
if ( flSpeed > 300.0 )
|
||||
{
|
||||
VectorScale( vecImpulse, 300.0 / flSpeed, vecImpulse );
|
||||
}
|
||||
|
||||
pGift->SetMoveType( MOVETYPE_FLYGRAVITY );
|
||||
pGift->SetAbsVelocity( vecImpulse * 2.f + Vector(0,0,200) );
|
||||
pGift->SetAbsAngles( QAngle(0,0,0) );
|
||||
pGift->UseClientSideAnimation();
|
||||
pGift->ResetSequence( pGift->LookupSequence("idle") );
|
||||
|
||||
pGift->EmitSound( "Christmas.GiftDrop" );
|
||||
|
||||
pGift->ActivateWhenAtRest();
|
||||
}
|
||||
|
||||
return pGift;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHolidayGift::Precache()
|
||||
{
|
||||
BaseClass::Precache();
|
||||
|
||||
PrecacheModel( CHRISTMAS_MODEL );
|
||||
PrecacheScriptSound( "Christmas.GiftDrop" );
|
||||
PrecacheScriptSound( "Christmas.GiftPickup" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHolidayGift::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
SetModel( CHRISTMAS_MODEL );
|
||||
|
||||
// Die in 30 seconds
|
||||
SetContextThink( &CBaseEntity::SUB_Remove, gpGlobals->curtime + 30, "DIE_THINK" );
|
||||
SetContextThink( &CHolidayGift::DropSoundThink, gpGlobals->curtime + 0.2f, "SOUND_THINK" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHolidayGift::DropSoundThink( void )
|
||||
{
|
||||
EmitSound( "Christmas.GiftDrop" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHolidayGift::MyTouch( CBasePlayer *pPlayer )
|
||||
{
|
||||
if( !pPlayer )
|
||||
return false;
|
||||
|
||||
if( !pPlayer->IsAlive() )
|
||||
return false;
|
||||
|
||||
if ( pPlayer->IsBot() )
|
||||
return false;
|
||||
|
||||
if ( ( pPlayer->GetTeamNumber() != TEAM_ALLIES ) && ( pPlayer->GetTeamNumber() != TEAM_AXIS ) )
|
||||
return false;
|
||||
|
||||
// Send a message for the achievement tracking.
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "christmas_gift_grab" );
|
||||
if ( event )
|
||||
{
|
||||
event->SetInt( "userid", pPlayer->GetUserID() );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
pPlayer->EmitSound( "Christmas.GiftPickup" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHolidayGift::ItemTouch( CBaseEntity *pOther )
|
||||
{
|
||||
if ( pOther->IsWorld() )
|
||||
{
|
||||
Vector absVel = GetAbsVelocity();
|
||||
SetAbsVelocity( Vector( 0,0,absVel.z ) );
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::ItemTouch( pOther );
|
||||
}
|
||||
36
game/server/dod/holiday_gift.h
Normal file
36
game/server/dod/holiday_gift.h
Normal file
@@ -0,0 +1,36 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef HOLIDAY_GIFT_H
|
||||
#define HOLIDAY_GIFT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "items.h"
|
||||
|
||||
|
||||
class CHolidayGift: public CItem
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CHolidayGift, CItem );
|
||||
|
||||
public:
|
||||
|
||||
virtual void Precache();
|
||||
virtual void Spawn( void );
|
||||
virtual bool MyTouch( CBasePlayer *pBasePlayer );
|
||||
virtual void ItemTouch( CBaseEntity *pOther );
|
||||
void DropSoundThink( void );
|
||||
|
||||
public:
|
||||
|
||||
static CHolidayGift* Create( const Vector &position, const QAngle &angles, const QAngle &eyeAngles, const Vector &velocity, CBaseCombatCharacter *pOwner );
|
||||
};
|
||||
|
||||
|
||||
#endif // HOLIDAY_GIFT_H
|
||||
30
game/server/dod/rocket_bazooka.cpp
Normal file
30
game/server/dod/rocket_bazooka.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "rocket_bazooka.h"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( rocket_bazooka, CBazookaRocket );
|
||||
PRECACHE_WEAPON_REGISTER( rocket_bazooka );
|
||||
|
||||
void CBazookaRocket::Spawn( void )
|
||||
{
|
||||
SetModel( BAZOOKA_ROCKET_MODEL );
|
||||
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
|
||||
void CBazookaRocket::Precache( void )
|
||||
{
|
||||
PrecacheModel( BAZOOKA_ROCKET_MODEL );
|
||||
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
CBazookaRocket *CBazookaRocket::Create( const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner )
|
||||
{
|
||||
return static_cast<CBazookaRocket *> ( CDODBaseRocket::Create( "rocket_bazooka", vecOrigin, vecAngles, pOwner ) );
|
||||
}
|
||||
36
game/server/dod/rocket_bazooka.h
Normal file
36
game/server/dod/rocket_bazooka.h
Normal file
@@ -0,0 +1,36 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#ifndef ROCKET_BAZOOKA_H
|
||||
#define ROCKET_BAZOOKA_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define BAZOOKA_ROCKET_MODEL "models/weapons/w_bazooka_rocket.mdl"
|
||||
|
||||
#include "dod_baserocket.h"
|
||||
|
||||
class CBazookaRocket : public CDODBaseRocket
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CBazookaRocket, CDODBaseRocket );
|
||||
|
||||
CBazookaRocket() {}
|
||||
|
||||
virtual void Spawn();
|
||||
virtual void Precache();
|
||||
|
||||
static CBazookaRocket *Create( const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner );
|
||||
|
||||
virtual DODWeaponID GetEmitterWeaponID() { return WEAPON_BAZOOKA; }
|
||||
|
||||
private:
|
||||
CBazookaRocket( const CBazookaRocket & );
|
||||
};
|
||||
|
||||
#endif //ROCKET_BAZOOKA_H
|
||||
30
game/server/dod/rocket_pschreck.cpp
Normal file
30
game/server/dod/rocket_pschreck.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "rocket_pschreck.h"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( rocket_pschreck, CPschreckRocket );
|
||||
PRECACHE_WEAPON_REGISTER( rocket_pschreck );
|
||||
|
||||
void CPschreckRocket::Spawn( void )
|
||||
{
|
||||
SetModel( PSCHRECK_ROCKET_MODEL );
|
||||
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
|
||||
void CPschreckRocket::Precache( void )
|
||||
{
|
||||
PrecacheModel( PSCHRECK_ROCKET_MODEL );
|
||||
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
CPschreckRocket *CPschreckRocket::Create( const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner )
|
||||
{
|
||||
return static_cast<CPschreckRocket *> ( CDODBaseRocket::Create( "rocket_pschreck", vecOrigin, vecAngles, pOwner ) );
|
||||
}
|
||||
36
game/server/dod/rocket_pschreck.h
Normal file
36
game/server/dod/rocket_pschreck.h
Normal file
@@ -0,0 +1,36 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
|
||||
#ifndef ROCKET_PSCHRECK_H
|
||||
#define ROCKET_PSCHRECK_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define PSCHRECK_ROCKET_MODEL "models/weapons/w_panzerschreck_rocket.mdl"
|
||||
|
||||
#include "dod_baserocket.h"
|
||||
|
||||
class CPschreckRocket : public CDODBaseRocket
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CPschreckRocket, CDODBaseRocket );
|
||||
|
||||
CPschreckRocket() {}
|
||||
|
||||
virtual void Spawn();
|
||||
virtual void Precache();
|
||||
|
||||
static CPschreckRocket *Create( const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner );
|
||||
|
||||
virtual DODWeaponID GetEmitterWeaponID() { return WEAPON_PSCHRECK; }
|
||||
|
||||
private:
|
||||
CPschreckRocket( const CPschreckRocket & );
|
||||
};
|
||||
|
||||
#endif //ROCKET_PSCHRECK_H
|
||||
114
game/server/dod/te_firebullets.cpp
Normal file
114
game/server/dod/te_firebullets.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "basetempentity.h"
|
||||
|
||||
|
||||
#define NUM_BULLET_SEED_BITS 8
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Display's a blood sprite
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTEFireBullets : public CBaseTempEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CTEFireBullets, CBaseTempEntity );
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
CTEFireBullets( const char *name );
|
||||
virtual ~CTEFireBullets( void );
|
||||
|
||||
virtual void Create( IRecipientFilter& filter, float delay = 0.0f );
|
||||
|
||||
|
||||
public:
|
||||
CNetworkVar( int, m_iPlayer );
|
||||
CNetworkVector( m_vecOrigin );
|
||||
CNetworkQAngle( m_vecAngles );
|
||||
CNetworkVar( int, m_iWeaponID );
|
||||
CNetworkVar( int, m_iMode );
|
||||
CNetworkVar( int, m_iSeed );
|
||||
CNetworkVar( float, m_flSpread );
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *name -
|
||||
//-----------------------------------------------------------------------------
|
||||
CTEFireBullets::CTEFireBullets( const char *name ) :
|
||||
CBaseTempEntity( name )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CTEFireBullets::~CTEFireBullets( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : msg_dest -
|
||||
// delay -
|
||||
// *origin -
|
||||
// *recipient -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTEFireBullets::Create( IRecipientFilter& filter, float delay )
|
||||
{
|
||||
engine->PlaybackTempEntity( filter, delay,
|
||||
(void *)this, GetServerClass()->m_pTable, GetServerClass()->m_ClassID );
|
||||
}
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST_NOBASE(CTEFireBullets, DT_TEFireBullets)
|
||||
SendPropVector( SENDINFO(m_vecOrigin), -1, SPROP_COORD ),
|
||||
SendPropAngle( SENDINFO_VECTORELEM( m_vecAngles, 0 ), 13, 0 ),
|
||||
SendPropAngle( SENDINFO_VECTORELEM( m_vecAngles, 1 ), 13, 0 ),
|
||||
SendPropInt( SENDINFO( m_iWeaponID ), 5, SPROP_UNSIGNED ), // max 31 weapons
|
||||
SendPropInt( SENDINFO( m_iMode ), 1, SPROP_UNSIGNED ),
|
||||
SendPropInt( SENDINFO( m_iSeed ), NUM_BULLET_SEED_BITS, SPROP_UNSIGNED ),
|
||||
SendPropInt( SENDINFO( m_iPlayer ), 6, SPROP_UNSIGNED ), // max 64 players, see MAX_PLAYERS
|
||||
SendPropFloat( SENDINFO( m_flSpread ), 10, 0, 0, 1 ),
|
||||
END_SEND_TABLE()
|
||||
|
||||
|
||||
// Singleton
|
||||
static CTEFireBullets g_TEFireBullets( "FireBullets" );
|
||||
|
||||
|
||||
void TE_FireBullets(
|
||||
int iPlayerIndex,
|
||||
const Vector &vOrigin,
|
||||
const QAngle &vAngles,
|
||||
int iWeaponID,
|
||||
int iMode,
|
||||
int iSeed,
|
||||
float flSpread )
|
||||
{
|
||||
CPASFilter filter( vOrigin );
|
||||
filter.UsePredictionRules();
|
||||
|
||||
g_TEFireBullets.m_iPlayer = iPlayerIndex-1;
|
||||
g_TEFireBullets.m_vecOrigin = vOrigin;
|
||||
g_TEFireBullets.m_vecAngles = vAngles;
|
||||
g_TEFireBullets.m_iSeed = iSeed;
|
||||
g_TEFireBullets.m_flSpread = flSpread;
|
||||
g_TEFireBullets.m_iMode = iMode;
|
||||
g_TEFireBullets.m_iWeaponID = iWeaponID;
|
||||
|
||||
Assert( iSeed < (1 << NUM_BULLET_SEED_BITS) );
|
||||
|
||||
g_TEFireBullets.Create( filter, 0 );
|
||||
}
|
||||
25
game/server/dod/te_firebullets.h
Normal file
25
game/server/dod/te_firebullets.h
Normal file
@@ -0,0 +1,25 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TE_FIREBULLETS_H
|
||||
#define TE_FIREBULLETS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
void TE_FireBullets(
|
||||
int iPlayerIndex,
|
||||
const Vector &vOrigin,
|
||||
const QAngle &vAngles,
|
||||
int iWeaponID,
|
||||
int iMode,
|
||||
int iSeed,
|
||||
float flSpread
|
||||
);
|
||||
|
||||
|
||||
#endif // TE_FIREBULLETS_H
|
||||
76
game/server/dod/unisignals.h
Normal file
76
game/server/dod/unisignals.h
Normal file
@@ -0,0 +1,76 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
|
||||
#ifndef __UNISIGNALS_H__
|
||||
#define __UNISIGNALS_H__
|
||||
|
||||
|
||||
|
||||
// Unified signals allow state updating to be performed at one point in the
|
||||
// calling code. The sequence of events is:
|
||||
//
|
||||
// 1. Signal( whatever ), Signal( whatever ), etc.
|
||||
// 2. ( GetState() & Update() ) to get only the changes since the last update
|
||||
// 3. Goto 1
|
||||
//
|
||||
// Or, alternately:
|
||||
//
|
||||
// 1. Signal( whatever ), Signal( whatever ), etc.
|
||||
// 2. Update()
|
||||
// 3. GetState()
|
||||
// 4. Goto 1
|
||||
|
||||
|
||||
class CUnifiedSignals
|
||||
{
|
||||
public:
|
||||
inline CUnifiedSignals();
|
||||
inline int Update(); // Returns a mask for the changed state bits; signals are cleared after this update is performed
|
||||
inline void Signal( int flSignal ); // ORed combo of BPSIG_xxx bits
|
||||
inline int GetState(); // Returns the current state (ORed combo of BPSIG_xxx flags)
|
||||
|
||||
private:
|
||||
int m_flSignal; // States to trigger
|
||||
int m_flState; // States after the previous update
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline CUnifiedSignals::CUnifiedSignals()
|
||||
{
|
||||
m_flSignal = 0;
|
||||
m_flState = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int CUnifiedSignals::Update()
|
||||
{
|
||||
int old = m_flState;
|
||||
m_flState = m_flSignal;
|
||||
m_flSignal = 0;
|
||||
|
||||
return m_flState ^ old;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void CUnifiedSignals::Signal( int flSignal )
|
||||
{
|
||||
m_flSignal |= flSignal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int CUnifiedSignals::GetState()
|
||||
{
|
||||
return m_flState;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // __UNISIGNALS_H__
|
||||
Reference in New Issue
Block a user