diff options
Diffstat (limited to 'game/server/RagdollBoogie.cpp')
| -rw-r--r-- | game/server/RagdollBoogie.cpp | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/game/server/RagdollBoogie.cpp b/game/server/RagdollBoogie.cpp new file mode 100644 index 0000000..6344b74 --- /dev/null +++ b/game/server/RagdollBoogie.cpp @@ -0,0 +1,268 @@ +//========= 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 ) ); +} |