|
|
//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: Dissolve entity to be attached to target entity. Serves two purposes:
//
// 1) An entity that can be placed by a level designer and triggered
// to ignite a target entity.
//
// 2) An entity that can be created at runtime to ignite a target entity.
//
//===========================================================================//
#include "cbase.h"
#include "RagdollBoogie.h"
#include "physics_prop_ragdoll.h"
#include "effect_dispatch_data.h"
#include "te_effect_dispatch.h"
#include "IEffects.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Make electriciy every so often
//-----------------------------------------------------------------------------
static const char *s_pZapContext = "ZapContext";
//-----------------------------------------------------------------------------
// Save/load
//-----------------------------------------------------------------------------
BEGIN_DATADESC( CRagdollBoogie )
DEFINE_FIELD( m_flStartTime, FIELD_TIME ), DEFINE_FIELD( m_flBoogieLength, FIELD_FLOAT ), DEFINE_FIELD( m_flMagnitude, FIELD_FLOAT ),
// Think this should be handled by StartTouch/etc.
// DEFINE_FIELD( m_nSuppressionCount, FIELD_INTEGER ),
DEFINE_FUNCTION( BoogieThink ), DEFINE_FUNCTION( ZapThink ),
END_DATADESC()
LINK_ENTITY_TO_CLASS( env_ragdoll_boogie, CRagdollBoogie );
//-----------------------------------------------------------------------------
// Purpose: Creates a flame and attaches it to a target entity.
// Input : pTarget -
//-----------------------------------------------------------------------------
CRagdollBoogie *CRagdollBoogie::Create( CBaseEntity *pTarget, float flMagnitude, float flStartTime, float flLengthTime, int nSpawnFlags ) { CRagdollProp *pRagdoll = dynamic_cast< CRagdollProp* >( pTarget ); if ( !pRagdoll ) return NULL;
CRagdollBoogie *pBoogie = (CRagdollBoogie *)CreateEntityByName( "env_ragdoll_boogie" ); if ( pBoogie == NULL ) return NULL;
pBoogie->AddSpawnFlags( nSpawnFlags ); pBoogie->AttachToEntity( pTarget ); pBoogie->SetBoogieTime( flStartTime, flLengthTime ); pBoogie->SetMagnitude( flMagnitude ); pBoogie->Spawn(); return pBoogie; }
//-----------------------------------------------------------------------------
// Spawn
//-----------------------------------------------------------------------------
void CRagdollBoogie::Precache() { BaseClass::Precache();
PrecacheEffect( "TeslaHitboxes" );
#ifdef HL2_EPISODIC
PrecacheScriptSound( "RagdollBoogie.Zap" ); #endif
}
//-----------------------------------------------------------------------------
// Spawn
//-----------------------------------------------------------------------------
void CRagdollBoogie::Spawn() { Precache();
BaseClass::Spawn();
SetThink( &CRagdollBoogie::BoogieThink ); SetNextThink( gpGlobals->curtime + 0.01f );
if ( HasSpawnFlags( SF_RAGDOLL_BOOGIE_ELECTRICAL ) ) { SetContextThink( &CRagdollBoogie::ZapThink, gpGlobals->curtime + random->RandomFloat( 0.1f, 0.3f ), s_pZapContext ); } }
//-----------------------------------------------------------------------------
// Zap!
//-----------------------------------------------------------------------------
void CRagdollBoogie::ZapThink() { if ( !GetMoveParent() ) return;
CBaseAnimating *pRagdoll = GetMoveParent()->GetBaseAnimating(); if ( !pRagdoll ) return;
// Make electricity on the client
CStudioHdr *pStudioHdr = pRagdoll->GetModelPtr( ); if (!pStudioHdr) return;
mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pRagdoll->GetHitboxSet() );
if ( set->numhitboxes == 0 ) return;
if ( m_nSuppressionCount == 0 ) { CEffectData data; data.m_nEntIndex = GetMoveParent()->entindex(); data.m_flMagnitude = 4; data.m_flScale = HasSpawnFlags(SF_RAGDOLL_BOOGIE_ELECTRICAL_NARROW_BEAM) ? 1.0f : 2.0f;
DispatchEffect( "TeslaHitboxes", data ); }
#ifdef HL2_EPISODIC
EmitSound( "RagdollBoogie.Zap" ); #endif
SetContextThink( &CRagdollBoogie::ZapThink, gpGlobals->curtime + random->RandomFloat( 0.1f, 0.3f ), s_pZapContext ); }
//-----------------------------------------------------------------------------
// Suppression count
//-----------------------------------------------------------------------------
void CRagdollBoogie::IncrementSuppressionCount( CBaseEntity *pTarget ) { // Look for other boogies on the ragdoll + kill them
for ( CBaseEntity *pChild = pTarget->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() ) { CRagdollBoogie *pBoogie = dynamic_cast<CRagdollBoogie*>(pChild); if ( !pBoogie ) continue;
++pBoogie->m_nSuppressionCount; } }
void CRagdollBoogie::DecrementSuppressionCount( CBaseEntity *pTarget ) { // Look for other boogies on the ragdoll + kill them
CBaseEntity *pNext; for ( CBaseEntity *pChild = pTarget->FirstMoveChild(); pChild; pChild = pNext ) { pNext = pChild->NextMovePeer(); CRagdollBoogie *pBoogie = dynamic_cast<CRagdollBoogie*>(pChild); if ( !pBoogie ) continue;
if ( --pBoogie->m_nSuppressionCount <= 0 ) { pBoogie->m_nSuppressionCount = 0;
float dt = gpGlobals->curtime - pBoogie->m_flStartTime; if ( dt >= pBoogie->m_flBoogieLength ) { PhysCallbackRemove( pBoogie->NetworkProp() ); } } } }
//-----------------------------------------------------------------------------
// Attach to an entity
//-----------------------------------------------------------------------------
void CRagdollBoogie::AttachToEntity( CBaseEntity *pTarget ) { m_nSuppressionCount = 0;
// Look for other boogies on the ragdoll + kill them
CBaseEntity *pNext; for ( CBaseEntity *pChild = pTarget->FirstMoveChild(); pChild; pChild = pNext ) { pNext = pChild->NextMovePeer(); CRagdollBoogie *pBoogie = dynamic_cast<CRagdollBoogie*>(pChild); if ( !pBoogie ) continue;
m_nSuppressionCount = pBoogie->m_nSuppressionCount; UTIL_Remove( pChild ); }
FollowEntity( pTarget ); }
//-----------------------------------------------------------------------------
// Purpose:
// Input : lifetime -
//-----------------------------------------------------------------------------
void CRagdollBoogie::SetBoogieTime( float flStartTime, float flLengthTime ) { m_flStartTime = flStartTime; m_flBoogieLength = flLengthTime; }
//-----------------------------------------------------------------------------
// Purpose: Burn targets around us
//-----------------------------------------------------------------------------
void CRagdollBoogie::SetMagnitude( float flMagnitude ) { m_flMagnitude = flMagnitude; }
//-----------------------------------------------------------------------------
// Purpose: Burn targets around us
//-----------------------------------------------------------------------------
void CRagdollBoogie::BoogieThink( void ) { CRagdollProp *pRagdoll = dynamic_cast< CRagdollProp* >( GetMoveParent() ); if ( !pRagdoll ) { UTIL_Remove( this ); return; }
float flMagnitude = m_flMagnitude; if ( m_flBoogieLength != 0 ) { float dt = gpGlobals->curtime - m_flStartTime; if ( dt >= m_flBoogieLength ) { // Don't remove while suppressed... this helps if we try to start another boogie
if ( m_nSuppressionCount == 0 ) { UTIL_Remove( this ); } SetThink( NULL ); return; }
if ( dt < 0 ) { SetNextThink( gpGlobals->curtime + random->RandomFloat( 0.1, 0.2f ) ); return; }
flMagnitude = SimpleSplineRemapVal( dt, 0.0f, m_flBoogieLength, m_flMagnitude, 0.0f ); }
if ( m_nSuppressionCount == 0 ) { ragdoll_t *pRagdollPhys = pRagdoll->GetRagdoll( ); for ( int j = 0; j < pRagdollPhys->listCount; ++j ) { float flMass = pRagdollPhys->list[j].pObject->GetMass(); float flForce = m_flMagnitude * flMass;
Vector vecForce; vecForce = RandomVector( -flForce, flForce ); pRagdollPhys->list[j].pObject->ApplyForceCenter( vecForce ); } }
SetNextThink( gpGlobals->curtime + random->RandomFloat( 0.1, 0.2f ) ); }
|