3using MPewsey.ManiaMap.Exceptions;
 
    4using System.Collections.Generic;
 
    6using UnityEngine.AddressableAssets;
 
    7using UnityEngine.Events;
 
    8using UnityEngine.ResourceManagement.AsyncOperations;
 
   33        private string _name = 
"<None>";
 
   37        public string Name { 
get => _name; 
set => _name = value; }
 
   47        private Vector2Int _size = Vector2Int.one;
 
   51        public Vector2Int 
Size { 
get => _size; 
set => SetSizeField(ref _size, value); }
 
   54        private Vector3 _cellSize = 
new Vector3(1, 1, 0.001f);
 
   58        public Vector3 
CellSize { 
get => _cellSize; 
set => _cellSize = Vector3.Max(value, 0.001f * Vector3.one); }
 
   62        private List<ActiveCellsRow> _activeCells = 
new List<ActiveCellsRow>();
 
   66        public List<ActiveCellsRow> 
ActiveCells { 
get => _activeCells; 
set => _activeCells = value; }
 
   69        private UnityEvent _onInitialize = 
new UnityEvent();
 
   73        public UnityEvent 
OnInitialize { 
get => _onInitialize; 
set => _onInitialize = value; }
 
   76        private UnityEvent _onInitialized = 
new UnityEvent();
 
   80        public UnityEvent 
OnInitialized { 
get => _onInitialized; 
set => _onInitialized = value; }
 
  126        private void SetSizeField(ref Vector2Int field, Vector2Int value)
 
  128            field = Vector2Int.Max(value, Vector2Int.one);
 
  132        private void OnValidate()
 
  138        private void OnDrawGizmos()
 
  140            var activeFillColor = 
new Color(0, 0, 1, 0.2f);
 
  141            var inactiveFillColor = 
new Color(1, 0, 0, 0.2f);
 
  142            var lineColor = 
new Color(0, 0, 0);
 
  143            DrawCells(activeFillColor, lineColor, 
true);
 
  144            DrawCells(inactiveFillColor, lineColor, 
false);
 
  153        private void DrawCells(Color fillColor, Color lineColor, 
bool activity)
 
  161                for (
int j = 0; j < row.Count; j++)
 
  163                    if (row[j] == activity)
 
  166                        Gizmos.color = fillColor;
 
  167                        Gizmos.DrawCube(center, cellSize);
 
  168                        Gizmos.color = lineColor;
 
  169                        Gizmos.DrawWireCube(center, cellSize);
 
  184            AssetReferenceGameObject prefab, Transform parent = 
null,
 
  185            bool assignLayoutPosition = 
false)
 
  187            var roomLayout = layoutPack.
Layout.Rooms[id];
 
  188            var roomState = layoutPack.
LayoutState.RoomStates[id];
 
  191            return InstantiateRoomAsync(prefab, parent, layoutPack, roomLayout, roomState, cellLayer, triggeringLayers, assignLayoutPosition);
 
  205        public static AsyncOperationHandle<GameObject> 
InstantiateRoomAsync(AssetReferenceGameObject prefab, Transform parent,
 
  207            int cellLayer, LayerMask triggeringLayers, 
bool assignLayoutPosition)
 
  209            var handle = prefab.InstantiateAsync(parent);
 
  211            handle.Completed += handle => handle.Result.GetComponent<
RoomComponent>()
 
  212                .
Initialize(layoutPack, roomLayout, roomState, cellLayer, triggeringLayers, assignLayoutPosition);
 
  226            bool assignLayoutPosition = 
false)
 
  228            var roomLayout = layoutPack.
Layout.Rooms[id];
 
  229            var roomState = layoutPack.
LayoutState.RoomStates[id];
 
  232            return InstantiateRoom(prefab, parent, layoutPack, roomLayout, roomState, cellLayer, triggeringLayers, assignLayoutPosition);
 
  248            int cellLayer, LayerMask triggeringLayers, 
bool assignLayoutPosition)
 
  250            var room = Instantiate(prefab, parent).GetComponent<
RoomComponent>();
 
  251            room.
Initialize(layoutPack, roomLayout, roomState, cellLayer, triggeringLayers, assignLayoutPosition);
 
  265            int cellLayer, LayerMask triggeringLayers, 
bool assignLayoutPosition)
 
  274            if (assignLayoutPosition)
 
  302            for (
int i = 0; i < 
Rows; i++)
 
  304                for (
int j = 0; j < 
Columns; j++)
 
  324                while (row.Values.Count > 
Columns)
 
  326                    row.Values.RemoveAt(row.Values.Count - 1);
 
  329                while (row.Values.Count < 
Columns)
 
  331                    row.Values.Add(
true);
 
  354            var startRow = Mathf.Min(startIndex.x, endIndex.x);
 
  355            var endRow = Mathf.Max(startIndex.x, endIndex.x);
 
  356            var startColumn = Mathf.Min(startIndex.y, endIndex.y);
 
  357            var endColumn = Mathf.Max(startIndex.y, endIndex.y);
 
  359            for (
int i = startRow; i <= endRow; i++)
 
  361                for (
int j = startColumn; j <= endColumn; j++)
 
  381                throw new System.IndexOutOfRangeException($
"Index out of range: ({row}, {column})");
 
  397                    throw new System.NotImplementedException($
"Unhandled cell activity: {activity}.");
 
  411                throw new System.IndexOutOfRangeException($
"Index out of range: ({row}, {column})");
 
  425                throw new System.IndexOutOfRangeException($
"Index out of range: ({row}, {column})");
 
  437            return (uint)row < (uint)
Rows && (uint)column < (uint)
Columns;
 
  456            var children = GetComponentsInChildren<CellChild>();
 
  458            foreach (var child 
in children)
 
  460                child.AutoAssign(
this);
 
  463            return children.Length;
 
  476                    return Quaternion.Euler(0, 0, 0);
 
  478                    return Quaternion.Euler(90, 0, 0);
 
  480                    throw new System.ArgumentException($
"Unhandled room type: {RoomType}.");
 
  522                    throw new System.ArgumentException($
"Unhandled room type: {RoomType}.");
 
  537                    return new Vector3(gridPosition.x, -gridPosition.y, -gridPosition.z);
 
  539                    return new Vector3(gridPosition.x, gridPosition.z, -gridPosition.y);
 
  541                    throw new System.ArgumentException($
"Unhandled room type: {RoomType}.");
 
  556                    return new Vector3(localPosition.x, -localPosition.y, -localPosition.z);
 
  558                    return new Vector3(localPosition.x, -localPosition.z, localPosition.y);
 
  560                    throw new System.ArgumentException($
"Unhandled room type: {RoomType}.");
 
  611            var row = Mathf.FloorToInt(position.y / 
CellSize.y);
 
  612            var column = Mathf.FloorToInt(position.x / 
CellSize.x);
 
  615                return new Vector2Int(row, column);
 
  617            return new Vector2Int(-1, -1);
 
  651            var 
template = 
new RoomTemplate(
id, name, cells, spots);
 
  664            for (
int i = 0; i < cells.Rows; i++)
 
  666                for (
int j = 0; j < cells.Columns; j++)
 
  669                        cells[i, j] = Cell.New;
 
  682            foreach (var door 
in GetComponentsInChildren<DoorComponent>())
 
  684                var cell = cells[door.Row, door.Column];
 
  685                cell.SetDoor(door.Direction, door.GetMMDoor());
 
  695            foreach (var feature 
in GetComponentsInChildren<Feature>())
 
  697                var cell = cells[feature.Row, feature.Column];
 
  698                cell.AddFeature(feature.Name);
 
  707            var spots = GetComponentsInChildren<CollectableSpotComponent>();
 
  708            var result = 
new Dictionary<int, CollectableSpot>(spots.Length);
 
  710            foreach (var spot 
in spots)
 
  712                result.Add(spot.Id, spot.GetMMCollectableSpot());
 
  724            var 
set = 
new HashSet<int>();
 
  726            foreach (var flag 
in GetComponentsInChildren<RoomFlag>())
 
  728                if (!
set.Add(flag.Id))
 
  729                    throw new DuplicateIdException($
"Duplicate room flag ID {flag.Id} for object {flag}.");
 
  744            var index = Vector2Int.zero;
 
  745            var minDistance = 
float.PositiveInfinity;
 
  748            for (
int i = 0; i < 
Rows; i++)
 
  750                for (
int j = 0; j < 
Columns; j++)
 
  755                        var distance = delta.sqrMagnitude;
 
  757                        if (distance < minDistance)
 
  759                            minDistance = distance;
 
  760                            index = 
new Vector2Int(i, j);
 
  777            System.Span<DoorDirection> directions = stackalloc DoorDirection[]
 
  784                DoorDirection.Bottom,
 
  787            System.Span<Vector3> vectors = stackalloc Vector3[]
 
  789                new Vector3(0, -1, 0),
 
  790                new Vector3(1, 0, 0),
 
  791                new Vector3(0, 1, 0),
 
  792                new Vector3(-1, 0, 0),
 
  793                new Vector3(0, 0, 1),
 
  794                new Vector3(0, 0, -1),
 
  798            var maxDistance = 
float.NegativeInfinity;
 
  805            for (
int i = 0; i < count; i++)
 
  807                var distance = Vector3.Dot(delta, vectors[i]);
 
  809                if (distance > maxDistance)
 
  811                    maxDistance = distance;
 
  816            return directions[index];
 
The base class for cell trigger areas.
 
static CellArea InstantiateCellArea(int row, int column, RoomComponent room, int cellLayer, LayerMask triggeringLayers)
Instantiates a new cell area within the specified room.
 
A manager for maintaining the current map data and state.
 
LayoutState LayoutState
The layout state.
 
ManiaMapSettings Settings
The applied settings.
 
LayerMask TriggeringLayers
The physics layers that trigger room cell area triggers.
 
int CellLayer
The physics layer assigned to room cell area triggers.
 
A component for creating a room.
 
Vector3 GridToLocalPosition(Vector3 gridPosition)
Converts the specified grid coordinate to local coordinates.
 
bool CellIndexExists(int row, int column)
Returns true if the cell index exists.
 
Vector3 CenterGlobalPosition()
Returns the center of the cell grid in global coordinates.
 
Vector3 LocalCellSize()
Returns the cell size in local coordinates.
 
static AsyncOperationHandle< GameObject > InstantiateRoomAsync(AssetReferenceGameObject prefab, Transform parent, LayoutPack layoutPack, Room roomLayout, RoomState roomState, int cellLayer, LayerMask triggeringLayers, bool assignLayoutPosition)
Instantiates and initializes a room asynchronously. Returns the operation handle.
 
void SetCellActivity(int row, int column, bool activity)
Sets the cell activity for the specified index.
 
void SizeActiveCells()
Sizes the active cells list to match the room size.
 
int AutoAssign()
Runs auto assign on the room's cell children. Returns the number of children.
 
Vector2Int GridPositionToCellIndex(Vector3 position)
Converts the specified grid position to the containing cell index. If the cell index does not exist,...
 
void MoveToLayoutPosition()
Sets the room's local position to its position in the layout.
 
static RoomComponent InstantiateRoom(GameObject prefab, Transform parent, LayoutPack layoutPack, Room roomLayout, RoomState roomState, int cellLayer, LayerMask triggeringLayers, bool assignLayoutPosition)
Instantiates and initializes a room and returns it.
 
Room RoomLayout
The room data.
 
bool Initialize(LayoutPack layoutPack, Room roomLayout, RoomState roomState, int cellLayer, LayerMask triggeringLayers, bool assignLayoutPosition)
Initializes the room. Returns false if the room has already been initialized.
 
UnityEvent OnInitialize
An event invoked when the room is initialized.
 
Vector2Int GlobalPositionToCellIndex(Vector3 position)
Converts the specified global position to the containing cell index. If the cell index does not exist...
 
Vector3 CenterLocalPosition()
Returns the center of the cell grid in local coordinates.
 
Array2D< Cell > GetMMCells()
Returns the Mania Map cells used by the procedural generator.
 
Dictionary< int, CollectableSpot > GetMMCollectableSpots()
Returns the Mania Map collectable spots by ID.
 
Vector2Int LocalPositionToCellIndex(Vector3 position)
Converts the specified local position to the containing cell index. If the cell index does not exist,...
 
Vector3 LocalToGridPosition(Vector3 localPosition)
Converts the specified local coordinate to grid coordinates.
 
static RoomComponent InstantiateRoom(Uid id, LayoutPack layoutPack, GameObject prefab, Transform parent=null, bool assignLayoutPosition=false)
Instantiates and initializes a room and returns it.
 
Vector3 CellCenterGridPosition(int row, int column)
Returns the cell center for the specified index in grid coordinates.
 
UnityEvent OnInitialized
The event invoked after the room has completed initialization.
 
Vector3 CellCenterLocalPosition(int row, int column)
Returns the cell center for the specified index in local coordinates.
 
string Name
The room name.
 
void AddMMFeatures(Array2D< Cell > cells)
Adds the cell features to the cells array.
 
Vector2Int Size
The size of the room grid in rows (x) and columns (y).
 
void AddMMDoors(Array2D< Cell > cells)
Adds the Mania Map doors to the cells array.
 
Vector3 CellSize
The size of each cell within the grid coordinate system.
 
bool CellIndexRangeExists(Vector2Int startIndex, Vector2Int endIndex)
Returns true if both cell indexes exist.
 
RoomTemplateResource RoomTemplate
The room template.
 
void DrawCells(Color fillColor, Color lineColor, bool activity)
Draws the cell cube gizmos for the specified cell activity.
 
void ValidateRoomFlags()
Validates that the room flag ID's are unique.
 
DoorDirection FindClosestDoorDirection(int row, int column, Vector3 position)
Returns the closest door direction based on the specified global position.
 
CellAreaTriggerEvent OnCellAreaEntered
The event invoked when a room cell has been entered. Message includes the enterered cell and the coll...
 
Vector3 CenterGridPosition()
Returns the center of the cell grid in grid coordinates.
 
RoomState RoomState
The room state.
 
bool SetCellActivities(Vector2Int startIndex, Vector2Int endIndex, CellActivity activity)
Sets the cell activities for the specified index range. No action is taken if one of the indexes is o...
 
void SetCellActivity(int row, int column, CellActivity activity)
Sets the cell activity for the specified index.
 
Vector2Int FindClosestActiveCellIndex(Vector3 position)
Returns the closest active cell index for the specified global position.
 
int Columns
The column index.
 
bool IsInitialized
True if the room has been initialized.
 
Quaternion GetCellViewDirection()
Returns the quaternion angle perpendicular to the cell plane.
 
RoomTemplate GetMMRoomTemplate(int id, string name)
Returns the Mania Map room template used by the procedural generator.
 
List< ActiveCellsRow > ActiveCells
A list of active cell rows.
 
CellAreaTriggerEvent OnCellAreaExited
The event invoked when a room cell has been exited. Message includes the exited cell and the collidin...
 
Vector3 GlobalToGridPosition(Vector3 globalPosition)
Converts the specified global position to grid coordinates.
 
Vector3 CellCenterGlobalPosition(int row, int column)
Returns the cell center for the specified index in global coordinates.
 
bool GetCellActivity(int row, int column)
Returns the cell activity for the specified index.
 
void CreateCellAreas(int cellLayer, LayerMask triggeringLayers)
Creates the cell area triggers as children of the room.
 
static AsyncOperationHandle< GameObject > InstantiateRoomAsync(Uid id, LayoutPack layoutPack, AssetReferenceGameObject prefab, Transform parent=null, bool assignLayoutPosition=false)
Instantiates and initializes a room asynchronously. Returns the operation handle.
 
A container for storing a serialized room template.
 
CellActivity
The cell activity.
 
RoomType
The type of room.
 
The row of the RoomComponent active cells list.