//----------------------------------------------------------------------------- // Purpose: // Input : &origin - // &normal - // scale - // r - // g - // b - // flags - //----------------------------------------------------------------------------- void FX_BloodSpray( const Vector &origin, const Vector &normal, float scale, unsigned char r, unsigned char g, unsigned char b, int flags ) { if ( UTIL_IsLowViolence() ) return; //debugoverlay->AddLineOverlay( origin, origin + normal * 72, 255, 255, 255, true, 10 ); Vector offset; float spread = 0.2f; //Find area ambient light color and use it to tint smoke Vector worldLight = WorldGetLightForPoint( origin, true ); Vector color = Vector( (float)(worldLight[0] * r) / 255.0f, (float)(worldLight[1] * g) / 255.0f, (float)(worldLight[2] * b) / 255.0f ); float colorRamp; int i; Vector offDir; Vector right; Vector up; if (normal != Vector(0, 0, 1) ) { right = normal.Cross( Vector(0, 0, 1) ); up = right.Cross( normal ); } else { right = Vector(0, 0, 1); up = right.Cross( normal ); } // // Dump out drops // if (flags & FX_BLOODSPRAY_DROPS) { TrailParticle *tParticle; CSmartPtr<CTrailParticles> pTrailEmitter = CTrailParticles::Create( "blooddrops" ); if ( !pTrailEmitter ) return; pTrailEmitter->SetSortOrigin( origin ); // Partial gravity on blood drops. pTrailEmitter->SetGravity( 600.0 ); pTrailEmitter->GetBinding().SetBBox( origin - Vector( 32, 32, 32 ), origin + Vector( 32, 32, 32 ) ); pTrailEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN ); pTrailEmitter->SetVelocityDampen( 0.2f ); PMaterialHandle hMaterial = ParticleMgr()->GetPMaterial( "effects/blood_drop" ); // // Long stringy drops of blood. // for ( i = 0; i < 14; i++ ) { // Originate from within a circle 'scale' inches in diameter. offset = origin; offset += right * random->RandomFloat( -0.5f, 0.5f ) * scale; offset += up * random->RandomFloat( -0.5f, 0.5f ) * scale; tParticle = (TrailParticle *) pTrailEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset ); if ( tParticle == NULL ) break; tParticle->m_flLifetime = 0.0f; offDir = normal + RandomVector( -0.3f, 0.3f ); tParticle->m_vecVelocity = offDir * random->RandomFloat( 4.0f * scale, 40.0f * scale ); tParticle->m_vecVelocity[2] += random->RandomFloat( 4.0f, 16.0f ) * scale; tParticle->m_flWidth = random->RandomFloat( 0.125f, 0.275f ) * scale; tParticle->m_flLength = random->RandomFloat( 0.02f, 0.03f ) * scale; tParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); FloatToColor32( tParticle->m_color, color[0], color[1], color[2], 1.0f ); } // // Shorter droplets. // for ( i = 0; i < 24; i++ ) { // Originate from within a circle 'scale' inches in diameter. offset = origin; offset += right * random->RandomFloat( -0.5f, 0.5f ) * scale; offset += up * random->RandomFloat( -0.5f, 0.5f ) * scale; tParticle = (TrailParticle *) pTrailEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset ); if ( tParticle == NULL ) break; tParticle->m_flLifetime = 0.0f; offDir = normal + RandomVector( -1.0f, 1.0f ); offDir[2] += random->RandomFloat(0, 1.0f); tParticle->m_vecVelocity = offDir * random->RandomFloat( 2.0f * scale, 25.0f * scale ); tParticle->m_vecVelocity[2] += random->RandomFloat( 4.0f, 16.0f ) * scale; tParticle->m_flWidth = random->RandomFloat( 0.25f, 0.375f ) * scale; tParticle->m_flLength = random->RandomFloat( 0.0025f, 0.005f ) * scale; tParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); FloatToColor32( tParticle->m_color, color[0], color[1], color[2], 1.0f ); } } if ((flags & FX_BLOODSPRAY_GORE) || (flags & FX_BLOODSPRAY_CLOUD)) { CSmartPtr<CBloodSprayEmitter> pSimple = CBloodSprayEmitter::Create( "bloodgore" ); if ( !pSimple ) return; pSimple->SetSortOrigin( origin ); pSimple->SetGravity( 0 ); PMaterialHandle hMaterial; // // Tight blossom of blood at the center. // if (flags & FX_BLOODSPRAY_GORE) { hMaterial = ParticleMgr()->GetPMaterial( "effects/blood_gore" ); SimpleParticle *pParticle; for ( i = 0; i < 6; i++ ) { // Originate from within a circle 'scale' inches in diameter. offset = origin + ( 0.5 * scale * normal ); offset += right * random->RandomFloat( -0.5f, 0.5f ) * scale; offset += up * random->RandomFloat( -0.5f, 0.5f ) * scale; pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), hMaterial, offset ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = 0.3f; spread = 0.2f; pParticle->m_vecVelocity.Random( -spread, spread ); pParticle->m_vecVelocity += normal * random->RandomInt( 10, 100 ); //VectorNormalize( pParticle->m_vecVelocity ); 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->RandomFloat( scale * 0.25, scale ); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 2; pParticle->m_uchStartAlpha = random->RandomInt( 200, 255 ); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = 0.0f; } } } // // Diffuse cloud just in front of the exit wound. // if (flags & FX_BLOODSPRAY_CLOUD) { hMaterial = ParticleMgr()->GetPMaterial( "effects/blood_puff" ); SimpleParticle *pParticle; for ( i = 0; i < 6; i++ ) { // Originate from within a circle '2 * scale' inches in diameter. offset = origin + ( scale * normal ); offset += right * random->RandomFloat( -1, 1 ) * scale; offset += up * random->RandomFloat( -1, 1 ) * scale; pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), hMaterial, offset ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.8f); spread = 0.5f; pParticle->m_vecVelocity.Random( -spread, spread ); pParticle->m_vecVelocity += normal * random->RandomInt( 100, 200 ); 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->RandomFloat( scale * 1.5f, scale * 2.0f ); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 4; pParticle->m_uchStartAlpha = random->RandomInt( 80, 128 ); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = 0.0f; } } } } // TODO: Play a sound? //CLocalPlayerFilter filter; //C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, CHAN_VOICE, "Physics.WaterSplash", 1.0, ATTN_NORM, 0, 100, &origin ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_WaterExplosionEffect::CreateMisc( void ) { Vector offset; float colorRamp; int i; float flScale = 2.0f; PMaterialHandle hMaterial = ParticleMgr()->GetPMaterial( "effects/splash2" ); #ifndef _XBOX int numDrops = 32; float length = 0.1f; Vector vForward, vRight, vUp; Vector offDir; TrailParticle *tParticle; CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create( "splash" ); if ( !sparkEmitter ) return; sparkEmitter->SetSortOrigin( m_vecWaterSurface ); sparkEmitter->m_ParticleCollision.SetGravity( 800.0f ); sparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN ); sparkEmitter->SetVelocityDampen( 2.0f ); //Dump out drops for ( i = 0; i < numDrops; i++ ) { offset = m_vecWaterSurface; offset[0] += random->RandomFloat( -16.0f, 16.0f ) * flScale; offset[1] += random->RandomFloat( -16.0f, 16.0f ) * flScale; tParticle = (TrailParticle *) sparkEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset ); if ( tParticle == NULL ) break; tParticle->m_flLifetime = 0.0f; tParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); offDir = Vector(0,0,1) + RandomVector( -1.0f, 1.0f ); tParticle->m_vecVelocity = offDir * random->RandomFloat( 50.0f * flScale * 2.0f, 100.0f * flScale * 2.0f ); tParticle->m_vecVelocity[2] += random->RandomFloat( 32.0f, 128.0f ) * flScale; tParticle->m_flWidth = clamp( random->RandomFloat( 1.0f, 3.0f ) * flScale, 0.1f, 4.0f ); tParticle->m_flLength = random->RandomFloat( length*0.25f, length )/* * flScale*/; colorRamp = random->RandomFloat( 1.5f, 2.0f ); FloatToColor32( tParticle->m_color, min( 1.0f, m_vecColor[0] * colorRamp ), min( 1.0f, m_vecColor[1] * colorRamp ), min( 1.0f, m_vecColor[2] * colorRamp ), m_flLuminosity ); } //Dump out drops for ( i = 0; i < 4; i++ ) { offset = m_vecWaterSurface; offset[0] += random->RandomFloat( -16.0f, 16.0f ) * flScale; offset[1] += random->RandomFloat( -16.0f, 16.0f ) * flScale; tParticle = (TrailParticle *) sparkEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset ); if ( tParticle == NULL ) break; tParticle->m_flLifetime = 0.0f; tParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f ); offDir = Vector(0,0,1) + RandomVector( -0.2f, 0.2f ); tParticle->m_vecVelocity = offDir * random->RandomFloat( 50 * flScale * 3.0f, 100 * flScale * 3.0f ); tParticle->m_vecVelocity[2] += random->RandomFloat( 32.0f, 128.0f ) * flScale; tParticle->m_flWidth = clamp( random->RandomFloat( 2.0f, 3.0f ) * flScale, 0.1f, 4.0f ); tParticle->m_flLength = random->RandomFloat( length*0.25f, length )/* * flScale*/; colorRamp = random->RandomFloat( 1.5f, 2.0f ); FloatToColor32( tParticle->m_color, min( 1.0f, m_vecColor[0] * colorRamp ), min( 1.0f, m_vecColor[1] * colorRamp ), min( 1.0f, m_vecColor[2] * colorRamp ), m_flLuminosity ); } #endif CSmartPtr<CSplashParticle> pSimple = CSplashParticle::Create( "splish" ); pSimple->SetSortOrigin( m_vecWaterSurface ); pSimple->SetClipHeight( m_vecWaterSurface.z ); pSimple->GetBinding().SetBBox( m_vecWaterSurface-(Vector(32.0f, 32.0f, 32.0f)*flScale), m_vecWaterSurface+(Vector(32.0f, 32.0f, 32.0f)*flScale) ); SimpleParticle *pParticle; for ( i = 0; i < 16; i++ ) { pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), hMaterial, m_vecWaterSurface ); if ( pParticle == NULL ) break; pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = 2.0f; //NOTENOTE: We use a clip plane to realistically control our lifespan pParticle->m_vecVelocity.Random( -0.2f, 0.2f ); pParticle->m_vecVelocity += ( Vector( 0, 0, random->RandomFloat( 4.0f, 6.0f ) ) ); VectorNormalize( pParticle->m_vecVelocity ); pParticle->m_vecVelocity *= 50 * flScale * (8-i); colorRamp = random->RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = min( 1.0f, m_vecColor[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = min( 1.0f, m_vecColor[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = min( 1.0f, m_vecColor[2] * colorRamp ) * 255.0f; pParticle->m_uchStartSize = 24 * flScale * RemapValClamped( i, 7, 0, 1, 0.5f ); pParticle->m_uchEndSize = min( 255, pParticle->m_uchStartSize * 2 ); pParticle->m_uchStartAlpha = RemapValClamped( i, 7, 0, 255, 32 ) * m_flLuminosity; pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -4.0f, 4.0f ); } }
//----------------------------------------------------------------------------- // Purpose: Used for bullets hitting bleeding surfaces // Input : origin - // normal - // scale - This parameter is not currently used //----------------------------------------------------------------------------- void FX_BloodBulletImpact( const Vector &origin, const Vector &normal, float scale /*NOTE: Unused!*/, unsigned char r, unsigned char g, unsigned char b ) { if ( UTIL_IsLowViolence() ) return; Vector offset; //Find area ambient light color and use it to tint smoke Vector worldLight = WorldGetLightForPoint( origin, true ); if ( gpGlobals->maxClients > 1 ) { worldLight = Vector( 1.0, 1.0, 1.0 ); r = 96; g = 0; b = 10; } Vector color = Vector( (float)(worldLight[0] * r) / 255.0f, (float)(worldLight[1] * g) / 255.0f, (float)(worldLight[2] * b) / 255.0f ); float colorRamp; Vector offDir; CSmartPtr<CBloodSprayEmitter> pSimple = CBloodSprayEmitter::Create( "bloodgore" ); if ( !pSimple ) return; pSimple->SetSortOrigin( origin ); pSimple->SetGravity( 200 ); // Setup a bounding box to contain the particles without (stops auto-updating) pSimple->GetBinding().SetBBox( origin - Vector( 16, 16, 16 ), origin + Vector( 16, 16, 16 ) ); // Cache the material if we haven't already if ( g_Blood_Core == NULL ) { g_Blood_Core = ParticleMgr()->GetPMaterial( "effects/blood_core" ); } SimpleParticle *pParticle; Vector dir = normal * RandomVector( -0.5f, 0.5f ); offset = origin + ( 2.0f * normal ); pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Blood_Core, offset ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f); pParticle->m_vecVelocity = dir * random->RandomFloat( 16.0f, 32.0f ); pParticle->m_vecVelocity[2] -= random->RandomFloat( 8.0f, 16.0f ); colorRamp = random->RandomFloat( 0.75f, 2.0f ); 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 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 8; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = 0.0f; } // Cache the material if we haven't already if ( g_Blood_Gore == NULL ) { g_Blood_Gore = ParticleMgr()->GetPMaterial( "effects/blood_gore" ); } for ( int i = 0; i < 4; i++ ) { offset = origin + ( 2.0f * normal ); pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Blood_Gore, offset ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.75f); pParticle->m_vecVelocity = dir * random->RandomFloat( 16.0f, 32.0f )*(i+1); pParticle->m_vecVelocity[2] -= random->RandomFloat( 32.0f, 64.0f )*(i+1); colorRamp = random->RandomFloat( 0.75f, 2.0f ); 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 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 4; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = 0.0f; } } // // Dump out drops // TrailParticle *tParticle; CSmartPtr<CTrailParticles> pTrailEmitter = CTrailParticles::Create( "blooddrops" ); if ( !pTrailEmitter ) return; pTrailEmitter->SetSortOrigin( origin ); // Partial gravity on blood drops pTrailEmitter->SetGravity( 400.0 ); // Enable simple collisions with nearby surfaces pTrailEmitter->Setup(origin, &normal, 1, 10, 100, 400, 0.2, 0 ); if ( g_Blood_Drops == NULL ) { g_Blood_Drops = ParticleMgr()->GetPMaterial( "effects/blood_drop" ); } // // Shorter droplets // for ( int i = 0; i < 8; i++ ) { // Originate from within a circle 'scale' inches in diameter offset = origin; tParticle = (TrailParticle *) pTrailEmitter->AddParticle( sizeof(TrailParticle), g_Blood_Drops, offset ); if ( tParticle == NULL ) break; tParticle->m_flLifetime = 0.0f; offDir = RandomVector( -1.0f, 1.0f ); tParticle->m_vecVelocity = offDir * random->RandomFloat( 64.0f, 128.0f ); tParticle->m_flWidth = random->RandomFloat( 0.5f, 2.0f ); tParticle->m_flLength = random->RandomFloat( 0.05f, 0.15f ); tParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f ); FloatToColor32( tParticle->m_color, color[0], color[1], color[2], 1.0f ); } // TODO: Play a sound? //CLocalPlayerFilter filter; //C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, CHAN_VOICE, "Physics.WaterSplash", 1.0, ATTN_NORM, 0, 100, &origin ); }
//----------------------------------------------------------------------------- // Purpose: // Input : origin - // normal - //----------------------------------------------------------------------------- void FX_ConcussiveExplosion(Vector &origin, Vector &normal) { VPROF_BUDGET("FX_ConcussiveExplosion", VPROF_BUDGETGROUP_PARTICLE_RENDERING); Vector offset = origin + (normal * 2.0f); Vector dir; int i; // // Smoke // CSmartPtr<CSimpleEmitter> pSmokeEmitter = CSimpleEmitter::Create("FX_ConcussiveExplosion 1"); pSmokeEmitter->SetSortOrigin(offset); //Quick moving sprites for (i = 0; i < 16; i++) { SimpleParticle *pParticle = (SimpleParticle *) pSmokeEmitter->AddParticle(sizeof(SimpleParticle), g_Mat_DustPuff[1], offset); if (pParticle == NULL) return; pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat(0.2f, 0.4f); pParticle->m_uchStartSize = random->RandomInt(4, 8); pParticle->m_uchEndSize = random->RandomInt(32, 64); dir[0] = random->RandomFloat(-1.0f, 1.0f); dir[1] = random->RandomFloat(-1.0f, 1.0f); dir[2] = random->RandomFloat(-1.0f, 1.0f); pParticle->m_vecVelocity = dir * random->RandomFloat(64.0f, 128.0f); pParticle->m_uchStartAlpha = random->RandomInt(64, 128); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomFloat(180, 360); pParticle->m_flRollDelta = random->RandomFloat(-4, 4); int colorRamp = random->RandomFloat(235, 255); pParticle->m_uchColor[0] = colorRamp; pParticle->m_uchColor[1] = colorRamp; pParticle->m_uchColor[2] = colorRamp; } //Slow lingering sprites for (i = 0; i < 2; i++) { SimpleParticle *pParticle = (SimpleParticle *) pSmokeEmitter->AddParticle(sizeof(SimpleParticle), g_Mat_DustPuff[1], offset); if (pParticle == NULL) return; pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat(1.0f, 2.0f); pParticle->m_uchStartSize = random->RandomInt(32, 64); pParticle->m_uchEndSize = random->RandomInt(100, 128); 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(16.0f, 32.0f); pParticle->m_uchStartAlpha = random->RandomInt(32, 64); pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomFloat(180, 360); pParticle->m_flRollDelta = random->RandomFloat(-1, 1); int colorRamp = random->RandomFloat(235, 255); pParticle->m_uchColor[0] = colorRamp; pParticle->m_uchColor[1] = colorRamp; pParticle->m_uchColor[2] = colorRamp; } // // Quick sphere // CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create("FX_ConcussiveExplosion 2"); pSimple->SetSortOrigin(offset); SimpleParticle *pParticle = (SimpleParticle *) pSimple->AddParticle(sizeof(SimpleParticle), pSimple->GetPMaterial("effects/blueflare1"), offset); if (pParticle) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = 0.1f; pParticle->m_vecVelocity.Init(); pParticle->m_flRoll = random->RandomFloat(180, 360); pParticle->m_flRollDelta = random->RandomFloat(-1, 1); pParticle->m_uchColor[0] = pParticle->m_uchColor[1] = pParticle->m_uchColor[2] = 128; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 0; pParticle->m_uchStartSize = 16; pParticle->m_uchEndSize = 64; } pParticle = (SimpleParticle *) pSimple->AddParticle(sizeof(SimpleParticle), pSimple->GetPMaterial("effects/blueflare1"), offset); if (pParticle) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = 0.2f; pParticle->m_vecVelocity.Init(); pParticle->m_flRoll = random->RandomFloat(180, 360); pParticle->m_flRollDelta = random->RandomFloat(-1, 1); pParticle->m_uchColor[0] = pParticle->m_uchColor[1] = pParticle->m_uchColor[2] = 32; pParticle->m_uchStartAlpha = 64; pParticle->m_uchEndAlpha = 0; pParticle->m_uchStartSize = 64; pParticle->m_uchEndSize = 128; } // // Dlight // dlight_t *dl = effects->CL_AllocDlight(0); dl->origin = offset; dl->color.r = dl->color.g = dl->color.b = 64; dl->radius = random->RandomFloat(128, 256); dl->die = gpGlobals->curtime + 0.1; // // Moving lines // TrailParticle *pTrailParticle; CSmartPtr<CTrailParticles> pSparkEmitter = CTrailParticles::Create("FX_ConcussiveExplosion 3"); PMaterialHandle hMaterial; int numSparks; if (pSparkEmitter.IsValid()) { hMaterial = pSparkEmitter->GetPMaterial("effects/blueflare1"); pSparkEmitter->SetSortOrigin(offset); pSparkEmitter->m_ParticleCollision.SetGravity(0.0f); numSparks = random->RandomInt(16, 32); //Dump out sparks for (i = 0; i < numSparks; i++) { pTrailParticle = (TrailParticle *) pSparkEmitter->AddParticle(sizeof(TrailParticle), hMaterial, offset); if (pTrailParticle == NULL) return; pTrailParticle->m_flLifetime = 0.0f; dir.Random(-1.0f, 1.0f); pTrailParticle->m_flWidth = random->RandomFloat(1.0f, 2.0f); pTrailParticle->m_flLength = random->RandomFloat(0.01f, 0.1f); pTrailParticle->m_flDieTime = random->RandomFloat(0.1f, 0.2f); pTrailParticle->m_vecVelocity = dir * random->RandomFloat(800, 1000); float colorRamp = random->RandomFloat(0.75f, 1.0f); FloatToColor32(pTrailParticle->m_color, colorRamp, colorRamp, 1.0f, 1.0f); } } //Moving particles CSmartPtr<CTrailParticles> pCollisionEmitter = CTrailParticles::Create("FX_ConcussiveExplosion 4"); if (pCollisionEmitter.IsValid()) { //Setup our collision information pCollisionEmitter->Setup((Vector &) offset, NULL, SPARK_ELECTRIC_SPREAD, SPARK_ELECTRIC_MINSPEED * 6, SPARK_ELECTRIC_MAXSPEED * 6, -400, SPARK_ELECTRIC_DAMPEN, bitsPARTICLE_TRAIL_FADE); pCollisionEmitter->SetSortOrigin(offset); numSparks = random->RandomInt(8, 16); hMaterial = pCollisionEmitter->GetPMaterial("effects/blueflare1"); //Dump out sparks for (i = 0; i < numSparks; i++) { pTrailParticle = (TrailParticle *) pCollisionEmitter->AddParticle(sizeof(TrailParticle), hMaterial, offset); if (pTrailParticle == NULL) return; pTrailParticle->m_flLifetime = 0.0f; dir.Random(-1.0f, 1.0f); dir[2] = random->RandomFloat(0.0f, 0.75f); pTrailParticle->m_flWidth = random->RandomFloat(1.0f, 2.0f); pTrailParticle->m_flLength = random->RandomFloat(0.01f, 0.1f); pTrailParticle->m_flDieTime = random->RandomFloat(0.2f, 1.0f); pTrailParticle->m_vecVelocity = dir * random->RandomFloat(128, 512); float colorRamp = random->RandomFloat(0.75f, 1.0f); FloatToColor32(pTrailParticle->m_color, colorRamp, colorRamp, 1.0f, 1.0f); } } }