diff options
Diffstat (limited to 'mp/src/game/client/hl2/fx_antlion.cpp')
| -rw-r--r-- | mp/src/game/client/hl2/fx_antlion.cpp | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/mp/src/game/client/hl2/fx_antlion.cpp b/mp/src/game/client/hl2/fx_antlion.cpp new file mode 100644 index 00000000..3933bc37 --- /dev/null +++ b/mp/src/game/client/hl2/fx_antlion.cpp @@ -0,0 +1,334 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "fx.h"
+#include "c_gib.h"
+#include "c_te_effect_dispatch.h"
+#include "iefx.h"
+#include "decals.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+PMaterialHandle g_Material_Blood[2] = { NULL, NULL };
+
+#ifdef _XBOX
+
+// XBox only uses a few gibs
+#define NUM_ANTLION_GIBS 3
+const char *pszAntlionGibs[NUM_ANTLION_GIBS] = {
+ "models/gibs/antlion_gib_large_2.mdl", // Head
+ "models/gibs/antlion_gib_medium_1.mdl", // Pincher
+ "models/gibs/antlion_gib_medium_2.mdl", // Leg
+};
+
+#else
+
+// Use all the gibs
+#define NUM_ANTLION_GIBS_UNIQUE 3
+const char *pszAntlionGibs_Unique[NUM_ANTLION_GIBS_UNIQUE] = {
+ "models/gibs/antlion_gib_large_1.mdl",
+ "models/gibs/antlion_gib_large_2.mdl",
+ "models/gibs/antlion_gib_large_3.mdl"
+};
+
+#define NUM_ANTLION_GIBS_MEDIUM 3
+const char *pszAntlionGibs_Medium[NUM_ANTLION_GIBS_MEDIUM] = {
+ "models/gibs/antlion_gib_medium_1.mdl",
+ "models/gibs/antlion_gib_medium_2.mdl",
+ "models/gibs/antlion_gib_medium_3.mdl"
+};
+
+// XBox doesn't use the smaller gibs, so don't cache them
+#define NUM_ANTLION_GIBS_SMALL 3
+const char *pszAntlionGibs_Small[NUM_ANTLION_GIBS_SMALL] = {
+ "models/gibs/antlion_gib_small_1.mdl",
+ "models/gibs/antlion_gib_small_2.mdl",
+ "models/gibs/antlion_gib_small_3.mdl"
+};
+#endif
+
+ConVar g_antlion_maxgibs( "g_antlion_maxgibs", "16", FCVAR_ARCHIVE );
+
+void CAntlionGibManager::LevelInitPreEntity( void )
+{
+ m_LRU.Purge();
+}
+
+CAntlionGibManager s_AntlionGibManager( "CAntlionGibManager" );
+
+void CAntlionGibManager::AddGib( C_BaseEntity *pEntity )
+{
+ m_LRU.AddToTail( pEntity );
+}
+
+void CAntlionGibManager::RemoveGib( C_BaseEntity *pEntity )
+{
+ m_LRU.FindAndRemove( pEntity );
+}
+
+
+//-----------------------------------------------------------------------------
+// Methods of IGameSystem
+//-----------------------------------------------------------------------------
+void CAntlionGibManager::Update( float frametime )
+{
+ if ( m_LRU.Count() < g_antlion_maxgibs.GetInt() )
+ return;
+
+ int i = 0;
+ i = m_LRU.Head();
+
+ if ( m_LRU[ i ].Get() )
+ {
+ m_LRU[ i ].Get()->SetNextClientThink( gpGlobals->curtime );
+ }
+
+ m_LRU.Remove(i);
+}
+
+// Antlion gib - marks surfaces when it bounces
+
+class C_AntlionGib : public C_Gib
+{
+ typedef C_Gib BaseClass;
+public:
+
+ static C_AntlionGib *CreateClientsideGib( const char *pszModelName, Vector vecOrigin, Vector vecForceDir, AngularImpulse vecAngularImp, float m_flLifetime = DEFAULT_GIB_LIFETIME )
+ {
+ C_AntlionGib *pGib = new C_AntlionGib;
+
+ if ( pGib == NULL )
+ return NULL;
+
+ if ( pGib->InitializeGib( pszModelName, vecOrigin, vecForceDir, vecAngularImp, m_flLifetime ) == false )
+ return NULL;
+
+ s_AntlionGibManager.AddGib( pGib );
+
+ return pGib;
+ }
+
+ // Decal the surface
+ virtual void HitSurface( C_BaseEntity *pOther )
+ {
+ //JDW: Removed for the time being
+
+ /*
+ int index = decalsystem->GetDecalIndexForName( "YellowBlood" );
+
+ if (index >= 0 )
+ {
+ effects->DecalShoot( index, pOther->entindex(), pOther->GetModel(), pOther->GetAbsOrigin(), pOther->GetAbsAngles(), GetAbsOrigin(), 0, 0 );
+ }
+ */
+ }
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &origin -
+//-----------------------------------------------------------------------------
+void FX_AntlionGib( const Vector &origin, const Vector &direction, float scale )
+{
+ Vector offset;
+
+#ifdef _XBOX
+
+ // Throw less gibs for XBox
+ for ( int i = 0; i < NUM_ANTLION_GIBS; i++ )
+ {
+ offset = RandomVector( -32, 32 ) + origin;
+ C_AntlionGib::CreateClientsideGib( pszAntlionGibs[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 250 * scale ), RandomAngularImpulse( -32, 32 ), 1.0f );
+ }
+
+#else
+
+ int numGibs = random->RandomInt( 1, NUM_ANTLION_GIBS_UNIQUE );
+
+ // Spawn all the unique gibs
+ for ( int i = 0; i < numGibs; i++ )
+ {
+ offset = RandomVector( -16, 16 ) + origin;
+
+ C_AntlionGib::CreateClientsideGib( pszAntlionGibs_Unique[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 150 * scale ), RandomAngularImpulse( -32, 32 ), 2.0f);
+ }
+
+ numGibs = random->RandomInt( 1, NUM_ANTLION_GIBS_MEDIUM );
+
+ // Spawn all the medium gibs
+ for ( int i = 0; i < numGibs; i++ )
+ {
+ offset = RandomVector( -16, 16 ) + origin;
+
+ C_AntlionGib::CreateClientsideGib( pszAntlionGibs_Medium[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 250 * scale ), RandomAngularImpulse( -200, 200 ), 1.0f );
+ }
+
+ numGibs = random->RandomInt( 1, NUM_ANTLION_GIBS_SMALL );
+
+ // Spawn all the small gibs
+ for ( int i = 0; i < NUM_ANTLION_GIBS_SMALL; i++ )
+ {
+ offset = RandomVector( -16, 16 ) + origin;
+
+ C_AntlionGib::CreateClientsideGib( pszAntlionGibs_Small[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 400 * scale ), RandomAngularImpulse( -300, 300 ), 0.5f );
+ }
+
+#endif
+
+#ifdef _XBOX
+
+ //
+ // Throw some blood
+ //
+
+ CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "FX_AntlionGib" );
+ pSimple->SetSortOrigin( origin );
+ pSimple->GetBinding().SetBBox( origin - Vector(64,64,64), origin + Vector(64,64,64) );
+
+ // Cache this if we're not already
+ if ( g_Material_Blood[0] == NULL )
+ {
+ g_Material_Blood[0] = g_Mat_BloodPuff[0];
+ }
+
+ if ( g_Material_Blood[1] == NULL )
+ {
+ g_Material_Blood[1] = g_Mat_BloodPuff[1];
+ }
+
+ Vector vDir;
+ vDir.Random( -1.0f, 1.0f );
+
+ // Gore bits
+ for ( int i = 0; i < 4; i++ )
+ {
+ SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Material_Blood[0], origin + RandomVector(-16,16));
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f );
+
+ float speed = random->RandomFloat( 16.0f, 64.0f );
+
+ sParticle->m_vecVelocity.Init();
+
+ sParticle->m_uchColor[0] = 255;
+ sParticle->m_uchColor[1] = 200;
+ sParticle->m_uchColor[2] = 32;
+ sParticle->m_uchStartAlpha = 255;
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchStartSize = random->RandomInt( 4, 16 );
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4;
+ sParticle->m_flRoll = random->RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = 0.0f;
+ }
+
+ // Middle core
+ SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Material_Blood[1], origin );
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.75f );
+
+ float speed = random->RandomFloat( 16.0f, 64.0f );
+
+ sParticle->m_vecVelocity = vDir * -speed;
+ sParticle->m_vecVelocity[2] += 16.0f;
+
+ sParticle->m_uchColor[0] = 255;
+ sParticle->m_uchColor[1] = 200;
+ sParticle->m_uchColor[2] = 32;
+ sParticle->m_uchStartAlpha = random->RandomInt( 64, 128 );
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 3;
+ sParticle->m_flRoll = random->RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = random->RandomFloat( -0.2f, 0.2f );
+
+#else
+
+ //
+ // Non-XBox blood
+ //
+
+ CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "FX_AntlionGib" );
+ pSimple->SetSortOrigin( origin );
+
+ Vector vDir;
+
+ vDir.Random( -1.0f, 1.0f );
+
+ for ( int i = 0; i < 4; i++ )
+ {
+ SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[0], origin );
+
+ if ( sParticle == NULL )
+ return;
+
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.75f );
+
+ float speed = random->RandomFloat( 16.0f, 64.0f );
+
+ sParticle->m_vecVelocity = vDir * -speed;
+ sParticle->m_vecVelocity[2] += 16.0f;
+
+ sParticle->m_uchColor[0] = 255;
+ sParticle->m_uchColor[1] = 200;
+ sParticle->m_uchColor[2] = 32;
+ sParticle->m_uchStartAlpha = 255;
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2;
+ sParticle->m_flRoll = random->RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f );
+ }
+
+ for ( int i = 0; i < 4; i++ )
+ {
+ SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[1], origin );
+
+ if ( sParticle == NULL )
+ {
+ return;
+ }
+
+ sParticle->m_flLifetime = 0.0f;
+ sParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.75f );
+
+ float speed = random->RandomFloat( 16.0f, 64.0f );
+
+ sParticle->m_vecVelocity = vDir * -speed;
+ sParticle->m_vecVelocity[2] += 16.0f;
+
+ sParticle->m_uchColor[0] = 255;
+ sParticle->m_uchColor[1] = 200;
+ sParticle->m_uchColor[2] = 32;
+ sParticle->m_uchStartAlpha = random->RandomInt( 64, 128 );
+ sParticle->m_uchEndAlpha = 0;
+ sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
+ sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2;
+ sParticle->m_flRoll = random->RandomInt( 0, 360 );
+ sParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f );
+ }
+
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &data -
+//-----------------------------------------------------------------------------
+void AntlionGibCallback( const CEffectData &data )
+{
+ FX_AntlionGib( data.m_vOrigin, data.m_vNormal, data.m_flScale );
+}
+
+DECLARE_CLIENT_EFFECT( "AntlionGib", AntlionGibCallback );
|