Editor-side shape description for arch bridges. Defines value types for bridge stands and bents and a container ArchBridgeShape that holds parts, frames, bents, wings and helper properties for usability, carrying range and deepest pier rise.
using System;
using System.Collections.Generic;
using Sandbox;
namespace Sunless.Architecture;
// One line of shafts under a bent - a LIST, one per gap the deck crosses.
public readonly struct ArchBridgeStand
{
public float From { get; init; }
public float To { get; init; }
public float Width { get; init; }
// The lowest ground under the shafts, not the centreline - a cross-slope blade reaches its own low end.
public float Ground { get; init; }
public List<float> Shafts { get; init; }
}
// Read at the bent's own station: a valley's middle piers are long, the ends short.
public readonly struct ArchBridgeBent
{
public ArchFrame Frame { get; init; }
public float Bearing { get; init; }
public float Ground { get; init; }
public List<ArchBridgeStand> Stands { get; init; }
public Vector2 Flat => Frame.Flat;
public float Rise => Bearing - Ground;
}
// One resolve feeds the generator, the overlay and arch_measure - what is drawn is what is built.
public sealed class ArchBridgeShape
{
public ArchBridgePart Part { get; init; }
public ArchRoadPart Road { get; init; }
public ArchRoadSpan Span { get; init; }
public List<ArchFrame> Frames { get; init; } = new();
public List<ArchBridgeBent> Bents { get; init; } = new();
public List<ArchWingWall> Wings { get; init; } = new();
public ArchBridgeBent Near { get; init; }
public ArchBridgeBent Far { get; init; }
public bool IsUsable => Frames.Count >= 2;
// The STRUCTURE, not the drag, carries this station - the span moved to the lip of what it crosses.
public bool Carries( float distance ) => distance > Span.From && distance < Span.To;
// The tallest pier - what says whether the bridge crosses anything at all.
public float Deepest
{
get
{
var rise = MathF.Max( Near.Rise, Far.Rise );
foreach ( var bent in Bents )
{
rise = MathF.Max( rise, bent.Rise );
}
return rise;
}
}
}