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.
186 lines
5.8 KiB
186 lines
5.8 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose: Game-specific impact effect hooks
|
||
|
//
|
||
|
//=============================================================================//
|
||
|
#include "cbase.h"
|
||
|
#include "fx_impact.h"
|
||
|
#include "engine/IEngineSound.h"
|
||
|
|
||
|
#include "decals.h"
|
||
|
#include "IEffects.h"
|
||
|
#include "fx.h"
|
||
|
#include "c_impact_effects.h"
|
||
|
#include "fx_fleck.h"
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// This does the actual debris flecks
|
||
|
//-----------------------------------------------------------------------------
|
||
|
#define FLECK_MIN_SPEED 64.0f
|
||
|
#define FLECK_MAX_SPEED 128.0f
|
||
|
#define FLECK_GRAVITY 800.0f
|
||
|
#define FLECK_DAMPEN 0.3f
|
||
|
#define FLECK_ANGULAR_SPRAY 0.6f
|
||
|
|
||
|
static void FX_Flecks( const Vector& origin, trace_t *trace, char materialType, int iScale )
|
||
|
{
|
||
|
Vector color;
|
||
|
GetColorForSurface( trace, &color );
|
||
|
|
||
|
Vector spawnOffset = trace->endpos + ( trace->plane.normal * 1.0f );
|
||
|
|
||
|
CSmartPtr<CFleckParticles> fleckEmitter = CFleckParticles::Create( "FX_DebrisFlecks", spawnOffset, Vector(5,5,5) );
|
||
|
|
||
|
if ( !fleckEmitter )
|
||
|
return;
|
||
|
|
||
|
// Handle increased scale
|
||
|
float flMaxSpeed = FLECK_MAX_SPEED * iScale;
|
||
|
float flAngularSpray = MAX( 0.2, FLECK_ANGULAR_SPRAY - ( (float)iScale * 0.2f) ); // More power makes the spray more controlled
|
||
|
|
||
|
// Setup our collision information
|
||
|
fleckEmitter->m_ParticleCollision.Setup( spawnOffset, &trace->plane.normal, flAngularSpray, FLECK_MIN_SPEED, flMaxSpeed, FLECK_GRAVITY, FLECK_DAMPEN );
|
||
|
|
||
|
PMaterialHandle *hMaterial;
|
||
|
|
||
|
switch ( materialType )
|
||
|
{
|
||
|
case CHAR_TEX_WOOD:
|
||
|
hMaterial = g_Mat_Fleck_Wood;
|
||
|
break;
|
||
|
|
||
|
case CHAR_TEX_CONCRETE:
|
||
|
case CHAR_TEX_TILE:
|
||
|
default:
|
||
|
hMaterial = g_Mat_Fleck_Cement;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
Vector dir, end;
|
||
|
|
||
|
float colorRamp;
|
||
|
|
||
|
int numFlecks = random->RandomInt( 4, 16 ) * iScale;
|
||
|
|
||
|
FleckParticle *pFleckParticle;
|
||
|
|
||
|
//Dump out flecks
|
||
|
int i;
|
||
|
for ( i = 0; i < numFlecks; i++ )
|
||
|
{
|
||
|
pFleckParticle = (FleckParticle *) fleckEmitter->AddParticle( sizeof(FleckParticle), hMaterial[random->RandomInt(0,1)], spawnOffset );
|
||
|
|
||
|
if ( pFleckParticle == NULL )
|
||
|
break;
|
||
|
|
||
|
pFleckParticle->m_flLifetime = 0.0f;
|
||
|
pFleckParticle->m_flDieTime = 3.0f;
|
||
|
|
||
|
dir[0] = trace->plane.normal[0] + random->RandomFloat( -flAngularSpray, flAngularSpray );
|
||
|
dir[1] = trace->plane.normal[1] + random->RandomFloat( -flAngularSpray, flAngularSpray );
|
||
|
dir[2] = trace->plane.normal[2] + random->RandomFloat( -flAngularSpray, flAngularSpray );
|
||
|
|
||
|
pFleckParticle->m_uchSize = random->RandomInt( 1, 2 );
|
||
|
|
||
|
pFleckParticle->m_vecVelocity = dir * ( random->RandomFloat( FLECK_MIN_SPEED, flMaxSpeed) * ( 3 - pFleckParticle->m_uchSize ) );
|
||
|
|
||
|
pFleckParticle->m_flRoll = random->RandomFloat( 0, 360 );
|
||
|
pFleckParticle->m_flRollDelta = random->RandomFloat( 0, 360 );
|
||
|
|
||
|
colorRamp = random->RandomFloat( 0.75f, 1.25f );
|
||
|
|
||
|
pFleckParticle->m_uchColor[0] = MIN( 1.0f, color[0]*colorRamp )*255.0f;
|
||
|
pFleckParticle->m_uchColor[1] = MIN( 1.0f, color[1]*colorRamp )*255.0f;
|
||
|
pFleckParticle->m_uchColor[2] = MIN( 1.0f, color[2]*colorRamp )*255.0f;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Perform custom effects based on the Decal index
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void DOD_PerformCustomEffects( const Vector &vecOrigin, trace_t &tr, const Vector &shotDir, int iMaterial, float flScale )
|
||
|
{
|
||
|
// Throw out the effect if any of these are true
|
||
|
if ( tr.surface.flags & (SURF_SKY|SURF_NODRAW|SURF_HINT|SURF_SKIP) )
|
||
|
return;
|
||
|
|
||
|
int iScale = (int)flScale;
|
||
|
if ( iScale < 1 )
|
||
|
iScale = 1;
|
||
|
|
||
|
// Cement and wood have dust and flecks
|
||
|
if ( ( iMaterial == CHAR_TEX_CONCRETE ) ||
|
||
|
( iMaterial == CHAR_TEX_TILE ) ||
|
||
|
( iMaterial == CHAR_TEX_WOOD ) )
|
||
|
{
|
||
|
FX_Flecks( vecOrigin, &tr, iMaterial, iScale );
|
||
|
FX_DustImpact( vecOrigin, &tr, flScale );
|
||
|
}
|
||
|
else if ( ( iMaterial == CHAR_TEX_DIRT ) || ( iMaterial == CHAR_TEX_SAND ) )
|
||
|
{
|
||
|
FX_DustImpact( vecOrigin, &tr, flScale );
|
||
|
}
|
||
|
else if ( ( iMaterial == CHAR_TEX_METAL ) || ( iMaterial == CHAR_TEX_VENT ) )
|
||
|
{
|
||
|
Vector reflect;
|
||
|
float dot = shotDir.Dot( tr.plane.normal );
|
||
|
reflect = shotDir + ( tr.plane.normal * ( dot*-2.0f ) );
|
||
|
|
||
|
reflect[0] += random->RandomFloat( -0.2f, 0.2f );
|
||
|
reflect[1] += random->RandomFloat( -0.2f, 0.2f );
|
||
|
reflect[2] += random->RandomFloat( -0.2f, 0.2f );
|
||
|
|
||
|
FX_MetalSpark( vecOrigin, reflect, tr.plane.normal, iScale );
|
||
|
}
|
||
|
else if ( iMaterial == CHAR_TEX_COMPUTER )
|
||
|
{
|
||
|
Vector offset = vecOrigin + ( tr.plane.normal * 1.0f );
|
||
|
|
||
|
g_pEffects->Sparks( offset );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Handle weapon impacts
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void ImpactCallback( const CEffectData &data )
|
||
|
{
|
||
|
trace_t tr;
|
||
|
Vector vecOrigin, vecStart, vecShotDir;
|
||
|
int iMaterial, iDamageType, iHitbox;
|
||
|
short nSurfaceProp;
|
||
|
|
||
|
C_BaseEntity *pEntity = ParseImpactData( data, &vecOrigin, &vecStart, &vecShotDir, nSurfaceProp, iMaterial, iDamageType, iHitbox );
|
||
|
|
||
|
if ( !pEntity )
|
||
|
return;
|
||
|
|
||
|
// If we hit, perform our custom effects and play the sound
|
||
|
if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr ) )
|
||
|
{
|
||
|
float flScale = 0.75f;
|
||
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||
|
|
||
|
if ( pPlayer )
|
||
|
{
|
||
|
float flDistSqr = (vecOrigin - pPlayer->GetAbsOrigin()).LengthSqr();
|
||
|
|
||
|
flScale = RemapValClamped( flDistSqr, (400*400), (1000*1000), 0.8, 1.2 );
|
||
|
}
|
||
|
|
||
|
// Check for custom effects based on the Decal index
|
||
|
DOD_PerformCustomEffects( vecOrigin, tr, vecShotDir, iMaterial, flScale );
|
||
|
PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
|
||
|
|
||
|
//Play a ricochet sound some of the time
|
||
|
if( random->RandomInt(1,10) <= 3 && (iDamageType == DMG_BULLET) )
|
||
|
{
|
||
|
CLocalPlayerFilter filter;
|
||
|
C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, "Bounce.Shrapnel", &vecOrigin );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DECLARE_CLIENT_EFFECT( "Impact", ImpactCallback );
|