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.
268 lines
7.6 KiB
268 lines
7.6 KiB
//========= Copyright 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::Spawn() |
|
{ |
|
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 ); |
|
} |
|
|
|
#ifndef _XBOX |
|
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 ); |
|
} |
|
} |
|
#endif // !_XBOX |
|
|
|
SetNextThink( gpGlobals->curtime + random->RandomFloat( 0.1, 0.2f ) ); |
|
}
|
|
|