SnakeNavigationReview.cs
using Sandbox;
namespace PaintballBaddies;
public sealed class SnakeNavigationReview : Component
{
private GameObject actor;
private NavMeshAgent agent;
private float elapsed,travelled,maxDetour;
private Vector3 previous;
private int crossings;
private bool started,reported;
protected override void OnStart()
{
Scene.NavMesh.IsEnabled=true;
Scene.NavMesh.IncludeStaticBodies=true;
Scene.NavMesh.IncludeKeyframedBodies=false;
Scene.NavMesh.AgentHeight=67;Scene.NavMesh.AgentRadius=17;
Scene.NavMesh.SetDirty();
}
protected override void OnUpdate()
{
elapsed+=Time.Delta;
if(reported || Scene.NavMesh.IsGenerating || elapsed<1)return;
if(!started)
{
actor=new GameObject {Name="Snake navigation probe"};
actor.WorldPosition=new Vector3(-450,1400,0);previous=actor.WorldPosition;
agent=actor.Components.Create<NavMeshAgent>();
agent.Height=67;agent.Radius=17;agent.MaxSpeed=140;agent.Acceleration=600;
agent.MoveTo(new Vector3(-250,1400,0));started=true;return;
}
var position=actor.WorldPosition;
travelled+=(position-previous).Length;
maxDetour=System.MathF.Max(maxDetour,System.MathF.Abs(position.y-1400));
var hit=Scene.Trace.Sphere(12,previous+Vector3.Up*20,position+Vector3.Up*20).IgnoreGameObjectHierarchy(actor).Run();
if(hit.Hit && hit.GameObject?.Name=="Inflatable snake bunker candidate")crossings++;
previous=position;
if(elapsed<8)return;
var remaining=(position-new Vector3(-250,1400,0)).WithZ(0).Length;
int shielded=0;
foreach(float y in new[]{-30f,0f,30f})
foreach(float z in new[]{35f,40f})
{
var ray=Scene.Trace.Ray(new Vector3(-150,1400+y,60),new Vector3(-385,1400+y,z)).IgnoreGameObjectHierarchy(actor).Run();
if(ray.Hit && ray.GameObject?.Name=="Inflatable snake bunker candidate")shielded++;
}
Log.Info("SNAKE_NAV "+Json.Serialize(new {passed=remaining<15 && crossings==0 && maxDetour>65 && shielded==6,shielded,remaining,crossings,maxDetour,travelled}));
reported=true;
}
protected override void OnDestroy(){if(actor.IsValid())actor.Destroy();}
}