PopRiotTarget.Crash.cs
using Sandbox;
using System;
namespace PaintballBaddies;
public sealed partial class PopRiotTarget
{
[Sync(SyncFlags.FromHost)] public bool Crashing {get;private set;}
[Sync(SyncFlags.FromHost)] public float CrashSeconds {get;private set;}
[Sync(SyncFlags.FromHost)] public Vector3 CrashVelocity {get;private set;}
private bool crashFinished,crashSoundStarted;
private float crashFlare;
private SoundHandle malfunction;
private void BeginCrash()
{
Crashing=true;Charging=Entering=false;AttackTarget=null;
CrashVelocity=FlightVelocity.WithZ(0)*.45f+Rotation.FromYaw(Seed*137).Forward*(100+Seed%5*12)+Vector3.Up*60;
NetworkEffects.RiotDroneFlare(WorldPosition,PaintTint,false,Round,Seed);
}
private void UpdateCrash()
{
if(!crashSoundStarted)
{
crashSoundStarted=true;malfunction=DroneAudio.Play("malfunction",WorldPosition);
}
if(malfunction is not null){malfunction.Position=WorldPosition;malfunction.Pitch=MathF.Max(.5f,1.2f-CrashSeconds*.35f);}
crashFlare-=Time.Delta;
if(crashFlare<=0){DroneDamageFlare.Spawn(Scene,WorldPosition,PaintTint,false,Seed);crashFlare=.18f;}
if(!MultiplayerSession.Authority || crashFinished)return;
var session=MultiplayerSession.Find(Scene);
if(!session.IsValid() || !session.InRound || session.RoundId!=Round){GameObject.Destroy();return;}
CrashSeconds+=Time.Delta;
float turn=(Seed%2==0 ? 1 : -1)*(100+Seed%4*25);
CrashVelocity=Rotation.FromYaw(turn*Time.Delta)*CrashVelocity.WithZ(0)+Vector3.Up*(CrashVelocity.z-260*Time.Delta);
var end=WorldPosition+CrashVelocity*Time.Delta;
var hit=Scene.Trace.Sphere(20,WorldPosition,end).IgnoreGameObjectHierarchy(GameObject)
.WithoutTags("pop_target","paintball_debris").Run();
if(hit.Hit || CrashSeconds>2.4f)
{
var point=hit.Hit ? hit.EndPosition : end;
if(hit.Hit && !ArenaShield.TryAbsorbImpact(hit,WorldPosition-CrashVelocity.Normal*40,PaintTint))
{
PaintballCombatant.Find(hit.GameObject)?.ReceiveRiotCrash(WorldPosition);
PaintImpactSystem.Find(Scene)?.Spawn(hit,PaintTint);
}
FinishCrash(point);return;
}
WorldPosition=end;
}
private void FinishCrash(Vector3 point)
{
if(crashFinished)return;crashFinished=true;
NetworkEffects.RiotBurst(point,Radius,PaintTint,false,false,Round);
NetworkEffects.RiotDroneFlare(point,PaintTint,true,Round,Seed);
GameObject.Destroy();
}
protected override void OnDestroy(){malfunction?.Stop();}
}