Editor-side class representing a platform part in the architecture system. Stores geometry (footprint, min/max), heights, ramp and guardrail properties, material palette, stair parts, and provides helpers for outline, footprint detection, dressing (copying visual properties), and reshaping from an outline.
using System;
using System.Collections.Generic;
using System.Linq;
using Sandbox;
namespace Sunless.Architecture;
// Flights are CARVED out of it, so they live here rather than on a room.
public sealed class ArchPlatformPart : IArchCarveHost, IArchCollides, IArchRamped, IArchPainted, IArchNamed
{
// Overrides the kit for THIS part alone: one wall that needs its exact holes, one tower that needs none.
public ArchCollisionMode? Collision { get; set; }
public int Id { get; set; }
public string Name { get; set; } = "Platform";
public int Level { get; set; }
public Vector2 Min { get; set; }
public Vector2 Max { get; set; }
public float GradeHeight { get; set; }
public float TopHeight { get; set; } = 24f;
// A slab that hangs in the air rather than being poured on the ground: it starts at its own grade
// instead of an embedment below it, and its underside is a soffit somebody stands under.
public bool Hung { get; set; }
// A raked deck. The yaw is the way the top CLIMBS and the fall is how far it drops getting to its foot;
// zero fall is the whole rise, so a ramp dragged and left alone is a wedge sitting on the ground and
// pulling its head is the only edit it needs.
public bool Ramp { get; set; }
public float RampFall { get; set; }
public float RampYaw { get; set; }
// Edge protection round the deck: the same post-and-rail engine a roof edge stands, following the
// CARVED outline so a notch is guarded down its sides and parting at each carved flight's mouth.
public bool Guardrail { get; set; }
public float GuardHeight { get; set; } = 42f;
public bool Coping { get; set; } = true;
public float CopingHeight { get; set; } = 4f;
// The oversail is the shadow line you read a cast coping by.
public float CopingWidth { get; set; } = 8f;
public float CopingOversail { get; set; } = 1.5f;
// The rim of anything carved out of it, finished the same way its own outside edge is.
public bool CopingInside { get; set; }
public List<ArchStairPart> Stairs { get; set; } = new();
public List<Vector2> Footprint { get; set; } = new();
public ArchPalette Palette { get; set; } = new();
public float Rise => MathF.Max( 1f, TopHeight - GradeHeight );
public bool HasFootprint => Footprint.Count >= 4;
public List<Vector2> Outline() => ArchFootprint.OrRect( Footprint, Min, Max );
// The DRESSING alone - everything a placement adopts from the seed it was drawn with, and nothing about
// where it stands. A placement that stamped its gesture on the seed itself carried it into the next one.
public ArchPlatformPart Dressing()
{
return new ArchPlatformPart
{
GradeHeight = GradeHeight,
TopHeight = TopHeight,
Hung = Hung,
Ramp = Ramp,
RampFall = RampFall,
RampYaw = RampYaw,
Guardrail = Guardrail,
GuardHeight = GuardHeight,
Coping = Coping,
CopingHeight = CopingHeight,
CopingWidth = CopingWidth,
CopingOversail = CopingOversail,
CopingInside = CopingInside
};
}
public void Reshape( List<Vector2> outline )
{
(Footprint, Min, Max) = ArchFootprint.Authored( outline );
}
}