153 lines
6.1 KiB
C#
153 lines
6.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using EscapeRoomEngine.Engine.Runtime.Modules;
|
|
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
|
|
using EscapeRoomEngine.Engine.Runtime.UI;
|
|
using EscapeRoomEngine.Engine.Runtime.Utilities;
|
|
using UnityEngine;
|
|
using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger;
|
|
using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType;
|
|
using Object = UnityEngine.Object;
|
|
using Range = EscapeRoomEngine.Engine.Runtime.Utilities.Range;
|
|
|
|
namespace EscapeRoomEngine.Engine.Runtime
|
|
{
|
|
/// <summary>
|
|
/// The space is responsible for placing and instantiating any modules in it.
|
|
/// </summary>
|
|
public class Space
|
|
{
|
|
/// <summary>
|
|
/// The room relative (<i>RR</i>) dimensions of this space.
|
|
/// </summary>
|
|
internal readonly Placement rrPlacement;
|
|
/// <summary>
|
|
/// The room this space is in.
|
|
/// </summary>
|
|
internal readonly Room room;
|
|
|
|
/// <summary>
|
|
/// A list of all modules.
|
|
/// </summary>
|
|
internal List<Module> Modules { get; } = new(2);
|
|
/// <summary>
|
|
/// A list of all staged and added modules.
|
|
/// </summary>
|
|
internal List<Module> AllModules
|
|
{
|
|
get
|
|
{
|
|
var modules = new List<Module>(Modules);
|
|
if (_stagedModules.Count > 0)
|
|
{
|
|
modules.AddRange(_stagedModules);
|
|
}
|
|
return modules;
|
|
}
|
|
}
|
|
|
|
private GameObject _spaceObject, _spaceTiles;
|
|
private List<Module> _stagedModules = new();
|
|
|
|
internal Space(Room room, Passage entrance)
|
|
{
|
|
this.room = room;
|
|
rrPlacement = new Placement
|
|
{
|
|
position = Vector3Int.zero,
|
|
size = new Vector2Int(GameControl.Instance.RoomSize.x, GameControl.Instance.RoomSize.y)
|
|
};
|
|
|
|
// connect the space to its entrance passage
|
|
entrance.PlaceEntrance(new DoorModule(this,
|
|
((DoorModuleDescription)entrance.fromOut.description).connectedDoorDescription));
|
|
Modules.Add(entrance.toIn);
|
|
}
|
|
|
|
internal bool AddModuleWithRequirements(Module module)
|
|
{
|
|
var requirementsFulfilled = module.CheckRequirements();
|
|
if (requirementsFulfilled)
|
|
{
|
|
// add all previously staged modules first ...
|
|
for (var i = _stagedModules.Count - 1; i >= 0; i--)
|
|
{
|
|
Modules.Add(_stagedModules[i]);
|
|
}
|
|
|
|
// ... and then add the module itself
|
|
Modules.Add(module);
|
|
}
|
|
|
|
// always clear the staged modules. if a module isn't added, its corresponding staged modules should be discarded
|
|
_stagedModules = new List<Module>();
|
|
|
|
return requirementsFulfilled;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stage a module if its requirements are currently met. It will be added as soon as the next module is added by <see cref="AddModuleWithRequirements"/>.
|
|
/// </summary>
|
|
/// <param name="module">The module to stage</param>
|
|
/// <returns>Whether the requirements were met and the module was staged</returns>
|
|
internal bool StageModuleWithRequirements(Module module)
|
|
{
|
|
var requirementsFulfilled = module.CheckRequirements();
|
|
if (requirementsFulfilled)
|
|
{
|
|
_stagedModules.Add(module);
|
|
}
|
|
|
|
return requirementsFulfilled;
|
|
}
|
|
|
|
internal void InstantiateSpace(Transform parent, string name)
|
|
{
|
|
_spaceObject = new GameObject($"Space {name}");
|
|
_spaceObject.transform.SetParent(parent, false);
|
|
_spaceObject.transform.localPosition = new Vector3(rrPlacement.position.x, 0, rrPlacement.position.z);
|
|
|
|
// build the space floor out of tiles
|
|
_spaceTiles = new GameObject($"Space Geometry");
|
|
_spaceTiles.transform.SetParent(_spaceObject.transform, false);
|
|
_spaceTiles.isStatic = true;
|
|
for (var z = 0; z < rrPlacement.size.y; z++)
|
|
{
|
|
for (var x = 0; x < rrPlacement.size.x; x++)
|
|
{
|
|
var left = x == 0;
|
|
var right = x == rrPlacement.size.x - 1;
|
|
var bottom = z == 0;
|
|
var top = z == rrPlacement.size.y - 1;
|
|
|
|
TileLocation location;
|
|
if (bottom)
|
|
location = left ? TileLocation.SW : right ? TileLocation.SE : TileLocation.S;
|
|
else if (top)
|
|
location = left ? TileLocation.NW : right ? TileLocation.NE : TileLocation.N;
|
|
else
|
|
location = left ? TileLocation.W : right ? TileLocation.E : TileLocation.C;
|
|
|
|
var tileObject = Object.Instantiate(Engine.Theme.spaceTile, _spaceTiles.transform, false);
|
|
tileObject.transform.localPosition = new Vector3(x, 0, z);
|
|
tileObject.showTile = location;
|
|
}
|
|
}
|
|
|
|
// instantiate all modules inside this space
|
|
Modules.ForEach(module => module.InstantiateModule(_spaceObject.transform));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a position relative to this space to one relative to the room.
|
|
/// </summary>
|
|
/// <param name="srPosition">The space relative (<i>SR</i>) position that should be converted to a room relative (<i>RR</i>) position.</param>
|
|
internal Vector3Int ToRoomRelative(Vector3Int srPosition) => srPosition + rrPlacement.position;
|
|
/// <summary>
|
|
/// Convert a position relative to the room to one relative to this space.
|
|
/// </summary>
|
|
/// <param name="rrPosition">The room relative (<i>RR</i>) position that should be converted to a space relative (<i>SR</i>) position.</param>
|
|
internal Vector3Int ToSpaceRelative(Vector3Int rrPosition) => rrPosition - rrPlacement.position;
|
|
}
|
|
}
|