station 46 room

This commit is contained in:
2023-05-14 18:13:02 +02:00
parent f03d723119
commit eba953b844
31 changed files with 978 additions and 672 deletions

View File

@@ -10,5 +10,5 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5aece1c1f67b46afaf249c4520a0478f, type: 3}
m_Name: Place On Bottom Row
m_Name: Place On Bottom Or Top Row Alternating
m_EditorClassIdentifier:

View File

@@ -72,14 +72,20 @@ namespace EscapeRoomEngine.Engine.Runtime
public void GenerateRoom()
{
Logger.Log("Generating room...", LogType.RoomGeneration);
var intro = NumberOfRooms == 0;
// get the last entrance from the newest room or create a spawn passage with no entrance door for where the player will start
var entrance = NumberOfRooms > 0 ? _rooms.Last().exit : new Passage(new DoorModule(null, theme.spawnDoor));
var entrance = intro ? new Passage(new DoorModule(null, theme.spawnDoor)) : _rooms.Last().exit;
var room = new Room(entrance);
_rooms.Add(room);
if (_plannedPuzzles.Count > 0)
if (intro)
{
GenerateIntroSpace(room, entrance);
}
else if (_plannedPuzzles.Count > 0)
{
GeneratePuzzleSpace(room, entrance);
}
@@ -92,7 +98,12 @@ namespace EscapeRoomEngine.Engine.Runtime
var roomId = _rooms.Count - 1;
room.InstantiateRoom(_playSpaceOrigin.transform, roomId * roomOffset, roomId.ToString());
if (theme.environment)
if (intro)
{
Instantiate(theme.intro, room.roomObject.transform, false);
FindObjectOfType<Intro>().Place(room.exit.fromOut.DoorState.transform);
}
else if (theme.environment)
{
Instantiate(theme.environment, room.roomObject.transform, false);
}
@@ -101,6 +112,20 @@ namespace EscapeRoomEngine.Engine.Runtime
UpdateUI();
}
private void GenerateIntroSpace(Room room, Passage entrance)
{
Logger.Log($"Generating intro space...", LogType.RoomGeneration);
var space = new IntroSpace(room, entrance);
var exitDoor = new DoorModule(space, theme.introExitDoor);
if (!space.AddModuleWithRequirements(exitDoor))
{
throw new EngineException("Could not satisfy requirements for exit door.");
}
var exit = new Passage(exitDoor);
room.AddSpace(space, exit);
}
private void GeneratePuzzleSpace(Room room, Passage entrance)
{
var puzzlesAdded = 0;
@@ -183,15 +208,11 @@ namespace EscapeRoomEngine.Engine.Runtime
GameControl.Instance.PlannedPuzzles = _plannedPuzzles;
}
/// <summary>
/// Hide or destroy the room two rooms ago. The actual previous room is kept for the player to be able to backtrack one room.
/// </summary>
/// <param name="destroy"></param>
public void HidePreviousRoom(bool destroy = true)
{
if (NumberOfRooms > 2)
if (NumberOfRooms >= 2)
{
var room = _rooms[NumberOfRooms - 3];
var room = _rooms[NumberOfRooms - 2];
// lock the doors that might be used to return to the old room
room.exit.toIn.DoorState.Lock();

View File

@@ -15,6 +15,9 @@ namespace EscapeRoomEngine.Engine.Runtime
{
#region Theme
[BoxGroup("Theme")]
public Intro intro;
[BoxGroup("Theme")] [Required]
[Tooltip("The tile that rooms are generated from.")]
public SpaceTile spaceTile;
@@ -33,6 +36,9 @@ namespace EscapeRoomEngine.Engine.Runtime
[BoxGroup("Doors")] [Required]
public DoorModuleDescription spawnDoor;
[BoxGroup("Doors")] [Required]
public DoorModuleDescription introExitDoor;
[BoxGroup("Doors")] [ValidateInput("IsNotEmpty", "At least one exit door type is required.")]
[Tooltip("The types of exit doors this theme provides. Entrance doors are connected to the exit doors and don't need to be specified here.")]
public List<DoorModuleDescription> exitDoorTypes;

View File

@@ -0,0 +1,14 @@
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime
{
public class Intro : MonoBehaviour
{
public void Place(Transform placement)
{
var t = transform;
t.position = placement.position;
t.rotation = placement.rotation;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c2e3fc71dc4142888bad2313cbf1bea9
timeCreated: 1684011098

View File

@@ -0,0 +1,19 @@
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime
{
public class IntroSpace : Space
{
internal IntroSpace(Room room, Passage entrance) : base(room, entrance) {}
internal override 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);
// instantiate all modules inside this space
Modules.ForEach(module => module.InstantiateModule(spaceObject.transform));
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 84603b46fb8d4513945a113de3e6af72
timeCreated: 1684066247

View File

@@ -0,0 +1,46 @@
using System.Collections.Generic;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Modules.State;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Requirements.Placement
{
/// <summary>
/// This requirement guarantees that the back side of the module is placed on the bottom row of an even-numbered space or on the top row of an odd-numbered space.
/// </summary>
[CreateAssetMenu(menuName = "Requirements/Place On Bottom Or Top Row Alternating")]
public class PlaceOnBottomOrTopRowAlternating : PlacementRequirement
{
protected override List<Utilities.Placement> FilterCandidates(List<Utilities.Placement> candidates, Module module, Space space)
{
if (!module.description.HasType(ModuleType.DoorExit))
{
throw new WrongTypeException(module.description.types[0], ModuleType.DoorExit);
}
var number = FindObjectsByType<DoorState>(FindObjectsInactive.Include, FindObjectsSortMode.None).Length;
if (number / 2 % 2 == 0)
{
candidates.RemoveAll(candidate =>
{
var (left, right) = candidate.BackCorners;
return !(left.z == 0 && right.z == 0);
});
}
else
{
var sizeMinusOne = space.rrPlacement.size - Vector2Int.one;
candidates.RemoveAll(candidate =>
{
var (left, right) = candidate.BackCorners;
return !(left.z == sizeMinusOne.y && right.z == sizeMinusOne.y);
});
}
return candidates;
}
}
}

View File

@@ -1,24 +0,0 @@
using System.Collections.Generic;
using EscapeRoomEngine.Engine.Runtime.Modules;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Requirements.Placement
{
/// <summary>
/// This requirement guarantees that the back side of the module is placed on the bottom row of the space.
/// </summary>
[CreateAssetMenu(menuName = "Requirements/Place On Bottom Row")]
public class PlaceOnBottomRow : PlacementRequirement
{
protected override List<Utilities.Placement> FilterCandidates(List<Utilities.Placement> candidates, Module module, Space space)
{
candidates.RemoveAll(candidate =>
{
var (left, right) = candidate.BackCorners;
return !(left.z == 0 && right.z == 0);
});
return candidates;
}
}
}

View File

@@ -91,7 +91,11 @@ namespace EscapeRoomEngine.Engine.Runtime
// start measurements on every puzzle as soon as the player enters the last room
case DoorEventType.ExitedFrom when door.Equals(entrance.toIn) && Engine.Instance.CurrentRoom.Contains(this):
puzzles.ForEach(puzzle => Measure.StartMeasuring((PuzzleModuleDescription)puzzle.description));
// Engine.Instance.HidePreviousRoom();
if (Engine.Instance.NumberOfRooms == 2)
{
// hide the intro room when exiting the first portal
Engine.Instance.HidePreviousRoom(false);
}
break;
}
};

View File

@@ -41,8 +41,10 @@ namespace EscapeRoomEngine.Engine.Runtime
return modules;
}
}
protected GameObject spaceObject;
private GameObject _spaceObject, _spaceTiles;
private GameObject _spaceTiles;
private List<Module> _stagedModules = new();
internal Space(Room room, Passage entrance)
@@ -97,15 +99,15 @@ namespace EscapeRoomEngine.Engine.Runtime
return requirementsFulfilled;
}
internal void InstantiateSpace(Transform parent, string name)
internal virtual 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);
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.transform.SetParent(spaceObject.transform, false);
_spaceTiles.isStatic = true;
for (var z = 0; z < rrPlacement.size.y; z++)
{
@@ -131,7 +133,7 @@ namespace EscapeRoomEngine.Engine.Runtime
}
// instantiate all modules inside this space
Modules.ForEach(module => module.InstantiateModule(_spaceObject.transform));
Modules.ForEach(module => module.InstantiateModule(spaceObject.transform));
}
/// <summary>

View File

@@ -130,6 +130,7 @@ namespace EscapeRoomEngine.Engine.Runtime.UI
public void StartGame()
{
gameState = GameState.Running;
PauseGame(); // the time is not running during the intro
TimeElapsed = 0;
@@ -174,6 +175,12 @@ namespace EscapeRoomEngine.Engine.Runtime.UI
pauseButton.GetComponent<PauseButton>().Paused = true;
break;
case GameState.Paused:
// check if the intro portal should be activated
if (Engine.Instance.NumberOfRooms == 1)
{
Engine.Instance.CurrentRoom.Unwrap().SkipRoom();
}
gameState = GameState.Running;
pauseButton.GetComponent<PauseButton>().Paused = false;
break;

View File

@@ -14,6 +14,8 @@ namespace EscapeRoomEngine.Engine.Runtime.Utilities
public WrongTypeException(DoorType expected, DoorType found) : base($"Wrong door type ({found} instead of {expected})") {}
public WrongTypeException(ModuleType expected, ModuleType found) : base($"Wrong module type ({found} instead of {expected})") {}
public WrongTypeException(string message) : base(message) {}
}