You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
301 lines
8.1 KiB
301 lines
8.1 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//=============================================================================// |
|
#include "cbase.h" |
|
#include "c_grenadetrail.h" |
|
#include "fx.h" |
|
//#include "engine/ivdebugoverlay.h" |
|
//#include "engine/IEngineSound.h" |
|
//#include "c_te_effect_dispatch.h" |
|
//#include "glow_overlay.h" |
|
//#include "fx_explosion.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
class CSmokeParticle : public CSimpleEmitter |
|
{ |
|
public: |
|
|
|
CSmokeParticle( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {} |
|
|
|
//Create |
|
static CSmokeParticle *Create( const char *pDebugName ) |
|
{ |
|
return new CSmokeParticle( pDebugName ); |
|
} |
|
|
|
//Alpha |
|
virtual float UpdateAlpha( const SimpleParticle *pParticle ) |
|
{ |
|
return ( ((float)pParticle->m_uchStartAlpha/255.0f) * sin( M_PI * (pParticle->m_flLifetime / pParticle->m_flDieTime) ) ); |
|
} |
|
|
|
//Color |
|
virtual Vector UpdateColor( const SimpleParticle *pParticle ) |
|
{ |
|
Vector color; |
|
|
|
float tLifetime = pParticle->m_flLifetime / pParticle->m_flDieTime; |
|
float ramp = 1.0f - tLifetime; |
|
|
|
Vector endcolor(75, 75, 75); |
|
|
|
color[0] = ( (float) pParticle->m_uchColor[0] * ramp ) / 255.0f + ( 1-ramp) * endcolor[0]; |
|
color[1] = ( (float) pParticle->m_uchColor[1] * ramp ) / 255.0f + ( 1-ramp) * endcolor[1]; |
|
color[2] = ( (float) pParticle->m_uchColor[2] * ramp ) / 255.0f + ( 1-ramp) * endcolor[2]; |
|
|
|
return color; |
|
} |
|
|
|
//Roll |
|
virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta ) |
|
{ |
|
pParticle->m_flRoll += pParticle->m_flRollDelta * timeDelta; |
|
|
|
pParticle->m_flRollDelta += pParticle->m_flRollDelta * ( timeDelta * -8.0f ); |
|
|
|
//Cap the minimum roll |
|
if ( fabs( pParticle->m_flRollDelta ) < 0.5f ) |
|
{ |
|
pParticle->m_flRollDelta = ( pParticle->m_flRollDelta > 0.0f ) ? 0.5f : -0.5f; |
|
} |
|
|
|
return pParticle->m_flRoll; |
|
} |
|
|
|
private: |
|
CSmokeParticle( const CSmokeParticle & ); |
|
}; |
|
|
|
// Datatable.. this can have all the smoketrail parameters when we need it to. |
|
IMPLEMENT_CLIENTCLASS_DT(C_GrenadeTrail, DT_GrenadeTrail, CGrenadeTrail) |
|
RecvPropFloat(RECVINFO(m_SpawnRate)), |
|
RecvPropFloat(RECVINFO(m_ParticleLifetime)), |
|
RecvPropFloat(RECVINFO(m_StopEmitTime)), |
|
RecvPropInt(RECVINFO(m_bEmit)), |
|
RecvPropInt(RECVINFO(m_nAttachment)), |
|
END_RECV_TABLE() |
|
|
|
// ------------------------------------------------------------------------- // |
|
// ParticleMovieExplosion |
|
// ------------------------------------------------------------------------- // |
|
C_GrenadeTrail::C_GrenadeTrail() |
|
{ |
|
m_MaterialHandle[0] = NULL; |
|
m_MaterialHandle[1] = NULL; |
|
|
|
// things that we will change |
|
m_SpawnRate = 10; |
|
m_ParticleLifetime = 5; |
|
m_bEmit = true; |
|
m_nAttachment = -1; |
|
m_StopEmitTime = 0; // No end time |
|
|
|
// invariants |
|
m_ParticleSpawn.Init(10); |
|
m_StartColor.Init(0.65, 0.65, 0.65); |
|
m_MinSpeed = 2; |
|
m_MaxSpeed = 6; |
|
m_MinDirectedSpeed = m_MaxDirectedSpeed = 0; |
|
m_StartSize = 2; |
|
m_EndSize = 6; |
|
m_SpawnRadius = 2; |
|
m_VelocityOffset.Init(); |
|
m_Opacity = 0.3f; |
|
|
|
m_pSmokeEmitter = NULL; |
|
m_pParticleMgr = NULL; |
|
} |
|
|
|
C_GrenadeTrail::~C_GrenadeTrail() |
|
{ |
|
if ( m_pParticleMgr ) |
|
{ |
|
m_pParticleMgr->RemoveEffect( &m_ParticleEffect ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void C_GrenadeTrail::GetAimEntOrigin( IClientEntity *pAttachedTo, Vector *pAbsOrigin, QAngle *pAbsAngles ) |
|
{ |
|
C_BaseEntity *pEnt = pAttachedTo->GetBaseEntity(); |
|
if (pEnt && (m_nAttachment > 0)) |
|
{ |
|
pEnt->GetAttachment( m_nAttachment, *pAbsOrigin, *pAbsAngles ); |
|
} |
|
else |
|
{ |
|
BaseClass::GetAimEntOrigin( pAttachedTo, pAbsOrigin, pAbsAngles ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : bEmit - |
|
//----------------------------------------------------------------------------- |
|
void C_GrenadeTrail::SetEmit(bool bEmit) |
|
{ |
|
m_bEmit = bEmit; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : rate - |
|
//----------------------------------------------------------------------------- |
|
void C_GrenadeTrail::SetSpawnRate(float rate) |
|
{ |
|
m_SpawnRate = rate; |
|
m_ParticleSpawn.Init(rate); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : bnewentity - |
|
//----------------------------------------------------------------------------- |
|
void C_GrenadeTrail::OnDataChanged(DataUpdateType_t updateType) |
|
{ |
|
C_BaseEntity::OnDataChanged(updateType); |
|
|
|
if ( updateType == DATA_UPDATE_CREATED ) |
|
{ |
|
Start( ParticleMgr(), NULL ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *pParticleMgr - |
|
// *pArgs - |
|
//----------------------------------------------------------------------------- |
|
void C_GrenadeTrail::Start( CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs ) |
|
{ |
|
if(!pParticleMgr->AddEffect( &m_ParticleEffect, this )) |
|
return; |
|
|
|
m_pParticleMgr = pParticleMgr; |
|
m_pSmokeEmitter = CSmokeParticle::Create("smokeTrail"); |
|
|
|
if ( !m_pSmokeEmitter ) |
|
{ |
|
Assert( false ); |
|
return; |
|
} |
|
|
|
m_pSmokeEmitter->SetSortOrigin( GetAbsOrigin() ); |
|
m_pSmokeEmitter->SetNearClip( 64.0f, 128.0f ); |
|
|
|
m_MaterialHandle[0] = g_Mat_DustPuff[0]; |
|
m_MaterialHandle[1] = g_Mat_DustPuff[1]; |
|
|
|
m_ParticleSpawn.Init( m_SpawnRate ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : fTimeDelta - |
|
//----------------------------------------------------------------------------- |
|
void C_GrenadeTrail::Update( float fTimeDelta ) |
|
{ |
|
if ( !m_pSmokeEmitter ) |
|
return; |
|
|
|
// Grenades thrown out of the PVS should not draw particles at the world origin |
|
if ( IsDormant() ) |
|
return; |
|
|
|
Vector offsetColor; |
|
|
|
// Add new particles |
|
if ( !m_bEmit ) |
|
return; |
|
|
|
if ( ( m_StopEmitTime != 0 ) && ( m_StopEmitTime <= gpGlobals->curtime ) ) |
|
return; |
|
|
|
float tempDelta = fTimeDelta; |
|
|
|
SimpleParticle *pParticle; |
|
Vector offset; |
|
|
|
Vector vecOrigin; |
|
VectorMA( GetAbsOrigin(), -fTimeDelta, GetAbsVelocity(), vecOrigin ); |
|
|
|
Vector vecForward; |
|
GetVectors( &vecForward, NULL, NULL ); |
|
|
|
while( m_ParticleSpawn.NextEvent( tempDelta ) ) |
|
{ |
|
float fldt = fTimeDelta - tempDelta; |
|
|
|
offset.Random( -m_SpawnRadius, m_SpawnRadius ); |
|
offset += vecOrigin; |
|
VectorMA( offset, fldt, GetAbsVelocity(), offset ); |
|
|
|
pParticle = (SimpleParticle *) m_pSmokeEmitter->AddParticle( sizeof( SimpleParticle ), m_MaterialHandle[random->RandomInt(0,1)], offset ); |
|
|
|
if ( pParticle == NULL ) |
|
continue; |
|
|
|
pParticle->m_flLifetime = 0.0f; |
|
pParticle->m_flDieTime = m_ParticleLifetime; |
|
|
|
pParticle->m_iFlags = 0; // no wind! |
|
|
|
pParticle->m_vecVelocity.Random( -1.0f, 1.0f ); |
|
pParticle->m_vecVelocity *= random->RandomFloat( m_MinSpeed, m_MaxSpeed ); |
|
|
|
float flDirectedVel = random->RandomFloat( m_MinDirectedSpeed, m_MaxDirectedSpeed ); |
|
VectorMA( pParticle->m_vecVelocity, flDirectedVel, vecForward, pParticle->m_vecVelocity ); |
|
|
|
pParticle->m_vecVelocity[2] += 15; |
|
|
|
offsetColor = m_StartColor; |
|
float flMaxVal = MAX( m_StartColor[0], m_StartColor[1] ); |
|
if ( flMaxVal < m_StartColor[2] ) |
|
{ |
|
flMaxVal = m_StartColor[2]; |
|
} |
|
offsetColor /= flMaxVal; |
|
|
|
offsetColor *= random->RandomFloat( -0.2f, 0.2f ); |
|
offsetColor += m_StartColor; |
|
|
|
offsetColor[0] = clamp( offsetColor[0], 0.0f, 1.0f ); |
|
offsetColor[1] = clamp( offsetColor[1], 0.0f, 1.0f ); |
|
offsetColor[2] = clamp( offsetColor[2], 0.0f, 1.0f ); |
|
|
|
pParticle->m_uchColor[0] = offsetColor[0]*255.0f; |
|
pParticle->m_uchColor[1] = offsetColor[1]*255.0f; |
|
pParticle->m_uchColor[2] = offsetColor[2]*255.0f; |
|
|
|
pParticle->m_uchStartSize = m_StartSize; |
|
pParticle->m_uchEndSize = m_EndSize; |
|
|
|
float alpha = random->RandomFloat( m_Opacity*0.75f, m_Opacity*1.25f ); |
|
alpha = clamp( alpha, 0.0f, 1.0f ); |
|
|
|
pParticle->m_uchStartAlpha = alpha * 255; |
|
pParticle->m_uchEndAlpha = 0; |
|
|
|
pParticle->m_flRoll = random->RandomInt( 0, 360 ); |
|
pParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f ); |
|
} |
|
} |
|
|
|
void C_GrenadeTrail::RenderParticles( CParticleRenderIterator *pIterator ) |
|
{ |
|
} |
|
|
|
|
|
void C_GrenadeTrail::SimulateParticles( CParticleSimulateIterator *pIterator ) |
|
{ |
|
}
|
|
|