module relations and module staging

This commit is contained in:
2022-11-21 11:40:54 +01:00
parent 95e447e8ef
commit eeb90ac24c
7 changed files with 69 additions and 21 deletions

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using EscapeRoomEngine.Engine.Runtime.Requirements;
using EscapeRoomEngine.Engine.Runtime.Utilities; using EscapeRoomEngine.Engine.Runtime.Utilities;
using UnityEngine; using UnityEngine;
using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger; using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger;
@@ -21,6 +22,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules
Orientation.North, Orientation.East, Orientation.South, Orientation.West Orientation.North, Orientation.East, Orientation.South, Orientation.West
}); });
public readonly List<Module> relatedModules = new();
public ModuleState State { get; private set; }
/// <summary> /// <summary>
/// Get the space relative (<i>SR</i>) position of this module. /// Get the space relative (<i>SR</i>) position of this module.
/// </summary> /// </summary>
@@ -29,7 +33,6 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules
/// Get the room relative (<i>RR</i>) position of this module. /// Get the room relative (<i>RR</i>) position of this module.
/// </summary> /// </summary>
internal Vector2Int RrPosition => space.ToRoomRelative(SrPosition); internal Vector2Int RrPosition => space.ToRoomRelative(SrPosition);
internal ModuleState State { get; private set; }
internal readonly ModuleDescription description; internal readonly ModuleDescription description;
internal Orientation orientation; internal Orientation orientation;
@@ -52,6 +55,13 @@ namespace EscapeRoomEngine.Engine.Runtime.Modules
return description.types.Contains(type); return description.types.Contains(type);
} }
internal bool CheckRequirements()
{
return PreconditionRequirement.CheckPreconditions(this, space) &&
PlacementRequirement.TryPlacing(this, space) &&
OrientationRequirement.TryOrienting(this, space);
}
/// <summary> /// <summary>
/// Place this module with a position relative to the room. /// Place this module with a position relative to the room.
/// </summary> /// </summary>

View File

@@ -16,7 +16,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Requirements
{ {
var candidates = space.rrDimensions.EveryPosition; var candidates = space.rrDimensions.EveryPosition;
space.Modules.ForEach(m => space.AllModules.ForEach(m =>
{ {
candidates.Remove(m.SrPosition); candidates.Remove(m.SrPosition);
m.description.placementRequirements m.description.placementRequirements

View File

@@ -32,7 +32,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Requirements
// ReSharper disable once RedundantIfElseBlock // ReSharper disable once RedundantIfElseBlock
else else
{ {
Logger.Log("Could not find suitable orientation for module", LogType.ModulePlacement); Logger.Log("Could not find suitable orientation for module", LogType.RequirementResolution);
return false; return false;
} }
} }

View File

@@ -35,7 +35,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Requirements
// ReSharper disable once RedundantIfElseBlock // ReSharper disable once RedundantIfElseBlock
else else
{ {
Logger.Log($"Could not find suitable placement for {module}", LogType.ModulePlacement); Logger.Log($"Could not find suitable placement for {module}", LogType.RequirementResolution);
return false; return false;
} }
} }

View File

@@ -1,6 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using EscapeRoomEngine.Engine.Runtime.Modules; using EscapeRoomEngine.Engine.Runtime.Modules;
using UnityEngine;
using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger; using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger;
using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType; using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType;
@@ -14,7 +13,6 @@ namespace EscapeRoomEngine.Engine.Runtime.Requirements
public static bool CheckPreconditions(Module module, Space space) public static bool CheckPreconditions(Module module, Space space)
{ {
Debug.Log($"{module}, {module.description.preconditionRequirements}");
if (module.description.preconditionRequirements.Count == 0) if (module.description.preconditionRequirements.Count == 0)
{ {
// don't evaluate requirements if there are none // don't evaluate requirements if there are none
@@ -31,7 +29,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Requirements
preconditionsMet preconditionsMet
? $"Preconditions for {module} satisfied" ? $"Preconditions for {module} satisfied"
: $"Could not satisfy preconditions for {module}", : $"Could not satisfy preconditions for {module}",
LogType.ModulePlacement); LogType.RequirementResolution);
return preconditionsMet; return preconditionsMet;
} }

View File

@@ -14,7 +14,10 @@ namespace EscapeRoomEngine.Engine.Runtime.Requirements
protected override IEnumerable<bool> GenerateCandidates(Module module, Space space) protected override IEnumerable<bool> GenerateCandidates(Module module, Space space)
{ {
return new []{ space.AddModuleWithRequirements(Module.CreateModuleByType(space, relatedModule)) }; var newModule = Module.CreateModuleByType(space, relatedModule);
module.relatedModules.Add(newModule);
return new []{ space.StageModuleWithRequirements(newModule) };
} }
} }
} }

View File

@@ -15,10 +15,30 @@ namespace EscapeRoomEngine.Engine.Runtime
/// The room relative (<i>RR</i>) dimensions of this space. /// The room relative (<i>RR</i>) dimensions of this space.
/// </summary> /// </summary>
internal readonly Dimensions rrDimensions; internal readonly Dimensions rrDimensions;
internal List<Module> Modules { get; } = new(2);
internal readonly Room room; internal readonly Room room;
/// <summary>
/// A list of all modules.
/// </summary>
internal List<Module> Modules { get; } = new(2);
/// <summary>
/// A list of all staged and added modules.
/// </summary>
internal List<Module> AllModules
{
get
{
var modules = new List<Module>(Modules);
if (_stagedModules.Count > 0)
{
modules.AddRange(_stagedModules);
}
return modules;
}
}
private GameObject _spaceObject, _spaceTiles; private GameObject _spaceObject, _spaceTiles;
private List<Module> _stagedModules = new();
internal Space(Room room, Passage entrance) internal Space(Room room, Passage entrance)
{ {
@@ -31,24 +51,41 @@ namespace EscapeRoomEngine.Engine.Runtime
// connect the space to its passage // connect the space to its passage
entrance.ConnectTo(new DoorModule(this, entrance.ConnectTo(new DoorModule(this,
((DoorModuleDescription)entrance.fromOut.description).connectedDoorDescription)); ((DoorModuleDescription)entrance.fromOut.description).connectedDoorDescription));
AddModule(entrance.toIn); Modules.Add(entrance.toIn);
}
internal void AddModule(Module module)
{
Modules.Add(module);
} }
internal bool AddModuleWithRequirements(Module module) internal bool AddModuleWithRequirements(Module module)
{ {
var requirementsFulfilled = var requirementsFulfilled = module.CheckRequirements();
PreconditionRequirement.CheckPreconditions(module, this) &&
PlacementRequirement.TryPlacing(module, this) &&
OrientationRequirement.TryOrienting(module, this);
if (requirementsFulfilled) if (requirementsFulfilled)
{ {
AddModule(module); // add all previously staged modules first ...
for (var i = _stagedModules.Count - 1; i >= 0; i--)
{
Modules.Add(_stagedModules[i]);
}
// ... and then add the module itself
Modules.Add(module);
}
// always clear the staged modules. if a module isn't added, its corresponding staged modules should be discarded
_stagedModules = new List<Module>();
return requirementsFulfilled;
}
/// <summary>
/// Stage a module if its requirements are currently met. It will be added as soon as the next module is added by <see cref="AddModuleWithRequirements"/>.
/// </summary>
/// <param name="module">The module to stage</param>
/// <returns>Whether the requirements were met and the module was staged</returns>
internal bool StageModuleWithRequirements(Module module)
{
var requirementsFulfilled = module.CheckRequirements();
if (requirementsFulfilled)
{
_stagedModules.Add(module);
} }
return requirementsFulfilled; return requirementsFulfilled;