|
|
//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Workfile: $
// $NoKeywords: $
//===========================================================================//
#include "cbase.h"
#include "c_te_particlesystem.h"
#include "tier1/keyvalues.h"
#include "toolframework_client.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Purpose: Blood Stream TE
//-----------------------------------------------------------------------------
class C_TEBloodStream : public C_TEParticleSystem { public: DECLARE_CLASS( C_TEBloodStream, C_TEParticleSystem ); DECLARE_CLIENTCLASS();
C_TEBloodStream( void ); virtual ~C_TEBloodStream( void );
virtual void PostDataUpdate( DataUpdateType_t updateType );
public: Vector m_vecDirection; int r, g, b, a; int m_nAmount; };
//-----------------------------------------------------------------------------
// Networking
//-----------------------------------------------------------------------------
IMPLEMENT_CLIENTCLASS_EVENT_DT(C_TEBloodStream, DT_TEBloodStream, CTEBloodStream) RecvPropVector( RECVINFO(m_vecDirection)), RecvPropInt( RECVINFO(r)), RecvPropInt( RECVINFO(g)), RecvPropInt( RECVINFO(b)), RecvPropInt( RECVINFO(a)), RecvPropInt( RECVINFO(m_nAmount)), END_RECV_TABLE()
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
C_TEBloodStream::C_TEBloodStream( void ) { m_vecOrigin.Init(); m_vecDirection.Init(); r = g = b = a = 0; m_nAmount = 0; }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
C_TEBloodStream::~C_TEBloodStream( void ) { }
//-----------------------------------------------------------------------------
// Recording
//-----------------------------------------------------------------------------
static inline void RecordBloodStream( const Vector &start, const Vector &direction, int r, int g, int b, int a, int amount ) { if ( !ToolsEnabled() ) return;
if ( clienttools->IsInRecordingMode() ) { Color clr( r, g, b, a );
KeyValues *msg = new KeyValues( "TempEntity" );
msg->SetInt( "te", TE_BLOOD_STREAM ); msg->SetString( "name", "TE_BloodStream" ); msg->SetFloat( "time", gpGlobals->curtime ); msg->SetFloat( "originx", start.x ); msg->SetFloat( "originy", start.y ); msg->SetFloat( "originz", start.z ); msg->SetFloat( "directionx", direction.x ); msg->SetFloat( "directiony", direction.y ); msg->SetFloat( "directionz", direction.z ); msg->SetColor( "color", clr ); msg->SetInt( "amount", amount );
ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg ); msg->deleteThis(); } }
void TE_BloodStream( IRecipientFilter& filter, float delay, const Vector* org, const Vector* direction, int r, int g, int b, int a, int amount ) { RecordBloodStream( *org, *direction, r, g, b, a, amount );
CSmartPtr<CTEParticleRenderer> pRen = CTEParticleRenderer::Create( "TEBloodStream", *org ); if( !pRen ) return;
// Add our particles.
Vector dirCopy; float arc = 0.05; int count, count2; float num; int speedCopy = amount; Vector dir; VectorCopy( *direction, dir ); VectorNormalize( dir ); for (count=0 ; count<100 ; count++) { StandardParticle_t *p = pRen->AddParticle(); if(p) { p->SetColor(r * random->RandomFloat(0.7, 1.0), g, b); p->SetAlpha(a); p->m_Pos = *org; pRen->SetParticleLifetime(p, 2); pRen->SetParticleType(p, pt_vox_grav); VectorCopy (dir, dirCopy); dirCopy[2] -= arc; arc -= 0.005; VectorScale (dirCopy, speedCopy, p->m_Velocity); speedCopy -= 0.00001;// so last few will drip
} } // now a few rogue voxels
arc = 0.075; for (count = 0 ; count < (amount/5); count ++) { StandardParticle_t *p = pRen->AddParticle(); if(p) { pRen->SetParticleLifetime(p, 3); p->SetColor(r * random->RandomFloat(0.7, 1.0), g, b); p->SetAlpha(a); p->m_Pos = *org; pRen->SetParticleType(p, pt_vox_slowgrav); VectorCopy (dir, dirCopy); dirCopy[2] -= arc; arc -= 0.005; num = random->RandomFloat(0,1); speedCopy = amount * num; num *= 1.7; VectorScale (dirCopy, num, dirCopy);// randomize a bit
p->m_Velocity = dirCopy * speedCopy; // add a few extra voxels directly adjacent to this one to give a
// 'chunkier' appearance.
for (count2 = 0; count2 < 2; count2++) { StandardParticle_t *p = pRen->AddParticle(); if(p) { pRen->SetParticleLifetime(p, 3); p->SetColor(random->RandomFloat(0.7, 1.0), g, b); p->SetAlpha(a); p->m_Pos.Init( (*org)[0] + random->RandomFloat(-1,1), (*org)[1] + random->RandomFloat(-1,1), (*org)[2] + random->RandomFloat(-1,1)); pRen->SetParticleType(p, pt_vox_slowgrav); VectorCopy (dir, dirCopy); dirCopy[2] -= arc; VectorScale (dirCopy, num, dirCopy);// randomize a bit
p->m_Velocity = dirCopy * speedCopy; } } } } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_TEBloodStream::PostDataUpdate( DataUpdateType_t updateType ) { CBroadcastRecipientFilter filter; TE_BloodStream( filter, 0.0f, &m_vecOrigin, &m_vecDirection, r, g, b, a, m_nAmount ); }
void TE_BloodStream( IRecipientFilter& filter, float delay, KeyValues *pKeyValues ) { Vector vecOrigin, vecDirection; vecOrigin.x = pKeyValues->GetFloat( "originx" ); vecOrigin.y = pKeyValues->GetFloat( "originy" ); vecOrigin.z = pKeyValues->GetFloat( "originz" ); vecDirection.x = pKeyValues->GetFloat( "directionx" ); vecDirection.y = pKeyValues->GetFloat( "directiony" ); vecDirection.z = pKeyValues->GetFloat( "directionz" ); Color c = pKeyValues->GetColor( "color" ); int nAmount = pKeyValues->GetInt( "amount" ); TE_BloodStream( filter, 0.0f, &vecOrigin, &vecDirection, c.r(), c.g(), c.b(), c.a(), nAmount ); }
|