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.
279 lines
8.1 KiB
279 lines
8.1 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "particles_simple.h" |
|
#include "c_tracer.h" |
|
#include "particle_collision.h" |
|
#include "view.h" |
|
#include "clienteffectprecachesystem.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
#define PLASMASPARK_LIFETIME 0.5 |
|
#define SPRAYS_PER_THINK 12 |
|
|
|
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectPlasmaBeam ) |
|
CLIENTEFFECT_MATERIAL( "sprites/plasmaember" ) |
|
CLIENTEFFECT_REGISTER_END() |
|
|
|
class C_PlasmaBeamNode; |
|
|
|
//################################################################## |
|
// |
|
// > CPlasmaSpray |
|
// |
|
//################################################################## |
|
class CPlasmaSpray : public CSimpleEmitter |
|
{ |
|
public: |
|
CPlasmaSpray( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {} |
|
|
|
static CSmartPtr<CPlasmaSpray> Create( const char *pDebugName ); |
|
void Think( void ); |
|
void UpdateVelocity( SimpleParticle *pParticle, float timeDelta ); |
|
virtual void RenderParticles( CParticleRenderIterator *pIterator ); |
|
virtual void SimulateParticles( CParticleSimulateIterator *pIterator ); |
|
EHANDLE m_pOwner; |
|
CParticleCollision m_ParticleCollision; |
|
|
|
private: |
|
CPlasmaSpray( const CPlasmaSpray & ); |
|
}; |
|
|
|
//################################################################## |
|
// |
|
// PlasmaBeamNode - generates plasma spray |
|
// |
|
//################################################################## |
|
class C_PlasmaBeamNode : public C_BaseEntity |
|
{ |
|
public: |
|
DECLARE_CLASS( C_PlasmaBeamNode, C_BaseEntity ); |
|
DECLARE_CLIENTCLASS(); |
|
|
|
C_PlasmaBeamNode(); |
|
~C_PlasmaBeamNode(void); |
|
|
|
public: |
|
void ClientThink(void); |
|
void AddEntity( void ); |
|
void OnDataChanged(DataUpdateType_t updateType); |
|
bool ShouldDraw(); |
|
bool m_bSprayOn; |
|
CSmartPtr<CPlasmaSpray> m_pFirePlasmaSpray; |
|
}; |
|
|
|
//################################################################## |
|
// |
|
// > CPlasmaSpray |
|
// |
|
//################################################################## |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *pParticle - |
|
// timeDelta - |
|
// Output : float |
|
//----------------------------------------------------------------------------- |
|
CSmartPtr<CPlasmaSpray> CPlasmaSpray::Create( const char *pDebugName ) |
|
{ |
|
CPlasmaSpray *pRet = new CPlasmaSpray( pDebugName ); |
|
return pRet; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : fTimeDelta - |
|
// Output : Vector |
|
//----------------------------------------------------------------------------- |
|
void CPlasmaSpray::UpdateVelocity( SimpleParticle *pParticle, float timeDelta ) |
|
{ |
|
Vector vGravity = Vector(0,0,-1000); |
|
float flFrametime = gpGlobals->frametime; |
|
vGravity = flFrametime * vGravity; |
|
pParticle->m_vecVelocity += vGravity; |
|
} |
|
|
|
|
|
void CPlasmaSpray::SimulateParticles( CParticleSimulateIterator *pIterator ) |
|
{ |
|
float timeDelta = pIterator->GetTimeDelta(); |
|
|
|
SimpleParticle *pParticle = (SimpleParticle*)pIterator->GetFirst(); |
|
while ( pParticle ) |
|
{ |
|
//Should this particle die? |
|
pParticle->m_flLifetime += timeDelta; |
|
|
|
C_PlasmaBeamNode* pNode = (C_PlasmaBeamNode*)((C_BaseEntity*)m_pOwner); |
|
if ( pParticle->m_flLifetime >= pParticle->m_flDieTime ) |
|
{ |
|
pIterator->RemoveParticle( pParticle ); |
|
} |
|
// If owner is gone or spray off remove me |
|
else if (pNode == NULL || !pNode->m_bSprayOn) |
|
{ |
|
pIterator->RemoveParticle( pParticle ); |
|
} |
|
|
|
//Simulate the movement with collision |
|
trace_t trace; |
|
m_ParticleCollision.MoveParticle( pParticle->m_Pos, pParticle->m_vecVelocity, NULL, timeDelta, &trace ); |
|
|
|
pParticle = (SimpleParticle*)pIterator->GetNext(); |
|
} |
|
} |
|
|
|
|
|
void CPlasmaSpray::RenderParticles( CParticleRenderIterator *pIterator ) |
|
{ |
|
const SimpleParticle *pParticle = (const SimpleParticle *)pIterator->GetFirst(); |
|
while ( pParticle ) |
|
{ |
|
float scale = random->RandomFloat( 0.02, 0.08 ); |
|
|
|
// NOTE: We need to do everything in screen space |
|
Vector delta; |
|
Vector start; |
|
TransformParticle(ParticleMgr()->GetModelView(), pParticle->m_Pos, start); |
|
float sortKey = start.z; |
|
|
|
Vector3DMultiply( CurrentWorldToViewMatrix(), pParticle->m_vecVelocity, delta ); |
|
|
|
delta[0] *= scale; |
|
delta[1] *= scale; |
|
delta[2] *= scale; |
|
|
|
// See c_tracer.* for this method |
|
Tracer_Draw( pIterator->GetParticleDraw(), start, delta, random->RandomInt( 2, 8 ), 0 ); |
|
|
|
pParticle = (const SimpleParticle *)pIterator->GetNext( sortKey ); |
|
} |
|
} |
|
|
|
|
|
//################################################################## |
|
// |
|
// PlasmaBeamNode - generates plasma spray |
|
// |
|
//################################################################## |
|
|
|
//------------------------------------------------------------------------------ |
|
// Purpose : |
|
// Input : |
|
// Output : |
|
//------------------------------------------------------------------------------ |
|
C_PlasmaBeamNode::C_PlasmaBeamNode(void) |
|
{ |
|
m_bSprayOn = false; |
|
m_pFirePlasmaSpray = CPlasmaSpray::Create( "C_PlasmaBeamNode" ); |
|
} |
|
|
|
//------------------------------------------------------------------------------ |
|
// Purpose : |
|
// Input : |
|
// Output : |
|
//------------------------------------------------------------------------------ |
|
C_PlasmaBeamNode::~C_PlasmaBeamNode(void) |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void C_PlasmaBeamNode::AddEntity( void ) |
|
{ |
|
m_pFirePlasmaSpray->SetSortOrigin( GetAbsOrigin() ); |
|
} |
|
|
|
//------------------------------------------------------------------------------ |
|
// Purpose : |
|
// Input : |
|
// Output : |
|
//------------------------------------------------------------------------------ |
|
void C_PlasmaBeamNode::OnDataChanged(DataUpdateType_t updateType) |
|
{ |
|
if (updateType == DATA_UPDATE_CREATED) |
|
{ |
|
Vector vMoveDir = GetAbsVelocity(); |
|
float flVel = VectorNormalize(vMoveDir); |
|
m_pFirePlasmaSpray->m_ParticleCollision.Setup( GetAbsOrigin(), &vMoveDir, 0.3, |
|
flVel-50, flVel+50, 800, 0.5 ); |
|
SetNextClientThink(gpGlobals->curtime + 0.01); |
|
} |
|
C_BaseEntity::OnDataChanged(updateType); |
|
} |
|
|
|
//------------------------------------------------------------------------------ |
|
// Purpose : |
|
// Input : |
|
// Output : |
|
//------------------------------------------------------------------------------ |
|
bool C_PlasmaBeamNode::ShouldDraw() |
|
{ |
|
return false; |
|
} |
|
|
|
//------------------------------------------------------------------------------ |
|
// Purpose : |
|
// Input : |
|
// Output : |
|
//------------------------------------------------------------------------------ |
|
void C_PlasmaBeamNode::ClientThink(void) |
|
{ |
|
if (!m_bSprayOn) |
|
{ |
|
return; |
|
} |
|
|
|
trace_t trace; |
|
Vector vEndTrace = GetAbsOrigin() + (0.3*GetAbsVelocity()); |
|
UTIL_TraceLine( GetAbsOrigin(), vEndTrace, MASK_SHOT, NULL, COLLISION_GROUP_NONE, &trace ); |
|
if ( trace.fraction != 1.0f || trace.startsolid) |
|
{ |
|
m_bSprayOn = false; |
|
return; |
|
} |
|
|
|
PMaterialHandle handle = m_pFirePlasmaSpray->GetPMaterial( "sprites/plasmaember" ); |
|
for (int i=0;i<SPRAYS_PER_THINK;i++) |
|
{ |
|
SimpleParticle *sParticle; |
|
|
|
//Make a new particle |
|
if ( random->RandomInt( 0, 2 ) == 0 ) |
|
{ |
|
float ranx = random->RandomFloat( -28.0f, 28.0f ); |
|
float rany = random->RandomFloat( -28.0f, 28.0f ); |
|
float ranz = random->RandomFloat( -28.0f, 28.0f ); |
|
|
|
Vector vNewPos = GetAbsOrigin(); |
|
Vector vAdd = Vector(GetAbsAngles().x,GetAbsAngles().y,GetAbsAngles().z)*random->RandomFloat(-60,120); |
|
vNewPos += vAdd; |
|
|
|
sParticle = (SimpleParticle *) m_pFirePlasmaSpray->AddParticle( sizeof(SimpleParticle), handle, vNewPos ); |
|
|
|
sParticle->m_flLifetime = 0.0f; |
|
sParticle->m_flDieTime = PLASMASPARK_LIFETIME; |
|
|
|
sParticle->m_vecVelocity = GetAbsVelocity(); |
|
sParticle->m_vecVelocity.x += ranx; |
|
sParticle->m_vecVelocity.y += rany; |
|
sParticle->m_vecVelocity.z += ranz; |
|
m_pFirePlasmaSpray->m_pOwner = this; |
|
} |
|
} |
|
|
|
SetNextClientThink(gpGlobals->curtime + 0.05); |
|
} |
|
|
|
IMPLEMENT_CLIENTCLASS_DT(C_PlasmaBeamNode, DT_PlasmaBeamNode, CPlasmaBeamNode ) |
|
RecvPropVector (RECVINFO(m_vecVelocity), 0, RecvProxy_LocalVelocity), |
|
RecvPropInt (RECVINFO(m_bSprayOn)), |
|
END_RECV_TABLE()
|
|
|