Editor/Walkway/ArchWalkwayTransitionService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Sandbox;

namespace Sunless.Architecture;


sealed class ArchWalkwayTransitionService {
	readonly ArchPlan plan;
	readonly ArchRoom room;
	readonly ArchKit kit;

	public ArchWalkwayTransitionService( ArchPlan plan, ArchRoom room, ArchKit kit ) {
		this.plan = plan;
		this.room = room;
		this.kit = kit;
	}

	public void AddLowerFlights( ArchWalkwaySpan span, IReadOnlyList<ArchWalkwayEndpoint> endpoints ) {
		var centre = (span.Min + span.Max) * 0.5f;
		var width = span.AlongX ? span.Max.y - span.Min.y : span.Max.x - span.Min.x;
		var kinds = ArchKinds.Load();

		foreach ( var endpoint in endpoints.Where( endpoint => endpoint.Room is not null && endpoint.Height < room.BaseHeight - 1f ) ) {
			var delta = room.BaseHeight - endpoint.Height;
			var along = span.AlongX
				? new Vector2( endpoint.Point.x < centre.x ? 1f : -1f, 0f )
				: new Vector2( 0f, endpoint.Point.y < centre.y ? 1f : -1f );
			var across = new Vector2( -along.y, along.x );
			var steps = Math.Max( 1, (int)MathF.Round( delta / MathF.Max( 3f, kit.StepRise ) ) );
			var going = MathF.Min( MathF.Max( 6f, kit.StepGoing ), MathF.Max( 24f, (span.AlongX ? span.Max.x - span.Min.x : span.Max.y - span.Min.y) * 0.45f / steps ) );
			var flight = new ArchStairPart {
				Id = plan.AllocateId(),
				Name = $"WalkwayStairs_{endpoint.Room.Name}",
				BaseHeight = endpoint.Height,
				Width = MathF.Max( 24f, width - 8f ),
				StepRise = delta / steps,
				StepGoing = going,
				TopLanding = false,
				WellGuard = false,
				Guard = StairGuard.Both,
				TreadThickness = 2.5f
			};

			var origin = endpoint.Point + along * 2f - across * (width - 8f) * 0.5f;
			var (core, lanes) = ArchStairCore.Straight( origin, along, steps * going, flight.Width, delta );

			flight.Core = core;
			flight.Lanes = lanes;

			plan.File( ArchKind.Stair, room, flight, kinds );
		}
	}
}