|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Implements the big scary boom-boom machine Antlions fear.
//
//=============================================================================//
#include "cbase.h"
#include "baseentity.h"
#include "npcevent.h"
#include "rotorwash.h"
#include "soundenvelope.h"
#include "engine/IEngineSound.h"
#include "npc_antlion.h"
#include "te_effect_dispatch.h"
#if HL2_EPISODIC
#define THUMPER_RADIUS m_iEffectRadius // this const is only used inside the thumper anyway
#else
#define THUMPER_RADIUS 1000
#endif
#define STATE_CHANGE_MODIFIER 0.02f
#define THUMPER_SOUND_DURATION 1.5f
#define THUMPER_MIN_SCALE 128
#define THUMPER_MODEL_NAME "models/props_combine/CombineThumper002.mdl"
ConVar thumper_show_radius("thumper_show_radius","0",FCVAR_CHEAT,"If true, advisor will use her custom impact damage table.");
class CPropThumper : public CBaseAnimating { public: DECLARE_CLASS( CPropThumper, CBaseAnimating ); DECLARE_DATADESC();
virtual void Spawn( void ); virtual void Precache( void ); virtual void Think ( void ); virtual void HandleAnimEvent( animevent_t *pEvent ); virtual void StopLoopingSounds( void );
void InputDisable( inputdata_t &inputdata ); void InputEnable( inputdata_t &inputdata );
void InitMotorSound( void );
void HandleState( void );
void Thump( void );
private: bool m_bEnabled; int m_iHammerAttachment; CSoundPatch* m_sndMotor; EHANDLE m_hRepellantEnt; int m_iDustScale; COutputEvent m_OnThumped; // Fired when thumper goes off
#if HL2_EPISODIC
int m_iEffectRadius; #endif
};
LINK_ENTITY_TO_CLASS( prop_thumper, CPropThumper );
//-----------------------------------------------------------------------------
// Save/load
//-----------------------------------------------------------------------------
BEGIN_DATADESC( CPropThumper ) DEFINE_FIELD( m_bEnabled, FIELD_BOOLEAN ), DEFINE_FIELD( m_hRepellantEnt, FIELD_EHANDLE ), DEFINE_FIELD( m_iHammerAttachment, FIELD_INTEGER ), DEFINE_KEYFIELD( m_iDustScale, FIELD_INTEGER, "dustscale" ), #if HL2_EPISODIC
DEFINE_KEYFIELD( m_iEffectRadius, FIELD_INTEGER, "EffectRadius" ), #endif
DEFINE_SOUNDPATCH( m_sndMotor ), DEFINE_THINKFUNC( Think ), DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
DEFINE_OUTPUT( m_OnThumped, "OnThumped" ), END_DATADESC()
void CPropThumper::Spawn( void ) { char *szModel = (char *)STRING( GetModelName() ); if (!szModel || !*szModel) { szModel = THUMPER_MODEL_NAME; SetModelName( AllocPooledString(szModel) ); }
Precache(); SetModel( szModel );
SetSolid( SOLID_VPHYSICS ); SetMoveType( MOVETYPE_NONE ); VPhysicsInitStatic();
BaseClass::Spawn();
m_bEnabled = true;
SetThink( &CPropThumper::Think ); SetNextThink( gpGlobals->curtime + 1.0f );
int iSequence = SelectHeaviestSequence ( ACT_IDLE );
if ( iSequence != ACT_INVALID ) { SetSequence( iSequence ); ResetSequenceInfo();
//Do this so we get the nice ramp-up effect.
m_flPlaybackRate = random->RandomFloat( 0.0f, 1.0f); }
m_iHammerAttachment = LookupAttachment( "hammer" ); CAntlionRepellant *pRepellant = (CAntlionRepellant*)CreateEntityByName( "point_antlion_repellant" );
if ( pRepellant ) { pRepellant->Spawn(); pRepellant->SetAbsOrigin( GetAbsOrigin() ); pRepellant->SetRadius( THUMPER_RADIUS );
m_hRepellantEnt = pRepellant; }
if ( m_iDustScale == 0 ) m_iDustScale = THUMPER_MIN_SCALE;
#if HL2_EPISODIC
if ( m_iEffectRadius == 0 ) m_iEffectRadius = 1000; #endif
}
void CPropThumper::Precache( void ) { BaseClass::Precache();
PrecacheModel( STRING( GetModelName() ) ); PrecacheScriptSound( "coast.thumper_hit" ); PrecacheScriptSound( "coast.thumper_ambient" ); PrecacheScriptSound( "coast.thumper_dust" ); PrecacheScriptSound( "coast.thumper_startup" ); PrecacheScriptSound( "coast.thumper_shutdown" ); PrecacheScriptSound( "coast.thumper_large_hit" ); }
void CPropThumper::InitMotorSound( void ) { CPASAttenuationFilter filter( this ); m_sndMotor = (CSoundEnvelopeController::GetController()).SoundCreate( filter, entindex(), CHAN_STATIC, "coast.thumper_ambient" , ATTN_NORM );
if ( m_sndMotor ) { (CSoundEnvelopeController::GetController()).Play( m_sndMotor, 1.0f, 100 ); } }
void CPropThumper::HandleState( void ) { if ( m_bEnabled == false ) { m_flPlaybackRate = MAX( m_flPlaybackRate - STATE_CHANGE_MODIFIER, 0.0f ); } else { m_flPlaybackRate = MIN( m_flPlaybackRate + STATE_CHANGE_MODIFIER, 1.0f ); }
(CSoundEnvelopeController::GetController()).Play( m_sndMotor, 1.0f, m_flPlaybackRate * 100 ); }
void CPropThumper::Think( void ) { StudioFrameAdvance(); DispatchAnimEvents( this ); SetNextThink( gpGlobals->curtime + 0.1 );
if ( m_sndMotor == NULL ) InitMotorSound(); else HandleState(); }
void CPropThumper::Thump ( void ) { if ( m_iHammerAttachment != -1 ) { Vector vOrigin; GetAttachment( m_iHammerAttachment, vOrigin );
CEffectData data;
data.m_nEntIndex = entindex(); data.m_vOrigin = vOrigin; data.m_flScale = m_iDustScale * m_flPlaybackRate; DispatchEffect( "ThumperDust", data ); UTIL_ScreenShake( vOrigin, 10.0 * m_flPlaybackRate, m_flPlaybackRate, m_flPlaybackRate / 2, THUMPER_RADIUS * m_flPlaybackRate, SHAKE_START, false ); }
EmitSound( "coast.thumper_dust" ); CSoundEnt::InsertSound ( SOUND_THUMPER, GetAbsOrigin(), THUMPER_RADIUS * m_flPlaybackRate, THUMPER_SOUND_DURATION, this );
if ( thumper_show_radius.GetBool() ) { NDebugOverlay::Box( GetAbsOrigin(), Vector(-THUMPER_RADIUS, -THUMPER_RADIUS, -THUMPER_RADIUS), Vector(THUMPER_RADIUS, THUMPER_RADIUS, THUMPER_RADIUS), 255, 64, 64, 255, THUMPER_SOUND_DURATION ); }
if ( m_flPlaybackRate < 0.7f ) return;
if( m_iDustScale == THUMPER_MIN_SCALE ) EmitSound( "coast.thumper_hit" ); else EmitSound( "coast.thumper_large_hit" );
// Signal that we've thumped
m_OnThumped.FireOutput( this, this ); }
void CPropThumper::HandleAnimEvent( animevent_t *pEvent ) { if ( pEvent->event == AE_THUMPER_THUMP ) { Thump(); return; }
BaseClass::HandleAnimEvent( pEvent ); }
//-----------------------------------------------------------------------------
// Shuts down sounds
//-----------------------------------------------------------------------------
void CPropThumper::StopLoopingSounds( void ) { if ( m_sndMotor != NULL ) { (CSoundEnvelopeController::GetController()).SoundDestroy( m_sndMotor ); m_sndMotor = NULL; }
BaseClass::StopLoopingSounds(); }
void CPropThumper::InputDisable( inputdata_t &inputdata ) { m_bEnabled = false; EmitSound( "coast.thumper_shutdown" ); if ( m_hRepellantEnt ) { variant_t emptyVariant; m_hRepellantEnt->AcceptInput( "Disable", this, this, emptyVariant, 0 ); } }
void CPropThumper::InputEnable( inputdata_t &inputdata ) { m_bEnabled = true;
EmitSound( "coast.thumper_startup" );
if ( m_hRepellantEnt ) { variant_t emptyVariant; m_hRepellantEnt->AcceptInput( "Enable", this, this, emptyVariant, 0 ); } }
|