Editor/Platform/ArchPlatformDeck.cs
using System;
using System.Collections.Generic;
using Sandbox;

namespace Sunless.Architecture;

public readonly record struct ArchPlatformHit( ArchBuilding On, ArchPlatformPart Platform, Vector3 World, float Seat );

// Poured on grade, not in building space — compare raw and a column seated on a podium lands a foundation too high.
public static class ArchPlatformDeck {
	// Raked or level, in the platform's OWN grade space - which is also world, because nothing lifts it.
	public static float Seat( ArchPlatformPart platform, Vector2 at ) => ArchRamp.Deck( platform ).At( at );

	// The same surface in the BUILDING's space, for anything that has to weigh it against a floor or a beam.
	public static float Seated( ArchPlan plan, ArchBuilding building, ArchKit kit, ArchPlatformPart platform, Vector2 at ) {
		return Seat( platform, at ) - ArchAsks.Lift( plan, building, kit );
	}

	// Nearest deck a downward ray meets — grade correction only on the way out (Seated).
	public static bool Struck( ArchPlan plan, ArchKit kit, int level, Ray ray, out ArchPlatformHit hit ) {
		hit = default;

		if ( plan is null || ray.Forward.z >= -0.001f ) {
			return false;
		}

		var answers = ArchAnswers.Load();
		var nearest = float.MaxValue;

		foreach ( var building in plan.Buildings ) {
			foreach ( var platform in ArchLayerGate.Enabled( building.Platforms ) ) {
				if ( platform.Level != level
					|| !ArchRamp.Deck( platform ).Crosses( ray, out var reach, out var struck )
					|| reach >= nearest
					|| !ArchFootprint.Contains( platform.Outline(), new Vector2( struck.x, struck.y ) ) ) {
					continue;
				}

				nearest = reach;
				hit = new ArchPlatformHit( building, platform, struck,
					struck.z - answers.Lift( plan, building, kit ) );
			}
		}

		return hit.Platform is not null;
	}
}