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.
189 lines
5.1 KiB
189 lines
5.1 KiB
//========= 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" ); |
|
} |
|
}
|
|
|