CoverInterruptionReview.cs
using Sandbox;
namespace PaintballBaddies;
/// <summary>Opt-in checks of actual cover interruption and input ownership.</summary>
public sealed class CoverInterruptionReview : Component
{
[Property] public string CaptureId { get; set; } = "";
private PlayerController player;
private CoverController cover;
private GameObject obstacle;
private bool input,look;
private Vector3 position;
private Angles angles;
private float elapsed;
private int stage;
protected override void OnStart()
{
player=Scene.GetAllComponents<PlayerController>().First();
cover=player.Components.Get<CoverController>();
input=player.UseInputControls;look=player.UseLookControls;
position=player.WorldPosition;angles=player.EyeAngles;
player.UseLookControls=false;cover.TestInput=true;
Place();
}
private void Place()
{
player.WorldPosition=new Vector3(-595,70,2);
player.EyeAngles=Angles.Zero;player.Body.Velocity=Vector3.Zero;
obstacle=TrainingRange.Box(null,"Cover interruption review",new Vector3(-550,70,24),new Vector3(20,180,48),Color.Gray,true);
obstacle.Components.Create<CoverSurface>();
}
private void Check(string name,bool passed) => Log.Info("COVER_INTERRUPTION "+Json.Serialize(new {capture_id=CaptureId,name,passed}));
protected override void OnUpdate()
{
elapsed+=Time.Delta;
if(elapsed<.6f)return;
elapsed=0;
switch(stage++)
{
case 0:
Check("entry before disable",cover.TryEnter() && !player.UseInputControls);
cover.Enabled=false;break;
case 1:
Check("disable releases controls",!cover.Attached && player.UseInputControls==input && !cover.LowCover);
Check("disabled controller rejects entry",!cover.TryEnter() && !cover.CanEnter);
cover.Enabled=true;break;
case 2:
Check("entry before surface removal",cover.TryEnter());
obstacle.Destroy();break;
case 3:
Check("removed surface releases controls",!cover.Attached && player.UseInputControls==input);
Place();player.UseInputControls=false;break;
case 4:
var surface=obstacle.Components.Get<CoverSurface>();
surface.Enabled=false;
Check("disabled surface rejects entry",!cover.TryEnter());
surface.Enabled=true;
Check("entry with external input owner",cover.TryEnter());
cover.Enabled=false;break;
case 5:
Check("preserves external input owner",!cover.Attached && !player.UseInputControls);
cover.Enabled=true;player.UseInputControls=input;break;
case 6:
Check("entry before component removal",cover.TryEnter());
cover.Destroy();break;
case 7:
Check("component removal restores controls",player.UseInputControls==input);
break;
}
}
protected override void OnDestroy()
{
if(cover.IsValid()){cover.Leave();cover.TestInput=false;cover.Enabled=true;}
if(obstacle.IsValid())obstacle.Destroy();
if(player.IsValid())
{
player.UseInputControls=input;player.UseLookControls=look;
player.WorldPosition=position;player.EyeAngles=angles;
}
}
}