//----------------------------------------------------------------------------- // Purpose: // Input : &color - //----------------------------------------------------------------------------- void C_TEAntlionDust::GetDustColor( Vector &color ) { trace_t tr; UTIL_TraceLine( m_vecOrigin+Vector(0,0,1), m_vecOrigin+Vector(0,0,-32), MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction < 1.0f ) { GetColorForSurface( &tr, &color ); } else { //Fill in a fallback color = g_AntlionDustColor; } }
static void PerformNewCustomEffects( const Vector &vecOrigin, trace_t &tr, const Vector &shotDir, int iMaterial, int iScale, int nFlags ) { bool bNoFlecks = !r_drawflecks.GetBool(); if ( !bNoFlecks ) { bNoFlecks = ( ( nFlags & FLAGS_CUSTIOM_EFFECTS_NOFLECKS ) != 0 ); } // Compute the impact effect name const ImpactEffect_t &effect = s_pImpactEffect[ iMaterial - 'A' ]; const char *pImpactName = effect.m_pName; if ( bNoFlecks && effect.m_pNameNoFlecks ) { pImpactName = effect.m_pNameNoFlecks; } if ( !pImpactName ) return; CSmartPtr<CNewParticleEffect> pEffect = CNewParticleEffect::Create( NULL, pImpactName ); if ( !pEffect->IsValid() ) return; Vector vecReflect; float flDot = DotProduct( shotDir, tr.plane.normal ); VectorMA( shotDir, -2.0f * flDot, tr.plane.normal, vecReflect ); Vector vecShotBackward; VectorMultiply( shotDir, -1.0f, vecShotBackward ); Vector vecImpactPoint = ( tr.fraction != 1.0f ) ? tr.endpos : vecOrigin; // Other games round m_vOrigin to nearest integer, so I guess we can afford skipping this check. #ifdef HL2_CLIENT_DLL Assert( VectorsAreEqual( vecOrigin, tr.endpos, 1e-1 ) ); #endif SetImpactControlPoint( pEffect.GetObject(), 0, vecImpactPoint, tr.plane.normal, tr.m_pEnt ); SetImpactControlPoint( pEffect.GetObject(), 1, vecImpactPoint, vecReflect, tr.m_pEnt ); SetImpactControlPoint( pEffect.GetObject(), 2, vecImpactPoint, vecShotBackward, tr.m_pEnt ); pEffect->SetControlPoint( 3, Vector( iScale, iScale, iScale ) ); if ( pEffect->m_pDef->ReadsControlPoint( 4 ) ) { Vector vecColor; GetColorForSurface( &tr, &vecColor ); pEffect->SetControlPoint( 4, vecColor ); } }
void FX_DustImpact( const Vector &origin, trace_t *tr, float flScale ) { // // PC version // VPROF_BUDGET( "FX_DustImpact", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); Vector offset; float spread = 0.2f; CSmartPtr<CDustParticle> pSimple = CDustParticle::Create( "dust" ); pSimple->SetSortOrigin( origin ); // Three types of particle, ideally we want 4 of each. float fNumParticles = 4.0f * g_pParticleSystemMgr->ParticleThrottleScaling(); int nParticles1 = (int)( 0.50f + fNumParticles ); int nParticles2 = (int)( 0.83f + fNumParticles ); // <-- most visible particle type. int nParticles3 = (int)( 0.17f + fNumParticles ); SimpleParticle *pParticle; Vector color; float colorRamp; GetColorForSurface( tr, &color ); // To get a decent spread even when scaling down the number of particles... const static int nParticleIdArray[4] = {3,1,2,0}; int i; for ( i = 0; i < nParticles1; i++ ) { int nId = nParticleIdArray[i]; pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[0], origin ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); pParticle->m_vecVelocity.Random( -spread, spread ); pParticle->m_vecVelocity += ( tr->plane.normal * random->RandomFloat( 1.0f, 6.0f ) ); VectorNormalize( pParticle->m_vecVelocity ); float fForce = random->RandomFloat( 250, 500 ) * nId; // scaled pParticle->m_vecVelocity *= fForce * flScale; colorRamp = random->RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f; // scaled pParticle->m_uchStartSize = ( unsigned char )( flScale * random->RandomInt( 3, 4 ) * (nId+1) ); // scaled pParticle->m_uchEndSize = ( unsigned char )( flScale * pParticle->m_uchStartSize * 4 ); pParticle->m_uchStartAlpha = random->RandomInt( 32, 255 ); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -8.0f, 8.0f ); } } //Dust specs for ( i = 0; i < nParticles2; i++ ) { int nId = nParticleIdArray[i]; pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[0], origin ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.75f ); pParticle->m_vecVelocity.Random( -spread, spread ); pParticle->m_vecVelocity += ( tr->plane.normal * random->RandomFloat( 1.0f, 6.0f ) ); VectorNormalize( pParticle->m_vecVelocity ); float fForce = random->RandomFloat( 250, 500 ) * nId; pParticle->m_vecVelocity *= fForce; colorRamp = random->RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f; pParticle->m_uchStartSize = random->RandomInt( 2, 4 ) * (nId+1); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 2; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -2.0f, 2.0f ); } } //Impact hit for ( i = 0; i < nParticles3; i++ ) { //int nId = nParticleIdArray[i]; pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[0], origin ); if ( pParticle != NULL ) { offset = origin; offset[0] += random->RandomFloat( -8.0f, 8.0f ); offset[1] += random->RandomFloat( -8.0f, 8.0f ); pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); spread = 1.0f; pParticle->m_vecVelocity.Random( -spread, spread ); pParticle->m_vecVelocity += tr->plane.normal; VectorNormalize( pParticle->m_vecVelocity ); float fForce = random->RandomFloat( 0, 50 ); pParticle->m_vecVelocity *= fForce; colorRamp = random->RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f; pParticle->m_uchStartSize = random->RandomInt( 1, 4 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 4; pParticle->m_uchStartAlpha = random->RandomInt( 32, 64 ); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -16.0f, 16.0f ); } } }
//----------------------------------------------------------------------------- // Purpose: Debris flecks caused by impacts // Input : origin - start // *trace - trace information // *materialName - material hit // materialType - type of material hit //----------------------------------------------------------------------------- void FX_DebrisFlecks( const Vector& origin, trace_t *tr, char materialType, int iScale, bool bNoFlecks ) { VPROF_BUDGET( "FX_DebrisFlecks", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); if ( !fx_drawimpactdebris.GetBool() ) return; #ifdef _XBOX // // XBox version // Vector offset; float spread = 0.2f; CSmartPtr<CDustParticle> pSimple = CDustParticle::Create( "dust" ); pSimple->SetSortOrigin( origin ); // Lock the bbox pSimple->GetBinding().SetBBox( origin - ( Vector( 16, 16, 16 ) * iScale ), origin + ( Vector( 16, 16, 16 ) * iScale ) ); // Get the color of the surface we've impacted Vector color; float colorRamp; GetColorForSurface( tr, &color ); int i; SimpleParticle *pParticle; for ( i = 0; i < 4; i++ ) { if ( i == 3 ) { pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[0], origin ); } else { pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[0], origin ); } if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); pParticle->m_vecVelocity.Random( -spread, spread ); pParticle->m_vecVelocity += ( tr->plane.normal * random->RandomFloat( 1.0f, 6.0f ) ); VectorNormalize( pParticle->m_vecVelocity ); float fForce = random->RandomFloat( 250, 500 ) * i * 0.5f; // scaled pParticle->m_vecVelocity *= fForce * iScale; // Ramp the color colorRamp = random->RandomFloat( 0.5f, 1.25f ); pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f; // scaled pParticle->m_uchStartSize = (iScale*0.5f) * random->RandomInt( 3, 4 ) * (i+1); // scaled pParticle->m_uchEndSize = (iScale*0.5f) * pParticle->m_uchStartSize * 4; pParticle->m_uchStartAlpha = random->RandomInt( 200, 255 ); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f ); } } // Covers the impact spot with flecks pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_DustPuff2, origin ); if ( pParticle != NULL ) { offset = origin; offset[0] += random->RandomFloat( -8.0f, 8.0f ); offset[1] += random->RandomFloat( -8.0f, 8.0f ); pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); spread = 1.0f; pParticle->m_vecVelocity.Init(); colorRamp = random->RandomFloat( 0.5f, 1.25f ); pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f; pParticle->m_uchStartSize = random->RandomInt( 4, 8 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 4; pParticle->m_uchStartAlpha = random->RandomInt( 64, 128 ); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -0.1f, 0.1f ); } #else // // PC version // Vector color; GetColorForSurface( tr, &color ); if ( !bNoFlecks ) { CreateFleckParticles( origin, color, tr, materialType, iScale ); } // // Dust trail // Vector offset = tr->endpos + ( tr->plane.normal * 2.0f ); SimpleParticle newParticle; int i; for ( i = 0; i < 2; i++ ) { newParticle.m_Pos = offset; newParticle.m_flLifetime = 0.0f; newParticle.m_flDieTime = 1.0f; Vector dir; dir[0] = tr->plane.normal[0] + random->RandomFloat( -0.8f, 0.8f ); dir[1] = tr->plane.normal[1] + random->RandomFloat( -0.8f, 0.8f ); dir[2] = tr->plane.normal[2] + random->RandomFloat( -0.8f, 0.8f ); newParticle.m_uchStartSize = random->RandomInt( 2, 4 ) * iScale; newParticle.m_uchEndSize = newParticle.m_uchStartSize * 8 * iScale; newParticle.m_vecVelocity = dir * random->RandomFloat( 2.0f, 24.0f )*(i+1); newParticle.m_vecVelocity[2] -= random->RandomFloat( 8.0f, 32.0f )*(i+1); newParticle.m_uchStartAlpha = random->RandomInt( 100, 200 ); newParticle.m_uchEndAlpha = 0; newParticle.m_flRoll = random->RandomFloat( 0, 360 ); newParticle.m_flRollDelta = random->RandomFloat( -1, 1 ); float colorRamp = random->RandomFloat( 0.5f, 1.25f ); newParticle.m_uchColor[0] = MIN( 1.0f, color[0]*colorRamp )*255.0f; newParticle.m_uchColor[1] = MIN( 1.0f, color[1]*colorRamp )*255.0f; newParticle.m_uchColor[2] = MIN( 1.0f, color[2]*colorRamp )*255.0f; AddSimpleParticle( &newParticle, g_Mat_DustPuff[0] ); } for ( i = 0; i < 4; i++ ) { newParticle.m_Pos = offset; newParticle.m_flLifetime = 0.0f; newParticle.m_flDieTime = random->RandomFloat( 0.25f, 0.5f ); Vector dir; dir[0] = tr->plane.normal[0] + random->RandomFloat( -0.8f, 0.8f ); dir[1] = tr->plane.normal[1] + random->RandomFloat( -0.8f, 0.8f ); dir[2] = tr->plane.normal[2] + random->RandomFloat( -0.8f, 0.8f ); newParticle.m_uchStartSize = random->RandomInt( 1, 4 ); newParticle.m_uchEndSize = newParticle.m_uchStartSize * 4; newParticle.m_vecVelocity = dir * random->RandomFloat( 8.0f, 32.0f ); newParticle.m_vecVelocity[2] -= random->RandomFloat( 8.0f, 64.0f ); newParticle.m_uchStartAlpha = 255; newParticle.m_uchEndAlpha = 0; newParticle.m_flRoll = random->RandomFloat( 0, 360 ); newParticle.m_flRollDelta = random->RandomFloat( -2.0f, 2.0f ); float colorRamp = random->RandomFloat( 0.5f, 1.25f ); newParticle.m_uchColor[0] = MIN( 1.0f, color[0]*colorRamp )*255.0f; newParticle.m_uchColor[1] = MIN( 1.0f, color[1]*colorRamp )*255.0f; newParticle.m_uchColor[2] = MIN( 1.0f, color[2]*colorRamp )*255.0f; AddSimpleParticle( &newParticle, g_Mat_BloodPuff[0] ); } // // Bullet hole capper // newParticle.m_Pos = offset; newParticle.m_flLifetime = 0.0f; newParticle.m_flDieTime = random->RandomFloat( 1.0f, 1.5f ); Vector dir; dir[0] = tr->plane.normal[0] + random->RandomFloat( -0.8f, 0.8f ); dir[1] = tr->plane.normal[1] + random->RandomFloat( -0.8f, 0.8f ); dir[2] = tr->plane.normal[2] + random->RandomFloat( -0.8f, 0.8f ); newParticle.m_uchStartSize = random->RandomInt( 4, 8 ); newParticle.m_uchEndSize = newParticle.m_uchStartSize * 4.0f; newParticle.m_vecVelocity = dir * random->RandomFloat( 2.0f, 24.0f ); newParticle.m_vecVelocity[2] = random->RandomFloat( -2.0f, 2.0f ); newParticle.m_uchStartAlpha = random->RandomInt( 100, 200 ); newParticle.m_uchEndAlpha = 0; newParticle.m_flRoll = random->RandomFloat( 0, 360 ); newParticle.m_flRollDelta = random->RandomFloat( -2, 2 ); float colorRamp = random->RandomFloat( 0.5f, 1.25f ); newParticle.m_uchColor[0] = MIN( 1.0f, color[0]*colorRamp )*255.0f; newParticle.m_uchColor[1] = MIN( 1.0f, color[1]*colorRamp )*255.0f; newParticle.m_uchColor[2] = MIN( 1.0f, color[2]*colorRamp )*255.0f; AddSimpleParticle( &newParticle, g_Mat_DustPuff[0] ); #endif }
//----------------------------------------------------------------------------- // Purpose: Dust impact // Input : &origin - position // &tr - trace information //----------------------------------------------------------------------------- void FX_DustImpact( const Vector &origin, trace_t *tr, int iScale ) { if ( !fx_drawimpactdust.GetBool() ) return; #ifdef _XBOX // // XBox version // VPROF_BUDGET( "FX_DustImpact", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); Vector offset; float spread = 0.2f; CSmartPtr<CDustParticle> pSimple = CDustParticle::Create( "dust" ); pSimple->SetSortOrigin( origin ); pSimple->GetBinding().SetBBox( origin - ( Vector( 32, 32, 32 ) * iScale ), origin + ( Vector( 32, 32, 32 ) * iScale ) ); Vector color; float colorRamp; GetColorForSurface( tr, &color ); int i; SimpleParticle *pParticle; for ( i = 0; i < 4; i++ ) { // Last puff is gritty (hides end) if ( i == 3 ) { pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[0], origin ); } else { pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[0], origin ); } if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_vecVelocity.Random( -spread, spread ); pParticle->m_vecVelocity += ( tr->plane.normal * random->RandomFloat( 1.0f, 6.0f ) ); VectorNormalize( pParticle->m_vecVelocity ); float fForce = random->RandomFloat( 250, 500 ) * i; // scaled pParticle->m_vecVelocity *= fForce * iScale; colorRamp = random->RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = min( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = min( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = min( 1.0f, color[2] * colorRamp ) * 255.0f; // scaled pParticle->m_uchStartSize = iScale * random->RandomInt( 3, 4 ) * (i+1); // scaled pParticle->m_uchEndSize = iScale * pParticle->m_uchStartSize * 4; pParticle->m_uchStartAlpha = random->RandomInt( 32, 255 ); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); if ( i == 3 ) { pParticle->m_flRollDelta = random->RandomFloat( -0.1f, 0.1f ); pParticle->m_flDieTime = 0.5f; } else { pParticle->m_flRollDelta = random->RandomFloat( -8.0f, 8.0f ); pParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); } } } //Impact hit pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_DustPuff, origin ); if ( pParticle != NULL ) { offset = origin; offset[0] += random->RandomFloat( -8.0f, 8.0f ); offset[1] += random->RandomFloat( -8.0f, 8.0f ); pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); pParticle->m_vecVelocity.Init(); colorRamp = random->RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = min( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = min( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = min( 1.0f, color[2] * colorRamp ) * 255.0f; pParticle->m_uchStartSize = random->RandomInt( 4, 8 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 4; pParticle->m_uchStartAlpha = random->RandomInt( 32, 64 ); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f ); } #else FX_DustImpact( origin, tr, (float)iScale ); #endif // _XBOX }
void FX_DustImpact( const Vector &origin, trace_t *tr, float flScale ) { // // PC version // VPROF_BUDGET( "FX_DustImpact", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); Vector offset; float spread = 0.2f; CSmartPtr<CDustParticle> pSimple = CDustParticle::Create( "dust" ); pSimple->SetSortOrigin( origin ); SimpleParticle *pParticle; Vector color; float colorRamp; GetColorForSurface( tr, &color ); int i; for ( i = 0; i < 4; i++ ) { pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[0], origin ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); pParticle->m_vecVelocity.Random( -spread, spread ); pParticle->m_vecVelocity += ( tr->plane.normal * random->RandomFloat( 1.0f, 6.0f ) ); VectorNormalize( pParticle->m_vecVelocity ); float fForce = random->RandomFloat( 250, 500 ) * i; // scaled pParticle->m_vecVelocity *= fForce * flScale; colorRamp = random->RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = min( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = min( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = min( 1.0f, color[2] * colorRamp ) * 255.0f; // scaled pParticle->m_uchStartSize = ( unsigned char )( flScale * random->RandomInt( 3, 4 ) * (i+1) ); // scaled pParticle->m_uchEndSize = ( unsigned char )( flScale * pParticle->m_uchStartSize * 4 ); pParticle->m_uchStartAlpha = random->RandomInt( 32, 255 ); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -8.0f, 8.0f ); } } //Dust specs for ( i = 0; i < 4; i++ ) { pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[0], origin ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.75f ); pParticle->m_vecVelocity.Random( -spread, spread ); pParticle->m_vecVelocity += ( tr->plane.normal * random->RandomFloat( 1.0f, 6.0f ) ); VectorNormalize( pParticle->m_vecVelocity ); float fForce = random->RandomFloat( 250, 500 ) * i; pParticle->m_vecVelocity *= fForce; colorRamp = random->RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = min( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = min( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = min( 1.0f, color[2] * colorRamp ) * 255.0f; pParticle->m_uchStartSize = random->RandomInt( 2, 4 ) * (i+1); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 2; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -2.0f, 2.0f ); } } //Impact hit for ( i = 0; i < 4; i++ ) { pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[0], origin ); if ( pParticle != NULL ) { offset = origin; offset[0] += random->RandomFloat( -8.0f, 8.0f ); offset[1] += random->RandomFloat( -8.0f, 8.0f ); pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); spread = 1.0f; pParticle->m_vecVelocity.Random( -spread, spread ); pParticle->m_vecVelocity += tr->plane.normal; VectorNormalize( pParticle->m_vecVelocity ); float fForce = random->RandomFloat( 0, 50 ); pParticle->m_vecVelocity *= fForce; colorRamp = random->RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = min( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = min( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = min( 1.0f, color[2] * colorRamp ) * 255.0f; pParticle->m_uchStartSize = random->RandomInt( 1, 4 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 4; pParticle->m_uchStartAlpha = random->RandomInt( 32, 64 ); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -16.0f, 16.0f ); } } }
//----------------------------------------------------------------------------- // Purpose: Debris flecks caused by impacts // Input : origin - start // *trace - trace information // *materialName - material hit // materialType - type of material hit //----------------------------------------------------------------------------- void FX_DebrisFlecks(const Vector& origin, trace_t *tr, char materialType, int iScale, bool bNoFlecks) { VPROF_BUDGET("FX_DebrisFlecks", VPROF_BUDGETGROUP_PARTICLE_RENDERING); if (!fx_drawimpactdebris.GetBool()) return; // // PC version // Vector color; GetColorForSurface(tr, &color); if (!bNoFlecks) { CreateFleckParticles(origin, color, tr, materialType, iScale); } // // Dust trail // Vector offset = tr->endpos + (tr->plane.normal * 2.0f); SimpleParticle newParticle; int i; for (i = 0; i < 2; i++) { newParticle.m_Pos = offset; newParticle.m_flLifetime = 0.0f; newParticle.m_flDieTime = 1.0f; Vector dir; dir[0] = tr->plane.normal[0] + random->RandomFloat(-0.8f, 0.8f); dir[1] = tr->plane.normal[1] + random->RandomFloat(-0.8f, 0.8f); dir[2] = tr->plane.normal[2] + random->RandomFloat(-0.8f, 0.8f); newParticle.m_uchStartSize = random->RandomInt(2, 4) * iScale; newParticle.m_uchEndSize = newParticle.m_uchStartSize * 8 * iScale; newParticle.m_vecVelocity = dir * random->RandomFloat(2.0f, 24.0f)*(i + 1); newParticle.m_vecVelocity[2] -= random->RandomFloat(8.0f, 32.0f)*(i + 1); newParticle.m_uchStartAlpha = random->RandomInt(100, 200); newParticle.m_uchEndAlpha = 0; newParticle.m_flRoll = random->RandomFloat(0, 360); newParticle.m_flRollDelta = random->RandomFloat(-1, 1); float colorRamp = random->RandomFloat(0.5f, 1.25f); newParticle.m_uchColor[0] = MIN(1.0f, color[0] * colorRamp)*255.0f; newParticle.m_uchColor[1] = MIN(1.0f, color[1] * colorRamp)*255.0f; newParticle.m_uchColor[2] = MIN(1.0f, color[2] * colorRamp)*255.0f; AddSimpleParticle(&newParticle, g_Mat_DustPuff[0]); } for (i = 0; i < 4; i++) { newParticle.m_Pos = offset; newParticle.m_flLifetime = 0.0f; newParticle.m_flDieTime = random->RandomFloat(0.25f, 0.5f); Vector dir; dir[0] = tr->plane.normal[0] + random->RandomFloat(-0.8f, 0.8f); dir[1] = tr->plane.normal[1] + random->RandomFloat(-0.8f, 0.8f); dir[2] = tr->plane.normal[2] + random->RandomFloat(-0.8f, 0.8f); newParticle.m_uchStartSize = random->RandomInt(1, 4); newParticle.m_uchEndSize = newParticle.m_uchStartSize * 4; newParticle.m_vecVelocity = dir * random->RandomFloat(8.0f, 32.0f); newParticle.m_vecVelocity[2] -= random->RandomFloat(8.0f, 64.0f); newParticle.m_uchStartAlpha = 255; newParticle.m_uchEndAlpha = 0; newParticle.m_flRoll = random->RandomFloat(0, 360); newParticle.m_flRollDelta = random->RandomFloat(-2.0f, 2.0f); float colorRamp = random->RandomFloat(0.5f, 1.25f); newParticle.m_uchColor[0] = MIN(1.0f, color[0] * colorRamp)*255.0f; newParticle.m_uchColor[1] = MIN(1.0f, color[1] * colorRamp)*255.0f; newParticle.m_uchColor[2] = MIN(1.0f, color[2] * colorRamp)*255.0f; AddSimpleParticle(&newParticle, g_Mat_BloodPuff[0]); } // // Bullet hole capper // newParticle.m_Pos = offset; newParticle.m_flLifetime = 0.0f; newParticle.m_flDieTime = random->RandomFloat(1.0f, 1.5f); Vector dir; dir[0] = tr->plane.normal[0] + random->RandomFloat(-0.8f, 0.8f); dir[1] = tr->plane.normal[1] + random->RandomFloat(-0.8f, 0.8f); dir[2] = tr->plane.normal[2] + random->RandomFloat(-0.8f, 0.8f); newParticle.m_uchStartSize = random->RandomInt(4, 8); newParticle.m_uchEndSize = newParticle.m_uchStartSize * 4.0f; newParticle.m_vecVelocity = dir * random->RandomFloat(2.0f, 24.0f); newParticle.m_vecVelocity[2] = random->RandomFloat(-2.0f, 2.0f); newParticle.m_uchStartAlpha = random->RandomInt(100, 200); newParticle.m_uchEndAlpha = 0; newParticle.m_flRoll = random->RandomFloat(0, 360); newParticle.m_flRollDelta = random->RandomFloat(-2, 2); float colorRamp = random->RandomFloat(0.5f, 1.25f); newParticle.m_uchColor[0] = MIN(1.0f, color[0] * colorRamp)*255.0f; newParticle.m_uchColor[1] = MIN(1.0f, color[1] * colorRamp)*255.0f; newParticle.m_uchColor[2] = MIN(1.0f, color[2] * colorRamp)*255.0f; AddSimpleParticle(&newParticle, g_Mat_DustPuff[0]); }
//----------------------------------------------------------------------------- // Purpose: Build impact //----------------------------------------------------------------------------- void FX_BuildImpact( const Vector &origin, const QAngle &vecAngles, const Vector &vecNormal, float flScale, bool bGround = false, CBaseEntity *pIgnore = NULL ) { Vector offset; float spread = 0.1f; CSmartPtr<CDustParticle> pSimple = CDustParticle::Create( "dust" ); pSimple->SetSortOrigin( origin ); SimpleParticle *pParticle; Vector color( 0.35, 0.35, 0.35 ); float colorRamp; // If we're hitting the ground, try and get the ground color if ( bGround ) { trace_t tr; UTIL_TraceLine( origin, origin + Vector(0,0,-32), MASK_SHOT, pIgnore, COLLISION_GROUP_NONE, &tr ); GetColorForSurface( &tr, &color ); } int iNumPuffs = 8; for ( int i = 0; i < iNumPuffs; i++ ) { QAngle vecTemp = vecAngles; vecTemp[YAW] += (360 / iNumPuffs) * i; Vector vecForward; AngleVectors( vecTemp, &vecForward ); pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "particle/particle_smokegrenade" ), origin ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = RandomFloat( 0.5f, 1.0f ); pParticle->m_vecVelocity.Random( -spread, spread ); pParticle->m_vecVelocity += ( vecForward * RandomFloat( 1.0f, 6.0f ) ); VectorNormalize( pParticle->m_vecVelocity ); float fForce = RandomFloat( 500, 750 ); // scaled pParticle->m_vecVelocity *= fForce * flScale; colorRamp = RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = min( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = min( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = min( 1.0f, color[2] * colorRamp ) * 255.0f; // scaled pParticle->m_uchStartSize = flScale * RandomInt( 15, 20 ); // scaled pParticle->m_uchEndSize = flScale * pParticle->m_uchStartSize * 4; pParticle->m_uchStartAlpha = RandomInt( 32, 255 ); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = RandomInt( 0, 360 ); pParticle->m_flRollDelta = RandomFloat( -8.0f, 8.0f ); } } }
void FX_DebrisFlecks( Vector& origin, trace_t *trace, char materialType, int iScale ) { VPROF_BUDGET( "FX_DebrisFlecks", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); Vector spawnOffset = trace->endpos + ( trace->plane.normal * 1.0f ); CSmartPtr<CFleckParticles> fleckEmitter = CFleckParticles::Create( "FX_DebrisFlecks" ); if ( !fleckEmitter ) return; fleckEmitter->SetSortOrigin( spawnOffset ); // 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[2]; switch ( materialType ) { case CHAR_TEX_CONCRETE: default: hMaterial[0] = fleckEmitter->GetPMaterial( "effects/fleck_cement1" ); hMaterial[1] = fleckEmitter->GetPMaterial( "effects/fleck_cement2" ); break; } Vector dir, end; Vector color; float colorRamp; GetColorForSurface( trace, &color ); 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; } // // Dust trail // Vector offset = trace->endpos + ( trace->plane.normal * 2.0f ); SimpleParticle newParticle; hMaterial[0] = g_ParticleMgr.GetPMaterial( "particle/particle_smokegrenade" ); for ( i = 0; i < 2; i++ ) { newParticle.m_Pos = offset; newParticle.m_flLifetime = 0.0f; newParticle.m_flDieTime = 1.0f; dir[0] = trace->plane.normal[0] + random->RandomFloat( -0.8f, 0.8f ); dir[1] = trace->plane.normal[1] + random->RandomFloat( -0.8f, 0.8f ); dir[2] = trace->plane.normal[2] + random->RandomFloat( -0.8f, 0.8f ); newParticle.m_uchStartSize = random->RandomInt( 2, 4 ) * iScale; newParticle.m_uchEndSize = newParticle.m_uchStartSize * 8 * iScale; newParticle.m_vecVelocity = dir * random->RandomFloat( 2.0f, 24.0f )*(i+1); newParticle.m_vecVelocity[2] -= random->RandomFloat( 8.0f, 32.0f )*(i+1); newParticle.m_uchStartAlpha = random->RandomInt( 100, 200 ); newParticle.m_uchEndAlpha = 0; newParticle.m_flRoll = random->RandomFloat( 0, 360 ); newParticle.m_flRollDelta = random->RandomFloat( -1, 1 ); colorRamp = random->RandomFloat( 0.5f, 1.25f ); newParticle.m_uchColor[0] = min( 1.0f, color[0]*colorRamp )*255.0f; newParticle.m_uchColor[1] = min( 1.0f, color[1]*colorRamp )*255.0f; newParticle.m_uchColor[2] = min( 1.0f, color[2]*colorRamp )*255.0f; AddSimpleParticle( &newParticle, hMaterial[0] ); } for ( i = 0; i < 4; i++ ) { newParticle.m_Pos = offset; newParticle.m_flLifetime = 0.0f; newParticle.m_flDieTime = random->RandomFloat( 0.25f, 0.5f ); dir[0] = trace->plane.normal[0] + random->RandomFloat( -0.8f, 0.8f ); dir[1] = trace->plane.normal[1] + random->RandomFloat( -0.8f, 0.8f ); dir[2] = trace->plane.normal[2] + random->RandomFloat( -0.8f, 0.8f ); newParticle.m_uchStartSize = random->RandomInt( 1, 4 ); newParticle.m_uchEndSize = newParticle.m_uchStartSize * 4; newParticle.m_vecVelocity = dir * random->RandomFloat( 8.0f, 32.0f ); newParticle.m_vecVelocity[2] -= random->RandomFloat( 8.0f, 64.0f ); newParticle.m_uchStartAlpha = 255; newParticle.m_uchEndAlpha = 0; newParticle.m_flRoll = random->RandomFloat( 0, 360 ); newParticle.m_flRollDelta = random->RandomFloat( -2.0f, 2.0f ); colorRamp = random->RandomFloat( 0.5f, 1.25f ); newParticle.m_uchColor[0] = min( 1.0f, color[0]*colorRamp )*255.0f; newParticle.m_uchColor[1] = min( 1.0f, color[1]*colorRamp )*255.0f; newParticle.m_uchColor[2] = min( 1.0f, color[2]*colorRamp )*255.0f; AddSimpleParticle( &newParticle, g_ParticleMgr.GetPMaterial("effects/blood") ); } // // Bullet hole capper // newParticle.m_Pos = offset; newParticle.m_flLifetime = 0.0f; newParticle.m_flDieTime = random->RandomFloat( 1.0f, 1.5f ); dir[0] = trace->plane.normal[0] + random->RandomFloat( -0.8f, 0.8f ); dir[1] = trace->plane.normal[1] + random->RandomFloat( -0.8f, 0.8f ); dir[2] = trace->plane.normal[2] + random->RandomFloat( -0.8f, 0.8f ); newParticle.m_uchStartSize = random->RandomInt( 4, 8 ); newParticle.m_uchEndSize = newParticle.m_uchStartSize * 4.0f; newParticle.m_vecVelocity = dir * random->RandomFloat( 2.0f, 24.0f ); newParticle.m_vecVelocity[2] = random->RandomFloat( -2.0f, 2.0f ); newParticle.m_uchStartAlpha = random->RandomInt( 100, 200 ); newParticle.m_uchEndAlpha = 0; newParticle.m_flRoll = random->RandomFloat( 0, 360 ); newParticle.m_flRollDelta = random->RandomFloat( -2, 2 ); colorRamp = random->RandomFloat( 0.5f, 1.25f ); newParticle.m_uchColor[0] = min( 1.0f, color[0]*colorRamp )*255.0f; newParticle.m_uchColor[1] = min( 1.0f, color[1]*colorRamp )*255.0f; newParticle.m_uchColor[2] = min( 1.0f, color[2]*colorRamp )*255.0f; AddSimpleParticle( &newParticle, hMaterial[0] ); }