DroneDamageFlare.cs
using Sandbox;
using System;
namespace PaintballBaddies;
// Native particles reused from shield shatter: small sparks and a brief falling airframe.
public sealed class DroneDamageFlare : Component
{
private float age;
private bool finished;
private int seed;
private float intensity=1;
public static void Spawn(Scene scene,Vector3 point,Color tint,bool finish,int seed,float intensity=1)
{
foreach(var old in scene.GetAllComponents<DroneDamageFlare>().OrderByDescending(x=>x.age).SkipLast(5).ToArray())old.GameObject.Destroy();
var go=new GameObject(false,"Drone damage flare"){WorldPosition=point,NetworkMode=NetworkMode.Never};go.Tags.Add("paintball_debris");
var effect=go.Components.Create<DroneDamageFlare>();effect.finished=finish;effect.seed=seed;effect.intensity=intensity.Clamp(.1f,1);go.Enabled=true;
}
protected override void OnStart()
{
int count=(int)MathF.Ceiling((finished ? 32 : 18)*intensity);
float life=.2f+.35f*intensity;
var sparks=Components.Create<ParticleEffect>();sparks.MaxParticles=count;sparks.Lifetime=life;sparks.LocalSpace=0;
sparks.ApplyAlpha=false;sparks.ApplyColor=false;sparks.ApplyRotation=false;sparks.ApplyShape=false;sparks.Collision=false;
sparks.Force=true;sparks.ForceDirection=Vector3.Down*250;sparks.ForceScale=1;sparks.ForceSpace=ParticleEffect.SimulationSpace.World;
var render=Components.Create<ParticleSpriteRenderer>();render.Sprite=new Sprite{Animations=[new Sprite.Animation{Name="Default",Frames=[new Sprite.Frame{Texture=Texture.Load("textures/particles/spark_white.vtex")}]}]};
render.Additive=true;render.Lighting=false;render.Shadows=false;render.Scale=1;
sparks.OnStep=(p,dt)=>p.Alpha=((life-p.Age)/(life*.75f)).Clamp(0,1);
for(int i=0;i<count;i++)
{
var direction=new Vector3(MathF.Cos(i*2.399f+seed),MathF.Sin(i*2.399f+seed),.4f+(i%4)*.2f).Normal;
var p=sparks.Emit(WorldPosition+direction*(2+6*intensity),0);p.Size=new Vector3(.5f+intensity);p.Color=(i%3==0 ? new Color(.4f,.75f,1) : new Color(1,.6f,.1f))*(1+2*intensity);
p.Velocity=direction*(finished ? 175 : 105)*(.55f+.45f*intensity);
}
}
protected override void OnUpdate(){age+=Time.Delta;if(age>1.65f)GameObject.Destroy();}
}