From 648919cf5a8c52fe37ad4ba02b1264a025652ab7 Mon Sep 17 00:00:00 2001 From: milan Date: Mon, 7 Nov 2022 20:51:00 +0100 Subject: [PATCH] make sure every module is accessible --- .../Generic Door Entrance.asset | 6 ++-- .../Generic Door Exit.asset | 4 ++- .../Module Descriptions/Generic Module.asset | 4 ++- .../Module Descriptions/Generic Puzzle.asset | 4 ++- .../Engine/Module Descriptions/Spawn.asset | 5 +-- .../Engine/Requirements/No Overlap.asset | 5 +++ .../Engine/Scripts/Engine.cs | 36 ++++++++++++++----- .../Engine/Scripts/Modules/Module.cs | 18 ++++++++++ .../Engine/Scripts/Requirements/NoOverlap.cs | 18 ++++++++-- .../Engine/Scripts/Space.cs | 15 ++++---- Assets/Scenes/TestScene.unity | 7 ++-- Packages/manifest.json | 1 + Packages/packages-lock.json | 7 ++++ 13 files changed, 100 insertions(+), 30 deletions(-) diff --git a/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Door Entrance.asset b/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Door Entrance.asset index fd2ac1e..57877bb 100644 --- a/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Door Entrance.asset +++ b/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Door Entrance.asset @@ -15,8 +15,8 @@ MonoBehaviour: types: 00000000 modulePrefab: {fileID: 5399176795272327488, guid: da9b7a57e7c37d149827fe17188bdeea, type: 3} - requirements: - - {fileID: 11400000, guid: ed4830127e9381245a6af07e42c52422, type: 2} - - {fileID: 11400000, guid: 1f1825b71bae09c438a1cb52603347d6, type: 2} + placementRequirements: + - {fileID: 11400000, guid: 43eb2a566a244964aa3a3319eaafe1a8, type: 2} + orientationRequirements: [] connectedDoorDescription: {fileID: 11400000, guid: 29e2ae36585f4e65966bc9ea2f95ac4a, type: 2} diff --git a/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Door Exit.asset b/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Door Exit.asset index 4b6d09d..465511c 100644 --- a/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Door Exit.asset +++ b/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Door Exit.asset @@ -15,8 +15,10 @@ MonoBehaviour: types: 01000000 modulePrefab: {fileID: 5399176795272327488, guid: d877ee36ba6ace440aebce2c20cf70d6, type: 3} - requirements: + placementRequirements: + - {fileID: 11400000, guid: 43eb2a566a244964aa3a3319eaafe1a8, type: 2} - {fileID: 11400000, guid: ed4830127e9381245a6af07e42c52422, type: 2} + orientationRequirements: - {fileID: 11400000, guid: 1f1825b71bae09c438a1cb52603347d6, type: 2} connectedDoorDescription: {fileID: 11400000, guid: a70cb93176094309a847f1928d6b950d, type: 2} diff --git a/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Module.asset b/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Module.asset index f343439..f31f469 100644 --- a/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Module.asset +++ b/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Module.asset @@ -15,4 +15,6 @@ MonoBehaviour: types: modulePrefab: {fileID: 3864228228344123331, guid: ad2655de8289afa40aa520f9fc474681, type: 3} - requirements: [] + placementRequirements: + - {fileID: 11400000, guid: 43eb2a566a244964aa3a3319eaafe1a8, type: 2} + orientationRequirements: [] diff --git a/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Puzzle.asset b/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Puzzle.asset index 19be419..01c2f50 100644 --- a/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Puzzle.asset +++ b/Assets/Escape Room Engine/Engine/Module Descriptions/Generic Puzzle.asset @@ -15,6 +15,8 @@ MonoBehaviour: types: 02000000 modulePrefab: {fileID: 1780958886295268827, guid: e419cb35bd744b24ea973860d8b1405d, type: 3} - requirements: + placementRequirements: + - {fileID: 11400000, guid: 43eb2a566a244964aa3a3319eaafe1a8, type: 2} - {fileID: 11400000, guid: ed4830127e9381245a6af07e42c52422, type: 2} + orientationRequirements: - {fileID: 11400000, guid: 1f1825b71bae09c438a1cb52603347d6, type: 2} diff --git a/Assets/Escape Room Engine/Engine/Module Descriptions/Spawn.asset b/Assets/Escape Room Engine/Engine/Module Descriptions/Spawn.asset index 02ed078..502ff8a 100644 --- a/Assets/Escape Room Engine/Engine/Module Descriptions/Spawn.asset +++ b/Assets/Escape Room Engine/Engine/Module Descriptions/Spawn.asset @@ -15,6 +15,7 @@ MonoBehaviour: types: 00000000 modulePrefab: {fileID: 641449049689494886, guid: db5350cd22f3a0f4f818a5f985342136, type: 3} - requirements: [] - doorType: 0 + placementRequirements: + - {fileID: 11400000, guid: 43eb2a566a244964aa3a3319eaafe1a8, type: 2} + orientationRequirements: [] connectedDoorDescription: {fileID: 11400000} diff --git a/Assets/Escape Room Engine/Engine/Requirements/No Overlap.asset b/Assets/Escape Room Engine/Engine/Requirements/No Overlap.asset index fd074fa..99ed9eb 100644 --- a/Assets/Escape Room Engine/Engine/Requirements/No Overlap.asset +++ b/Assets/Escape Room Engine/Engine/Requirements/No Overlap.asset @@ -12,3 +12,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 58ae9c09c887475d833d2cd4ee4ccffb, type: 3} m_Name: No Overlap m_EditorClassIdentifier: + mrReservedPositions: + - {x: 1, y: 0} + - {x: 0, y: 1} + - {x: -1, y: 0} + - {x: 0, y: -1} diff --git a/Assets/Escape Room Engine/Engine/Scripts/Engine.cs b/Assets/Escape Room Engine/Engine/Scripts/Engine.cs index 6b8a6f4..cb822c4 100644 --- a/Assets/Escape Room Engine/Engine/Scripts/Engine.cs +++ b/Assets/Escape Room Engine/Engine/Scripts/Engine.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using Escape_Room_Engine.Engine.Scripts.Modules; using Escape_Room_Engine.Engine.Scripts.Utilities; +using NaughtyAttributes; using UnityEngine; using Logger = Escape_Room_Engine.Engine.Scripts.Utilities.Logger; using LogType = Escape_Room_Engine.Engine.Scripts.Utilities.LogType; @@ -23,16 +24,31 @@ namespace Escape_Room_Engine.Engine.Scripts } } private static Engine _foundEngine; + + [BoxGroup("Size")] + [Tooltip("The minimum size that should be allowed for rooms.")] + public Vector2Int minRoomSize; + + [BoxGroup("Size")] + [Tooltip("The size of the physical play space available to the engine.")] + public Vector2Int playSpace; + + [BoxGroup("Doors")] + [Required] + public DoorModuleDescription spawnDoor; + + [BoxGroup("Doors")] + [ValidateInput("IsNotEmpty", "At least one exit door type is required")] + public List exitDoorTypes; + + [BoxGroup("Puzzles")] + [MinMaxSlider(0, 10)] public Vector2Int puzzleCount; + + [BoxGroup("Puzzles")] + public List puzzleTypes; public Material roomMaterial; - - [Range(0, 10)] public int minPuzzleCount, maxPuzzleCount; - [Tooltip("The minimum size that should be allowed for rooms.")] public Vector2Int minRoomSize; - [Tooltip("The size of the physical play space available to the engine.")] public Vector2Int playSpace; public ModuleDescription genericModule; - public DoorModuleDescription spawnDoor; - public List exitDoorTypes; - public List puzzleTypes; private int NumberOfRooms => _rooms.Count; @@ -75,7 +91,7 @@ namespace Escape_Room_Engine.Engine.Scripts var exit = new Passage(exitDoor); // add puzzles - for (var i = 0; i < Utilities.Utilities.RandomInclusive(minPuzzleCount, maxPuzzleCount); i++) + for (var i = 0; i < Utilities.Utilities.RandomInclusive(puzzleCount.x, puzzleCount.y); i++) { space.AddModuleWithRequirements(new PuzzleModule(space, puzzleTypes.RandomElement())); } @@ -90,5 +106,9 @@ namespace Escape_Room_Engine.Engine.Scripts _rooms[NumberOfRooms - 1].roomObject.SetActive(false); } } + + // ReSharper disable once SuggestBaseTypeForParameter + // ReSharper disable once UnusedMember.Local + private bool IsNotEmpty(List modules) => modules.Count > 0; } } diff --git a/Assets/Escape Room Engine/Engine/Scripts/Modules/Module.cs b/Assets/Escape Room Engine/Engine/Scripts/Modules/Module.cs index a09ec17..1e6c03f 100644 --- a/Assets/Escape Room Engine/Engine/Scripts/Modules/Module.cs +++ b/Assets/Escape Room Engine/Engine/Scripts/Modules/Module.cs @@ -74,6 +74,24 @@ namespace Escape_Room_Engine.Engine.Scripts.Modules Logger.Log($"{this} has been placed at {srPosition} (SR)", LogType.ModulePlacement); } + /// + /// Convert a position relative to this module to one relative to its space. + /// The module relative position (0, 1) should always be in front of the module, wherever it faces. + /// + /// The module relative (MR) position that should be converted to a space relative (SR) position. + /// + internal Vector2Int ToSpaceRelative(Vector2Int mrPosition) + { + return srDimensions.Position + orientation switch + { + Orientation.North => mrPosition, + Orientation.East => new Vector2Int(mrPosition.y, -mrPosition.x), + Orientation.South => -mrPosition, + Orientation.West => new Vector2Int(-mrPosition.y, mrPosition.x), + _ => throw new ArgumentOutOfRangeException() + }; + } + internal void InstantiateModule(Transform parent) { _moduleObject = new GameObject(ToString()); diff --git a/Assets/Escape Room Engine/Engine/Scripts/Requirements/NoOverlap.cs b/Assets/Escape Room Engine/Engine/Scripts/Requirements/NoOverlap.cs index a247354..1c6d7d7 100644 --- a/Assets/Escape Room Engine/Engine/Scripts/Requirements/NoOverlap.cs +++ b/Assets/Escape Room Engine/Engine/Scripts/Requirements/NoOverlap.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Escape_Room_Engine.Engine.Scripts.Modules; +using NaughtyAttributes; using UnityEngine; namespace Escape_Room_Engine.Engine.Scripts.Requirements @@ -7,13 +8,24 @@ namespace Escape_Room_Engine.Engine.Scripts.Requirements [CreateAssetMenu(menuName = "Requirements/No Overlap")] public class NoOverlap : PlacementRequirement { + [InfoBox("A module relative position will be oriented with the module (e.g. (0, 1) is always in front of the module).")] + [Label("Reserved Positions (Module Relative)")] + public List mrReservedPositions; + protected override IEnumerable GenerateCandidates(Module module, Space space) { - var edgePositions = space.rrDimensions.EveryPosition; + var candidates = space.rrDimensions.EveryPosition; - space.Modules.ForEach(m => edgePositions.Remove(m.SrPosition)); + space.Modules.ForEach(m => + { + candidates.Remove(m.SrPosition); + m.description.placementRequirements + .FindAll(r => r is NoOverlap) + .ForEach(r => ((NoOverlap)r).mrReservedPositions + .ForEach(p => candidates.Remove(m.ToSpaceRelative(p)))); + }); - return edgePositions; + return candidates; } } } \ No newline at end of file diff --git a/Assets/Escape Room Engine/Engine/Scripts/Space.cs b/Assets/Escape Room Engine/Engine/Scripts/Space.cs index 70f2800..d43f710 100644 --- a/Assets/Escape Room Engine/Engine/Scripts/Space.cs +++ b/Assets/Escape Room Engine/Engine/Scripts/Space.cs @@ -35,13 +35,16 @@ namespace Escape_Room_Engine.Engine.Scripts internal bool AddModuleWithRequirements(Module module) { - var result = + var requirementsFulfilled = PlacementRequirement.TryPlacing(module, this) && OrientationRequirement.TryOrienting(module, this); - - AddModule(module); - - return result; + + if (requirementsFulfilled) + { + AddModule(module); + } + + return requirementsFulfilled; } internal void InstantiateSpace(Transform parent, string name) @@ -64,13 +67,11 @@ namespace Escape_Room_Engine.Engine.Scripts /// Convert a position relative to this space to one relative to the room. /// /// The space relative (SR) position that should be converted to a room relative (RR) position. - /// internal Vector2Int ToRoomRelative(Vector2Int srPosition) => srPosition + rrDimensions.Position; /// /// Convert a position relative to the room to one relative to this space. /// /// The room relative (RR) position that should be converted to a space relative (SR) position. - /// internal Vector2Int ToSpaceRelative(Vector2Int rrPosition) => rrPosition - rrDimensions.Position; private Mesh GenerateMesh() diff --git a/Assets/Scenes/TestScene.unity b/Assets/Scenes/TestScene.unity index 886c65d..6eb39a8 100644 --- a/Assets/Scenes/TestScene.unity +++ b/Assets/Scenes/TestScene.unity @@ -1232,17 +1232,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 9a9b6b8b557abbb4ab172444615ebf23, type: 3} m_Name: m_EditorClassIdentifier: - roomMaterial: {fileID: 2100000, guid: 39e2ed014eda5d6408c16fbf0fa80781, type: 2} - minPuzzleCount: 2 - maxPuzzleCount: 5 minRoomSize: {x: 3, y: 3} playSpace: {x: 4, y: 6} - genericModule: {fileID: 11400000, guid: cba85a4318ad4750860b84245d9685c4, type: 2} spawnDoor: {fileID: 11400000, guid: 6e937b2e9f774999b5962c4b40947165, type: 2} exitDoorTypes: - {fileID: 11400000, guid: 29e2ae36585f4e65966bc9ea2f95ac4a, type: 2} + puzzleCount: {x: 2, y: 5} puzzleTypes: - {fileID: 11400000, guid: 2a6dd6683bdc4db9b200ccfab1dd4bed, type: 2} + roomMaterial: {fileID: 2100000, guid: 39e2ed014eda5d6408c16fbf0fa80781, type: 2} + genericModule: {fileID: 11400000, guid: cba85a4318ad4750860b84245d9685c4, type: 2} --- !u!4 &1568048335 Transform: m_ObjectHideFlags: 0 diff --git a/Packages/manifest.json b/Packages/manifest.json index 4f3a28b..1e0d9f1 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -1,5 +1,6 @@ { "dependencies": { + "com.dbrizov.naughtyattributes": "https://github.com/dbrizov/NaughtyAttributes.git#upm", "com.unity.collab-proxy": "1.17.6", "com.unity.ide.rider": "3.0.16", "com.unity.ide.visualstudio": "2.0.16", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index c07e8b0..02fca94 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -1,5 +1,12 @@ { "dependencies": { + "com.dbrizov.naughtyattributes": { + "version": "https://github.com/dbrizov/NaughtyAttributes.git#upm", + "depth": 0, + "source": "git", + "dependencies": {}, + "hash": "8a8fa5a9659a6d63f196391c71e06c4286c8acd7" + }, "com.unity.burst": { "version": "1.7.3", "depth": 1,