You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
294 lines
7.6 KiB
294 lines
7.6 KiB
//========= 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; |
|
}
|
|
|