Editor/InteriorLayoutBuilder/RoomLayoutTool.Floors.cs
using System;
using System.Linq;
namespace ReusableRoomLayout;
public sealed partial class RoomLayoutTool
{
public int ActiveFloor => activeFloor;
public string ActiveFloorName => FloorLabel( activeFloor );
public float FloorSpacing => document.Settings.EffectiveFloorSpacing;
public bool CanMoveSelectedToActiveFloor
{
get
{
var selectedFloor = SelectedFloor();
return selectedFloor.HasValue && selectedFloor.Value != activeFloor;
}
}
public void SetActiveFloor( int floor )
{
SetActiveFloor( floor, keepSelection: false );
}
public void StepActiveFloor( int delta )
{
SetActiveFloor( activeFloor + delta );
}
public void MoveSelectedToActiveFloor()
{
EnsureLayoutLoadedForControls();
if ( !CanMoveSelectedToActiveFloor )
{
return;
}
PushLayoutUndo();
if ( SelectedDoor() is { } selectedDoor )
{
SetParentFloor( selectedDoor, activeFloor );
}
else if ( SelectedWindow() is { } selectedWindow )
{
SetParentFloor( selectedWindow, activeFloor );
}
else if ( SelectedCorridor() is { } selectedCorridor )
{
SetCorridorFloorWithEndpointRooms( selectedCorridor, activeFloor );
}
else if ( document.FindRoom( selectedRoomId ) is { } selectedRoom )
{
selectedRoom.Floor = activeFloor;
}
else if ( SelectedFloorCutout() is { } selectedCutout )
{
selectedCutout.Floor = activeFloor;
}
CommitLayoutChange();
}
public void SetFloorSpacing( float spacing )
{
EnsureLayoutLoadedForControls();
spacing = Math.Clamp( spacing, 0.0f, 8192.0f );
if ( Math.Abs( document.Settings.FloorSpacing - spacing ) < 0.001f )
{
return;
}
PushLayoutUndo();
document.Settings.FloorSpacing = spacing;
CommitLayoutChange();
}
private void SetActiveFloorFromSelection()
{
var selectedFloor = SelectedFloor();
if ( selectedFloor.HasValue )
{
SetActiveFloor( selectedFloor.Value, keepSelection: true );
}
}
private void SetActiveFloor( int floor, bool keepSelection )
{
floor = RoomLayoutDocument.ClampFloor( floor );
if ( activeFloor == floor )
{
return;
}
CancelLayoutInteraction( restoreActiveEdit: true );
activeFloor = floor;
if ( !keepSelection )
{
ClearSelectionOutsideActiveFloor();
}
}
private void ClearSelectionOutsideActiveFloor()
{
if ( SelectedFloor() == activeFloor )
{
return;
}
selectedRoomId = 0;
selectedDoorId = 0;
selectedWindowId = 0;
selectedCorridorId = 0;
selectedFloorCutoutId = 0;
}
private int? SelectedFloor()
{
if ( SelectedDoor() is { } door )
{
return document.FloorFor( door );
}
if ( SelectedWindow() is { } window )
{
return document.FloorFor( window );
}
if ( SelectedCorridor() is { } corridor )
{
return document.FloorFor( corridor );
}
if ( document.FindRoom( selectedRoomId ) is { } room )
{
return document.FloorFor( room );
}
if ( SelectedFloorCutout() is { } cutout )
{
return document.FloorFor( cutout );
}
return null;
}
private void SetParentFloor( RoomLayoutDoor door, int floor )
{
if ( door.RoomId != 0 && document.FindRoom( door.RoomId ) is { } room )
{
room.Floor = floor;
return;
}
if ( door.CorridorId != 0 && document.Corridors.FirstOrDefault( corridor => corridor.Id == door.CorridorId ) is { } corridor )
{
corridor.Floor = floor;
}
}
private void SetCorridorFloorWithEndpointRooms( RoomLayoutCorridor corridor, int floor )
{
corridor.Floor = floor;
SetDoorRoomFloor( corridor.StartDoorId, floor );
SetDoorRoomFloor( corridor.EndDoorId, floor );
}
private void SetDoorRoomFloor( int doorId, int floor )
{
var door = document.FindDoor( doorId );
if ( door is not null && door.RoomId != 0 && document.FindRoom( door.RoomId ) is { } room )
{
room.Floor = floor;
}
}
private void SetParentFloor( RoomLayoutWindow window, int floor )
{
if ( window.RoomId != 0 && document.FindRoom( window.RoomId ) is { } room )
{
room.Floor = floor;
return;
}
if ( window.CorridorId != 0 && document.Corridors.FirstOrDefault( corridor => corridor.Id == window.CorridorId ) is { } corridor )
{
corridor.Floor = floor;
}
}
private bool IsActiveFloor( RoomLayoutRoom room )
{
return document.FloorFor( room ) == activeFloor;
}
private bool IsActiveFloor( RoomLayoutDoor door )
{
return document.FloorFor( door ) == activeFloor;
}
private bool IsActiveFloor( RoomLayoutWindow window )
{
return document.FloorFor( window ) == activeFloor;
}
private bool IsActiveFloor( RoomLayoutCorridor corridor )
{
return document.FloorFor( corridor ) == activeFloor;
}
private bool IsActiveFloor( RoomLayoutFloorCutout cutout )
{
return document.FloorFor( cutout ) == activeFloor;
}
private float ActiveFloorZ()
{
return FloorWorldZ( activeFloor );
}
private float FloorWorldZ( int floor )
{
return document.Settings.EffectiveFloorSpacing * floor;
}
private static string FloorLabel( int floor )
{
return floor >= 0
? $"Floor {floor}"
: $"Basement {Math.Abs( floor )}";
}
}