using System; using System.Collections.Generic; using System.Linq; using Escape_Room_Engine.Engine.Scripts.Utilities; using UnityEngine; using Logger = Escape_Room_Engine.Engine.Scripts.Utilities.Logger; using LogType = Escape_Room_Engine.Engine.Scripts.Utilities.LogType; using Object = UnityEngine.Object; namespace Escape_Room_Engine.Engine.Scripts.Modules { public enum Orientation { North = 0, East = 90, South = 180, West = 270 } public class Module { public static HashSet EveryOrientation => new(new[] { Orientation.North, Orientation.East, Orientation.South, Orientation.West }); /// /// Get the space relative (SR) position of this module. /// internal Vector2Int SrPosition => srDimensions.Position; /// /// Get the room relative (RR) position of this module. /// internal Vector2Int RrPosition => _space.ToRoomRelative(SrPosition); internal readonly ModuleDescription _description; protected GameObject _moduleObject; /// /// The space relative (SR) dimensions of this module. /// protected Dimensions srDimensions; protected Orientation orientation; private readonly Space _space; internal Module(Space space, ModuleDescription description) { _space = space; _description = description; } internal bool IsType(ModuleType type) { return _description.types.Contains(type); } /// /// Place this module with a position relative to the room. /// /// The room relative (RR) position of this module. Must be inside the space dimensions. /// If the position is not inside the space dimensions. internal void PlaceRoomRelative(Vector2Int rrPosition) => Place(_space.ToSpaceRelative(rrPosition)); /// /// Place this module with a position relative to the space it is in. /// /// The space relative (SR) position of this module. Must be inside the space dimensions. /// If the position is not inside the space dimensions. internal void Place(Vector2Int srPosition) { if (_space != null && !srPosition.IsInsideRelative(_space.rrDimensions)) { throw new Exception($"Trying to place {this} at {srPosition}, which is outside space dimensions {_space.rrDimensions}."); } srDimensions.Position = srPosition; Logger.Log($"{this} has been placed at {srPosition} (SR)", LogType.ModulePlacement); } internal void Orient(Orientation o) { orientation = o; } internal void InstantiateModule(Transform parent) { _moduleObject = new GameObject(ToString()); _moduleObject.transform.SetParent(parent, false); _moduleObject.transform.localPosition = new Vector3(srDimensions.x + .5f, 0, srDimensions.z + .5f); _moduleObject.transform.Rotate(Vector3.up, (float)orientation); Object.Instantiate(_description.modulePrefab, _moduleObject.transform, false); } public override string ToString() { return $"Module ({string.Join(", ", _description.types.ToList().ConvertAll(type => type.ToString()))})"; } } }