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.
283 lines
6.9 KiB
283 lines
6.9 KiB
//========= 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 ); |
|
} |
|
}
|
|
|