mirror of
https://github.com/celisej567/source-engine.git
synced 2026-01-05 22:09:59 +03:00
1
This commit is contained in:
330
game/server/hl2/grenade_pathfollower.cpp
Normal file
330
game/server/hl2/grenade_pathfollower.cpp
Normal file
@@ -0,0 +1,330 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This is the brickbat weapon
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "grenade_pathfollower.h"
|
||||
#include "soundent.h"
|
||||
#include "decals.h"
|
||||
#include "shake.h"
|
||||
#include "smoke_trail.h"
|
||||
#include "entitylist.h"
|
||||
#include "vstdlib/random.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define GRENADE_PF_TURN_RATE 30
|
||||
#define GRENADE_PF_TOLERANCE 300
|
||||
#define GRENADE_PF_MODEL "models/Weapons/w_missile.mdl"
|
||||
|
||||
extern short g_sModelIndexFireball; // (in combatweapon.cpp) holds the index for the smoke cloud
|
||||
|
||||
ConVar sk_dmg_pathfollower_grenade ( "sk_dmg_pathfollower_grenade","0");
|
||||
ConVar sk_pathfollower_grenade_radius ( "sk_pathfollower_grenade_radius","0");
|
||||
|
||||
BEGIN_DATADESC( CGrenadePathfollower )
|
||||
|
||||
DEFINE_FIELD( m_pPathTarget, FIELD_CLASSPTR ),
|
||||
DEFINE_FIELD( m_flFlySpeed, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( m_sFlySound, FIELD_SOUNDNAME ),
|
||||
DEFINE_FIELD( m_flNextFlySoundTime, FIELD_TIME),
|
||||
DEFINE_FIELD( m_hRocketTrail, FIELD_EHANDLE),
|
||||
|
||||
DEFINE_THINKFUNC( AimThink ),
|
||||
|
||||
// Function pointers
|
||||
DEFINE_ENTITYFUNC( GrenadeTouch ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( grenade_pathfollower, CGrenadePathfollower );
|
||||
|
||||
void CGrenadePathfollower::Precache()
|
||||
{
|
||||
BaseClass::Precache();
|
||||
|
||||
PrecacheScriptSound( "GrenadePathfollower.StopSounds" );
|
||||
}
|
||||
|
||||
void CGrenadePathfollower::Spawn( void )
|
||||
{
|
||||
Precache( );
|
||||
|
||||
// -------------------------
|
||||
// Inert when first spawned
|
||||
// -------------------------
|
||||
SetSolid( SOLID_BBOX );
|
||||
AddSolidFlags( FSOLID_NOT_SOLID );
|
||||
|
||||
SetMoveType( MOVETYPE_NONE );
|
||||
AddFlag( FL_OBJECT ); // So can be shot down
|
||||
AddEffects( EF_NODRAW );
|
||||
|
||||
UTIL_SetSize(this, Vector(0, 0, 0), Vector(0, 0, 0));
|
||||
|
||||
m_flDamage = sk_dmg_pathfollower_grenade.GetFloat();
|
||||
m_DmgRadius = sk_pathfollower_grenade_radius.GetFloat();
|
||||
m_takedamage = DAMAGE_YES;
|
||||
m_iHealth = 200;
|
||||
|
||||
SetGravity( 0.00001 );
|
||||
SetFriction( 0.8 );
|
||||
SetSequence( 1 );
|
||||
}
|
||||
|
||||
void CGrenadePathfollower::Event_Killed( const CTakeDamageInfo &info )
|
||||
{
|
||||
Detonate( );
|
||||
}
|
||||
|
||||
void CGrenadePathfollower::GrenadeTouch( CBaseEntity *pOther )
|
||||
{
|
||||
// ----------------------------------
|
||||
// If I hit the sky, don't explode
|
||||
// ----------------------------------
|
||||
trace_t tr;
|
||||
UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + GetAbsVelocity(), MASK_SOLID_BRUSHONLY,
|
||||
this, COLLISION_GROUP_NONE, &tr);
|
||||
|
||||
if (tr.surface.flags & SURF_SKY)
|
||||
{
|
||||
if(m_hRocketTrail)
|
||||
{
|
||||
UTIL_Remove(m_hRocketTrail);
|
||||
m_hRocketTrail = NULL;
|
||||
}
|
||||
UTIL_Remove( this );
|
||||
}
|
||||
Detonate();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void CGrenadePathfollower::Detonate(void)
|
||||
{
|
||||
StopSound(entindex(), CHAN_BODY, STRING(m_sFlySound));
|
||||
|
||||
m_takedamage = DAMAGE_NO;
|
||||
|
||||
if(m_hRocketTrail)
|
||||
{
|
||||
UTIL_Remove(m_hRocketTrail);
|
||||
m_hRocketTrail = NULL;
|
||||
}
|
||||
|
||||
CPASFilter filter( GetAbsOrigin() );
|
||||
|
||||
te->Explosion( filter, 0.0,
|
||||
&GetAbsOrigin(),
|
||||
g_sModelIndexFireball,
|
||||
0.5,
|
||||
15,
|
||||
TE_EXPLFLAG_NONE,
|
||||
m_DmgRadius,
|
||||
m_flDamage );
|
||||
|
||||
Vector vecForward = GetAbsVelocity();
|
||||
VectorNormalize(vecForward);
|
||||
trace_t tr;
|
||||
UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + 60*vecForward, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, & tr);
|
||||
|
||||
UTIL_DecalTrace( &tr, "Scorch" );
|
||||
|
||||
UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START );
|
||||
CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin(), 400, 0.2 );
|
||||
|
||||
RadiusDamage ( CTakeDamageInfo( this, GetThrower(), m_flDamage, DMG_BLAST ), GetAbsOrigin(), m_DmgRadius, CLASS_NONE, NULL );
|
||||
CPASAttenuationFilter filter2( this, "GrenadePathfollower.StopSounds" );
|
||||
EmitSound( filter2, entindex(), "GrenadePathfollower.StopSounds" );
|
||||
UTIL_Remove( this );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void CGrenadePathfollower::Launch( float flLaunchSpeed, string_t sPathCornerName)
|
||||
{
|
||||
m_pPathTarget = gEntList.FindEntityByName( NULL, sPathCornerName );
|
||||
if (m_pPathTarget)
|
||||
{
|
||||
m_flFlySpeed = flLaunchSpeed;
|
||||
Vector vTargetDir = (m_pPathTarget->GetAbsOrigin() - GetAbsOrigin());
|
||||
VectorNormalize(vTargetDir);
|
||||
SetAbsVelocity( m_flFlySpeed * vTargetDir );
|
||||
QAngle angles;
|
||||
VectorAngles( GetAbsVelocity(), angles );
|
||||
SetLocalAngles( angles );
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "ERROR: Grenade_Pathfollower (%s) with no pathcorner!\n",GetDebugName());
|
||||
return;
|
||||
}
|
||||
|
||||
// Make this thing come to life
|
||||
RemoveSolidFlags( FSOLID_NOT_SOLID );
|
||||
SetMoveType( MOVETYPE_FLYGRAVITY );
|
||||
RemoveEffects( EF_NODRAW );
|
||||
|
||||
SetUse( &CGrenadePathfollower::DetonateUse );
|
||||
SetTouch( &CGrenadePathfollower::GrenadeTouch );
|
||||
SetThink( &CGrenadePathfollower::AimThink );
|
||||
|
||||
SetNextThink( gpGlobals->curtime + 0.1f );
|
||||
|
||||
// Make the trail
|
||||
m_hRocketTrail = RocketTrail::CreateRocketTrail();
|
||||
|
||||
if ( m_hRocketTrail )
|
||||
{
|
||||
m_hRocketTrail->m_Opacity = 0.2f;
|
||||
m_hRocketTrail->m_SpawnRate = 100;
|
||||
m_hRocketTrail->m_ParticleLifetime = 0.5f;
|
||||
m_hRocketTrail->m_StartColor.Init( 0.65f, 0.65f , 0.65f );
|
||||
m_hRocketTrail->m_EndColor.Init( 0.0, 0.0, 0.0 );
|
||||
m_hRocketTrail->m_StartSize = 8;
|
||||
m_hRocketTrail->m_EndSize = 16;
|
||||
m_hRocketTrail->m_SpawnRadius = 4;
|
||||
m_hRocketTrail->m_MinSpeed = 2;
|
||||
m_hRocketTrail->m_MaxSpeed = 16;
|
||||
|
||||
m_hRocketTrail->SetLifetime( 999 );
|
||||
m_hRocketTrail->FollowEntity( this, "0" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input :
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
void CGrenadePathfollower::PlayFlySound(void)
|
||||
{
|
||||
if (gpGlobals->curtime > m_flNextFlySoundTime)
|
||||
{
|
||||
CPASAttenuationFilter filter( this, 0.8 );
|
||||
|
||||
EmitSound_t ep;
|
||||
ep.m_nChannel = CHAN_BODY;
|
||||
ep.m_pSoundName = STRING(m_sFlySound);
|
||||
ep.m_flVolume = 1.0f;
|
||||
ep.m_SoundLevel = SNDLVL_NORM;
|
||||
|
||||
EmitSound( filter, entindex(), ep );
|
||||
m_flNextFlySoundTime = gpGlobals->curtime + 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void CGrenadePathfollower::AimThink( void )
|
||||
{
|
||||
PlayFlySound();
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Check if it's time to skip to the next path corner
|
||||
// ---------------------------------------------------
|
||||
if (m_pPathTarget)
|
||||
{
|
||||
float flLength = (GetAbsOrigin() - m_pPathTarget->GetAbsOrigin()).Length();
|
||||
if (flLength < GRENADE_PF_TOLERANCE)
|
||||
{
|
||||
m_pPathTarget = gEntList.FindEntityByName( NULL, m_pPathTarget->m_target );
|
||||
if (!m_pPathTarget)
|
||||
{
|
||||
SetGravity( 1.0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// If I have a pathcorner, aim towards it
|
||||
// --------------------------------------------------
|
||||
if (m_pPathTarget)
|
||||
{
|
||||
Vector vTargetDir = (m_pPathTarget->GetAbsOrigin() - GetAbsOrigin());
|
||||
VectorNormalize(vTargetDir);
|
||||
|
||||
Vector vecNewVelocity = GetAbsVelocity();
|
||||
VectorNormalize(vecNewVelocity);
|
||||
|
||||
float flTimeToUse = gpGlobals->frametime;
|
||||
while (flTimeToUse > 0)
|
||||
{
|
||||
vecNewVelocity += vTargetDir;
|
||||
flTimeToUse = -0.1;
|
||||
}
|
||||
vecNewVelocity *= m_flFlySpeed;
|
||||
SetAbsVelocity( vecNewVelocity );
|
||||
}
|
||||
|
||||
QAngle angles;
|
||||
VectorAngles( GetAbsVelocity(), angles );
|
||||
SetLocalAngles( angles );
|
||||
SetNextThink( gpGlobals->curtime + 0.1f );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
Class_T CGrenadePathfollower::Classify( void)
|
||||
{
|
||||
return CLASS_MISSILE;
|
||||
};
|
||||
|
||||
CGrenadePathfollower::CGrenadePathfollower(void)
|
||||
{
|
||||
m_hRocketTrail = NULL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : In case somehow we get removed w/o detonating, make sure
|
||||
// we stop making sounds
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
CGrenadePathfollower::~CGrenadePathfollower(void)
|
||||
{
|
||||
StopSound(entindex(), CHAN_BODY, STRING(m_sFlySound));
|
||||
}
|
||||
|
||||
///------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
CGrenadePathfollower* CGrenadePathfollower::CreateGrenadePathfollower( string_t sModelName, string_t sFlySound, const Vector &vecOrigin, const QAngle &vecAngles, edict_t *pentOwner )
|
||||
{
|
||||
CGrenadePathfollower *pGrenade = (CGrenadePathfollower*)CreateEntityByName( "grenade_pathfollower" );
|
||||
if ( !pGrenade )
|
||||
{
|
||||
Warning( "NULL Ent in CGrenadePathfollower!\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( pGrenade->edict() )
|
||||
{
|
||||
pGrenade->m_sFlySound = sFlySound;
|
||||
pGrenade->SetOwnerEntity( Instance( pentOwner ) );
|
||||
pGrenade->SetLocalOrigin( vecOrigin );
|
||||
pGrenade->SetLocalAngles( vecAngles );
|
||||
pGrenade->SetModel( STRING(sModelName) );
|
||||
pGrenade->Spawn();
|
||||
}
|
||||
return pGrenade;
|
||||
}
|
||||
Reference in New Issue
Block a user