RestaurantSiteProbe.cs
using Sandbox;
using System;
namespace PaintballBaddies;
/// <summary>One-off survey of Last Orders and the ground around it, to plan the
/// back alley expansion. Logs a top-down grid (RS lines):
/// # wall/solid at waist height . indoor floor (ceiling above)
/// , outdoor floor (open sky) ~ floor at a different level
/// (space) no floor
/// plus every door-like object in the map.</summary>
public sealed class RestaurantSiteProbe : Component
{
[Property] public bool SurveyEnabled {get;set;}
private float wait;private bool done;
protected override void OnUpdate()
{
if(!Game.IsEditor || !SurveyEnabled || done || ArenaSelection.Current(Scene)!=ArenaSelection.Restaurant)return;
wait+=Time.Delta;
if(wait<5 || Scene.GetAllComponents<MapInstance>().Any(m=>m.Active && !m.IsLoaded))return;
done=true;
const int step=25,x0=-900,x1=1900,y0=100,y1=2500;const float baseZ=33;
var lines=new List<string>();
for(int y=y1;y>=y0;y-=step)
{
var row=new System.Text.StringBuilder();
for(int x=x0;x<=x1;x+=step)
{
var down=Scene.Trace.Ray(new Vector3(x,y,baseZ+220),new Vector3(x,y,baseZ-300)).WithoutTags("paintball_actor","paintball_debris","overdrive_enemy").Run();
if(!down.Hit){row.Append(' ');continue;}
float floor=down.HitPosition.z;
if(floor>baseZ+60){row.Append('#');continue;}
var waist=new Vector3(x,y,floor+45);
var solid=Scene.Trace.Sphere(6,waist,waist).WithoutTags("paintball_actor","paintball_debris","overdrive_enemy").Run();
if(solid.Hit || solid.StartedSolid){row.Append('#');continue;}
var up=Scene.Trace.Ray(waist,waist+Vector3.Up*400).WithoutTags("paintball_actor","paintball_debris","overdrive_enemy").Run();
row.Append(MathF.Abs(floor-baseZ)>12 ? '~' : up.Hit ? '.' : ',');
}
lines.Add($"{y,5} |{row}");
}
var doors=Scene.GetAllObjects(false).Where(g=>g.Name.Contains("door",StringComparison.OrdinalIgnoreCase))
.Select(g=>$"{g.Name}@{g.WorldPosition.x:0},{g.WorldPosition.y:0},{g.WorldPosition.z:0}");
Log.Info($"RESTAURANT_SITE x {x0}..{x1} y {y0}..{y1} step {step} (left=low x, top=high y)");
Log.Info("RESTAURANT_SITE_DOORS "+string.Join(" ; ",doors));
foreach(var l in lines)Log.Info("RS "+l);
}
}