Editor/Tunnel/ArchTunnelAnswers.cs
namespace Sunless.Architecture;

public sealed class ArchTunnelHeadroom : IArchHeadroom {
	public bool Over( ArchPlan plan, ArchKit kit, int level, IReadOnlyList<Vector2> footprint, out float top ) {
		top = 0f;

		var found = false;

		ArchFootprint.Bounds( footprint, out var min, out var max );

		var centre = (min + max) * 0.5f;

		foreach ( var road in plan.Roads() ) {
			if ( road.Tunnels.Count == 0 || !road.Curve().Nearest( centre, out var frame, out var gap ) ) {
				continue;
			}

			// Nearest() answers for a point anywhere in the plan, so unbounded this took the crown of the
			// nearest tunnelled road for a drag on the other side of the map.
			if ( gap > road.Reach() + Bored( road ) ) {
				continue;
			}

			foreach ( var tunnel in ArchLayerGate.Enabled( road.Tunnels ).Where( bore => bore.Carries( frame.Distance ) ) ) {
				var crown = ArchTunnel.Crown( road, tunnel, frame ) + MathF.Max( 0f, tunnel.PortalRise );

				top = found ? MathF.Max( top, crown ) : crown;
				found = true;
			}
		}

		return found;
	}

	static float Bored( ArchRoadPart road ) {
		var reach = 0f;

		foreach ( var tunnel in road.Tunnels ) {
			reach = MathF.Max( reach, MathF.Max( 0f, tunnel.Clearance ) + MathF.Max( 2f, tunnel.Lining ) );
		}

		return reach;
	}
}