|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "grenade_satchel.h"
#include "player.h"
#include "soundenvelope.h"
#include "engine/IEngineSound.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
ConVar sk_plr_dmg_satchel ( "sk_plr_dmg_satchel","0"); ConVar sk_npc_dmg_satchel ( "sk_npc_dmg_satchel","0"); ConVar sk_satchel_radius ( "sk_satchel_radius","0");
BEGIN_DATADESC( CSatchelCharge )
DEFINE_SOUNDPATCH( m_soundSlide ),
DEFINE_FIELD( m_flSlideVolume, FIELD_FLOAT ), DEFINE_FIELD( m_flNextBounceSoundTime, FIELD_TIME ), DEFINE_FIELD( m_bInAir, FIELD_BOOLEAN ), DEFINE_FIELD( m_vLastPosition, FIELD_POSITION_VECTOR ), DEFINE_FIELD( m_pMyWeaponSLAM, FIELD_CLASSPTR ), DEFINE_FIELD( m_bIsAttached, FIELD_BOOLEAN ),
// Function Pointers
DEFINE_FUNCTION( SatchelTouch ), DEFINE_FUNCTION( SatchelThink ), DEFINE_FUNCTION( SatchelUse ),
END_DATADESC()
LINK_ENTITY_TO_CLASS( npc_satchel, CSatchelCharge );
//=========================================================
// Deactivate - do whatever it is we do to an orphaned
// satchel when we don't want it in the world anymore.
//=========================================================
void CSatchelCharge::Deactivate( void ) { AddSolidFlags( FSOLID_NOT_SOLID ); UTIL_Remove( this ); }
void CSatchelCharge::Spawn( void ) { Precache( ); // motor
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); SetSolid( SOLID_BBOX ); SetCollisionGroup( COLLISION_GROUP_PROJECTILE ); SetModel( "models/Weapons/w_slam.mdl" );
UTIL_SetSize(this, Vector( -6, -6, -2), Vector(6, 6, 2));
SetTouch( SatchelTouch ); SetUse( SatchelUse ); SetThink( SatchelThink ); SetNextThink( gpGlobals->curtime + 0.1f );
m_flDamage = sk_plr_dmg_satchel.GetFloat(); m_DmgRadius = sk_satchel_radius.GetFloat(); m_takedamage = DAMAGE_YES; m_iHealth = 1;
SetGravity( UTIL_ScaleForGravity( 560 ) ); // slightly lower gravity
SetFriction( 1.0 ); SetSequence( 1 );
m_bIsAttached = false; m_bInAir = true; m_flSlideVolume = -1.0; m_flNextBounceSoundTime = 0;
m_vLastPosition = vec3_origin;
InitSlideSound(); }
//-----------------------------------------------------------------------------
void CSatchelCharge::InitSlideSound(void) { CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); CPASAttenuationFilter filter( this ); m_soundSlide = controller.SoundCreate( filter, entindex(), CHAN_STATIC, "SatchelCharge.Slide", ATTN_NORM ); }
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CSatchelCharge::KillSlideSound(void) { CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); controller.CommandClear( m_soundSlide ); controller.SoundFadeOut( m_soundSlide, 0.0 ); }
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CSatchelCharge::SatchelUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { KillSlideSound(); SetThink( Detonate ); SetNextThink( gpGlobals->curtime ); }
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CSatchelCharge::SatchelTouch( CBaseEntity *pOther ) { Assert( pOther ); if ( !pOther->IsSolid() ) return;
// If successfully thrown and touching the
// NPC that released this grenade, pick it up
if ( pOther == GetThrower() && GetOwnerEntity() == NULL ) { CBasePlayer *pPlayer = ToBasePlayer( m_pMyWeaponSLAM->GetOwner() ); if (pPlayer) { // Give the player ammo
pPlayer->GiveAmmo(1, m_pMyWeaponSLAM->m_iSecondaryAmmoType);
CPASAttenuationFilter filter( pPlayer, "SatchelCharge.Pickup" ); EmitSound( filter, pPlayer->entindex(), "SatchelCharge.Pickup" );
m_bIsLive = false;
// Take weapon out of detonate mode if necessary
if (!m_pMyWeaponSLAM->AnyUndetonatedCharges()) { m_pMyWeaponSLAM->m_bDetonatorArmed = false; m_pMyWeaponSLAM->m_bNeedDetonatorHolster = true;
// Put detonator away right away
m_pMyWeaponSLAM->SetWeaponIdleTime( gpGlobals->curtime ); }
// Kill any sliding sound
KillSlideSound();
// Remove satchel charge from world
UTIL_Remove( this ); return; }
}
StudioFrameAdvance( );
// Is it attached to a wall?
if (m_bIsAttached) { return; }
SetGravity( 1 );// normal gravity now
// HACKHACK - On ground isn't always set, so look for ground underneath
trace_t tr; UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,10), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
if ( tr.fraction < 1.0 ) { // add a bit of static friction
SetAbsVelocity( GetAbsVelocity() * 0.85 ); SetLocalAngularVelocity( GetLocalAngularVelocity() * 0.8 ); }
UpdateSlideSound();
if (m_bInAir) { BounceSound(); m_bInAir = false; }
}
void CSatchelCharge::UpdateSlideSound( void ) { if (!m_soundSlide) { return; }
float volume = GetAbsVelocity().Length2D()/1000; if (volume < 0.01 && m_soundSlide) { KillSlideSound(); return; } // HACKHACK - On ground isn't always set, so look for ground underneath
trace_t tr; UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,10), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
if ( tr.fraction < 1.0 ) { if (m_flSlideVolume == -1.0) { controller.CommandClear( m_soundSlide ); controller.Play( m_soundSlide, 1.0, 100 ); m_flSlideVolume = 1.0; } else { float volume = GetAbsVelocity().Length()/1000; if ( volume < m_flSlideVolume ) { m_flSlideVolume = volume; controller.CommandClear( m_soundSlide ); controller.SoundChangeVolume( m_soundSlide, volume, 0.1 ); } } } else { controller.CommandClear( m_soundSlide ); controller.SoundChangeVolume( m_soundSlide, 0.0, 0.01 ); m_flSlideVolume = -1.0; m_bInAir = true; return; } }
void CSatchelCharge::SatchelThink( void ) { // If attached resize so player can pick up off wall
if (m_bIsAttached) { UTIL_SetSize(this, Vector( -2, -2, -6), Vector(2, 2, 6)); }
UpdateSlideSound();
// See if I can lose my owner (has dropper moved out of way?)
// Want do this so owner can shoot the satchel charge
if (GetOwnerEntity()) { trace_t tr; Vector vUpABit = GetAbsOrigin(); vUpABit.z += 5.0;
CBaseEntity* saveOwner = GetOwnerEntity(); SetOwnerEntity( NULL ); UTIL_TraceEntity( this, GetAbsOrigin(), vUpABit, MASK_SOLID, &tr ); if ( tr.startsolid || tr.fraction != 1.0 ) { SetOwnerEntity( saveOwner ); } } // Bounce movement code gets this think stuck occasionally so check if I've
// succeeded in moving, otherwise kill my motions.
else if ((GetAbsOrigin() - m_vLastPosition).LengthSqr()<1) { SetAbsVelocity( vec3_origin );
QAngle angVel = GetLocalAngularVelocity(); angVel.y = 0; SetLocalAngularVelocity( angVel );
// Kill any remaining sound
KillSlideSound();
// Clear think function
SetThink(NULL); return; } m_vLastPosition= GetAbsOrigin();
StudioFrameAdvance( ); SetNextThink( gpGlobals->curtime + 0.1f );
if (!IsInWorld()) { // Kill any remaining sound
KillSlideSound();
UTIL_Remove( this ); return; }
// Is it attached to a wall?
if (m_bIsAttached) { return; }
Vector vecNewVel = GetAbsVelocity(); if (GetWaterLevel() == 3) { SetMoveType( MOVETYPE_FLY ); vecNewVel *= 0.8; vecNewVel.z += 8; SetLocalAngularVelocity( GetLocalAngularVelocity() * 0.9 ); } else if (GetWaterLevel() == 0) { SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); } else { vecNewVel.z -= 8; } SetAbsVelocity( vecNewVel ); }
void CSatchelCharge::Precache( void ) { PrecacheModel("models/Weapons/w_slam.mdl");
PrecacheScriptSound( "SatchelCharge.Pickup" ); PrecacheScriptSound( "SatchelCharge.Bounce" );
PrecacheScriptSound( "SatchelCharge.Slide" ); }
void CSatchelCharge::BounceSound( void ) { if (gpGlobals->curtime > m_flNextBounceSoundTime) { EmitSound( "SatchelCharge.Bounce" );
m_flNextBounceSoundTime = gpGlobals->curtime + 0.1; } }
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input :
// Output :
//-----------------------------------------------------------------------------
CSatchelCharge::CSatchelCharge(void) { m_vLastPosition.Init(); m_pMyWeaponSLAM = NULL; }
CSatchelCharge::~CSatchelCharge(void) { CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); controller.SoundDestroy( m_soundSlide ); }
|