source-engine/game/client/c_te_bloodstream.cpp
FluorescentCIAAfricanAmerican 3bf9df6b27 1
2020-04-22 12:56:21 -04:00

224 lines
6.2 KiB
C++

//========= Copyright 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;
float 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 *pChunky = pRen->AddParticle();
if( pChunky )
{
pRen->SetParticleLifetime( pChunky, 3);
pChunky->SetColor(random->RandomFloat(0.7, 1.0), g, b);
pChunky->SetAlpha(a);
pChunky->m_Pos.Init(
(*org)[0] + random->RandomFloat(-1,1),
(*org)[1] + random->RandomFloat(-1,1),
(*org)[2] + random->RandomFloat(-1,1));
pRen->SetParticleType( pChunky, pt_vox_slowgrav);
VectorCopy (dir, dirCopy);
dirCopy[2] -= arc;
VectorScale (dirCopy, num, dirCopy);// randomize a bit
pChunky->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 );
}