diff options
Diffstat (limited to 'game/shared/tf2/grenade_rocket.cpp')
| -rw-r--r-- | game/shared/tf2/grenade_rocket.cpp | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/game/shared/tf2/grenade_rocket.cpp b/game/shared/tf2/grenade_rocket.cpp new file mode 100644 index 0000000..881ed74 --- /dev/null +++ b/game/shared/tf2/grenade_rocket.cpp @@ -0,0 +1,176 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" +#include "tf_player.h" +#include "engine/IEngineSound.h" +#include "grenade_rocket.h" + +extern short g_sModelIndexFireball; + +IMPLEMENT_SERVERCLASS_ST( CGrenadeRocket, DT_GrenadeRocket) +END_SEND_TABLE() + +BEGIN_DATADESC( CGrenadeRocket ) + + DEFINE_FIELD( m_flDamage, FIELD_FLOAT ), + + // Function Pointers + DEFINE_FUNCTION( MissileTouch ), + DEFINE_FUNCTION( FollowThink ), + +END_DATADESC() +LINK_ENTITY_TO_CLASS( grenade_rocket, CGrenadeRocket ); +PRECACHE_REGISTER(grenade_rocket); + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CGrenadeRocket::CGrenadeRocket() +{ + m_pRealOwner = NULL; + m_hLockTarget = NULL; + UseClientSideAnimation(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGrenadeRocket::Precache( void ) +{ + PrecacheModel( "models/weapons/w_missile.mdl" ); + + PrecacheScriptSound( "GrenadeRocket.FlyLoop" ); + +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGrenadeRocket::Spawn( void ) +{ + Precache(); + + SetMoveType( MOVETYPE_FLY ); + SetSolid( SOLID_BBOX ); + SetModel( "models/weapons/w_missile.mdl" ); + UTIL_SetSize( this, vec3_origin, vec3_origin ); + + SetCollisionGroup( TFCOLLISION_GROUP_WEAPON ); + SetTouch( MissileTouch ); + + SetDamage( 50 ); + + // Forward! + Vector forward; + AngleVectors( GetLocalAngles(), &forward, NULL, NULL ); + SetAbsVelocity( forward * ROCKET_VELOCITY ); + + EmitSound( "GrenadeRocket.FlyLoop" ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGrenadeRocket::MissileTouch( CBaseEntity *pOther ) +{ + Assert( pOther ); + if ( !pOther->IsSolid() ) + return; + + Vector vecAbsOrigin = GetAbsOrigin(); + CPASFilter filter( vecAbsOrigin ); + te->Explosion( filter, 0.0, &vecAbsOrigin, g_sModelIndexFireball, 2.0, 15, TE_EXPLFLAG_NONE, 100, m_flDamage ); + + StopSound( "GrenadeRocket.FlyLoop" ); + + // Don't apply explosive damage if it hit a shield of any kind... + bool bHittingShield = false; + if (pOther->GetCollisionGroup() == TFCOLLISION_GROUP_SHIELD) + { + bHittingShield = true; + } + else if ( pOther->IsPlayer() ) + { + CBaseTFPlayer *pPlayer = static_cast<CBaseTFPlayer*>(pOther); + + trace_t tr; + float flDamage = m_flDamage; + bHittingShield = pPlayer->IsHittingShield( GetAbsVelocity(), &flDamage ); + } + + if (!bHittingShield) + { + RadiusDamage( CTakeDamageInfo( this, m_pRealOwner, m_flDamage, DMG_BLAST ), vecAbsOrigin, 100, CLASS_NONE, NULL ); + } + + UTIL_Remove( this ); +} + +//----------------------------------------------------------------------------- +// Purpose: Make this rocket lock onto it's target and track it +//----------------------------------------------------------------------------- +void CGrenadeRocket::LockOnto( CBaseEntity *pTarget ) +{ + m_hLockTarget = pTarget; + SetThink( FollowThink ); + SetNextThink( gpGlobals->curtime + 0.1f ); +} + +//----------------------------------------------------------------------------- +// Purpose: Try and turn towards the target point +//----------------------------------------------------------------------------- +void CGrenadeRocket::FollowThink( void ) +{ + if ( m_hLockTarget == NULL ) + return; + + // Weave slightly drunkenly to target + Vector vecTarget = m_hLockTarget->GetAbsOrigin() - GetLocalOrigin(); + VectorNormalize( vecTarget ); + + QAngle angles; + VectorAngles( vecTarget, angles ); + SetLocalAngles( angles ); + + Vector vecVelocity = GetAbsVelocity(); + float flSpeed = vecVelocity.Length(); + vecVelocity = vecVelocity * 0.2 + vecTarget * flSpeed * 1.2; + // Clip to maxspeed + if ( vecVelocity.Length() > ROCKET_VELOCITY ) + { + VectorNormalize( vecVelocity ); + vecVelocity *= ROCKET_VELOCITY; + } + SetAbsVelocity( vecVelocity ); + + SetNextThink( gpGlobals->curtime + 0.1f ); +} + +//----------------------------------------------------------------------------- +// Purpose: Create a missile +//----------------------------------------------------------------------------- +CGrenadeRocket *CGrenadeRocket::Create( const Vector &vecOrigin, const Vector &vecForward, edict_t *pentOwner = NULL, CBaseEntity *pRealOwner = NULL ) +{ + CGrenadeRocket *pRocket = (CGrenadeRocket *)CreateEntityByName("grenade_rocket" ); + + UTIL_SetOrigin( pRocket, vecOrigin ); + QAngle angles; + VectorAngles( vecForward, angles ); + pRocket->SetLocalAngles( angles ); + pRocket->Spawn(); + pRocket->SetOwnerEntity( Instance( pentOwner ) ); + pRocket->m_pRealOwner = pRealOwner; + + if (pentOwner) + { + CBaseEntity *pOwnerEnt = GetContainingEntity( pentOwner ); + pRocket->ChangeTeam( pOwnerEnt->GetTeamNumber() ); + } + + return pRocket; +} |