mirror of
https://github.com/nillerusr/source-engine.git
synced 2025-01-27 15:24:28 +00:00
252 lines
6.4 KiB
C++
252 lines
6.4 KiB
C++
#include "cbase.h"
|
|
#include "precache_register.h"
|
|
#include "particles_simple.h"
|
|
#include "iefx.h"
|
|
#include "dlight.h"
|
|
#include "view.h"
|
|
#include "fx.h"
|
|
#include "clientsideeffects.h"
|
|
#include "c_pixel_visibility.h"
|
|
#include "c_asw_flare_projectile.h"
|
|
#include "soundenvelope.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
//Precahce the effects
|
|
PRECACHE_REGISTER_BEGIN( GLOBAL, ASWPrecacheEffectFlares )
|
|
PRECACHE_REGISTER_END()
|
|
|
|
|
|
IMPLEMENT_CLIENTCLASS_DT( C_ASW_Flare_Projectile, DT_ASW_Flare_Projectile, CASW_Flare_Projectile )
|
|
RecvPropFloat( RECVINFO( m_flTimeBurnOut ) ),
|
|
RecvPropFloat( RECVINFO( m_flScale ) ),
|
|
RecvPropInt( RECVINFO( m_bLight ) ),
|
|
RecvPropInt( RECVINFO( m_bSmoke ) ),
|
|
END_RECV_TABLE()
|
|
|
|
// flares maintain a linked list of themselves, for quick checking for autoaim
|
|
C_ASW_Flare_Projectile* g_pHeadFlare = NULL;
|
|
|
|
ConVar asw_flare_r("asw_flare_r", "240", 0, "Colour of flares");
|
|
ConVar asw_flare_g("asw_flare_g", "255", 0, "Colour of flares");
|
|
ConVar asw_flare_b("asw_flare_b", "200", 0, "Colour of flares");
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Constructor
|
|
//-----------------------------------------------------------------------------
|
|
C_ASW_Flare_Projectile::C_ASW_Flare_Projectile()
|
|
{
|
|
m_flTimeBurnOut = 0.0f;
|
|
m_pDLight = NULL;
|
|
|
|
m_bLight = true;
|
|
m_bSmoke = true;
|
|
|
|
//SetDynamicallyAllocated( false );
|
|
m_queryHandle = 0;
|
|
m_fStartLightTime = 0;
|
|
m_fLightRadius = 0;
|
|
|
|
m_pFlareEffect = NULL;
|
|
|
|
// keep a linked list of flares (used for autoaim)
|
|
if (g_pHeadFlare)
|
|
{
|
|
m_pNextFlare = g_pHeadFlare;
|
|
g_pHeadFlare = this;
|
|
}
|
|
else
|
|
{
|
|
g_pHeadFlare = this;
|
|
m_pNextFlare = NULL;
|
|
}
|
|
}
|
|
|
|
C_ASW_Flare_Projectile::~C_ASW_Flare_Projectile( void )
|
|
{
|
|
// remove ourselves from the linked list of flares
|
|
if (g_pHeadFlare == this)
|
|
{
|
|
g_pHeadFlare = m_pNextFlare;
|
|
}
|
|
else
|
|
{
|
|
C_ASW_Flare_Projectile* pFlare = g_pHeadFlare;
|
|
int k=0;
|
|
while (pFlare != this && pFlare != NULL && k < 256) // some paranoid checks (should always break out of the while anyway)
|
|
{
|
|
k++;
|
|
if (pFlare->m_pNextFlare == this)
|
|
{
|
|
pFlare->m_pNextFlare = m_pNextFlare; // pulled ourselves out of the list
|
|
break;
|
|
}
|
|
pFlare = pFlare->m_pNextFlare;
|
|
}
|
|
}
|
|
|
|
if (m_pDLight)
|
|
{
|
|
m_pDLight->die = gpGlobals->curtime;
|
|
m_pDLight = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : state -
|
|
//-----------------------------------------------------------------------------
|
|
void C_ASW_Flare_Projectile::NotifyShouldTransmit( ShouldTransmitState_t state )
|
|
{
|
|
if ( state == SHOULDTRANSMIT_END )
|
|
{
|
|
AddEffects( EF_NODRAW );
|
|
}
|
|
else if ( state == SHOULDTRANSMIT_START )
|
|
{
|
|
RemoveEffects( EF_NODRAW );
|
|
}
|
|
|
|
BaseClass::NotifyShouldTransmit( state );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : bool -
|
|
//-----------------------------------------------------------------------------
|
|
void C_ASW_Flare_Projectile::OnDataChanged( DataUpdateType_t updateType )
|
|
{
|
|
if ( updateType == DATA_UPDATE_CREATED )
|
|
{
|
|
SetNextClientThink(gpGlobals->curtime);
|
|
//SetSortOrigin( GetAbsOrigin() );
|
|
SoundInit();
|
|
}
|
|
|
|
BaseClass::OnDataChanged( updateType );
|
|
}
|
|
|
|
const Vector& C_ASW_Flare_Projectile::GetEffectOrigin()
|
|
{
|
|
static Vector s_vecEffectPos;
|
|
Vector forward, right, up;
|
|
AngleVectors(GetAbsAngles(), &forward, &right, &up);
|
|
s_vecEffectPos = GetAbsOrigin() + up * 5;
|
|
return s_vecEffectPos;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : timeDelta -
|
|
//-----------------------------------------------------------------------------
|
|
//void C_ASW_Flare_Projectile::Update( float timeDelta )
|
|
void C_ASW_Flare_Projectile::ClientThink( void )
|
|
{
|
|
if ( m_pFlareEffect.GetObject() == NULL )
|
|
{
|
|
//m_flTimePulse = gpGlobals->curtime + asw_buffgrenade_pulse_interval.GetFloat();
|
|
|
|
m_pFlareEffect = ParticleProp()->Create( "flare_fx_main", PATTACH_ABSORIGIN_FOLLOW, -1, GetEffectOrigin() - GetAbsOrigin() );
|
|
//flare_fx_main
|
|
}
|
|
|
|
float baseScale = m_flScale;
|
|
|
|
//Account for fading out
|
|
if ( ( m_flTimeBurnOut != -1.0f ) && ( ( m_flTimeBurnOut - gpGlobals->curtime ) <= 10.0f ) )
|
|
{
|
|
baseScale *= ( ( m_flTimeBurnOut - gpGlobals->curtime ) / 10.0f );
|
|
|
|
CSoundEnvelopeController::GetController().SoundChangeVolume( m_pBurnSound, clamp<float>(0.6f * baseScale, 0.0f, 0.6f), 0 );
|
|
}
|
|
|
|
if ( baseScale < 0.01f )
|
|
return;
|
|
//
|
|
// Dynamic light
|
|
//
|
|
|
|
if ( m_bLight )
|
|
{
|
|
if (m_fStartLightTime == 0)
|
|
{
|
|
m_fStartLightTime = gpGlobals->curtime;
|
|
}
|
|
if (!m_pDLight)
|
|
{
|
|
m_pDLight = effects->CL_AllocDlight( index );
|
|
m_pDLight->color.r = asw_flare_r.GetInt();
|
|
m_pDLight->color.g = asw_flare_g.GetInt();
|
|
m_pDLight->color.b = asw_flare_b.GetInt();
|
|
m_pDLight->color.exponent = 3;
|
|
}
|
|
|
|
m_pDLight->origin = GetAbsOrigin() + Vector(0, 0, 5); // make the dlight slightly higher than the flare, so it doesn't bury the light being so close to the ground
|
|
|
|
float flTimeLeft = MAX( 2.0, m_flTimeBurnOut - gpGlobals->curtime );
|
|
if (m_fLightRadius < 8.0f)
|
|
{
|
|
m_fLightRadius += flTimeLeft * (1.0f + random->RandomFloat() * 36.0f);
|
|
if (m_fLightRadius > 8.0f)
|
|
m_fLightRadius = 8.0f;
|
|
}
|
|
m_pDLight->radius = MAX( 64.0, baseScale * 120 * (m_fLightRadius/8.0f) );
|
|
|
|
if ( ( m_flTimeBurnOut != -1.0f ) && ( ( m_flTimeBurnOut - gpGlobals->curtime ) <= 4.0f ) )
|
|
{
|
|
// flicker as we're going out
|
|
//m_pDLight->die = gpGlobals->curtime;
|
|
//m_pDLight = NULL;
|
|
}
|
|
else
|
|
{
|
|
m_pDLight->die = gpGlobals->curtime + 30.0f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_fStartLightTime = 0;
|
|
}
|
|
|
|
SetNextClientThink(gpGlobals->curtime + 0.1f);
|
|
}
|
|
|
|
void C_ASW_Flare_Projectile::OnRestore()
|
|
{
|
|
BaseClass::OnRestore();
|
|
SoundInit();
|
|
}
|
|
|
|
void C_ASW_Flare_Projectile::UpdateOnRemove()
|
|
{
|
|
BaseClass::UpdateOnRemove();
|
|
SoundShutdown();
|
|
}
|
|
|
|
void C_ASW_Flare_Projectile::SoundInit()
|
|
{
|
|
// play flare start sound!!
|
|
CPASAttenuationFilter filter( this );
|
|
|
|
EmitSound("ASW_Flare.IgniteFlare");
|
|
|
|
// Bring up the flare burning loop sound
|
|
if( !m_pBurnSound )
|
|
{
|
|
m_pBurnSound = CSoundEnvelopeController::GetController().SoundCreate( filter, entindex(), "ASW_Flare.FlareLoop" );
|
|
CSoundEnvelopeController::GetController().Play( m_pBurnSound, 0.0, 100 );
|
|
CSoundEnvelopeController::GetController().SoundChangeVolume( m_pBurnSound, 0.6, 2.0 );
|
|
}
|
|
}
|
|
|
|
void C_ASW_Flare_Projectile::SoundShutdown()
|
|
{
|
|
if ( m_pBurnSound )
|
|
{
|
|
CSoundEnvelopeController::GetController().SoundDestroy( m_pBurnSound );
|
|
m_pBurnSound = NULL;
|
|
}
|
|
}
|