source-engine/game/server/hl2/prop_thumper.cpp

284 lines
6.9 KiB
C++
Raw Normal View History

2020-04-22 16:56:21 +00:00
//========= 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 );
}
}