requirements foundation

This commit is contained in:
2022-11-07 14:21:00 +01:00
parent 7e9331f612
commit 8719543f96
34 changed files with 332 additions and 160 deletions

View File

@@ -1,4 +1,5 @@
using UnityEngine;
using System.Collections.Generic;
using UnityEngine;
namespace Escape_Room_Engine.Engine.Scripts
{
@@ -39,6 +40,24 @@ namespace Escape_Room_Engine.Engine.Scripts
public int Area => width * length;
public HashSet<Vector2Int> EveryPosition
{
get
{
var positions = new HashSet<Vector2Int>();
for (var zIter = 0; zIter < length; zIter++)
{
for (var xIter = 0; xIter < width; xIter++)
{
positions.Add(new Vector2Int(xIter, zIter));
}
}
return positions;
}
}
public override string ToString() => $"({width}, {length}) at ({x}, {z})";
}
}

View File

@@ -82,17 +82,31 @@ namespace Escape_Room_Engine.Engine.Scripts
// add puzzles
for (var i = 0; i < Utilities.Utilities.RandomInclusive(minPuzzleCount, maxPuzzleCount); i++)
{
var puzzle = new PuzzleModule(space, puzzleTypes.RandomElement());
puzzle.Place(new Vector2Int(
Random.Range(0, rrDimensions.width),
Random.Range(0, rrDimensions.length)
));
space.AddModule(puzzle);
GeneratePuzzle(space);
}
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.PlacementRequirements.ForEach(requirement =>
placementCandidates.IntersectWith(requirement.PlacementCandidates(puzzle, space)));
if (placementCandidates.Count > 0)
{
puzzle.Place(placementCandidates.RandomElement());
space.AddModule(puzzle);
}
else
{
Logger.Log("Could not find suitable placement for puzzle", LogType.PuzzleGeneration);
}
}
/// <summary>
/// Generate space dimensions that fit the required size constraints and cover the position of the entrance.
/// </summary>

View File

@@ -16,7 +16,6 @@ namespace Escape_Room_Engine.Engine.Scripts.Modules
internal DoorModule(Space space, DoorModuleDescription description) : base(space, description)
{
_description.types.Add((ModuleType)description.doorType);
srDimensions.Size = Vector2Int.one; // door always has size 1x1
}

View File

@@ -5,7 +5,6 @@ namespace Escape_Room_Engine.Engine.Scripts.Modules
[CreateAssetMenu(menuName = "Modules/Door")]
public class DoorModuleDescription : ModuleDescription
{
public DoorType doorType;
/// <summary>
/// The description for the door that should be connected with this one.
/// <example>If this is a teleporter entrance, the connected door should be a teleporter exit.</example>

View File

@@ -8,6 +8,11 @@ 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
{
/// <summary>
@@ -25,6 +30,7 @@ namespace Escape_Room_Engine.Engine.Scripts.Modules
/// The space relative (<i>SR</i>) dimensions of this module.
/// </summary>
protected Dimensions srDimensions;
protected Orientation orientation;
private readonly Space _space;
@@ -65,7 +71,8 @@ namespace Escape_Room_Engine.Engine.Scripts.Modules
{
_moduleObject = new GameObject(ToString());
_moduleObject.transform.SetParent(parent, false);
_moduleObject.transform.localPosition = new Vector3(srDimensions.x, 0, srDimensions.z);
_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);
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Escape_Room_Engine.Engine.Scripts.Requirements;
using UnityEngine;
namespace Escape_Room_Engine.Engine.Scripts.Modules
@@ -6,7 +7,12 @@ namespace Escape_Room_Engine.Engine.Scripts.Modules
[CreateAssetMenu(menuName = "Modules/Generic Module")]
public class ModuleDescription : ScriptableObject
{
public readonly HashSet<ModuleType> types = new();
public List<ModuleType> types = new();
public GameObject modulePrefab;
public List<Requirement> requirements = new();
public List<PlacementRequirement> PlacementRequirements => requirements
.FindAll(requirement => requirement is PlacementRequirement)
.ConvertAll(requirement => (PlacementRequirement)requirement);
}
}

View File

@@ -6,7 +6,6 @@ namespace Escape_Room_Engine.Engine.Scripts.Modules
{
internal PuzzleModule(Space space, PuzzleModuleDescription description) : base(space, description)
{
_description.types.Add(ModuleType.Puzzle);
srDimensions.Size = Vector2Int.one; // TODO: larger modules
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 629d8948cbb04005b050a6aa1e66c0f4
timeCreated: 1667874124

View File

@@ -0,0 +1,28 @@
using System.Collections.Generic;
using Escape_Room_Engine.Engine.Scripts.Modules;
using UnityEngine;
namespace Escape_Room_Engine.Engine.Scripts.Requirements
{
[CreateAssetMenu(menuName = "Requirements/Place Along Space Edges")]
public class PlaceAlongSpaceEdges : PlacementRequirement
{
public override HashSet<Vector2Int> PlacementCandidates(Module module, Space space)
{
var edgePositions = new HashSet<Vector2Int>();
for (var x = 0; x < space.rrDimensions.width; x++)
{
edgePositions.Add(new Vector2Int(x, 0));
edgePositions.Add(new Vector2Int(x, space.rrDimensions.length));
}
for (var z = 0; z < space.rrDimensions.length; z++)
{
edgePositions.Add(new Vector2Int(0, z));
edgePositions.Add(new Vector2Int(space.rrDimensions.width, z));
}
return edgePositions;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8ec2cdf0145347e18e7c68221333be2c
timeCreated: 1667876484

View File

@@ -0,0 +1,15 @@
using System.Collections.Generic;
using Escape_Room_Engine.Engine.Scripts.Modules;
using UnityEngine;
namespace Escape_Room_Engine.Engine.Scripts.Requirements
{
[CreateAssetMenu(menuName = "Requirements/Place Anywhere")]
public class PlaceAnywhere : PlacementRequirement
{
public override HashSet<Vector2Int> PlacementCandidates(Module module, Space space)
{
return space.rrDimensions.EveryPosition;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: aa4ff365b4e844e782cd12d8aeebd3d4
timeCreated: 1667876850

View File

@@ -0,0 +1,11 @@
using System.Collections.Generic;
using Escape_Room_Engine.Engine.Scripts.Modules;
using UnityEngine;
namespace Escape_Room_Engine.Engine.Scripts.Requirements
{
public abstract class PlacementRequirement : Requirement
{
public abstract HashSet<Vector2Int> PlacementCandidates(Module module, Space space);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 65f297b8d32b4f09b89c21b88b43b646
timeCreated: 1667876036

View File

@@ -0,0 +1,9 @@
using UnityEngine;
namespace Escape_Room_Engine.Engine.Scripts.Requirements
{
public abstract class Requirement : ScriptableObject
{
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9123b592f74444c8b6225f725b6407b3
timeCreated: 1667874140

View File

@@ -5,7 +5,7 @@ namespace Escape_Room_Engine.Engine.Scripts.Utilities
{
public enum LogType
{
Important, ModulePlacement, PassageConnection, RoomGeneration
Important, ModulePlacement, PassageConnection, RoomGeneration, PuzzleGeneration
}
public class Logger : MonoBehaviour

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Escape_Room_Engine.Engine.Scripts.Utilities
@@ -24,6 +25,7 @@ namespace Escape_Room_Engine.Engine.Scripts.Utilities
public static int RandomInclusive(int from, int to) => Random.Range(from, to + 1);
public static T RandomElement<T>(this List<T> list) => list[Random.Range(0, list.Count)];
public static T RandomElement<T>(this HashSet<T> set) => set.ElementAt(Random.Range(0, set.Count));
#endregion
}