410 lines
11 KiB
C++
410 lines
11 KiB
C++
//========= 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();
|
|
}
|