Editor/Cabinet/ArchCabinetExtent.cs
namespace Sunless.Architecture;
// A run's extent is its RESOLVE, corners and all - so a stretch given away to a corner unit reports the shape it
// really has rather than the drag it was drawn over, and a selection outline sits on the carcasses that stand.
public sealed class ArchCabinetExtentProvider : IArchExtentProvider {
public ArchKind Kind => ArchKind.Cabinet;
public ArchExtent Measure( object payload, ArchExtentContext context ) {
var extent = new ArchExtent();
if ( payload is not ArchCabinetPart part ) {
return extent;
}
// Found rather than taken: an ask that arrived with neither - a viewport pick, an mcp argument - would
// otherwise measure the run off plan zero and report it a storey and a plinth below what stands there.
var room = context.Room ?? context.Plan?.HostOf<ArchRoom>( part );
var building = context.Building ?? context.Plan?.OwnerOf( room );
var shape = ArchCabinetShape.Resolve( context.Plan, context.Kit, room, building, part );
if ( !shape.Standing ) {
return extent;
}
// The generator draws under the building's own space, which its foundation lifts off the ground. A planned
// extent left in plan space reads as the whole run standing a plinth below what was built.
var lift = ArchAnswers.Load().Lift( context.Plan, building, context.Kit );
if ( shape.Cells.Count > 0 ) {
extent.Add( shape.Outline(), shape.Seat + lift, shape.Head + lift );
}
foreach ( var joint in shape.Joints ) {
extent.Add( joint.Top, joint.Seat + lift, joint.Head + joint.Counter + lift );
if ( joint.Cornice > 0.01f ) {
extent.Add( joint.Crown, joint.Head + lift, joint.Head + joint.Cornice + lift );
}
}
return extent;
}
}