Editor/Beam/ArchBeamPart.cs

Editor class representing a beam part in the architecture editor. Stores identity, geometry (footprint, bounds, heights), visual palette and member layout, and exposes convenience computed properties and a Reshape method that delegates to ArchFootprint.Authored.

File Access
using System;
using System.Collections.Generic;
using Sandbox;

namespace Sunless.Architecture;

// One member filling the shape, or the shape filled with members. A single beam is not a special case of
// the field with the count set to one: the field divides what it was dragged, and one beam IS what it was
// dragged, which is why the two are named rather than counted.
public enum BeamMembers
{
	One,
	Field
}

// Timber hung UNDER a plane rather than poured on the ground - the difference between this and a platform,
// and the only reason it is not one.
public sealed class ArchBeamPart : IArchCollides, 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; } = "Beam";
	public int Level { get; set; }
	public BeamMembers Members { get; set; }
	// The pillar type the member is SHAPED by: its section width, its bay and the number of sides it is
	// turned in. A slat is a pillar lying down, so it is dressed from the same authored presets rather than
	// from a second set of numbers that would drift from them.
	public string Type { get; set; } = "";
	public int Sides { get; set; }

	public Vector2 Min { get; set; }
	public Vector2 Max { get; set; }
	public List<Vector2> Footprint { get; set; } = new();

	// The plane it hangs from - the ceiling soffit it was drawn on - and how far it drops below it.
	public float TopHeight { get; set; }
	public float Drop { get; set; } = 12f;

	public float MemberWidth { get; set; } = 6f;
	public float MemberGap { get; set; } = 10f;
	public float Yaw { get; set; }

	public ArchPalette Palette { get; set; } = new();

	public float Depth => MathF.Max( 1f, Drop );

	public float Soffit => TopHeight - Depth;

	public bool HasFootprint => Footprint.Count >= 4;

	public List<Vector2> Outline() => ArchFootprint.OrRect( Footprint, Min, Max );

	public void Reshape( List<Vector2> outline )
	{
		(Footprint, Min, Max) = ArchFootprint.Authored( outline );
	}
}