//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_FireSmoke::UpdateEffects( void ) { if ( m_pEmberEmitter.IsValid() ) { m_pEmberEmitter->SetSortOrigin( GetAbsOrigin() ); } if ( m_pSmokeEmitter.IsValid() ) { m_pSmokeEmitter->SetSortOrigin( GetAbsOrigin() ); } if ( m_pFireOverlay != NULL ) { m_pFireOverlay->m_vPos = GetAbsOrigin(); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_RotorWashEmitter::InitSpawner( void ) { if ( m_pSimple.IsValid() ) return; m_pSimple = WashEmitter::Create( "wash" ); m_pSimple->SetNearClip( 128, 256 ); }
//----------------------------------------------------------------------------- // Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool C_WeaponPhysCannon::SetupEmitter( void ) { if ( !m_pLocalEmitter.IsValid() ) { m_pLocalEmitter = CLocalSpaceEmitter::Create( "physpowerup", GetRefEHandle(), LookupAttachment( "core" ) ); if ( m_pLocalEmitter.IsValid() == false ) return false; } if ( !m_pAttractor.IsValid() ) { m_pAttractor = CParticleAttractor::Create( vec3_origin, "physpowerup_att" ); if ( m_pAttractor.IsValid() == false ) return false; } if ( !m_pEmitter.IsValid() ) { m_pEmitter = CSimpleEmitter::Create( "physpowerup_glow" ); if ( m_pEmitter.IsValid() == false ) return false; } return true; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool C_EnvPortalPathTrack::SetupEmitters( void ) { // Setup the basic core emitter if ( m_pSimpleEmitter.IsValid() == false ) { m_pSimpleEmitter = CSimpleEmitter::Create( "portaltracktrainendpoint" ); if ( m_pSimpleEmitter.IsValid() == false ) return false; } // Setup the attractor emitter if ( m_pAttractorEmitter.IsValid() == false ) { m_pAttractorEmitter = CParticleAttractor::Create( GetAbsOrigin(), "portaltracktrainendpointattractor" ); if ( m_pAttractorEmitter.IsValid() == false ) return false; } return true; }
//----------------------------------------------------------------------------- // Purpose: Setup the emitters we'll be using //----------------------------------------------------------------------------- bool C_HopwireExplosion::SetupEmitters( void ) { // Setup the basic core emitter if ( m_pSimpleEmitter.IsValid() == false ) { m_pSimpleEmitter = CSimpleEmitter::Create( "hopwirecore" ); if ( m_pSimpleEmitter.IsValid() == false ) return false; } // Setup the attractor emitter if ( m_pAttractorEmitter.IsValid() == false ) { m_pAttractorEmitter = CParticleAttractor::Create( GetRenderOrigin(), "hopwireattractor" ); if ( m_pAttractorEmitter.IsValid() == false ) return false; } return true; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool C_AlyxEmpEffect::SetupEmitters( void ) { // Setup the basic core emitter if ( m_pSimpleEmitter.IsValid() == false ) { m_pSimpleEmitter = CSimpleEmitter::Create( "energycore" ); if ( m_pSimpleEmitter.IsValid() == false ) return false; } // Setup the attractor emitter if ( m_pAttractorEmitter.IsValid() == false ) { m_pAttractorEmitter = CParticleAttractor::Create( GetAbsOrigin(), "energyattractor" ); if ( m_pAttractorEmitter.IsValid() == false ) return false; } return true; }
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 ); } }
//----------------------------------------------------------------------------- // Purpose: Called when data changes on the server //----------------------------------------------------------------------------- void C_Sparkler::OnDataChanged( DataUpdateType_t updateType ) { // NOTE: We MUST call the base classes' implementation of this function BaseClass::OnDataChanged( updateType ); // Setup our entity's particle system on creation if ( updateType == DATA_UPDATE_CREATED ) { // Creat the emitter m_hEmitter = CSimpleEmitter::Create( "env_sparkler" ); // Obtain a reference handle to our particle's desired material if ( m_hEmitter.IsValid() ) { m_hMaterial = m_hEmitter->GetPMaterial( "effects/yellowflare" ); } // Spawn 128 particles per second m_tParticleTimer.Init( 128 ); // Call our ClientThink() function once every client frame SetNextClientThink( CLIENT_THINK_ALWAYS ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_RotorWashEmitter::ClientThink( void ) { SetNextClientThink( gpGlobals->curtime + ROTORWASH_THINK_INTERVAL ); trace_t tr; UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin()+(Vector(0, 0, -1024)), (MASK_SOLID_BRUSHONLY|CONTENTS_WATER|CONTENTS_SLIME), NULL, COLLISION_GROUP_NONE, &tr ); if ( /*!m_bIgnoreSolid && */(tr.fraction == 1.0f || tr.startsolid || tr.allsolid) ) return; // If we hit the skybox, don't do it either if ( tr.surface.flags & SURF_SKY ) return; float heightScale = RemapValClamped( tr.fraction * 1024, 512, 1024, 1.0f, 0.0f ); Vector vecDustColor; if ( tr.contents & CONTENTS_WATER ) { vecDustColor.x = 0.8f; vecDustColor.y = 0.8f; vecDustColor.z = 0.75f; } else if ( tr.contents & CONTENTS_SLIME ) { vecDustColor.x = 0.6f; vecDustColor.y = 0.5f; vecDustColor.z = 0.15f; } else { vecDustColor.x = 0.35f; vecDustColor.y = 0.3f; vecDustColor.z = 0.25f; } #ifndef _XBOX InitSpawner(); if ( m_pSimple.IsValid() == false ) return; m_pSimple->SetSortOrigin( GetAbsOrigin() ); PMaterialHandle *hMaterial; // Cache and set our material based on the surface we're over (ie. water) if ( tr.contents & (CONTENTS_WATER|CONTENTS_SLIME) ) { if ( m_hWaterMaterial[0] == NULL ) { m_hWaterMaterial[0] = m_pSimple->GetPMaterial("effects/splash1"); m_hWaterMaterial[1] = m_pSimple->GetPMaterial("effects/splash2"); } hMaterial = m_hWaterMaterial; } else { hMaterial = g_Mat_DustPuff; } #endif // !XBOX // If we're above water, make ripples if ( tr.contents & (CONTENTS_WATER|CONTENTS_SLIME) ) { float flScale = random->RandomFloat( 7.5f, 8.5f ); Vector color = Vector( 0.8f, 0.8f, 0.75f ); Vector startPos = tr.endpos + Vector(0,0,8); Vector endPos = tr.endpos + Vector(0,0,-64); if ( tr.fraction < 1.0f ) { //Add a ripple quad to the surface FX_AddQuad( tr.endpos + ( tr.plane.normal * 0.5f ), tr.plane.normal, 64.0f * flScale, 128.0f * flScale, 0.8f, 0.75f * heightScale, 0.0f, 0.75f, random->RandomFloat( 0, 360 ), random->RandomFloat( -2.0f, 2.0f ), vecDustColor, 0.2f, "effects/splashwake3", (FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) ); } } #ifndef _XBOX int numRingSprites = 32; float yaw = random->RandomFloat( 0, 2*M_PI ); // Randomly placed on the unit circle float yawIncr = (2*M_PI) / numRingSprites; Vector vecForward; Vector offset; SimpleParticle *pParticle; // Draw the rings for ( int i = 0; i < numRingSprites; i++ ) { // Get our x,y on the unit circle SinCos( yaw, &vecForward.y, &vecForward.x ); // Increment ahead yaw += yawIncr; // @NOTE toml (3-28-07): broke out following expression because vc2005 optimizer was screwing up in presence of SinCos inline assembly. Would also // go away if offset were referenced below as in the AddLineOverlay() //offset = ( RandomVector( -4.0f, 4.0f ) + tr.endpos ) + ( vecForward * 128.0f ); offset = vecForward * 128.0f; offset += tr.endpos + RandomVector( -4.0f, 4.0f ); pParticle = (SimpleParticle *) m_pSimple->AddParticle( sizeof(SimpleParticle), hMaterial[random->RandomInt(0,1)], offset ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = random->RandomFloat( 0.25f, 1.0f ); pParticle->m_vecVelocity = vecForward * random->RandomFloat( 1000, 1500 ); #if __EXPLOSION_DEBUG debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 ); #endif if ( tr.contents & CONTENTS_SLIME ) { vecDustColor.x = random->RandomFloat( 0.4f, 0.6f ); vecDustColor.y = random->RandomFloat( 0.3f, 0.5f ); vecDustColor.z = random->RandomFloat( 0.1f, 0.2f ); } pParticle->m_uchColor[0] = vecDustColor.x * 255.0f; pParticle->m_uchColor[1] = vecDustColor.y * 255.0f; pParticle->m_uchColor[2] = vecDustColor.z * 255.0f; pParticle->m_uchStartSize = random->RandomInt( 16, 64 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 4; pParticle->m_uchStartAlpha = random->RandomFloat( 16, 32 ) * heightScale; pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta = random->RandomFloat( -16.0f, 16.0f ); } } #endif // !XBOX }
//----------------------------------------------------------------------------- // Purpose: // Input : fTimeDelta - //----------------------------------------------------------------------------- void C_ExtinguisherJet::Update( float fTimeDelta ) { if ( m_bEmit == false ) return; C_BasePlayer *player = C_BasePlayer::GetLocalPlayer(); if ( m_bUseMuzzlePoint ) { C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL; if ( vm ) { int iAttachment = vm->LookupAttachment( "muzzle" ); Vector origin; QAngle angles; vm->GetAttachment( iAttachment, origin, angles ); Assert( !GetMoveParent() ); SetLocalOrigin( origin ); SetLocalAngles( angles ); } } trace_t tr; Vector shotDir, vRight, vUp; AngleVectors( GetAbsAngles(), &shotDir, &vRight, &vUp ); //FIXME: Muzzle point is incorrect on the model! if ( m_bUseMuzzlePoint ) { shotDir.Negate(); } Vector endPoint = GetAbsOrigin() + ( shotDir * 150.0f ); UTIL_TraceLine( GetAbsOrigin(), endPoint, MASK_SHOT, NULL, COLLISION_GROUP_NONE, &tr ); bool hitWall = ( tr.fraction < 1.0f ); //Add normal jet if ( m_pEmitter.IsValid() ) { SimpleParticle *pParticle; m_pEmitter->SetSortOrigin( GetAbsOrigin() ); float tempDelta = fTimeDelta; //FIXME: All particles need to be within this loop while( m_ParticleSpawn.NextEvent( tempDelta ) ) { pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, GetAbsOrigin() ); if ( pParticle ) { pParticle->m_flDieTime = 0.2f; pParticle->m_flLifetime = 0.0f; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta= random->RandomFloat( -4.0f, 4.0f ); pParticle->m_uchStartSize = 1; pParticle->m_uchEndSize = random->RandomInt( 32, 48 ); pParticle->m_uchStartAlpha = random->RandomInt( 128, 164 ); pParticle->m_uchEndAlpha = 0; int cScale = random->RandomInt( 192, 255 ); pParticle->m_uchColor[0] = cScale; pParticle->m_uchColor[1] = cScale; pParticle->m_uchColor[2] = cScale; Vector dir; QAngle ofsAngles; ofsAngles.Random( -8.0f, 8.0f ); ofsAngles += GetAbsAngles(); AngleVectors( ofsAngles, &dir ); if ( m_bUseMuzzlePoint ) { dir.Negate(); } pParticle->m_vecVelocity = dir * random->RandomInt( 400, 800 ); } //Add muzzle effect pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, GetAbsOrigin() ); if ( pParticle ) { pParticle->m_flDieTime = 0.1f; pParticle->m_flLifetime = 0.0f; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta= random->RandomFloat( -4.0f, 4.0f ); pParticle->m_uchStartSize = 1; pParticle->m_uchEndSize = random->RandomInt( 8, 16 ); pParticle->m_uchStartAlpha = random->RandomInt( 128, 255 ); pParticle->m_uchEndAlpha = 0; int cScale = random->RandomInt( 192, 255 ); pParticle->m_uchColor[0] = cScale; pParticle->m_uchColor[1] = cScale; pParticle->m_uchColor[2] = cScale; Vector dir; QAngle ofsAngles; ofsAngles.Random( -64.0f, 64.0f ); ofsAngles += GetAbsAngles(); AngleVectors( ofsAngles, &dir ); if ( m_bUseMuzzlePoint ) { dir.Negate(); } pParticle->m_vecVelocity = dir * random->RandomInt( 32, 64 ); } //Add a wall effect if needed if ( hitWall ) { AddExtinguisherDecal( tr ); Vector offDir; offDir.Random( -16.0f, 16.0f ); pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, ( tr.endpos + ( tr.plane.normal * 8.0f ) ) + offDir ); if ( pParticle ) { pParticle->m_flDieTime = 0.4f; pParticle->m_flLifetime = 0.0f; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta= random->RandomFloat( -2.0f, 2.0f ); pParticle->m_uchStartSize = random->RandomInt( 8, 16 ); pParticle->m_uchEndSize = random->RandomInt( 24, 32 ); pParticle->m_uchStartAlpha = random->RandomInt( 64, 128 ); pParticle->m_uchEndAlpha = 0; int cScale = random->RandomInt( 192, 255 ); pParticle->m_uchColor[0] = cScale; pParticle->m_uchColor[1] = cScale; pParticle->m_uchColor[2] = cScale; Vector rDir; rDir = tr.plane.normal; rDir[0] += random->RandomFloat( -0.9f, 0.9f ); rDir[1] += random->RandomFloat( -0.9f, 0.9f ); rDir[2] += random->RandomFloat( -0.9f, 0.9f ); pParticle->m_vecVelocity = rDir * random->RandomInt( 32, 64 ); } } //Add small ember-like particles if ( random->RandomInt( 0, 1 ) == 0 ) { m_pEmberEmitter->SetSortOrigin( GetAbsOrigin() ); pParticle = (SimpleParticle *) m_pEmberEmitter->AddParticle( sizeof(SimpleParticle), m_pEmberEmitter->GetPMaterial( "particle/particle_smokegrenade" ), GetAbsOrigin() ); assert(pParticle); if ( pParticle ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = 1.0f; pParticle->m_flRoll = 0; pParticle->m_flRollDelta = 0; pParticle->m_uchColor[0] = 255; pParticle->m_uchColor[1] = 255; pParticle->m_uchColor[2] = 255; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 0; pParticle->m_uchStartSize = 1; pParticle->m_uchEndSize = 0; Vector dir; QAngle ofsAngles; ofsAngles.Random( -8.0f, 8.0f ); ofsAngles += GetAbsAngles(); AngleVectors( ofsAngles, &dir ); if ( m_bUseMuzzlePoint ) { dir.Negate(); } pParticle->m_vecVelocity = dir * random->RandomInt( 400, 800 ); } } } } // Inner beam CBeamSegDraw beamDraw; CBeamSeg seg; const int numPoints = 4; Vector beamPoints[numPoints]; beamPoints[0] = GetAbsOrigin(); // Create our beam points int i; for ( i = 0; i < numPoints; i++ ) { beamPoints[i] = GetAbsOrigin() + ( shotDir * (32*i*i) ); beamPoints[i] += vRight * sin( gpGlobals->curtime * 4.0f ) * (2.0f*i); beamPoints[i] += vUp * sin( gpGlobals->curtime * 8.0f ) * (1.0f*i); beamPoints[i] += shotDir * sin( gpGlobals->curtime * (16.0f*i) ) * (1.0f*i); } IMaterial *pMat = materials->FindMaterial( "particle/particle_smokegrenade", NULL ); beamDraw.Start( numPoints, pMat ); //Setup and draw those points for( i = 0; i < numPoints; i++ ) { float t = (float) i / (numPoints - 1); float color = 1.0f * (1.0f - t); seg.m_vColor = Vector( color, color, color ); seg.m_vPos = beamPoints[i]; seg.m_flTexCoord = (float)i/(float)(numPoints-1) - ((gpGlobals->curtime - (int)gpGlobals->curtime) * 4.0f ); seg.m_flWidth = 4.0f + ( (64.0f*t) * (fabs( sin( gpGlobals->curtime * 16.0f ) )) ); seg.m_flAlpha = color; beamDraw.NextSeg( &seg ); } beamDraw.End(); }
//----------------------------------------------------------------------------- // 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); } } }