StandingStrafeChecks.cs
using Sandbox;
using System;
namespace PaintballBaddies;
/// <summary>Opt-in actual controller movement and directional animation review.</summary>
public sealed class StandingStrafeChecks : Component
{
[Property] public int CharacterIndex { get; set; }
private PlayerController player;
private PaintballMarker weapon;
private float elapsed;
private int stage;
private Vector3 start;
private float maxTime;
private bool originalInput,originalLook,originalAccept,selected;
protected override void OnStart()
{
player=Components.Get<PlayerController>();weapon=Components.Get<PaintballMarker>();
originalInput=player.UseInputControls;originalLook=player.UseLookControls;originalAccept=weapon.AcceptInput;
player.UseInputControls=player.UseLookControls=false;weapon.AcceptInput=false;weapon.ReviewAimOverride=true;
WorldPosition=new Vector3(-950,0,2);player.EyeAngles=new Angles(0,0,0);start=WorldPosition;
}
protected override void OnUpdate()
{
if(!selected){Components.Get<RosterSelection>().Select(CharacterIndex);selected=true;}
elapsed+=Time.Delta;
player.WishVelocity=stage==0 ? Vector3.Left*55 : stage==1 ? Vector3.Right*55 : Vector3.Zero;
maxTime=MathF.Max(maxTime,player.Renderer.Sequence.Time);
if(elapsed<2.5f)return;
if(stage<2)
{
var expected=stage==0 ? "walk_left" : "walk_right";
var direction=stage==0 ? Vector3.Left : Vector3.Right;
var distance=Vector3.Dot(WorldPosition-start,direction);
Check(expected+" moves",distance>70,$"distance={distance}");
Check(expected+" plays",player.Renderer.Sequence.Name==expected && maxTime>.25f,$"clip={player.Renderer.Sequence.Name},time={maxTime}");
Check(expected+" holds facing",Vector3.Dot(player.Renderer.WorldRotation.Forward,Vector3.Forward)>.98f,$"yaw={player.Renderer.WorldRotation.Yaw()}");
}
else
{
Check("selected character",player.Renderer.Model?.Name==RosterSelection.GetModelPath(CharacterIndex),player.Renderer.Model?.Name);
Check("returns to idle",player.Renderer.Sequence.Name=="idle",player.Renderer.Sequence.Name);
Log.Info("STANDING_STRAFE COMPLETE");Destroy();return;
}
stage++;elapsed=0;maxTime=0;start=WorldPosition;
}
private void Check(string name,bool pass,string detail)=>Log.Info($"STANDING_STRAFE {(pass ? "PASS" : "FAIL")} {name}: {detail}");
protected override void OnDestroy()
{
if(player.IsValid()){player.WishVelocity=Vector3.Zero;player.UseInputControls=originalInput;player.UseLookControls=originalLook;}
if(weapon.IsValid()){weapon.ReviewAimOverride=null;weapon.AcceptInput=originalAccept;}
}
}