void FX_MetalScrape(Vector &position, Vector &normal) { VPROF_BUDGET("FX_MetalScrape", VPROF_BUDGETGROUP_PARTICLE_RENDERING); Vector offset = position + (normal * 1.0f); CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create("FX_MetalScrape 1"); if (!sparkEmitter) return; sparkEmitter->SetSortOrigin(offset); //Setup our collision information sparkEmitter->Setup(offset, &normal, METAL_SCRAPE_SPREAD, METAL_SCRAPE_MINSPEED, METAL_SCRAPE_MAXSPEED, METAL_SCRAPE_GRAVITY, METAL_SCRAPE_DAMPEN, bitsPARTICLE_TRAIL_VELOCITY_DAMPEN); int numSparks = random->RandomInt(4, 8); if (g_Material_Spark == NULL) { g_Material_Spark = sparkEmitter->GetPMaterial("effects/spark"); } Vector dir; TrailParticle *pParticle; float length = 0.06f; //Dump out sparks for (int i = 0; i < numSparks; i++) { pParticle = (TrailParticle *) sparkEmitter->AddParticle(sizeof(TrailParticle), g_Material_Spark, offset); if (pParticle == NULL) return; pParticle->m_flLifetime = 0.0f; float spreadOfs = random->RandomFloat(0.0f, 2.0f); dir[0] = normal[0] + random->RandomFloat(-(METAL_SCRAPE_SPREAD*spreadOfs), (METAL_SCRAPE_SPREAD*spreadOfs)); dir[1] = normal[1] + random->RandomFloat(-(METAL_SCRAPE_SPREAD*spreadOfs), (METAL_SCRAPE_SPREAD*spreadOfs)); dir[2] = normal[2] + random->RandomFloat(-(METAL_SCRAPE_SPREAD*spreadOfs), (METAL_SCRAPE_SPREAD*spreadOfs)); pParticle->m_flWidth = random->RandomFloat(2.0f, 5.0f); pParticle->m_flLength = random->RandomFloat(length*0.25f, length); pParticle->m_flDieTime = random->RandomFloat(2.0f, 2.0f); pParticle->m_vecVelocity = dir * random->RandomFloat((METAL_SCRAPE_MINSPEED*(2.0f - spreadOfs)), (METAL_SCRAPE_MAXSPEED*(2.0f - spreadOfs))); Color32Init(pParticle->m_color, 255, 255, 255, 255); } }
//----------------------------------------------------------------------------- // Purpose: // Input : &pos - // &dir - // type - //----------------------------------------------------------------------------- void FX_GaussExplosion( const Vector &pos, const Vector &dir, int type ) { Vector vDir; vDir[0] = dir[0] + random->RandomFloat( -1.0f, 1.0f ); vDir[1] = dir[1] + random->RandomFloat( -1.0f, 1.0f ); vDir[2] = dir[2] + random->RandomFloat( -1.0f, 1.0f ); VectorNormalize( vDir ); int i; #if defined(_XBOX) || defined(_X360) // // XBox version // CSmartPtr<CTrailParticles> pSparkEmitter = CTrailParticles::Create( "FX_GaussExplosion" ); if ( pSparkEmitter == NULL ) { Assert(0); return; } if ( g_Material_Spark == NULL ) { g_Material_Spark = pSparkEmitter->GetPMaterial( "effects/spark" ); } pSparkEmitter->SetSortOrigin( pos ); pSparkEmitter->m_ParticleCollision.SetGravity( 800.0f ); pSparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN ); pSparkEmitter->GetBinding().SetBBox( pos - Vector( 32, 32, 32 ), pos + Vector( 32, 32, 32 ) ); int numSparks = random->RandomInt( 8, 16 ); TrailParticle *pParticle; // Dump out sparks for ( i = 0; i < numSparks; i++ ) { pParticle = (TrailParticle *) pSparkEmitter->AddParticle( sizeof(TrailParticle), g_Material_Spark, pos ); if ( pParticle == NULL ) return; pParticle->m_flLifetime = 0.0f; vDir.Random( -0.6f, 0.6f ); vDir += dir; VectorNormalize( vDir ); pParticle->m_flWidth = random->RandomFloat( 1.0f, 4.0f ); pParticle->m_flLength = random->RandomFloat( 0.01f, 0.1f ); pParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f ); pParticle->m_vecVelocity = vDir * random->RandomFloat( 128, 512 ); Color32Init( pParticle->m_color, 255, 255, 255, 255 ); } // End cap SimpleParticle particle; particle.m_Pos = pos; particle.m_flLifetime = 0.0f; particle.m_flDieTime = 0.1f; particle.m_vecVelocity.Init(); particle.m_flRoll = random->RandomInt( 0, 360 ); particle.m_flRollDelta = 0.0f; particle.m_uchColor[0] = 255; particle.m_uchColor[1] = 255; particle.m_uchColor[2] = 255; particle.m_uchStartAlpha = 255; particle.m_uchEndAlpha = 255; particle.m_uchStartSize = random->RandomInt( 24, 32 ); particle.m_uchEndSize = 0; AddSimpleParticle( &particle, ParticleMgr()->GetPMaterial( "effects/yellowflare" ) ); #else // // PC version // CSmartPtr<CTrailParticles> pSparkEmitter = CTrailParticles::Create( "FX_ElectricSpark" ); if ( !pSparkEmitter ) { Assert(0); return; } PMaterialHandle hMaterial = pSparkEmitter->GetPMaterial( "effects/spark" ); pSparkEmitter->SetSortOrigin( pos ); pSparkEmitter->m_ParticleCollision.SetGravity( 800.0f ); pSparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN|bitsPARTICLE_TRAIL_COLLIDE ); //Setup our collision information pSparkEmitter->m_ParticleCollision.Setup( pos, &vDir, 0.8f, 128, 512, 800, 0.3f ); int numSparks = random->RandomInt( 16, 32 ); TrailParticle *pParticle; // Dump out sparks for ( i = 0; i < numSparks; i++ ) { pParticle = (TrailParticle *) pSparkEmitter->AddParticle( sizeof(TrailParticle), hMaterial, pos ); if ( pParticle == NULL ) return; pParticle->m_flLifetime = 0.0f; vDir.Random( -0.6f, 0.6f ); vDir += dir; VectorNormalize( vDir ); pParticle->m_flWidth = random->RandomFloat( 1.0f, 4.0f ); pParticle->m_flLength = random->RandomFloat( 0.01f, 0.1f ); pParticle->m_flDieTime = random->RandomFloat( 0.25f, 1.0f ); pParticle->m_vecVelocity = vDir * random->RandomFloat( 128, 512 ); Color32Init( pParticle->m_color, 255, 255, 255, 255 ); } FX_ElectricSpark( pos, 1, 1, &vDir ); #endif }
//----------------------------------------------------------------------------- // Purpose: // Input : &pos - // &dir - // type - //----------------------------------------------------------------------------- void FX_GaussExplosion(const Vector &pos, const Vector &dir, int type) { Vector vDir; vDir[0] = dir[0] + random->RandomFloat(-1.0f, 1.0f); vDir[1] = dir[1] + random->RandomFloat(-1.0f, 1.0f); vDir[2] = dir[2] + random->RandomFloat(-1.0f, 1.0f); VectorNormalize(vDir); int i; // // PC version // CSmartPtr<CTrailParticles> pSparkEmitter = CTrailParticles::Create("FX_ElectricSpark"); if (!pSparkEmitter) { Assert(0); return; } PMaterialHandle hMaterial = pSparkEmitter->GetPMaterial("effects/spark"); pSparkEmitter->SetSortOrigin(pos); pSparkEmitter->m_ParticleCollision.SetGravity(800.0f); pSparkEmitter->SetFlag(bitsPARTICLE_TRAIL_VELOCITY_DAMPEN | bitsPARTICLE_TRAIL_COLLIDE); //Setup our collision information pSparkEmitter->m_ParticleCollision.Setup(pos, &vDir, 0.8f, 128, 512, 800, 0.3f); int numSparks = random->RandomInt(16, 32); TrailParticle *pParticle; // Dump out sparks for (i = 0; i < numSparks; i++) { pParticle = (TrailParticle *) pSparkEmitter->AddParticle(sizeof(TrailParticle), hMaterial, pos); if (pParticle == NULL) return; pParticle->m_flLifetime = 0.0f; vDir.Random(-0.6f, 0.6f); vDir += dir; VectorNormalize(vDir); pParticle->m_flWidth = random->RandomFloat(1.0f, 4.0f); pParticle->m_flLength = random->RandomFloat(0.01f, 0.1f); pParticle->m_flDieTime = random->RandomFloat(0.25f, 1.0f); pParticle->m_vecVelocity = vDir * random->RandomFloat(128, 512); Color32Init(pParticle->m_color, 255, 255, 255, 255); } FX_ElectricSpark(pos, 1, 1, &vDir); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_BaseExplosionEffect::CreateDebris( void ) { if ( m_fFlags & TE_EXPLFLAG_NOPARTICLES ) return; // // Sparks // CSmartPtr<CTrailParticles> pSparkEmitter = CTrailParticles::Create( "CreateDebris 1" ); if ( pSparkEmitter == NULL ) { assert(0); return; } if ( m_Material_FireCloud == NULL ) { m_Material_FireCloud = pSparkEmitter->GetPMaterial( "effects/fire_cloud2" ); } pSparkEmitter->SetSortOrigin( m_vecOrigin ); pSparkEmitter->m_ParticleCollision.SetGravity( 200.0f ); pSparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN ); pSparkEmitter->SetVelocityDampen( 8.0f ); // Set our bbox, don't auto-calculate it! pSparkEmitter->GetBinding().SetBBox( m_vecOrigin - Vector( 128, 128, 128 ), m_vecOrigin + Vector( 128, 128, 128 ) ); #ifndef _XBOX int numSparks = random->RandomInt( 8, 16 ); #else int numSparks = random->RandomInt( 2, 4 ); #endif Vector dir; float spread = 1.0f; TrailParticle *tParticle; // Dump out sparks int i; for ( i = 0; i < numSparks; i++ ) { tParticle = (TrailParticle *) pSparkEmitter->AddParticle( sizeof(TrailParticle), m_Material_FireCloud, m_vecOrigin ); if ( tParticle == NULL ) break; tParticle->m_flLifetime = 0.0f; tParticle->m_flDieTime = random->RandomFloat( 0.1f, 0.15f ); dir.Random( -spread, spread ); dir += m_vecDirection; VectorNormalize( dir ); tParticle->m_flWidth = random->RandomFloat( 2.0f, 16.0f ); tParticle->m_flLength = random->RandomFloat( 0.05f, 0.1f ); tParticle->m_vecVelocity = dir * random->RandomFloat( 1500, 2500 ); Color32Init( tParticle->m_color, 255, 255, 255, 255 ); } #ifndef _XBOX // // Chunks // Vector offset; CSmartPtr<CFleckParticles> fleckEmitter = CFleckParticles::Create( "CreateDebris 2", m_vecOrigin, Vector(128,128,128) ); if ( !fleckEmitter ) return; // Setup our collision information fleckEmitter->m_ParticleCollision.Setup( m_vecOrigin, &m_vecDirection, 0.9f, 512, 1024, 800, 0.5f ); #ifdef _XBOX int numFlecks = random->RandomInt( 8, 16 ); #else int numFlecks = random->RandomInt( 16, 32 ); #endif // _XBOX // Dump out flecks for ( i = 0; i < numFlecks; i++ ) { offset = m_vecOrigin + ( m_vecDirection * 16.0f ); offset[0] += random->RandomFloat( -8.0f, 8.0f ); offset[1] += random->RandomFloat( -8.0f, 8.0f ); offset[2] += random->RandomFloat( -8.0f, 8.0f ); FleckParticle *pParticle = (FleckParticle *) fleckEmitter->AddParticle( sizeof(FleckParticle), g_Mat_Fleck_Cement[random->RandomInt(0,1)], offset ); if ( pParticle == NULL ) break; pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = 3.0f; dir[0] = m_vecDirection[0] + random->RandomFloat( -1.0f, 1.0f ); dir[1] = m_vecDirection[1] + random->RandomFloat( -1.0f, 1.0f ); dir[2] = m_vecDirection[2] + random->RandomFloat( -1.0f, 1.0f ); pParticle->m_uchSize = random->RandomInt( 1, 3 ); VectorNormalize( dir ); float fForce = ( random->RandomFloat( 64, 256 ) * ( 4 - pParticle->m_uchSize ) ); float fDev = ScaleForceByDeviation( dir, m_vecDirection, 0.8f ); pParticle->m_vecVelocity = dir * ( fForce * ( 16.0f * (fDev*fDev*0.5f) ) ); pParticle->m_flRoll = random->RandomFloat( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( 0, 360 ); float colorRamp = random->RandomFloat( 0.5f, 1.5f ); pParticle->m_uchColor[0] = min( 1.0f, 0.25f*colorRamp )*255.0f; pParticle->m_uchColor[1] = min( 1.0f, 0.25f*colorRamp )*255.0f; pParticle->m_uchColor[2] = min( 1.0f, 0.25f*colorRamp )*255.0f; } #endif // !_XBOX }
//----------------------------------------------------------------------------- // Purpose: // Input : &origin - // &normal - // scale - //----------------------------------------------------------------------------- void FX_AirboatGunImpact( const Vector &origin, const Vector &normal, float scale ) { #ifdef _XBOX Vector offset = origin + ( normal * 1.0f ); CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create( "FX_MetalSpark 1" ); if ( sparkEmitter == NULL ) return; //Setup our information sparkEmitter->SetSortOrigin( offset ); sparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN ); sparkEmitter->SetVelocityDampen( 8.0f ); sparkEmitter->SetGravity( 800.0f ); sparkEmitter->SetCollisionDamped( 0.25f ); sparkEmitter->GetBinding().SetBBox( offset - Vector( 32, 32, 32 ), offset + Vector( 32, 32, 32 ) ); int numSparks = random->RandomInt( 4, 8 ); TrailParticle *pParticle; PMaterialHandle hMaterial = sparkEmitter->GetPMaterial( "effects/spark" ); Vector dir; float length = 0.1f; //Dump out sparks for ( int i = 0; i < numSparks; i++ ) { pParticle = (TrailParticle *) sparkEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset ); if ( pParticle == NULL ) return; pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.05f, 0.1f ); float spreadOfs = random->RandomFloat( 0.0f, 2.0f ); dir[0] = normal[0] + random->RandomFloat( -(0.5f*spreadOfs), (0.5f*spreadOfs) ); dir[1] = normal[1] + random->RandomFloat( -(0.5f*spreadOfs), (0.5f*spreadOfs) ); dir[2] = normal[2] + random->RandomFloat( -(0.5f*spreadOfs), (0.5f*spreadOfs) ); VectorNormalize( dir ); pParticle->m_flWidth = random->RandomFloat( 1.0f, 4.0f ); pParticle->m_flLength = random->RandomFloat( length*0.25f, length ); pParticle->m_vecVelocity = dir * random->RandomFloat( (128.0f*(2.0f-spreadOfs)), (512.0f*(2.0f-spreadOfs)) ); Color32Init( pParticle->m_color, 255, 255, 255, 255 ); } #else // Normal metal spark FX_MetalSpark( origin, normal, normal, (int) scale ); #endif // _XBOX // Add a quad to highlite the hit point FX_AddQuad( origin, normal, random->RandomFloat( 16, 32 ), random->RandomFloat( 32, 48 ), 0.75f, 1.0f, 0.0f, 0.4f, random->RandomInt( 0, 360 ), 0, Vector( 1.0f, 1.0f, 1.0f ), 0.05f, "effects/combinemuzzle2_nocull", (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CBasePlasmaProjectile::Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs) { m_pParticleMgr = pParticleMgr; m_pParticleMgr->AddEffect( &m_ParticleEffect, this ); PMaterialHandle HeadMaterial, TrailMaterial; // Load the projectile material if ( GetTeamNumber() == TEAM_HUMANS ) { HeadMaterial = m_ParticleEffect.FindOrAddMaterial( "effects/human_tracers/human_sparksprite_A1" ); TrailMaterial = m_ParticleEffect.FindOrAddMaterial( "effects/human_tracers/human_sparktracer_A_" ); } else { HeadMaterial = m_ParticleEffect.FindOrAddMaterial( "effects/alien_tracers/alien_pbsprite_A1" ); TrailMaterial = m_ParticleEffect.FindOrAddMaterial( "effects/alien_tracers/alien_pbtracer_A_" ); } // Create the head & trail m_pHeadParticle = (SimpleParticle *)m_ParticleEffect.AddParticle(sizeof(SimpleParticle), HeadMaterial ); m_pTrailParticle = (TrailParticle *)m_ParticleEffect.AddParticle(sizeof(TrailParticle), TrailMaterial ); if ( !m_pHeadParticle || !m_pTrailParticle ) return; // 3rd person particles are larger bool bFirst = (GetOwnerEntity() == C_BasePlayer::GetLocalPlayer()); m_pHeadParticle->m_Pos = GetRenderOrigin(); m_pHeadParticle->m_uchColor[0] = 255; m_pHeadParticle->m_uchColor[1] = 255; m_pHeadParticle->m_uchColor[2] = 255; if ( bFirst ) { m_pHeadParticle->m_uchStartSize = 6; } else { m_pHeadParticle->m_uchStartSize = shot_head_size.GetInt(); } m_pHeadParticle->m_uchEndSize = m_pHeadParticle->m_uchStartSize; m_pHeadParticle->m_uchStartAlpha = 255; m_pHeadParticle->m_uchEndAlpha = 255; m_pHeadParticle->m_flRoll = 0; m_pHeadParticle->m_flRollDelta = 10; m_pHeadParticle->m_iFlags = 0; m_pTrailParticle->m_flLifetime = 0; m_pTrailParticle->m_Pos = GetRenderOrigin(); if ( bFirst ) { m_pTrailParticle->m_flWidth = 25; m_pTrailParticle->m_flLength = 140; } else { m_pTrailParticle->m_flWidth = shot_width.GetFloat(); m_pTrailParticle->m_flLength = shot_length.GetFloat(); } Color32Init( m_pTrailParticle->m_color, 255, 255, 255, 255 ); m_flNextSparkEffect = gpGlobals->curtime + RandomFloat( 0.05, 0.4 ); }
void FX_MicroExplosion(Vector &position, Vector &normal) { VPROF_BUDGET("FX_MicroExplosion", VPROF_BUDGETGROUP_PARTICLE_RENDERING); Vector offset = position + (normal * 2.0f); CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create("FX_MicroExplosion 1"); if (!sparkEmitter) return; sparkEmitter->SetSortOrigin(offset); //Setup our collision information sparkEmitter->Setup(offset, &normal, MICRO_EXPLOSION_SPREAD, MICRO_EXPLOSION_MINSPEED, MICRO_EXPLOSION_MAXSPEED, MICRO_EXPLOSION_GRAVITY, MICRO_EXPLOSION_DAMPEN, bitsPARTICLE_TRAIL_VELOCITY_DAMPEN); int numSparks = random->RandomInt(8, 16); if (g_Material_Spark == NULL) { g_Material_Spark = sparkEmitter->GetPMaterial("effects/spark"); } TrailParticle *pParticle; Vector dir, vOfs; float length = 0.2f; //Fast lines for (int i = 0; i < numSparks; i++) { pParticle = (TrailParticle *) sparkEmitter->AddParticle(sizeof(TrailParticle), g_Material_Spark, offset); if (pParticle) { pParticle->m_flLifetime = 0.0f; float ramp = ((float) i / (float) numSparks); dir[0] = normal[0] + random->RandomFloat(-MICRO_EXPLOSION_SPREAD*ramp, MICRO_EXPLOSION_SPREAD*ramp); dir[1] = normal[1] + random->RandomFloat(-MICRO_EXPLOSION_SPREAD*ramp, MICRO_EXPLOSION_SPREAD*ramp); dir[2] = normal[2] + random->RandomFloat(-MICRO_EXPLOSION_SPREAD*ramp, MICRO_EXPLOSION_SPREAD*ramp); pParticle->m_flWidth = random->RandomFloat(5.0f, 10.0f); pParticle->m_flLength = (length*((1.0f - ramp)*(1.0f - ramp)*0.5f)); pParticle->m_flDieTime = 0.2f; pParticle->m_vecVelocity = dir * random->RandomFloat(MICRO_EXPLOSION_MINSPEED*(1.5f - ramp), MICRO_EXPLOSION_MAXSPEED*(1.5f - ramp)); Color32Init(pParticle->m_color, 255, 255, 255, 255); } } // // Filler // CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create("FX_MicroExplosion 2"); pSimple->SetSortOrigin(offset); SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle(sizeof(SimpleParticle), pSimple->GetPMaterial("sprites/rico1"), offset); if (sParticle) { sParticle->m_flLifetime = 0.0f; sParticle->m_flDieTime = 0.3f; sParticle->m_vecVelocity.Init(); sParticle->m_uchColor[0] = 255; sParticle->m_uchColor[1] = 255; sParticle->m_uchColor[2] = 255; sParticle->m_uchStartAlpha = random->RandomInt(128, 255); sParticle->m_uchEndAlpha = 0; sParticle->m_uchStartSize = random->RandomInt(12, 16); sParticle->m_uchEndSize = sParticle->m_uchStartSize; sParticle->m_flRoll = random->RandomInt(0, 360); sParticle->m_flRollDelta = 0.0f; } }
void FX_Sparks(const Vector &pos, int nMagnitude, int nTrailLength, const Vector &vecDir, float flWidth, float flMinSpeed, float flMaxSpeed, char *pSparkMaterial) { VPROF_BUDGET("FX_Sparks", VPROF_BUDGETGROUP_PARTICLE_RENDERING); CSmartPtr<CTrailParticles> pSparkEmitter = CTrailParticles::Create("FX_Sparks 1"); if (!pSparkEmitter) { Assert(0); return; } PMaterialHandle hMaterial; if (pSparkMaterial) { hMaterial = pSparkEmitter->GetPMaterial(pSparkMaterial); } else { if (g_Material_Spark == NULL) { g_Material_Spark = pSparkEmitter->GetPMaterial("effects/spark"); } hMaterial = g_Material_Spark; } //Setup our collision information pSparkEmitter->Setup((Vector &) pos, NULL, SPARK_SPREAD, flMinSpeed, flMaxSpeed, SPARK_GRAVITY, SPARK_DAMPEN, bitsPARTICLE_TRAIL_VELOCITY_DAMPEN); pSparkEmitter->SetSortOrigin(pos); // // Big sparks. // Vector dir; int numSparks = nMagnitude * nMagnitude * random->RandomFloat(2, 4); int i; TrailParticle *pParticle; for (i = 0; i < numSparks; i++) { pParticle = (TrailParticle *) pSparkEmitter->AddParticle(sizeof(TrailParticle), hMaterial, pos); if (pParticle == NULL) return; pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = nMagnitude * random->RandomFloat(1.0f, 2.0f); float spreadOfs = random->RandomFloat(0.0f, 2.0f); dir[0] = vecDir[0] + random->RandomFloat(-(SPARK_SPREAD*spreadOfs), (SPARK_SPREAD*spreadOfs)); dir[1] = vecDir[1] + random->RandomFloat(-(SPARK_SPREAD*spreadOfs), (SPARK_SPREAD*spreadOfs)); dir[2] = vecDir[2] + random->RandomFloat(-(SPARK_SPREAD*spreadOfs), (SPARK_SPREAD*spreadOfs)); pParticle->m_vecVelocity = dir * random->RandomFloat((flMinSpeed*(2.0f - spreadOfs)), (flMaxSpeed*(2.0f - spreadOfs))); pParticle->m_flWidth = flWidth + random->RandomFloat(0.0f, 0.5f); pParticle->m_flLength = nTrailLength * random->RandomFloat(0.02, 0.05f); Color32Init(pParticle->m_color, 255, 255, 255, 255); } // // Little sparks // CSmartPtr<CTrailParticles> pSparkEmitter2 = CTrailParticles::Create("FX_ElectricSpark 2"); if (!pSparkEmitter2) { Assert(0); return; } if (pSparkMaterial) { hMaterial = pSparkEmitter->GetPMaterial(pSparkMaterial); } else { if (g_Material_Spark == NULL) { g_Material_Spark = pSparkEmitter2->GetPMaterial("effects/spark"); } hMaterial = g_Material_Spark; } pSparkEmitter2->SetSortOrigin(pos); pSparkEmitter2->m_ParticleCollision.SetGravity(400.0f); pSparkEmitter2->SetFlag(bitsPARTICLE_TRAIL_VELOCITY_DAMPEN); numSparks = nMagnitude * random->RandomInt(4, 8); // Dump out sparks for (i = 0; i < numSparks; i++) { pParticle = (TrailParticle *) pSparkEmitter2->AddParticle(sizeof(TrailParticle), hMaterial, pos); if (pParticle == NULL) return; pParticle->m_flLifetime = 0.0f; dir.Random(-1.0f, 1.0f); dir += vecDir; VectorNormalize(dir); pParticle->m_flWidth = (flWidth * 0.25) + random->RandomFloat(0.0f, 0.5f); pParticle->m_flLength = nTrailLength * random->RandomFloat(0.02f, 0.03f); pParticle->m_flDieTime = nMagnitude * random->RandomFloat(0.3f, 0.5f); pParticle->m_vecVelocity = dir * random->RandomFloat(flMinSpeed, flMaxSpeed); Color32Init(pParticle->m_color, 255, 255, 255, 255); } }
void FX_MetalSpark(const Vector &position, const Vector &direction, const Vector &surfaceNormal, int iScale) { VPROF_BUDGET("FX_MetalSpark", VPROF_BUDGETGROUP_PARTICLE_RENDERING); if (!fx_drawmetalspark.GetBool()) return; // // Emitted particles // Vector offset = position + (surfaceNormal * 1.0f); CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create("FX_MetalSpark 1"); if (sparkEmitter == NULL) return; //Setup our information sparkEmitter->SetSortOrigin(offset); sparkEmitter->SetFlag(bitsPARTICLE_TRAIL_VELOCITY_DAMPEN); sparkEmitter->SetVelocityDampen(8.0f); sparkEmitter->SetGravity(METAL_SPARK_GRAVITY); sparkEmitter->SetCollisionDamped(METAL_SPARK_DAMPEN); sparkEmitter->GetBinding().SetBBox(offset - Vector(32, 32, 32), offset + Vector(32, 32, 32)); int numSparks = random->RandomInt(4, 8) * (iScale * 2); numSparks = (int) (0.5f + (float) numSparks * g_pParticleSystemMgr->ParticleThrottleScaling()); if (g_Material_Spark == NULL) { g_Material_Spark = sparkEmitter->GetPMaterial("effects/spark"); } TrailParticle *pParticle; Vector dir; float length = 0.1f; //Dump out sparks for (int i = 0; i < numSparks; i++) { pParticle = (TrailParticle *) sparkEmitter->AddParticle(sizeof(TrailParticle), g_Material_Spark, offset); if (pParticle == NULL) return; pParticle->m_flLifetime = 0.0f; if (iScale > 1 && i % 3 == 0) { // Every third spark goes flying far if we're having a big batch of sparks. pParticle->m_flDieTime = random->RandomFloat(0.15f, 0.25f); } else { pParticle->m_flDieTime = random->RandomFloat(0.05f, 0.1f); } float spreadOfs = random->RandomFloat(0.0f, 2.0f); dir[0] = direction[0] + random->RandomFloat(-(METAL_SPARK_SPREAD*spreadOfs), (METAL_SPARK_SPREAD*spreadOfs)); dir[1] = direction[1] + random->RandomFloat(-(METAL_SPARK_SPREAD*spreadOfs), (METAL_SPARK_SPREAD*spreadOfs)); dir[2] = direction[2] + random->RandomFloat(-(METAL_SPARK_SPREAD*spreadOfs), (METAL_SPARK_SPREAD*spreadOfs)); VectorNormalize(dir); pParticle->m_flWidth = random->RandomFloat(1.0f, 4.0f); pParticle->m_flLength = random->RandomFloat(length*0.25f, length); pParticle->m_vecVelocity = dir * random->RandomFloat((METAL_SPARK_MINSPEED*(2.0f - spreadOfs)), (METAL_SPARK_MAXSPEED*(2.0f - spreadOfs))); Color32Init(pParticle->m_color, 255, 255, 255, 255); } // // Impact point glow // FXQuadData_t data; data.SetMaterial("effects/yellowflare"); data.SetColor(1.0f, 1.0f, 1.0f); data.SetOrigin(offset); data.SetNormal(surfaceNormal); data.SetAlpha(1.0f, 0.0f); data.SetLifeTime(0.1f); data.SetYaw(random->RandomInt(0, 360)); int scale = random->RandomInt(24, 28); data.SetScale(scale, 0); FX_AddQuad(data); }
void FX_ElectricSpark(const Vector &pos, int nMagnitude, int nTrailLength, const Vector *vecDir) { VPROF_BUDGET("FX_ElectricSpark", VPROF_BUDGETGROUP_PARTICLE_RENDERING); CSmartPtr<CTrailParticles> pSparkEmitter = CTrailParticles::Create("FX_ElectricSpark 1"); if (!pSparkEmitter) { Assert(0); return; } if (g_Material_Spark == NULL) { g_Material_Spark = pSparkEmitter->GetPMaterial("effects/spark"); } //Setup our collision information pSparkEmitter->Setup((Vector &) pos, NULL, SPARK_ELECTRIC_SPREAD, SPARK_ELECTRIC_MINSPEED, SPARK_ELECTRIC_MAXSPEED, SPARK_ELECTRIC_GRAVITY, SPARK_ELECTRIC_DAMPEN, bitsPARTICLE_TRAIL_VELOCITY_DAMPEN); pSparkEmitter->SetSortOrigin(pos); // // Big sparks. // Vector dir; int numSparks = nMagnitude * nMagnitude * random->RandomFloat(2, 4); int i; TrailParticle *pParticle; for (i = 0; i < numSparks; i++) { pParticle = (TrailParticle *) pSparkEmitter->AddParticle(sizeof(TrailParticle), g_Material_Spark, pos); if (pParticle == NULL) return; pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = nMagnitude * random->RandomFloat(1.0f, 2.0f); dir.Random(-1.0f, 1.0f); dir[2] = random->RandomFloat(0.5f, 1.0f); if (vecDir) { dir += 2 * (*vecDir); VectorNormalize(dir); } pParticle->m_flWidth = random->RandomFloat(2.0f, 5.0f); pParticle->m_flLength = nTrailLength * random->RandomFloat(0.02, 0.05f); pParticle->m_vecVelocity = dir * random->RandomFloat(SPARK_ELECTRIC_MINSPEED, SPARK_ELECTRIC_MAXSPEED); Color32Init(pParticle->m_color, 255, 255, 255, 255); } // // Little sparks // CSmartPtr<CTrailParticles> pSparkEmitter2 = CTrailParticles::Create( "FX_ElectricSpark 2" ); if ( !pSparkEmitter2 ) { Assert(0); return; } pSparkEmitter2->SetSortOrigin( pos ); pSparkEmitter2->m_ParticleCollision.SetGravity( 400.0f ); pSparkEmitter2->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN ); numSparks = nMagnitude * random->RandomInt( 16, 32 ); // Dump out sparks for ( i = 0; i < numSparks; i++ ) { pParticle = (TrailParticle *) pSparkEmitter2->AddParticle( sizeof(TrailParticle), g_Material_Spark, pos ); if ( pParticle == NULL ) return; pParticle->m_flLifetime = 0.0f; dir.Random(-1.0f, 1.0f); if (vecDir) { dir += *vecDir; VectorNormalize(dir); } pParticle->m_flWidth = random->RandomFloat(2.0f, 4.0f); pParticle->m_flLength = nTrailLength * random->RandomFloat(0.02f, 0.03f); pParticle->m_flDieTime = nMagnitude * random->RandomFloat(0.1f, 0.2f); pParticle->m_vecVelocity = dir * random->RandomFloat(128, 256); Color32Init(pParticle->m_color, 255, 255, 255, 255); } // // Caps // CSmartPtr<CSimpleGlowEmitter> pSimple = CSimpleGlowEmitter::Create("FX_ElectricSpark 3", pos, gpGlobals->curtime + 0.2); // NOTE: None of these will render unless the effect is visible! // // Inner glow // SimpleParticle *sParticle; sParticle = (SimpleParticle *) pSimple->AddParticle(sizeof(SimpleParticle), pSimple->GetPMaterial("effects/yellowflare_noz"), pos); if (sParticle == NULL) return; sParticle->m_flLifetime = 0.0f; sParticle->m_flDieTime = 0.2f; sParticle->m_vecVelocity.Init(); sParticle->m_uchColor[0] = 255; sParticle->m_uchColor[1] = 255; sParticle->m_uchColor[2] = 255; sParticle->m_uchStartAlpha = 255; sParticle->m_uchEndAlpha = 255; sParticle->m_uchStartSize = nMagnitude * random->RandomInt(4, 8); sParticle->m_uchEndSize = 0; sParticle->m_flRoll = random->RandomInt(0, 360); sParticle->m_flRollDelta = 0.0f; sParticle = (SimpleParticle *) pSimple->AddParticle(sizeof(SimpleParticle), pSimple->GetPMaterial("effects/yellowflare_noz"), pos); if (sParticle == NULL) return; sParticle->m_flLifetime = 0.0f; sParticle->m_flDieTime = 0.2f; sParticle->m_vecVelocity.Init(); float fColor = random->RandomInt(32, 64); sParticle->m_uchColor[0] = fColor; sParticle->m_uchColor[1] = fColor; sParticle->m_uchColor[2] = fColor; sParticle->m_uchStartAlpha = fColor; sParticle->m_uchEndAlpha = 0; sParticle->m_uchStartSize = nMagnitude * random->RandomInt(32, 64); sParticle->m_uchEndSize = 0; sParticle->m_flRoll = random->RandomInt(0, 360); sParticle->m_flRollDelta = random->RandomFloat(-1.0f, 1.0f); // // Smoke // Vector sOffs; sOffs[0] = pos[0] + random->RandomFloat(-4.0f, 4.0f); sOffs[1] = pos[1] + random->RandomFloat(-4.0f, 4.0f); sOffs[2] = pos[2]; sParticle = (SimpleParticle *) pSimple->AddParticle(sizeof(SimpleParticle), g_Mat_DustPuff[1], sOffs); if (sParticle == NULL) return; sParticle->m_flLifetime = 0.0f; sParticle->m_flDieTime = 1.0f; sParticle->m_vecVelocity.Init(); sParticle->m_vecVelocity[2] = 16.0f; sParticle->m_vecVelocity[0] = random->RandomFloat(-16.0f, 16.0f); sParticle->m_vecVelocity[1] = random->RandomFloat(-16.0f, 16.0f); sParticle->m_uchColor[0] = 255; sParticle->m_uchColor[1] = 255; sParticle->m_uchColor[2] = 200; sParticle->m_uchStartAlpha = random->RandomInt(16, 32); sParticle->m_uchEndAlpha = 0; sParticle->m_uchStartSize = random->RandomInt(4, 8); sParticle->m_uchEndSize = sParticle->m_uchStartSize*4.0f; sParticle->m_flRoll = random->RandomInt(0, 360); sParticle->m_flRollDelta = random->RandomFloat(-2.0f, 2.0f); // // Dlight // /* dlight_t *dl= effects->CL_AllocDlight ( 0 ); dl->origin = pos; dl->color.r = dl->color.g = dl->color.b = 250; dl->radius = random->RandomFloat(16,32); dl->die = gpGlobals->curtime + 0.001; */ }
void FX_Explosion(Vector& origin, Vector& normal, char materialType) { VPROF_BUDGET("FX_Explosion", VPROF_BUDGETGROUP_PARTICLE_RENDERING); Vector offset = origin + (normal * 2.0f); CSmartPtr<CTrailParticles> pSparkEmitter = CTrailParticles::Create("FX_Explosion 1"); if (!pSparkEmitter) return; // Get color data from our hit point IMaterial *pTraceMaterial; Vector diffuseColor, baseColor; pTraceMaterial = engine->TraceLineMaterialAndLighting(origin, normal * -16.0f, diffuseColor, baseColor); // Get final light value float r = pow(diffuseColor[0], 1.0f / 2.2f) * baseColor[0]; float g = pow(diffuseColor[1], 1.0f / 2.2f) * baseColor[1]; float b = pow(diffuseColor[2], 1.0f / 2.2f) * baseColor[2]; if (g_Material_Spark == NULL) { g_Material_Spark = pSparkEmitter->GetPMaterial("effects/spark"); } // Setup our collision information pSparkEmitter->Setup(offset, &normal, EXPLOSION_SPREAD, EXPLOSION_MINSPEED, EXPLOSION_MAXSPEED, EXPLOSION_GRAVITY, EXPLOSION_DAMPEN, bitsPARTICLE_TRAIL_VELOCITY_DAMPEN); pSparkEmitter->SetSortOrigin(offset); Vector dir; int numSparks = random->RandomInt(8, 16); // Dump out sparks int i; for (i = 0; i < numSparks; i++) { TrailParticle *pParticle = (TrailParticle *) pSparkEmitter->AddParticle(sizeof(TrailParticle), g_Material_Spark, offset); if (pParticle == NULL) break; pParticle->m_flLifetime = 0.0f; pParticle->m_flWidth = random->RandomFloat(5.0f, 10.0f); pParticle->m_flLength = random->RandomFloat(0.05, 0.1f); pParticle->m_flDieTime = random->RandomFloat(1.0f, 2.0f); dir[0] = normal[0] + random->RandomFloat(-EXPLOSION_SPREAD, EXPLOSION_SPREAD); dir[1] = normal[1] + random->RandomFloat(-EXPLOSION_SPREAD, EXPLOSION_SPREAD); dir[2] = normal[2] + random->RandomFloat(-EXPLOSION_SPREAD, EXPLOSION_SPREAD); pParticle->m_vecVelocity = dir * random->RandomFloat(EXPLOSION_MINSPEED, EXPLOSION_MAXSPEED); Color32Init(pParticle->m_color, 255, 255, 255, 255); } // Chunks o'dirt // Only create dirt chunks on concrete/world if (materialType == 'C' || materialType == 'W') { CSmartPtr<CFleckParticles> fleckEmitter = CFleckParticles::Create("FX_Explosion 10", offset, Vector(5, 5, 5)); if (!fleckEmitter) return; // Setup our collision information fleckEmitter->m_ParticleCollision.Setup(offset, &normal, EXPLOSION_FLECK_ANGULAR_SPRAY, EXPLOSION_FLECK_MIN_SPEED, EXPLOSION_FLECK_MAX_SPEED, EXPLOSION_FLECK_GRAVITY, EXPLOSION_FLECK_DAMPEN); PMaterialHandle *hMaterialArray; switch (materialType) { case 'C': case 'c': default: hMaterialArray = g_Mat_Fleck_Cement; break; } int numFlecks = random->RandomInt(48, 64); // Dump out flecks for (i = 0; i < numFlecks; i++) { FleckParticle *pParticle = (FleckParticle *) fleckEmitter->AddParticle(sizeof(FleckParticle), hMaterialArray[random->RandomInt(0, 1)], offset); if (pParticle == NULL) break; pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = 3.0f; dir[0] = normal[0] + random->RandomFloat(-EXPLOSION_FLECK_ANGULAR_SPRAY, EXPLOSION_FLECK_ANGULAR_SPRAY); dir[1] = normal[1] + random->RandomFloat(-EXPLOSION_FLECK_ANGULAR_SPRAY, EXPLOSION_FLECK_ANGULAR_SPRAY); dir[2] = normal[2] + random->RandomFloat(-EXPLOSION_FLECK_ANGULAR_SPRAY, EXPLOSION_FLECK_ANGULAR_SPRAY); pParticle->m_uchSize = random->RandomInt(2, 6); pParticle->m_vecVelocity = dir * (random->RandomFloat(EXPLOSION_FLECK_MIN_SPEED, EXPLOSION_FLECK_MAX_SPEED) * (7 - pParticle->m_uchSize)); pParticle->m_flRoll = random->RandomFloat(0, 360); pParticle->m_flRollDelta = random->RandomFloat(0, 360); float colorRamp = random->RandomFloat(0.75f, 1.5f); pParticle->m_uchColor[0] = MIN(1.0f, r*colorRamp)*255.0f; pParticle->m_uchColor[1] = MIN(1.0f, g*colorRamp)*255.0f; pParticle->m_uchColor[2] = MIN(1.0f, b*colorRamp)*255.0f; } } // Large sphere bursts CSmartPtr<CSimpleEmitter> pSimpleEmitter = CSimpleEmitter::Create("FX_Explosion 1"); PMaterialHandle hSphereMaterial = g_Mat_DustPuff[1]; Vector vecBurstOrigin = offset + normal * 8.0; pSimpleEmitter->SetSortOrigin(vecBurstOrigin); SimpleParticle *pSphereParticle = (SimpleParticle *) pSimpleEmitter->AddParticle(sizeof(SimpleParticle), hSphereMaterial, vecBurstOrigin); if (pSphereParticle) { pSphereParticle->m_flLifetime = 0.0f; pSphereParticle->m_flDieTime = 0.3f; pSphereParticle->m_uchStartAlpha = 150.0; pSphereParticle->m_uchEndAlpha = 64.0; pSphereParticle->m_uchStartSize = 0.0; pSphereParticle->m_uchEndSize = 255.0; pSphereParticle->m_vecVelocity = Vector(0, 0, 0); float colorRamp = random->RandomFloat(0.75f, 1.5f); pSphereParticle->m_uchColor[0] = MIN(1.0f, r*colorRamp)*255.0f; pSphereParticle->m_uchColor[1] = MIN(1.0f, g*colorRamp)*255.0f; pSphereParticle->m_uchColor[2] = MIN(1.0f, b*colorRamp)*255.0f; } // Throw some smoke balls out around the normal int numBalls = 12; Vector vecRight, vecForward, vecUp; QAngle vecAngles; VectorAngles(normal, vecAngles); AngleVectors(vecAngles, NULL, &vecRight, &vecUp); for (i = 0; i < numBalls; i++) { SimpleParticle *pParticle = (SimpleParticle *) pSimpleEmitter->AddParticle(sizeof(SimpleParticle), hSphereMaterial, vecBurstOrigin); if (pParticle) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = 0.25f; pParticle->m_uchStartAlpha = 128.0; pParticle->m_uchEndAlpha = 64.0; pParticle->m_uchStartSize = 16.0; pParticle->m_uchEndSize = 64.0; float flAngle = ((float) i * M_PI * 2) / numBalls; float x = cos(flAngle); float y = sin(flAngle); pParticle->m_vecVelocity = (vecRight*x + vecUp*y) * 1024.0; float colorRamp = random->RandomFloat(0.75f, 1.5f); pParticle->m_uchColor[0] = MIN(1.0f, r*colorRamp)*255.0f; pParticle->m_uchColor[1] = MIN(1.0f, g*colorRamp)*255.0f; pParticle->m_uchColor[2] = MIN(1.0f, b*colorRamp)*255.0f; } } // Create a couple of big, floating smoke clouds CSmartPtr<CSimpleEmitter> pSmokeEmitter = CSimpleEmitter::Create("FX_Explosion 2"); pSmokeEmitter->SetSortOrigin(offset); for (i = 0; i < 2; i++) { SimpleParticle *pParticle = (SimpleParticle *) pSmokeEmitter->AddParticle(sizeof(SimpleParticle), g_Mat_DustPuff[1], offset); if (pParticle == NULL) break; pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat(2.0f, 3.0f); pParticle->m_uchStartSize = 64; pParticle->m_uchEndSize = 255; dir[0] = normal[0] + random->RandomFloat(-0.8f, 0.8f); dir[1] = normal[1] + random->RandomFloat(-0.8f, 0.8f); dir[2] = normal[2] + random->RandomFloat(-0.8f, 0.8f); pParticle->m_vecVelocity = dir * random->RandomFloat(2.0f, 24.0f)*(i + 1); pParticle->m_uchStartAlpha = 160; pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomFloat(180, 360); pParticle->m_flRollDelta = random->RandomFloat(-1, 1); float colorRamp = random->RandomFloat(0.5f, 1.25f); pParticle->m_uchColor[0] = MIN(1.0f, r*colorRamp)*255.0f; pParticle->m_uchColor[1] = MIN(1.0f, g*colorRamp)*255.0f; pParticle->m_uchColor[2] = MIN(1.0f, b*colorRamp)*255.0f; } }