mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-29 09:33:00 +00:00
190 lines
5.1 KiB
C++
190 lines
5.1 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================//
|
|
|
|
#include "cbase.h"
|
|
#include "smokegrenade_projectile.h"
|
|
#include "sendproxy.h"
|
|
#include "particle_smokegrenade.h"
|
|
#include "cs_player.h"
|
|
#include "KeyValues.h"
|
|
#include "bot_manager.h"
|
|
#include "weapon_csbase.h"
|
|
|
|
#define GRENADE_MODEL "models/Weapons/w_eq_smokegrenade_thrown.mdl"
|
|
|
|
|
|
LINK_ENTITY_TO_CLASS( smokegrenade_projectile, CSmokeGrenadeProjectile );
|
|
PRECACHE_WEAPON_REGISTER( smokegrenade_projectile );
|
|
|
|
BEGIN_DATADESC( CSmokeGrenadeProjectile )
|
|
DEFINE_THINKFUNC( Think_Detonate ),
|
|
DEFINE_THINKFUNC( Think_Fade ),
|
|
DEFINE_THINKFUNC( Think_Remove )
|
|
END_DATADESC()
|
|
|
|
|
|
CSmokeGrenadeProjectile* CSmokeGrenadeProjectile::Create(
|
|
const Vector &position,
|
|
const QAngle &angles,
|
|
const Vector &velocity,
|
|
const AngularImpulse &angVelocity,
|
|
CBaseCombatCharacter *pOwner )
|
|
{
|
|
CSmokeGrenadeProjectile *pGrenade = (CSmokeGrenadeProjectile*)CBaseEntity::Create( "smokegrenade_projectile", position, angles, pOwner );
|
|
|
|
// Set the timer for 1 second less than requested. We're going to issue a SOUND_DANGER
|
|
// one second before detonation.
|
|
pGrenade->SetTimer( 1.5 );
|
|
pGrenade->SetAbsVelocity( velocity );
|
|
pGrenade->SetupInitialTransmittedGrenadeVelocity( velocity );
|
|
pGrenade->SetThrower( pOwner );
|
|
pGrenade->SetGravity( 0.55 );
|
|
pGrenade->SetFriction( 0.7 );
|
|
pGrenade->m_flDamage = 100;
|
|
pGrenade->ChangeTeam( pOwner->GetTeamNumber() );
|
|
pGrenade->ApplyLocalAngularVelocityImpulse( angVelocity );
|
|
pGrenade->SetTouch( &CBaseGrenade::BounceTouch );
|
|
|
|
pGrenade->SetGravity( BaseClass::GetGrenadeGravity() );
|
|
pGrenade->SetFriction( BaseClass::GetGrenadeFriction() );
|
|
pGrenade->SetElasticity( BaseClass::GetGrenadeElasticity() );
|
|
pGrenade->m_bDidSmokeEffect = false;
|
|
|
|
pGrenade->m_pWeaponInfo = GetWeaponInfo( WEAPON_SMOKEGRENADE );
|
|
|
|
return pGrenade;
|
|
}
|
|
|
|
|
|
void CSmokeGrenadeProjectile::SetTimer( float timer )
|
|
{
|
|
SetThink( &CSmokeGrenadeProjectile::Think_Detonate );
|
|
SetNextThink( gpGlobals->curtime + timer );
|
|
|
|
TheBots->SetGrenadeRadius( this, 0.0f );
|
|
}
|
|
|
|
void CSmokeGrenadeProjectile::Think_Detonate()
|
|
{
|
|
if ( GetAbsVelocity().Length() > 0.1 )
|
|
{
|
|
// Still moving. Don't detonate yet.
|
|
SetNextThink( gpGlobals->curtime + 0.2 );
|
|
return;
|
|
}
|
|
|
|
TheBots->SetGrenadeRadius( this, SmokeGrenadeRadius );
|
|
|
|
// Ok, we've stopped rolling or whatever. Now detonate.
|
|
ParticleSmokeGrenade *pGren = (ParticleSmokeGrenade*)CBaseEntity::Create( PARTICLESMOKEGRENADE_ENTITYNAME, GetAbsOrigin(), QAngle(0,0,0), NULL );
|
|
if ( pGren )
|
|
{
|
|
pGren->FillVolume();
|
|
pGren->SetFadeTime( 15, 20 );
|
|
pGren->SetAbsOrigin( GetAbsOrigin() );
|
|
|
|
//tell the hostages about the smoke!
|
|
CBaseEntity *pEntity = NULL;
|
|
variant_t var; //send the location of the smoke?
|
|
var.SetVector3D( GetAbsOrigin() );
|
|
while ( ( pEntity = gEntList.FindEntityByClassname( pEntity, "hostage_entity" ) ) != NULL)
|
|
{
|
|
//send to hostages that have a resonable chance of being in it while its still smoking
|
|
if( (GetAbsOrigin() - pEntity->GetAbsOrigin()).Length() < 1000 )
|
|
pEntity->AcceptInput( "smokegrenade", this, this, var, 0 );
|
|
}
|
|
|
|
// tell the bots a smoke grenade has exploded
|
|
CCSPlayer *player = ToCSPlayer(GetThrower());
|
|
if ( player )
|
|
{
|
|
IGameEvent * event = gameeventmanager->CreateEvent( "smokegrenade_detonate" );
|
|
if ( event )
|
|
{
|
|
event->SetInt( "userid", player->GetUserID() );
|
|
event->SetFloat( "x", GetAbsOrigin().x );
|
|
event->SetFloat( "y", GetAbsOrigin().y );
|
|
event->SetFloat( "z", GetAbsOrigin().z );
|
|
gameeventmanager->FireEvent( event );
|
|
}
|
|
}
|
|
}
|
|
|
|
m_hSmokeEffect = pGren;
|
|
m_bDidSmokeEffect = true;
|
|
|
|
EmitSound( "BaseSmokeEffect.Sound" );
|
|
|
|
m_nRenderMode = kRenderTransColor;
|
|
SetNextThink( gpGlobals->curtime + 5 );
|
|
SetThink( &CSmokeGrenadeProjectile::Think_Fade );
|
|
}
|
|
|
|
|
|
// Fade the projectile out over time before making it disappear
|
|
void CSmokeGrenadeProjectile::Think_Fade()
|
|
{
|
|
SetNextThink( gpGlobals->curtime );
|
|
|
|
color32 c = GetRenderColor();
|
|
c.a -= 1;
|
|
SetRenderColor( c.r, c.b, c.g, c.a );
|
|
|
|
if ( !c.a )
|
|
{
|
|
TheBots->RemoveGrenade( this );
|
|
|
|
SetModelName( NULL_STRING );//invisible
|
|
SetNextThink( gpGlobals->curtime + 20 );
|
|
SetThink( &CSmokeGrenadeProjectile::Think_Remove ); // Spit out smoke for 10 seconds.
|
|
SetSolid( SOLID_NONE );
|
|
}
|
|
}
|
|
|
|
|
|
void CSmokeGrenadeProjectile::Think_Remove()
|
|
{
|
|
if ( m_hSmokeEffect.Get() )
|
|
UTIL_Remove( m_hSmokeEffect );
|
|
|
|
TheBots->RemoveGrenade( this );
|
|
|
|
SetModelName( NULL_STRING );//invisible
|
|
SetSolid( SOLID_NONE );
|
|
SetMoveType( MOVETYPE_NONE );
|
|
}
|
|
|
|
//Implement this so we never call the base class,
|
|
//but this should never be called either.
|
|
void CSmokeGrenadeProjectile::Detonate( void )
|
|
{
|
|
Assert(!"Smoke grenade handles its own detonation");
|
|
}
|
|
|
|
|
|
void CSmokeGrenadeProjectile::Spawn()
|
|
{
|
|
SetModel( GRENADE_MODEL );
|
|
BaseClass::Spawn();
|
|
}
|
|
|
|
|
|
void CSmokeGrenadeProjectile::Precache()
|
|
{
|
|
PrecacheModel( GRENADE_MODEL );
|
|
PrecacheScriptSound( "BaseSmokeEffect.Sound" );
|
|
PrecacheScriptSound( "SmokeGrenade.Bounce" );
|
|
BaseClass::Precache();
|
|
}
|
|
|
|
void CSmokeGrenadeProjectile::BounceSound( void )
|
|
{
|
|
if ( !m_bDidSmokeEffect )
|
|
{
|
|
EmitSound( "SmokeGrenade.Bounce" );
|
|
}
|
|
}
|