diff options
Diffstat (limited to 'game/client/hl2/c_extinguisher.cpp')
| -rw-r--r-- | game/client/hl2/c_extinguisher.cpp | 413 |
1 files changed, 413 insertions, 0 deletions
diff --git a/game/client/hl2/c_extinguisher.cpp b/game/client/hl2/c_extinguisher.cpp new file mode 100644 index 0000000..c5dd042 --- /dev/null +++ b/game/client/hl2/c_extinguisher.cpp @@ -0,0 +1,413 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" +#include "particles_simple.h" +#include "baseparticleentity.h" +#include "iefx.h" +#include "decals.h" +#include "beamdraw.h" +#include "hud.h" +#include "clienteffectprecachesystem.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +CLIENTEFFECT_REGISTER_BEGIN( PrecacheExtinguisher ) +CLIENTEFFECT_MATERIAL( "particle/particle_smokegrenade" ) +CLIENTEFFECT_REGISTER_END() + +class C_ExtinguisherJet : public C_BaseEntity +{ +public: + DECLARE_CLIENTCLASS(); + DECLARE_CLASS( C_ExtinguisherJet, C_BaseEntity ); + + C_ExtinguisherJet(); + ~C_ExtinguisherJet(); + + void OnDataChanged( DataUpdateType_t updateType ); + void Update( float fTimeDelta ); + void Start( void ); + int DrawModel( int flags ); + bool ShouldDraw( void ) { return m_bEmit; } + +protected: + + void AddExtinguisherDecal( trace_t &tr ); + + bool m_bEmit; + bool m_bUseMuzzlePoint; + int m_nLength; + int m_nSize; + + PMaterialHandle m_MaterialHandle; + PMaterialHandle m_EmberMaterialHandle; + TimedEvent m_ParticleSpawn; + CSmartPtr<CSimpleEmitter> m_pEmitter; + CSmartPtr<CEmberEffect> m_pEmberEmitter; + +private: + C_ExtinguisherJet( const C_ExtinguisherJet & ); +}; + +//Datatable +IMPLEMENT_CLIENTCLASS_DT( C_ExtinguisherJet, DT_ExtinguisherJet, CExtinguisherJet ) + RecvPropInt(RECVINFO(m_bEmit), 0), + RecvPropInt(RECVINFO(m_bUseMuzzlePoint), 0), + RecvPropInt(RECVINFO(m_nLength), 0), + RecvPropInt(RECVINFO(m_nSize), 0), +END_RECV_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +C_ExtinguisherJet::C_ExtinguisherJet( void ) +{ + m_bEmit = false; + + m_pEmitter = NULL; + m_pEmberEmitter = NULL; +} + +C_ExtinguisherJet::~C_ExtinguisherJet( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : bnewentity - +//----------------------------------------------------------------------------- +void C_ExtinguisherJet::OnDataChanged( DataUpdateType_t updateType ) +{ + C_BaseEntity::OnDataChanged(updateType); + + if( updateType == DATA_UPDATE_CREATED ) + { + Start(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_ExtinguisherJet::Start( void ) +{ + AddToLeafSystem( RENDER_GROUP_TRANSLUCENT_ENTITY ); + + m_ParticleSpawn.Init( 100 ); //Events per second + + //Create the basic emitter + m_pEmitter = CSimpleEmitter::Create("C_ExtinguisherJet::m_pEmitter"); + + Assert( m_pEmitter.IsValid() ); + if ( m_pEmitter.IsValid() ) + { + m_MaterialHandle = g_Mat_DustPuff[0]; + m_pEmitter->SetSortOrigin( GetAbsOrigin() ); + } + + //Create the "ember" emitter for the smaller flecks + m_pEmberEmitter = CEmberEffect::Create( "C_ExtinguisherJet::m_pEmberEmitter" ); + + Assert( m_pEmberEmitter.IsValid() ); + if ( m_pEmberEmitter.IsValid() ) + { + m_EmberMaterialHandle = g_Mat_DustPuff[0]; + m_pEmberEmitter->SetSortOrigin( GetAbsOrigin() ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_ExtinguisherJet::AddExtinguisherDecal( trace_t &tr ) +{ + C_BaseEntity *ent = cl_entitylist->GetEnt( 0 ); + + if ( ent != NULL ) + { + int index = decalsystem->GetDecalIndexForName( "Extinguish" ); + if ( index >= 0 ) + { + Vector endpos; + endpos.Random( -24.0f, 24.0f ); + endpos += tr.endpos; + + effects->DecalShoot( index, 0, ent->GetModel(), ent->GetAbsOrigin(), ent->GetAbsAngles(), endpos, 0, 0 ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : fTimeDelta - +//----------------------------------------------------------------------------- +void C_ExtinguisherJet::Update( float fTimeDelta ) +{ + if ( m_bEmit == false ) + return; + + C_BasePlayer *player = C_BasePlayer::GetLocalPlayer(); + + if ( m_bUseMuzzlePoint ) + { + C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL; + + if ( vm ) + { + int iAttachment = vm->LookupAttachment( "muzzle" ); + Vector origin; + QAngle angles; + vm->GetAttachment( iAttachment, origin, angles ); + + Assert( !GetMoveParent() ); + SetLocalOrigin( origin ); + SetLocalAngles( angles ); + } + } + + trace_t tr; + Vector shotDir, vRight, vUp; + + AngleVectors( GetAbsAngles(), &shotDir, &vRight, &vUp ); + + //FIXME: Muzzle point is incorrect on the model! + if ( m_bUseMuzzlePoint ) + { + shotDir.Negate(); + } + + Vector endPoint = GetAbsOrigin() + ( shotDir * 150.0f ); + + UTIL_TraceLine( GetAbsOrigin(), endPoint, MASK_SHOT, NULL, COLLISION_GROUP_NONE, &tr ); + + bool hitWall = ( tr.fraction < 1.0f ); + + //Add normal jet + if ( m_pEmitter.IsValid() ) + { + SimpleParticle *pParticle; + + m_pEmitter->SetSortOrigin( GetAbsOrigin() ); + + float tempDelta = fTimeDelta; + + //FIXME: All particles need to be within this loop + while( m_ParticleSpawn.NextEvent( tempDelta ) ) + { + pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, GetAbsOrigin() ); + + if ( pParticle ) + { + pParticle->m_flDieTime = 0.2f; + pParticle->m_flLifetime = 0.0f; + + pParticle->m_flRoll = random->RandomInt( 0, 360 ); + pParticle->m_flRollDelta= random->RandomFloat( -4.0f, 4.0f ); + + pParticle->m_uchStartSize = 1; + pParticle->m_uchEndSize = random->RandomInt( 32, 48 ); + pParticle->m_uchStartAlpha = random->RandomInt( 128, 164 ); + pParticle->m_uchEndAlpha = 0; + + int cScale = random->RandomInt( 192, 255 ); + pParticle->m_uchColor[0] = cScale; + pParticle->m_uchColor[1] = cScale; + pParticle->m_uchColor[2] = cScale; + + Vector dir; + QAngle ofsAngles; + + ofsAngles.Random( -8.0f, 8.0f ); + ofsAngles += GetAbsAngles(); + + AngleVectors( ofsAngles, &dir ); + + if ( m_bUseMuzzlePoint ) + { + dir.Negate(); + } + + pParticle->m_vecVelocity = dir * random->RandomInt( 400, 800 ); + } + + //Add muzzle effect + pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, GetAbsOrigin() ); + + if ( pParticle ) + { + pParticle->m_flDieTime = 0.1f; + pParticle->m_flLifetime = 0.0f; + + pParticle->m_flRoll = random->RandomInt( 0, 360 ); + pParticle->m_flRollDelta= random->RandomFloat( -4.0f, 4.0f ); + + pParticle->m_uchStartSize = 1; + pParticle->m_uchEndSize = random->RandomInt( 8, 16 ); + pParticle->m_uchStartAlpha = random->RandomInt( 128, 255 ); + pParticle->m_uchEndAlpha = 0; + + int cScale = random->RandomInt( 192, 255 ); + pParticle->m_uchColor[0] = cScale; + pParticle->m_uchColor[1] = cScale; + pParticle->m_uchColor[2] = cScale; + + Vector dir; + QAngle ofsAngles; + + ofsAngles.Random( -64.0f, 64.0f ); + ofsAngles += GetAbsAngles(); + + AngleVectors( ofsAngles, &dir ); + + if ( m_bUseMuzzlePoint ) + { + dir.Negate(); + } + + pParticle->m_vecVelocity = dir * random->RandomInt( 32, 64 ); + } + + //Add a wall effect if needed + if ( hitWall ) + { + AddExtinguisherDecal( tr ); + + Vector offDir; + + offDir.Random( -16.0f, 16.0f ); + + pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, ( tr.endpos + ( tr.plane.normal * 8.0f ) ) + offDir ); + + if ( pParticle ) + { + pParticle->m_flDieTime = 0.4f; + pParticle->m_flLifetime = 0.0f; + + pParticle->m_flRoll = random->RandomInt( 0, 360 ); + pParticle->m_flRollDelta= random->RandomFloat( -2.0f, 2.0f ); + + pParticle->m_uchStartSize = random->RandomInt( 8, 16 ); + pParticle->m_uchEndSize = random->RandomInt( 24, 32 ); + pParticle->m_uchStartAlpha = random->RandomInt( 64, 128 ); + pParticle->m_uchEndAlpha = 0; + + int cScale = random->RandomInt( 192, 255 ); + pParticle->m_uchColor[0] = cScale; + pParticle->m_uchColor[1] = cScale; + pParticle->m_uchColor[2] = cScale; + + Vector rDir; + + rDir = tr.plane.normal; + rDir[0] += random->RandomFloat( -0.9f, 0.9f ); + rDir[1] += random->RandomFloat( -0.9f, 0.9f ); + rDir[2] += random->RandomFloat( -0.9f, 0.9f ); + + pParticle->m_vecVelocity = rDir * random->RandomInt( 32, 64 ); + } + } + + //Add small ember-like particles + if ( random->RandomInt( 0, 1 ) == 0 ) + { + m_pEmberEmitter->SetSortOrigin( GetAbsOrigin() ); + + pParticle = (SimpleParticle *) m_pEmberEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[0], GetAbsOrigin() ); + + assert(pParticle); + + if ( pParticle ) + { + pParticle->m_flLifetime = 0.0f; + pParticle->m_flDieTime = 1.0f; + + pParticle->m_flRoll = 0; + pParticle->m_flRollDelta = 0; + + pParticle->m_uchColor[0] = 255; + pParticle->m_uchColor[1] = 255; + pParticle->m_uchColor[2] = 255; + pParticle->m_uchStartAlpha = 255; + pParticle->m_uchEndAlpha = 0; + pParticle->m_uchStartSize = 1; + pParticle->m_uchEndSize = 0; + + Vector dir; + QAngle ofsAngles; + + ofsAngles.Random( -8.0f, 8.0f ); + ofsAngles += GetAbsAngles(); + + AngleVectors( ofsAngles, &dir ); + + if ( m_bUseMuzzlePoint ) + { + dir.Negate(); + } + + pParticle->m_vecVelocity = dir * random->RandomInt( 400, 800 ); + } + } + } + } + + // Inner beam + + CBeamSegDraw beamDraw; + CBeamSeg seg; + const int numPoints = 4; + Vector beamPoints[numPoints]; + + beamPoints[0] = GetAbsOrigin(); + + // Create our beam points + int i; + for ( i = 0; i < numPoints; i++ ) + { + beamPoints[i] = GetAbsOrigin() + ( shotDir * (32*i*i) ); + + beamPoints[i] += vRight * sin( gpGlobals->curtime * 4.0f ) * (2.0f*i); + beamPoints[i] += vUp * sin( gpGlobals->curtime * 8.0f ) * (1.0f*i); + beamPoints[i] += shotDir * sin( gpGlobals->curtime * (16.0f*i) ) * (1.0f*i); + } + + IMaterial *pMat = materials->FindMaterial( "particle/particle_smokegrenade", TEXTURE_GROUP_PARTICLE ); + + beamDraw.Start( numPoints, pMat ); + + //Setup and draw those points + for( i = 0; i < numPoints; i++ ) + { + float t = (float) i / (numPoints - 1); + float color = 1.0f * (1.0f - t); + + seg.m_vColor = Vector( color, color, color ); + seg.m_vPos = beamPoints[i]; + seg.m_flTexCoord = (float)i/(float)(numPoints-1) - ((gpGlobals->curtime - (int)gpGlobals->curtime) * 4.0f ); + seg.m_flWidth = 4.0f + ( (64.0f*t) * (fabs( sin( gpGlobals->curtime * 16.0f ) )) ); + seg.m_flAlpha = color; + + beamDraw.NextSeg( &seg ); + } + + beamDraw.End(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : flags - +//----------------------------------------------------------------------------- +int C_ExtinguisherJet::DrawModel( int flags ) +{ + if ( m_bEmit == false ) + return 1; + + Update( Helper_GetFrameTime() ); + + return 1; +} |