diff options
Diffstat (limited to 'game/client/c_fire_smoke.cpp')
| -rw-r--r-- | game/client/c_fire_smoke.cpp | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/game/client/c_fire_smoke.cpp b/game/client/c_fire_smoke.cpp new file mode 100644 index 0000000..7e2aa05 --- /dev/null +++ b/game/client/c_fire_smoke.cpp @@ -0,0 +1,409 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" +#include "iviewrender.h" +#include "clienteffectprecachesystem.h" +#include "studio.h" +#include "bone_setup.h" +#include "engine/ivmodelinfo.h" +#include "c_fire_smoke.h" +#include "engine/IEngineSound.h" +#include "iefx.h" +#include "dlight.h" +#include "tier0/icommandline.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +CLIENTEFFECT_REGISTER_BEGIN( SmokeStackMaterials ) + CLIENTEFFECT_MATERIAL( "particle/SmokeStack" ) +CLIENTEFFECT_REGISTER_END() + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pRecvProp - +// *pStruct - +// *pVarData - +// *pIn - +// objectID - +//----------------------------------------------------------------------------- +void RecvProxy_Scale( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + C_FireSmoke *pFireSmoke = (C_FireSmoke *) pStruct; + float scale = pData->m_Value.m_Float; + + //If changed, update our internal information + if ( ( pFireSmoke->m_flScale != scale ) && ( pFireSmoke->m_flScaleEnd != scale ) ) + { + pFireSmoke->m_flScaleStart = pFireSmoke->m_flScaleRegister; + pFireSmoke->m_flScaleEnd = scale; + } + + pFireSmoke->m_flScale = scale; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pRecvProp - +// *pStruct - +// *pVarData - +// *pIn - +// objectID - +//----------------------------------------------------------------------------- +void RecvProxy_ScaleTime( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + C_FireSmoke *pFireSmoke = (C_FireSmoke *) pStruct; + float time = pData->m_Value.m_Float; + + //If changed, update our internal information + //if ( pFireSmoke->m_flScaleTime != time ) + { + if ( time == -1.0f ) + { + pFireSmoke->m_flScaleTimeStart = Helper_GetTime()-1.0f; + pFireSmoke->m_flScaleTimeEnd = pFireSmoke->m_flScaleTimeStart; + } + else + { + pFireSmoke->m_flScaleTimeStart = Helper_GetTime(); + pFireSmoke->m_flScaleTimeEnd = Helper_GetTime() + time; + } + } + + pFireSmoke->m_flScaleTime = time; +} + +//Receive datatable +IMPLEMENT_CLIENTCLASS_DT( C_FireSmoke, DT_FireSmoke, CFireSmoke ) + RecvPropFloat( RECVINFO( m_flStartScale )), + RecvPropFloat( RECVINFO( m_flScale ), 0, RecvProxy_Scale ), + RecvPropFloat( RECVINFO( m_flScaleTime ), 0, RecvProxy_ScaleTime ), + RecvPropInt( RECVINFO( m_nFlags ) ), + RecvPropInt( RECVINFO( m_nFlameModelIndex ) ), + RecvPropInt( RECVINFO( m_nFlameFromAboveModelIndex ) ), +END_RECV_TABLE() + +//================================================== +// C_FireSmoke +//================================================== + +C_FireSmoke::C_FireSmoke() +{ +} + +C_FireSmoke::~C_FireSmoke() +{ + + // Shut down our effect if we have it + if ( m_hEffect ) + { + m_hEffect->StopEmission(false, false , true); + m_hEffect = NULL; + } + +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_FireSmoke::Simulate( void ) +{ +} + +#define FLAME_ALPHA_START 0.9f +#define FLAME_ALPHA_END 1.0f + +#define FLAME_TRANS_START 0.75f + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_FireSmoke::AddFlames( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : bnewentity - +//----------------------------------------------------------------------------- +void C_FireSmoke::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + + + if ( updateType == DATA_UPDATE_CREATED ) + { + Start(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_FireSmoke::UpdateEffects( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool C_FireSmoke::ShouldDraw() +{ + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_FireSmoke::Start( void ) +{ + const char *lpszEffectName; + int nSize = (int) floor( m_flStartScale / 36.0f ); + switch ( nSize ) + { + case 0: + lpszEffectName = ( m_nFlags & bitsFIRESMOKE_SMOKE ) ? "env_fire_tiny_smoke" : "env_fire_tiny"; + break; + + case 1: + lpszEffectName = ( m_nFlags & bitsFIRESMOKE_SMOKE ) ? "env_fire_small_smoke" : "env_fire_small"; + break; + + case 2: + lpszEffectName = ( m_nFlags & bitsFIRESMOKE_SMOKE ) ? "env_fire_medium_smoke" : "env_fire_medium"; + break; + + case 3: + default: + lpszEffectName = ( m_nFlags & bitsFIRESMOKE_SMOKE ) ? "env_fire_large_smoke" : "env_fire_large"; + break; + } + + // Create the effect of the correct size + m_hEffect = ParticleProp()->Create( lpszEffectName, PATTACH_ABSORIGIN ); + +} + + +//----------------------------------------------------------------------------- +// Purpose: FIXME: what's the right way to do this? +//----------------------------------------------------------------------------- +void C_FireSmoke::StartClientOnly( void ) +{ + Start(); + + ClientEntityList().AddNonNetworkableEntity( this ); + CollisionProp()->CreatePartitionHandle(); + AddEffects( EF_NORECEIVESHADOW | EF_NOSHADOW ); + AddToLeafSystem(); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_FireSmoke::RemoveClientOnly(void) +{ + ClientThinkList()->RemoveThinkable( GetClientHandle() ); + + // Remove from the client entity list. + ClientEntityList().RemoveEntity( GetClientHandle() ); + + ::partition->Remove( PARTITION_CLIENT_SOLID_EDICTS | PARTITION_CLIENT_RESPONSIVE_EDICTS | PARTITION_CLIENT_NON_STATIC_EDICTS, CollisionProp()->GetPartitionHandle() ); + + RemoveFromLeafSystem(); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_FireSmoke::UpdateAnimation( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_FireSmoke::UpdateFlames( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_FireSmoke::UpdateScale( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_FireSmoke::Update( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_FireSmoke::FindClipPlane( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: Spawn smoke (...duh) +//----------------------------------------------------------------------------- + +void C_FireSmoke::SpawnSmoke( void ) +{ +} + + +IMPLEMENT_CLIENTCLASS_DT( C_EntityFlame, DT_EntityFlame, CEntityFlame ) + RecvPropEHandle(RECVINFO(m_hEntAttached)), +END_RECV_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +C_EntityFlame::C_EntityFlame( void ) : +m_hEffect( NULL ) +{ + m_hOldAttached = NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +C_EntityFlame::~C_EntityFlame( void ) +{ + StopEffect(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_EntityFlame::StopEffect( void ) +{ + if ( m_hEffect ) + { + ParticleProp()->StopEmission( m_hEffect, true ); + m_hEffect->SetControlPointEntity( 0, NULL ); + m_hEffect->SetControlPointEntity( 1, NULL ); + m_hEffect = NULL; + } + + if ( m_hEntAttached ) + { + m_hEntAttached->RemoveFlag( FL_ONFIRE ); + m_hEntAttached->SetEffectEntity( NULL ); + m_hEntAttached->StopSound( "General.BurningFlesh" ); + m_hEntAttached->StopSound( "General.BurningObject" ); + + + m_hEntAttached = NULL; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_EntityFlame::UpdateOnRemove( void ) +{ + StopEffect(); + BaseClass::UpdateOnRemove(); +} + +void C_EntityFlame::CreateEffect( void ) +{ + if ( m_hEffect ) + { + ParticleProp()->StopEmission( m_hEffect, true ); + m_hEffect->SetControlPointEntity( 0, NULL ); + m_hEffect->SetControlPointEntity( 1, NULL ); + m_hEffect = NULL; + } + +#ifdef TF_CLIENT_DLL + m_hEffect = ParticleProp()->Create( "burningplayer_red", PATTACH_ABSORIGIN_FOLLOW ); +#else + m_hEffect = ParticleProp()->Create( "burning_character", PATTACH_ABSORIGIN_FOLLOW ); +#endif + + if ( m_hEffect ) + { + C_BaseEntity *pEntity = m_hEntAttached; + m_hOldAttached = m_hEntAttached; + + ParticleProp()->AddControlPoint( m_hEffect, 1, pEntity, PATTACH_ABSORIGIN_FOLLOW ); + m_hEffect->SetControlPoint( 0, GetAbsOrigin() ); + m_hEffect->SetControlPoint( 1, GetAbsOrigin() ); + m_hEffect->SetControlPointEntity( 0, pEntity ); + m_hEffect->SetControlPointEntity( 1, pEntity ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_EntityFlame::OnDataChanged( DataUpdateType_t updateType ) +{ + if ( updateType == DATA_UPDATE_CREATED ) + { + CreateEffect(); + } + + // FIXME: This is a bit of a shady path + if ( updateType == DATA_UPDATE_DATATABLE_CHANGED ) + { + // If our owner changed, then recreate the effect + if ( m_hEntAttached != m_hOldAttached ) + { + CreateEffect(); + } + } + + BaseClass::OnDataChanged( updateType ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_EntityFlame::Simulate( void ) +{ + if ( gpGlobals->frametime <= 0.0f ) + return; + +#ifdef HL2_EPISODIC + + if ( IsEffectActive(EF_BRIGHTLIGHT) || IsEffectActive(EF_DIMLIGHT) ) + { + dlight_t *dl = effects->CL_AllocDlight ( index ); + dl->origin = GetAbsOrigin(); + dl->origin[2] += 16; + dl->color.r = 254; + dl->color.g = 174; + dl->color.b = 10; + dl->radius = random->RandomFloat(400,431); + dl->die = gpGlobals->curtime + 0.001; + } + +#endif // HL2_EPISODIC +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_EntityFlame::ClientThink( void ) +{ + StopEffect(); + Release(); +} |