From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- sp/src/game/server/EntityDissolve.cpp | 776 +++++++++++++++++----------------- 1 file changed, 388 insertions(+), 388 deletions(-) (limited to 'sp/src/game/server/EntityDissolve.cpp') diff --git a/sp/src/game/server/EntityDissolve.cpp b/sp/src/game/server/EntityDissolve.cpp index 5bae4cba..7979e852 100644 --- a/sp/src/game/server/EntityDissolve.cpp +++ b/sp/src/game/server/EntityDissolve.cpp @@ -1,388 +1,388 @@ -//========= 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 "EntityDissolve.h" -#include "baseanimating.h" -#include "physics_prop_ragdoll.h" -#include "ai_basenpc.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -static const char *s_pElectroThinkContext = "ElectroThinkContext"; - - -//----------------------------------------------------------------------------- -// Lifetime -//----------------------------------------------------------------------------- -#define DISSOLVE_FADE_IN_START_TIME 0.0f -#define DISSOLVE_FADE_IN_END_TIME 1.0f -#define DISSOLVE_FADE_OUT_MODEL_START_TIME 1.9f -#define DISSOLVE_FADE_OUT_MODEL_END_TIME 2.0f -#define DISSOLVE_FADE_OUT_START_TIME 2.0f -#define DISSOLVE_FADE_OUT_END_TIME 2.0f - -//----------------------------------------------------------------------------- -// Model -//----------------------------------------------------------------------------- -#define DISSOLVE_SPRITE_NAME "sprites/blueglow1.vmt" - -//----------------------------------------------------------------------------- -// Save/load -//----------------------------------------------------------------------------- -BEGIN_DATADESC( CEntityDissolve ) - - DEFINE_FIELD( m_flStartTime, FIELD_TIME ), - DEFINE_FIELD( m_flFadeInStart, FIELD_FLOAT ), - DEFINE_FIELD( m_flFadeInLength, FIELD_FLOAT ), - DEFINE_FIELD( m_flFadeOutModelStart, FIELD_FLOAT ), - DEFINE_FIELD( m_flFadeOutModelLength, FIELD_FLOAT ), - DEFINE_FIELD( m_flFadeOutStart, FIELD_FLOAT ), - DEFINE_FIELD( m_flFadeOutLength, FIELD_FLOAT ), - DEFINE_KEYFIELD( m_nDissolveType, FIELD_INTEGER, "dissolvetype" ), - DEFINE_FIELD( m_vDissolverOrigin, FIELD_VECTOR ), - DEFINE_KEYFIELD( m_nMagnitude, FIELD_INTEGER, "magnitude" ), - - DEFINE_FUNCTION( DissolveThink ), - DEFINE_FUNCTION( ElectrocuteThink ), - - DEFINE_INPUTFUNC( FIELD_STRING, "Dissolve", InputDissolve ), - -END_DATADESC() - - -//----------------------------------------------------------------------------- -// Networking -//----------------------------------------------------------------------------- -IMPLEMENT_SERVERCLASS_ST( CEntityDissolve, DT_EntityDissolve ) - SendPropTime( SENDINFO( m_flStartTime ) ), - SendPropFloat( SENDINFO( m_flFadeInStart ), 0, SPROP_NOSCALE ), - SendPropFloat( SENDINFO( m_flFadeInLength ), 0, SPROP_NOSCALE ), - SendPropFloat( SENDINFO( m_flFadeOutModelStart ), 0, SPROP_NOSCALE ), - SendPropFloat( SENDINFO( m_flFadeOutModelLength ), 0, SPROP_NOSCALE ), - SendPropFloat( SENDINFO( m_flFadeOutStart ), 0, SPROP_NOSCALE ), - SendPropFloat( SENDINFO( m_flFadeOutLength ), 0, SPROP_NOSCALE ), - SendPropInt( SENDINFO( m_nDissolveType ), ENTITY_DISSOLVE_BITS, SPROP_UNSIGNED ), - SendPropVector (SENDINFO(m_vDissolverOrigin), 0, SPROP_NOSCALE ), - SendPropInt( SENDINFO( m_nMagnitude ), 8, SPROP_UNSIGNED ), -END_SEND_TABLE() - -LINK_ENTITY_TO_CLASS( env_entity_dissolver, CEntityDissolve ); - - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CEntityDissolve::CEntityDissolve( void ) -{ - m_flStartTime = 0.0f; - m_nMagnitude = 250; -} - -CEntityDissolve::~CEntityDissolve( void ) -{ -} - - -//----------------------------------------------------------------------------- -// Precache -//----------------------------------------------------------------------------- -void CEntityDissolve::Precache() -{ - if ( NULL_STRING == GetModelName() ) - { - PrecacheModel( DISSOLVE_SPRITE_NAME ); - } - else - { - PrecacheModel( STRING( GetModelName() ) ); - } -} - - -//----------------------------------------------------------------------------- -// Spawn -//----------------------------------------------------------------------------- -void CEntityDissolve::Spawn() -{ - BaseClass::Spawn(); - Precache(); - UTIL_SetModel( this, STRING( GetModelName() ) ); - - if ( (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) - { - if ( dynamic_cast< CRagdollProp* >( GetMoveParent() ) ) - { - SetContextThink( &CEntityDissolve::ElectrocuteThink, gpGlobals->curtime + 0.01f, s_pElectroThinkContext ); - } - } - - // Setup our times - m_flFadeInStart = DISSOLVE_FADE_IN_START_TIME; - m_flFadeInLength = DISSOLVE_FADE_IN_END_TIME - DISSOLVE_FADE_IN_START_TIME; - - m_flFadeOutModelStart = DISSOLVE_FADE_OUT_MODEL_START_TIME; - m_flFadeOutModelLength = DISSOLVE_FADE_OUT_MODEL_END_TIME - DISSOLVE_FADE_OUT_MODEL_START_TIME; - - m_flFadeOutStart = DISSOLVE_FADE_OUT_START_TIME; - m_flFadeOutLength = DISSOLVE_FADE_OUT_END_TIME - DISSOLVE_FADE_OUT_START_TIME; - - if ( m_nDissolveType == ENTITY_DISSOLVE_CORE ) - { - m_flFadeInStart = 0.0f; - m_flFadeOutStart = CORE_DISSOLVE_FADE_START; - m_flFadeOutModelStart = CORE_DISSOLVE_MODEL_FADE_START; - m_flFadeOutModelLength = CORE_DISSOLVE_MODEL_FADE_LENGTH; - m_flFadeInLength = CORE_DISSOLVE_FADEIN_LENGTH; - } - - m_nRenderMode = kRenderTransColor; - SetRenderColor( 255, 255, 255, 255 ); - m_nRenderFX = kRenderFxNone; - - SetThink( &CEntityDissolve::DissolveThink ); - if ( gpGlobals->curtime > m_flStartTime ) - { - // Necessary for server-side ragdolls - DissolveThink(); - } - else - { - SetNextThink( gpGlobals->curtime + 0.01f ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : inputdata - -//----------------------------------------------------------------------------- -void CEntityDissolve::InputDissolve( inputdata_t &inputdata ) -{ - string_t strTarget = inputdata.value.StringID(); - - if (strTarget == NULL_STRING) - { - strTarget = m_target; - } - - CBaseEntity *pTarget = NULL; - while ((pTarget = gEntList.FindEntityGeneric(pTarget, STRING(strTarget), this, inputdata.pActivator)) != NULL) - { - CBaseAnimating *pBaseAnim = pTarget->GetBaseAnimating(); - if (pBaseAnim) - { - pBaseAnim->Dissolve( NULL, gpGlobals->curtime, false, m_nDissolveType, GetAbsOrigin(), m_nMagnitude ); - } - } -} - - - -//----------------------------------------------------------------------------- -// Purpose: Creates a flame and attaches it to a target entity. -// Input : pTarget - -//----------------------------------------------------------------------------- -CEntityDissolve *CEntityDissolve::Create( CBaseEntity *pTarget, const char *pMaterialName, - float flStartTime, int nDissolveType, bool *pRagdollCreated ) -{ - if ( pRagdollCreated ) - { - *pRagdollCreated = false; - } - - if ( !pMaterialName ) - { - pMaterialName = DISSOLVE_SPRITE_NAME; - } - - if ( pTarget->IsPlayer() ) - { - // Simply immediately kill the player. - CBasePlayer *pPlayer = assert_cast< CBasePlayer* >( pTarget ); - pPlayer->SetArmorValue( 0 ); - CTakeDamageInfo info( pPlayer, pPlayer, pPlayer->GetHealth(), DMG_GENERIC | DMG_REMOVENORAGDOLL | DMG_PREVENT_PHYSICS_FORCE ); - pPlayer->TakeDamage( info ); - return NULL; - } - - CEntityDissolve *pDissolve = (CEntityDissolve *) CreateEntityByName( "env_entity_dissolver" ); - - if ( pDissolve == NULL ) - return NULL; - - pDissolve->m_nDissolveType = nDissolveType; - if ( (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) - { - if ( pTarget->IsNPC() && pTarget->MyNPCPointer()->CanBecomeRagdoll() ) - { - CTakeDamageInfo info; - CBaseEntity *pRagdoll = CreateServerRagdoll( pTarget->MyNPCPointer(), 0, info, COLLISION_GROUP_DEBRIS, true ); - pRagdoll->SetCollisionBounds( pTarget->CollisionProp()->OBBMins(), pTarget->CollisionProp()->OBBMaxs() ); - - // Necessary to cause it to do the appropriate death cleanup - if ( pTarget->m_lifeState == LIFE_ALIVE ) - { - CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); - CTakeDamageInfo ragdollInfo( pPlayer, pPlayer, 10000.0, DMG_SHOCK | DMG_REMOVENORAGDOLL | DMG_PREVENT_PHYSICS_FORCE ); - pTarget->TakeDamage( ragdollInfo ); - } - - if ( pRagdollCreated ) - { - *pRagdollCreated = true; - } - - UTIL_Remove( pTarget ); - pTarget = pRagdoll; - } - } - - pDissolve->SetModelName( AllocPooledString(pMaterialName) ); - pDissolve->AttachToEntity( pTarget ); - pDissolve->SetStartTime( flStartTime ); - pDissolve->Spawn(); - - // Send to the client even though we don't have a model - pDissolve->AddEFlags( EFL_FORCE_CHECK_TRANSMIT ); - - // Play any appropriate noises when we start to dissolve - if ( (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) - { - pTarget->DispatchResponse( "TLK_ELECTROCUTESCREAM" ); - } - else - { - pTarget->DispatchResponse( "TLK_DISSOLVESCREAM" ); - } - return pDissolve; -} - - -//----------------------------------------------------------------------------- -// What type of dissolve? -//----------------------------------------------------------------------------- -CEntityDissolve *CEntityDissolve::Create( CBaseEntity *pTarget, CBaseEntity *pSource ) -{ - // Look for other boogies on the ragdoll + kill them - for ( CBaseEntity *pChild = pSource->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() ) - { - CEntityDissolve *pDissolve = dynamic_cast(pChild); - if ( !pDissolve ) - continue; - - return Create( pTarget, STRING( pDissolve->GetModelName() ), pDissolve->m_flStartTime, pDissolve->m_nDissolveType ); - } - - return NULL; -} - - -//----------------------------------------------------------------------------- -// Purpose: Attaches the flame to an entity and moves with it -// Input : pTarget - target entity to attach to -//----------------------------------------------------------------------------- -void CEntityDissolve::AttachToEntity( CBaseEntity *pTarget ) -{ - // So our dissolver follows the entity around on the server. - SetParent( pTarget ); - SetLocalOrigin( vec3_origin ); - SetLocalAngles( vec3_angle ); -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : lifetime - -//----------------------------------------------------------------------------- -void CEntityDissolve::SetStartTime( float flStartTime ) -{ - m_flStartTime = flStartTime; -} - -//----------------------------------------------------------------------------- -// Purpose: Burn targets around us -//----------------------------------------------------------------------------- -void CEntityDissolve::DissolveThink( void ) -{ - CBaseAnimating *pTarget = ( GetMoveParent() ) ? GetMoveParent()->GetBaseAnimating() : NULL; - - if ( GetModelName() == NULL_STRING && pTarget == NULL ) - return; - - if ( pTarget == NULL ) - { - UTIL_Remove( this ); - return; - } - - // Turn them into debris - pTarget->SetCollisionGroup( COLLISION_GROUP_DISSOLVING ); - - if ( pTarget && pTarget->GetFlags() & FL_TRANSRAGDOLL ) - { - SetRenderColorA( 0 ); - } - - float dt = gpGlobals->curtime - m_flStartTime; - - if ( dt < m_flFadeInStart ) - { - SetNextThink( m_flStartTime + m_flFadeInStart ); - return; - } - - // If we're done fading, then kill our target entity and us - if ( dt >= m_flFadeOutStart + m_flFadeOutLength ) - { - // Necessary to cause it to do the appropriate death cleanup - // Yeah, the player may have nothing to do with it, but - // passing NULL to TakeDamage causes bad things to happen - CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); - int iNoPhysicsDamage = g_pGameRules->Damage_GetNoPhysicsForce(); - CTakeDamageInfo info( pPlayer, pPlayer, 10000.0, DMG_GENERIC | DMG_REMOVENORAGDOLL | iNoPhysicsDamage ); - pTarget->TakeDamage( info ); - - if ( pTarget != pPlayer ) - { - UTIL_Remove( pTarget ); - } - - UTIL_Remove( this ); - - return; - } - - SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); -} - - -//----------------------------------------------------------------------------- -// Purpose: Burn targets around us -//----------------------------------------------------------------------------- -void CEntityDissolve::ElectrocuteThink( void ) -{ - CRagdollProp *pRagdoll = dynamic_cast< CRagdollProp* >( GetMoveParent() ); - if ( !pRagdoll ) - return; - - ragdoll_t *pRagdollPhys = pRagdoll->GetRagdoll( ); - for ( int j = 0; j < pRagdollPhys->listCount; ++j ) - { - Vector vecForce; - vecForce = RandomVector( -2400.0f, 2400.0f ); - pRagdollPhys->list[j].pObject->ApplyForceCenter( vecForce ); - } - - SetContextThink( &CEntityDissolve::ElectrocuteThink, gpGlobals->curtime + random->RandomFloat( 0.1, 0.2f ), - s_pElectroThinkContext ); -} +//========= 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 "EntityDissolve.h" +#include "baseanimating.h" +#include "physics_prop_ragdoll.h" +#include "ai_basenpc.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static const char *s_pElectroThinkContext = "ElectroThinkContext"; + + +//----------------------------------------------------------------------------- +// Lifetime +//----------------------------------------------------------------------------- +#define DISSOLVE_FADE_IN_START_TIME 0.0f +#define DISSOLVE_FADE_IN_END_TIME 1.0f +#define DISSOLVE_FADE_OUT_MODEL_START_TIME 1.9f +#define DISSOLVE_FADE_OUT_MODEL_END_TIME 2.0f +#define DISSOLVE_FADE_OUT_START_TIME 2.0f +#define DISSOLVE_FADE_OUT_END_TIME 2.0f + +//----------------------------------------------------------------------------- +// Model +//----------------------------------------------------------------------------- +#define DISSOLVE_SPRITE_NAME "sprites/blueglow1.vmt" + +//----------------------------------------------------------------------------- +// Save/load +//----------------------------------------------------------------------------- +BEGIN_DATADESC( CEntityDissolve ) + + DEFINE_FIELD( m_flStartTime, FIELD_TIME ), + DEFINE_FIELD( m_flFadeInStart, FIELD_FLOAT ), + DEFINE_FIELD( m_flFadeInLength, FIELD_FLOAT ), + DEFINE_FIELD( m_flFadeOutModelStart, FIELD_FLOAT ), + DEFINE_FIELD( m_flFadeOutModelLength, FIELD_FLOAT ), + DEFINE_FIELD( m_flFadeOutStart, FIELD_FLOAT ), + DEFINE_FIELD( m_flFadeOutLength, FIELD_FLOAT ), + DEFINE_KEYFIELD( m_nDissolveType, FIELD_INTEGER, "dissolvetype" ), + DEFINE_FIELD( m_vDissolverOrigin, FIELD_VECTOR ), + DEFINE_KEYFIELD( m_nMagnitude, FIELD_INTEGER, "magnitude" ), + + DEFINE_FUNCTION( DissolveThink ), + DEFINE_FUNCTION( ElectrocuteThink ), + + DEFINE_INPUTFUNC( FIELD_STRING, "Dissolve", InputDissolve ), + +END_DATADESC() + + +//----------------------------------------------------------------------------- +// Networking +//----------------------------------------------------------------------------- +IMPLEMENT_SERVERCLASS_ST( CEntityDissolve, DT_EntityDissolve ) + SendPropTime( SENDINFO( m_flStartTime ) ), + SendPropFloat( SENDINFO( m_flFadeInStart ), 0, SPROP_NOSCALE ), + SendPropFloat( SENDINFO( m_flFadeInLength ), 0, SPROP_NOSCALE ), + SendPropFloat( SENDINFO( m_flFadeOutModelStart ), 0, SPROP_NOSCALE ), + SendPropFloat( SENDINFO( m_flFadeOutModelLength ), 0, SPROP_NOSCALE ), + SendPropFloat( SENDINFO( m_flFadeOutStart ), 0, SPROP_NOSCALE ), + SendPropFloat( SENDINFO( m_flFadeOutLength ), 0, SPROP_NOSCALE ), + SendPropInt( SENDINFO( m_nDissolveType ), ENTITY_DISSOLVE_BITS, SPROP_UNSIGNED ), + SendPropVector (SENDINFO(m_vDissolverOrigin), 0, SPROP_NOSCALE ), + SendPropInt( SENDINFO( m_nMagnitude ), 8, SPROP_UNSIGNED ), +END_SEND_TABLE() + +LINK_ENTITY_TO_CLASS( env_entity_dissolver, CEntityDissolve ); + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CEntityDissolve::CEntityDissolve( void ) +{ + m_flStartTime = 0.0f; + m_nMagnitude = 250; +} + +CEntityDissolve::~CEntityDissolve( void ) +{ +} + + +//----------------------------------------------------------------------------- +// Precache +//----------------------------------------------------------------------------- +void CEntityDissolve::Precache() +{ + if ( NULL_STRING == GetModelName() ) + { + PrecacheModel( DISSOLVE_SPRITE_NAME ); + } + else + { + PrecacheModel( STRING( GetModelName() ) ); + } +} + + +//----------------------------------------------------------------------------- +// Spawn +//----------------------------------------------------------------------------- +void CEntityDissolve::Spawn() +{ + BaseClass::Spawn(); + Precache(); + UTIL_SetModel( this, STRING( GetModelName() ) ); + + if ( (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) + { + if ( dynamic_cast< CRagdollProp* >( GetMoveParent() ) ) + { + SetContextThink( &CEntityDissolve::ElectrocuteThink, gpGlobals->curtime + 0.01f, s_pElectroThinkContext ); + } + } + + // Setup our times + m_flFadeInStart = DISSOLVE_FADE_IN_START_TIME; + m_flFadeInLength = DISSOLVE_FADE_IN_END_TIME - DISSOLVE_FADE_IN_START_TIME; + + m_flFadeOutModelStart = DISSOLVE_FADE_OUT_MODEL_START_TIME; + m_flFadeOutModelLength = DISSOLVE_FADE_OUT_MODEL_END_TIME - DISSOLVE_FADE_OUT_MODEL_START_TIME; + + m_flFadeOutStart = DISSOLVE_FADE_OUT_START_TIME; + m_flFadeOutLength = DISSOLVE_FADE_OUT_END_TIME - DISSOLVE_FADE_OUT_START_TIME; + + if ( m_nDissolveType == ENTITY_DISSOLVE_CORE ) + { + m_flFadeInStart = 0.0f; + m_flFadeOutStart = CORE_DISSOLVE_FADE_START; + m_flFadeOutModelStart = CORE_DISSOLVE_MODEL_FADE_START; + m_flFadeOutModelLength = CORE_DISSOLVE_MODEL_FADE_LENGTH; + m_flFadeInLength = CORE_DISSOLVE_FADEIN_LENGTH; + } + + m_nRenderMode = kRenderTransColor; + SetRenderColor( 255, 255, 255, 255 ); + m_nRenderFX = kRenderFxNone; + + SetThink( &CEntityDissolve::DissolveThink ); + if ( gpGlobals->curtime > m_flStartTime ) + { + // Necessary for server-side ragdolls + DissolveThink(); + } + else + { + SetNextThink( gpGlobals->curtime + 0.01f ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : inputdata - +//----------------------------------------------------------------------------- +void CEntityDissolve::InputDissolve( inputdata_t &inputdata ) +{ + string_t strTarget = inputdata.value.StringID(); + + if (strTarget == NULL_STRING) + { + strTarget = m_target; + } + + CBaseEntity *pTarget = NULL; + while ((pTarget = gEntList.FindEntityGeneric(pTarget, STRING(strTarget), this, inputdata.pActivator)) != NULL) + { + CBaseAnimating *pBaseAnim = pTarget->GetBaseAnimating(); + if (pBaseAnim) + { + pBaseAnim->Dissolve( NULL, gpGlobals->curtime, false, m_nDissolveType, GetAbsOrigin(), m_nMagnitude ); + } + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: Creates a flame and attaches it to a target entity. +// Input : pTarget - +//----------------------------------------------------------------------------- +CEntityDissolve *CEntityDissolve::Create( CBaseEntity *pTarget, const char *pMaterialName, + float flStartTime, int nDissolveType, bool *pRagdollCreated ) +{ + if ( pRagdollCreated ) + { + *pRagdollCreated = false; + } + + if ( !pMaterialName ) + { + pMaterialName = DISSOLVE_SPRITE_NAME; + } + + if ( pTarget->IsPlayer() ) + { + // Simply immediately kill the player. + CBasePlayer *pPlayer = assert_cast< CBasePlayer* >( pTarget ); + pPlayer->SetArmorValue( 0 ); + CTakeDamageInfo info( pPlayer, pPlayer, pPlayer->GetHealth(), DMG_GENERIC | DMG_REMOVENORAGDOLL | DMG_PREVENT_PHYSICS_FORCE ); + pPlayer->TakeDamage( info ); + return NULL; + } + + CEntityDissolve *pDissolve = (CEntityDissolve *) CreateEntityByName( "env_entity_dissolver" ); + + if ( pDissolve == NULL ) + return NULL; + + pDissolve->m_nDissolveType = nDissolveType; + if ( (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) + { + if ( pTarget->IsNPC() && pTarget->MyNPCPointer()->CanBecomeRagdoll() ) + { + CTakeDamageInfo info; + CBaseEntity *pRagdoll = CreateServerRagdoll( pTarget->MyNPCPointer(), 0, info, COLLISION_GROUP_DEBRIS, true ); + pRagdoll->SetCollisionBounds( pTarget->CollisionProp()->OBBMins(), pTarget->CollisionProp()->OBBMaxs() ); + + // Necessary to cause it to do the appropriate death cleanup + if ( pTarget->m_lifeState == LIFE_ALIVE ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); + CTakeDamageInfo ragdollInfo( pPlayer, pPlayer, 10000.0, DMG_SHOCK | DMG_REMOVENORAGDOLL | DMG_PREVENT_PHYSICS_FORCE ); + pTarget->TakeDamage( ragdollInfo ); + } + + if ( pRagdollCreated ) + { + *pRagdollCreated = true; + } + + UTIL_Remove( pTarget ); + pTarget = pRagdoll; + } + } + + pDissolve->SetModelName( AllocPooledString(pMaterialName) ); + pDissolve->AttachToEntity( pTarget ); + pDissolve->SetStartTime( flStartTime ); + pDissolve->Spawn(); + + // Send to the client even though we don't have a model + pDissolve->AddEFlags( EFL_FORCE_CHECK_TRANSMIT ); + + // Play any appropriate noises when we start to dissolve + if ( (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) + { + pTarget->DispatchResponse( "TLK_ELECTROCUTESCREAM" ); + } + else + { + pTarget->DispatchResponse( "TLK_DISSOLVESCREAM" ); + } + return pDissolve; +} + + +//----------------------------------------------------------------------------- +// What type of dissolve? +//----------------------------------------------------------------------------- +CEntityDissolve *CEntityDissolve::Create( CBaseEntity *pTarget, CBaseEntity *pSource ) +{ + // Look for other boogies on the ragdoll + kill them + for ( CBaseEntity *pChild = pSource->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() ) + { + CEntityDissolve *pDissolve = dynamic_cast(pChild); + if ( !pDissolve ) + continue; + + return Create( pTarget, STRING( pDissolve->GetModelName() ), pDissolve->m_flStartTime, pDissolve->m_nDissolveType ); + } + + return NULL; +} + + +//----------------------------------------------------------------------------- +// Purpose: Attaches the flame to an entity and moves with it +// Input : pTarget - target entity to attach to +//----------------------------------------------------------------------------- +void CEntityDissolve::AttachToEntity( CBaseEntity *pTarget ) +{ + // So our dissolver follows the entity around on the server. + SetParent( pTarget ); + SetLocalOrigin( vec3_origin ); + SetLocalAngles( vec3_angle ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : lifetime - +//----------------------------------------------------------------------------- +void CEntityDissolve::SetStartTime( float flStartTime ) +{ + m_flStartTime = flStartTime; +} + +//----------------------------------------------------------------------------- +// Purpose: Burn targets around us +//----------------------------------------------------------------------------- +void CEntityDissolve::DissolveThink( void ) +{ + CBaseAnimating *pTarget = ( GetMoveParent() ) ? GetMoveParent()->GetBaseAnimating() : NULL; + + if ( GetModelName() == NULL_STRING && pTarget == NULL ) + return; + + if ( pTarget == NULL ) + { + UTIL_Remove( this ); + return; + } + + // Turn them into debris + pTarget->SetCollisionGroup( COLLISION_GROUP_DISSOLVING ); + + if ( pTarget && pTarget->GetFlags() & FL_TRANSRAGDOLL ) + { + SetRenderColorA( 0 ); + } + + float dt = gpGlobals->curtime - m_flStartTime; + + if ( dt < m_flFadeInStart ) + { + SetNextThink( m_flStartTime + m_flFadeInStart ); + return; + } + + // If we're done fading, then kill our target entity and us + if ( dt >= m_flFadeOutStart + m_flFadeOutLength ) + { + // Necessary to cause it to do the appropriate death cleanup + // Yeah, the player may have nothing to do with it, but + // passing NULL to TakeDamage causes bad things to happen + CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); + int iNoPhysicsDamage = g_pGameRules->Damage_GetNoPhysicsForce(); + CTakeDamageInfo info( pPlayer, pPlayer, 10000.0, DMG_GENERIC | DMG_REMOVENORAGDOLL | iNoPhysicsDamage ); + pTarget->TakeDamage( info ); + + if ( pTarget != pPlayer ) + { + UTIL_Remove( pTarget ); + } + + UTIL_Remove( this ); + + return; + } + + SetNextThink( gpGlobals->curtime + TICK_INTERVAL ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Burn targets around us +//----------------------------------------------------------------------------- +void CEntityDissolve::ElectrocuteThink( void ) +{ + CRagdollProp *pRagdoll = dynamic_cast< CRagdollProp* >( GetMoveParent() ); + if ( !pRagdoll ) + return; + + ragdoll_t *pRagdollPhys = pRagdoll->GetRagdoll( ); + for ( int j = 0; j < pRagdollPhys->listCount; ++j ) + { + Vector vecForce; + vecForce = RandomVector( -2400.0f, 2400.0f ); + pRagdollPhys->list[j].pObject->ApplyForceCenter( vecForce ); + } + + SetContextThink( &CEntityDissolve::ElectrocuteThink, gpGlobals->curtime + random->RandomFloat( 0.1, 0.2f ), + s_pElectroThinkContext ); +} -- cgit v1.2.3