mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-29 17:43:01 +00:00
284 lines
6.9 KiB
C++
284 lines
6.9 KiB
C++
//========= 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 );
|
|
}
|
|
}
|