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.
212 lines
6.7 KiB
212 lines
6.7 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// $NoKeywords: $
|
||
|
//=============================================================================//
|
||
|
#include "cbase.h"
|
||
|
#include "tf_player.h"
|
||
|
#include "tf_basecombatweapon.h"
|
||
|
#include "basegrenade_shared.h"
|
||
|
#include "engine/IEngineSound.h"
|
||
|
#include "tf_shareddefs.h"
|
||
|
#include "IEffects.h"
|
||
|
#include "Sprite.h"
|
||
|
#include "grenade_antipersonnel.h"
|
||
|
|
||
|
// Damage CVars
|
||
|
ConVar weapon_antipersonnel_grenade_damage( "weapon_antipersonnel_grenade_damage","0", FCVAR_NONE, "Anti-personnel grenade maximum damage" );
|
||
|
ConVar weapon_antipersonnel_grenade_radius( "weapon_antipersonnel_grenade_radius","0", FCVAR_NONE, "Anti-personnel grenade splash radius" );
|
||
|
|
||
|
#if !defined( CLIENT_DLL )
|
||
|
// Server Only
|
||
|
ConVar weapon_antipersonnel_grenade_force( "weapon_antipersonnel_grenade_force","225.0", FCVAR_NONE, "Grenade explosive force modifier." );
|
||
|
#endif
|
||
|
|
||
|
|
||
|
IMPLEMENT_SERVERCLASS_ST(CGrenadeAntiPersonnel, DT_GrenadeAntiPersonnel)
|
||
|
END_SEND_TABLE()
|
||
|
|
||
|
LINK_ENTITY_TO_CLASS( grenade_antipersonnel, CGrenadeAntiPersonnel );
|
||
|
PRECACHE_WEAPON_REGISTER(grenade_antipersonnel);
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CGrenadeAntiPersonnel::CGrenadeAntiPersonnel()
|
||
|
{
|
||
|
UseClientSideAnimation();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGrenadeAntiPersonnel::Precache( void )
|
||
|
{
|
||
|
BaseClass::Precache( );
|
||
|
|
||
|
PrecacheModel( "models/weapons/w_grenade.mdl" );
|
||
|
PrecacheModel( "sprites/redglow1.vmt" );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGrenadeAntiPersonnel::Spawn( void )
|
||
|
{
|
||
|
Precache();
|
||
|
|
||
|
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
|
||
|
SetSolid( SOLID_BBOX );
|
||
|
SetGravity( 1.0 );
|
||
|
SetFriction( 0.9 );
|
||
|
SetElasticity( 2.0f );
|
||
|
SetModel( "models/weapons/w_grenade.mdl" );
|
||
|
UTIL_SetSize(this, vec3_origin, vec3_origin);
|
||
|
SetTouch( BounceTouch );
|
||
|
SetCollisionGroup( TFCOLLISION_GROUP_GRENADE );
|
||
|
|
||
|
m_flDetonateTime = gpGlobals->curtime + 3.0;
|
||
|
SetThink( TumbleThink );
|
||
|
SetNextThink( gpGlobals->curtime + 0.1f );
|
||
|
|
||
|
// Set my damages to the cvar values
|
||
|
SetDamage( weapon_antipersonnel_grenade_damage.GetFloat() );
|
||
|
SetDamageRadius( weapon_antipersonnel_grenade_radius.GetFloat() );
|
||
|
|
||
|
// Create a green light
|
||
|
m_pLiveSprite = CSprite::SpriteCreate( "sprites/redglow1.vmt", GetLocalOrigin() + Vector(0,0,1), false );
|
||
|
m_pLiveSprite->SetTransparency( kRenderGlow, 0, 255, 0, 128, kRenderFxNoDissipation );
|
||
|
m_pLiveSprite->SetBrightness( 255 );
|
||
|
m_pLiveSprite->SetScale( 1 );
|
||
|
m_pLiveSprite->SetAttachment( this, 0 );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGrenadeAntiPersonnel::UpdateOnRemove( void )
|
||
|
{
|
||
|
// Remove our live sprite
|
||
|
if ( m_pLiveSprite )
|
||
|
{
|
||
|
UTIL_Remove( m_pLiveSprite );
|
||
|
m_pLiveSprite = NULL;
|
||
|
}
|
||
|
|
||
|
// Chain at end to mimic destructor unwind order
|
||
|
BaseClass::UpdateOnRemove();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Allow shield parry's
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGrenadeAntiPersonnel::BounceTouch( CBaseEntity *pOther )
|
||
|
{
|
||
|
// Don't blow up on trigger brushes
|
||
|
Assert( pOther );
|
||
|
if ( !pOther->IsSolid() )
|
||
|
return;
|
||
|
|
||
|
if ( pOther->GetCollisionGroup() == TFCOLLISION_GROUP_SHIELD )
|
||
|
{
|
||
|
// Move away from the shield...
|
||
|
// Fling it out a little extra along the plane normal
|
||
|
Vector vecCenter;
|
||
|
AngleVectors( pOther->GetAbsAngles(), &vecCenter );
|
||
|
|
||
|
// Bounce off the ground if it's on the ground...
|
||
|
Vector vecNewVelocity = GetAbsVelocity();
|
||
|
VectorMultiply( vecCenter, 400.0f, vecNewVelocity );
|
||
|
if ((GetFlags() & FL_ONGROUND) && vecNewVelocity.z <= 100.0f)
|
||
|
{
|
||
|
vecNewVelocity.z = 100.0f;
|
||
|
}
|
||
|
SetAbsVelocity( vecNewVelocity );
|
||
|
}
|
||
|
|
||
|
// If we're set to explode on contact, and we just hit an enemy, go kaboom
|
||
|
if ( m_bExplodeOnContact && !InSameTeam(pOther) && pOther->m_takedamage != DAMAGE_NO )
|
||
|
{
|
||
|
Detonate();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
BaseClass::BounceTouch( pOther );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Return the radius for the screenshake
|
||
|
//-----------------------------------------------------------------------------
|
||
|
float CGrenadeAntiPersonnel::GetShakeRadius( void )
|
||
|
{
|
||
|
return (m_DmgRadius * 2);
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Create a missile
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CGrenadeAntiPersonnel::Detonate( void )
|
||
|
{
|
||
|
BaseClass::Detonate();
|
||
|
|
||
|
// iterate on all entities in the vicinity and find vehicles
|
||
|
CBaseEntity *pEntity = NULL;
|
||
|
for ( CEntitySphereQuery sphere( GetAbsOrigin(), m_DmgRadius ); ( pEntity = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() )
|
||
|
{
|
||
|
// Check team.
|
||
|
if ( pEntity->GetTeam() == GetTeam() )
|
||
|
continue;
|
||
|
|
||
|
if ( pEntity->GetServerVehicle() )
|
||
|
{
|
||
|
IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject();
|
||
|
if ( pPhysObject )
|
||
|
{
|
||
|
// Rocket the vehicle in the direction of the incoming rocket.
|
||
|
Vector vecForceDir = pEntity->GetAbsOrigin() - GetAbsOrigin();
|
||
|
float flDistance = VectorNormalize( vecForceDir );
|
||
|
|
||
|
if ( flDistance >= 0.0f && flDistance < m_DmgRadius )
|
||
|
{
|
||
|
vecForceDir.z = 1.0f;
|
||
|
VectorNormalize( vecForceDir );
|
||
|
|
||
|
float flForce = pPhysObject->GetMass();
|
||
|
flForce += ( 4 * 500.0f ); // Wheels
|
||
|
flForce *= weapon_antipersonnel_grenade_force.GetFloat();
|
||
|
flForce *= ( 1.0f - ( flDistance / m_DmgRadius ) );
|
||
|
|
||
|
vecForceDir *= flForce;
|
||
|
|
||
|
pPhysObject->ApplyForceOffset( vecForceDir, GetAbsOrigin() );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Create a missile
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CGrenadeAntiPersonnel *CGrenadeAntiPersonnel::Create( const Vector &vecOrigin, const Vector &vecForward, CBasePlayer *pOwner )
|
||
|
{
|
||
|
CGrenadeAntiPersonnel *pGrenade = (CGrenadeAntiPersonnel*)CreateEntityByName("grenade_antipersonnel");
|
||
|
|
||
|
UTIL_SetOrigin( pGrenade, vecOrigin );
|
||
|
pGrenade->Spawn();
|
||
|
pGrenade->ChangeTeam( pOwner->GetTeamNumber() );
|
||
|
pGrenade->SetOwnerEntity( pOwner );
|
||
|
pGrenade->SetThrower( pOwner );
|
||
|
pGrenade->SetAbsVelocity( vecForward );
|
||
|
QAngle angles;
|
||
|
VectorAngles( vecForward, angles );
|
||
|
pGrenade->SetLocalAngles( angles );
|
||
|
pGrenade->SetLocalAngularVelocity( RandomAngle(-500,500) );
|
||
|
|
||
|
return pGrenade;
|
||
|
}
|
||
|
|
||
|
|
||
|
|