requirements for exit door
This commit is contained in:
@@ -73,64 +73,19 @@ namespace Escape_Room_Engine.Engine.Scripts
|
|||||||
|
|
||||||
// add exit
|
// add exit
|
||||||
var exitDoor = new DoorModule(space, exitDoorTypes.RandomElement());
|
var exitDoor = new DoorModule(space, exitDoorTypes.RandomElement());
|
||||||
exitDoor.Place(new Vector2Int(
|
if (!space.AddModuleWithRequirements(exitDoor))
|
||||||
Random.Range(0, rrDimensions.width),
|
throw new Exception("Could not satisfy requirements for exit door.");
|
||||||
Random.Range(0, rrDimensions.length)
|
|
||||||
));
|
|
||||||
exitDoor.orientation = Module.EveryOrientation.RandomElement();
|
|
||||||
var exit = new Passage(exitDoor);
|
var exit = new Passage(exitDoor);
|
||||||
space.AddModule(exitDoor);
|
|
||||||
|
|
||||||
// add puzzles
|
// add puzzles
|
||||||
for (var i = 0; i < Utilities.Utilities.RandomInclusive(minPuzzleCount, maxPuzzleCount); i++)
|
for (var i = 0; i < Utilities.Utilities.RandomInclusive(minPuzzleCount, maxPuzzleCount); i++)
|
||||||
{
|
{
|
||||||
GeneratePuzzle(space);
|
space.AddModuleWithRequirements(new PuzzleModule(space, puzzleTypes.RandomElement()));
|
||||||
}
|
}
|
||||||
|
|
||||||
room.AddSpace(space, exit);
|
room.AddSpace(space, exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GeneratePuzzle(Space space)
|
|
||||||
{
|
|
||||||
var puzzle = new PuzzleModule(space, puzzleTypes.RandomElement());
|
|
||||||
|
|
||||||
// place puzzle
|
|
||||||
var placementCandidates = space.rrDimensions.EveryPosition;
|
|
||||||
puzzle.description.RequirementsOfType<PlacementRequirement>().ForEach(requirement =>
|
|
||||||
placementCandidates.IntersectWith(requirement.PlacementCandidates(puzzle, space)));
|
|
||||||
|
|
||||||
Logger.Log($"placement candidates: {string.Join(", ", placementCandidates.ToList().ConvertAll(c => c.ToString()))}", LogType.RequirementResolution);
|
|
||||||
|
|
||||||
if (placementCandidates.Count > 0)
|
|
||||||
{
|
|
||||||
puzzle.Place(placementCandidates.RandomElement());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger.Log("Could not find suitable placement for puzzle", LogType.PuzzleGeneration);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// orient puzzle
|
|
||||||
var orientationCandidates = Module.EveryOrientation;
|
|
||||||
puzzle.description.RequirementsOfType<OrientationRequirement>().ForEach(requirement =>
|
|
||||||
orientationCandidates.IntersectWith(requirement.OrientationCandidates(puzzle, space)));
|
|
||||||
|
|
||||||
Logger.Log($"orientation candidates: {string.Join(",", orientationCandidates.ToList().ConvertAll(c => c.ToString()))}", LogType.RequirementResolution);
|
|
||||||
|
|
||||||
if (orientationCandidates.Count > 0)
|
|
||||||
{
|
|
||||||
puzzle.orientation = orientationCandidates.RandomElement();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger.Log("Could not find suitable orientation for puzzle", LogType.PuzzleGeneration);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
space.AddModule(puzzle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate space dimensions that fit the required size constraints and cover the position of the entrance.
|
/// Generate space dimensions that fit the required size constraints and cover the position of the entrance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -9,11 +9,7 @@ namespace Escape_Room_Engine.Engine.Scripts.Modules
|
|||||||
{
|
{
|
||||||
public List<ModuleType> types = new();
|
public List<ModuleType> types = new();
|
||||||
public GameObject modulePrefab;
|
public GameObject modulePrefab;
|
||||||
public List<Requirement> requirements = new();
|
public List<PlacementRequirement> placementRequirements = new();
|
||||||
|
public List<OrientationRequirement> orientationRequirements = new();
|
||||||
public List<T> RequirementsOfType<T>() where T : Requirement
|
|
||||||
{
|
|
||||||
return requirements.FindAll(requirement => requirement is T).ConvertAll(requirement => (T)requirement);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,13 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Escape_Room_Engine.Engine.Scripts.Modules;
|
using Escape_Room_Engine.Engine.Scripts.Modules;
|
||||||
using Unity.XR.CoreUtils;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Logger = Escape_Room_Engine.Engine.Scripts.Utilities.Logger;
|
|
||||||
using LogType = Escape_Room_Engine.Engine.Scripts.Utilities.LogType;
|
|
||||||
|
|
||||||
namespace Escape_Room_Engine.Engine.Scripts.Requirements
|
namespace Escape_Room_Engine.Engine.Scripts.Requirements
|
||||||
{
|
{
|
||||||
[CreateAssetMenu(menuName = "Requirements/Face Space Center")]
|
[CreateAssetMenu(menuName = "Requirements/Face Space Center")]
|
||||||
public class FaceSpaceCenter : OrientationRequirement
|
public class FaceSpaceCenter : OrientationRequirement
|
||||||
{
|
{
|
||||||
public override IEnumerable<Orientation> OrientationCandidates(Module module, Space space)
|
protected override IEnumerable<Orientation> GenerateCandidates(Module module, Space space)
|
||||||
{
|
{
|
||||||
var orientation = new HashSet<Orientation>(1);
|
var orientation = new HashSet<Orientation>(1);
|
||||||
float width = space.rrDimensions.width;
|
float width = space.rrDimensions.width;
|
||||||
@@ -18,8 +15,6 @@ namespace Escape_Room_Engine.Engine.Scripts.Requirements
|
|||||||
var xRel = module.SrPosition.x / (width - 1);
|
var xRel = module.SrPosition.x / (width - 1);
|
||||||
var zRel = module.SrPosition.y / (length - 1);
|
var zRel = module.SrPosition.y / (length - 1);
|
||||||
|
|
||||||
Debug.Log($"{xRel}, {zRel}, {1 - xRel}");
|
|
||||||
|
|
||||||
if (zRel > xRel)
|
if (zRel > xRel)
|
||||||
{
|
{
|
||||||
orientation.Add(zRel > 1 - xRel ? Orientation.South : Orientation.East);
|
orientation.Add(zRel > 1 - xRel ? Orientation.South : Orientation.East);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Escape_Room_Engine.Engine.Scripts.Requirements
|
|||||||
[CreateAssetMenu(menuName = "Requirements/No Overlap")]
|
[CreateAssetMenu(menuName = "Requirements/No Overlap")]
|
||||||
public class NoOverlap : PlacementRequirement
|
public class NoOverlap : PlacementRequirement
|
||||||
{
|
{
|
||||||
public override IEnumerable<Vector2Int> PlacementCandidates(Module module, Space space)
|
protected override IEnumerable<Vector2Int> GenerateCandidates(Module module, Space space)
|
||||||
{
|
{
|
||||||
var edgePositions = space.rrDimensions.EveryPosition;
|
var edgePositions = space.rrDimensions.EveryPosition;
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,34 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Escape_Room_Engine.Engine.Scripts.Modules;
|
using Escape_Room_Engine.Engine.Scripts.Modules;
|
||||||
|
using Escape_Room_Engine.Engine.Scripts.Utilities;
|
||||||
|
|
||||||
namespace Escape_Room_Engine.Engine.Scripts.Requirements
|
namespace Escape_Room_Engine.Engine.Scripts.Requirements
|
||||||
{
|
{
|
||||||
public abstract class OrientationRequirement : Requirement
|
public abstract class OrientationRequirement : Requirement<Orientation>
|
||||||
{
|
{
|
||||||
public abstract IEnumerable<Orientation> OrientationCandidates(Module module, Space space);
|
protected abstract override IEnumerable<Orientation> GenerateCandidates(Module module, Space space);
|
||||||
|
|
||||||
|
public static bool TryOrienting(Module module, Space space)
|
||||||
|
{
|
||||||
|
var orientationCandidates = Candidates(
|
||||||
|
Module.EveryOrientation,
|
||||||
|
module.description.orientationRequirements,
|
||||||
|
module, space);
|
||||||
|
|
||||||
|
Logger.Log($"orientation candidates: {string.Join(",", orientationCandidates.ToList().ConvertAll(c => c.ToString()))}", LogType.RequirementResolution);
|
||||||
|
|
||||||
|
if (orientationCandidates.Count > 0)
|
||||||
|
{
|
||||||
|
module.orientation = orientationCandidates.RandomElement();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// ReSharper disable once RedundantIfElseBlock
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Log("Could not find suitable orientation for module", LogType.PuzzleGeneration);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ namespace Escape_Room_Engine.Engine.Scripts.Requirements
|
|||||||
[CreateAssetMenu(menuName = "Requirements/Place Along Space Edges")]
|
[CreateAssetMenu(menuName = "Requirements/Place Along Space Edges")]
|
||||||
public class PlaceAlongSpaceEdges : PlacementRequirement
|
public class PlaceAlongSpaceEdges : PlacementRequirement
|
||||||
{
|
{
|
||||||
public override IEnumerable<Vector2Int> PlacementCandidates(Module module, Space space)
|
protected override IEnumerable<Vector2Int> GenerateCandidates(Module module, Space space)
|
||||||
{
|
{
|
||||||
var edgePositions = new HashSet<Vector2Int>();
|
var edgePositions = new HashSet<Vector2Int>();
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Escape_Room_Engine.Engine.Scripts.Requirements
|
|||||||
[CreateAssetMenu(menuName = "Requirements/Place Anywhere")]
|
[CreateAssetMenu(menuName = "Requirements/Place Anywhere")]
|
||||||
public class PlaceAnywhere : PlacementRequirement
|
public class PlaceAnywhere : PlacementRequirement
|
||||||
{
|
{
|
||||||
public override IEnumerable<Vector2Int> PlacementCandidates(Module module, Space space)
|
protected override IEnumerable<Vector2Int> GenerateCandidates(Module module, Space space)
|
||||||
{
|
{
|
||||||
return space.rrDimensions.EveryPosition;
|
return space.rrDimensions.EveryPosition;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,35 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Escape_Room_Engine.Engine.Scripts.Modules;
|
using Escape_Room_Engine.Engine.Scripts.Modules;
|
||||||
|
using Escape_Room_Engine.Engine.Scripts.Utilities;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Escape_Room_Engine.Engine.Scripts.Requirements
|
namespace Escape_Room_Engine.Engine.Scripts.Requirements
|
||||||
{
|
{
|
||||||
public abstract class PlacementRequirement : Requirement
|
public abstract class PlacementRequirement : Requirement<Vector2Int>
|
||||||
{
|
{
|
||||||
public abstract IEnumerable<Vector2Int> PlacementCandidates(Module module, Space space);
|
protected abstract override IEnumerable<Vector2Int> GenerateCandidates(Module module, Space space);
|
||||||
|
|
||||||
|
public static bool TryPlacing(Module module, Space space)
|
||||||
|
{
|
||||||
|
var placementCandidates = Candidates(
|
||||||
|
space.rrDimensions.EveryPosition,
|
||||||
|
module.description.placementRequirements,
|
||||||
|
module, space);
|
||||||
|
|
||||||
|
Utilities.Logger.Log($"placement candidates: {string.Join(", ", placementCandidates.ToList().ConvertAll(c => c.ToString()))}", Utilities.LogType.RequirementResolution);
|
||||||
|
|
||||||
|
if (placementCandidates.Count > 0)
|
||||||
|
{
|
||||||
|
module.Place(placementCandidates.RandomElement());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// ReSharper disable once RedundantIfElseBlock
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Utilities.Logger.Log("Could not find suitable placement for module", Utilities.LogType.PuzzleGeneration);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,27 @@
|
|||||||
using UnityEngine;
|
using System.Collections.Generic;
|
||||||
|
using Escape_Room_Engine.Engine.Scripts.Modules;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Escape_Room_Engine.Engine.Scripts.Requirements
|
namespace Escape_Room_Engine.Engine.Scripts.Requirements
|
||||||
{
|
{
|
||||||
public abstract class Requirement : ScriptableObject
|
public abstract class Requirement<T> : ScriptableObject
|
||||||
{
|
{
|
||||||
|
protected abstract IEnumerable<T> GenerateCandidates(Module module, Space space);
|
||||||
|
|
||||||
|
public void Restrict(HashSet<T> candidates, Module module, Space space) =>
|
||||||
|
candidates.IntersectWith(GenerateCandidates(module, space));
|
||||||
|
|
||||||
|
public static HashSet<T> Candidates(
|
||||||
|
HashSet<T> initialCandidates,
|
||||||
|
IEnumerable<Requirement<T>> requirements,
|
||||||
|
Module module, Space space)
|
||||||
|
{
|
||||||
|
foreach (var requirement in requirements)
|
||||||
|
{
|
||||||
|
requirement.Restrict(initialCandidates, module, space);
|
||||||
|
}
|
||||||
|
|
||||||
|
return initialCandidates;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Escape_Room_Engine.Engine.Scripts.Modules;
|
using Escape_Room_Engine.Engine.Scripts.Modules;
|
||||||
|
using Escape_Room_Engine.Engine.Scripts.Requirements;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Escape_Room_Engine.Engine.Scripts
|
namespace Escape_Room_Engine.Engine.Scripts
|
||||||
@@ -29,6 +30,17 @@ namespace Escape_Room_Engine.Engine.Scripts
|
|||||||
Modules.Add(module);
|
Modules.Add(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal bool AddModuleWithRequirements(Module module)
|
||||||
|
{
|
||||||
|
var result =
|
||||||
|
PlacementRequirement.TryPlacing(module, this) &&
|
||||||
|
OrientationRequirement.TryOrienting(module, this);
|
||||||
|
|
||||||
|
AddModule(module);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
internal void InstantiateSpace(Transform parent, string name)
|
internal void InstantiateSpace(Transform parent, string name)
|
||||||
{
|
{
|
||||||
_spaceObject = new GameObject($"Space {name}", typeof(MeshFilter), typeof(MeshRenderer));
|
_spaceObject = new GameObject($"Space {name}", typeof(MeshFilter), typeof(MeshRenderer));
|
||||||
|
|||||||
Reference in New Issue
Block a user