summaryrefslogtreecommitdiff
path: root/game/server/hl2/grenade_satchel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/server/hl2/grenade_satchel.cpp')
-rw-r--r--game/server/hl2/grenade_satchel.cpp365
1 files changed, 365 insertions, 0 deletions
diff --git a/game/server/hl2/grenade_satchel.cpp b/game/server/hl2/grenade_satchel.cpp
new file mode 100644
index 0000000..d8777f9
--- /dev/null
+++ b/game/server/hl2/grenade_satchel.cpp
@@ -0,0 +1,365 @@
+//========= 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 );
+}