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;
|
|
}
|