move puzzle implementations out of engine

This commit is contained in:
2023-03-22 09:44:17 +01:00
parent e1bfecbd4b
commit 30d8f986df
70 changed files with 82 additions and 46 deletions

View File

@@ -2,6 +2,7 @@ using System.Collections.Generic;
using System.Linq;
using EscapeRoomEngine.Engine.Runtime.Measurements;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using EscapeRoomEngine.Engine.Runtime.UI;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using NaughtyAttributes;

View File

@@ -1,5 +1,5 @@
using System.Collections.Generic;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using JetBrains.Annotations;
using NaughtyAttributes;

View File

@@ -1,6 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using EscapeRoomEngine.Engine.Runtime.UI;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using UnityEngine;

View File

@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using JetBrains.Annotations;
using Realms;

View File

@@ -1,4 +1,4 @@
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using EscapeRoomEngine.Engine.Runtime.UI;
using Realms;
using UnityEngine;

View File

@@ -1,40 +0,0 @@
using NaughtyAttributes;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Modules
{
/// <summary>
/// A <see cref="StepPuzzle"/> whose steps are considered a cycle that can be started anywhere and must be stepped through once.
/// </summary>
public class CyclicStepPuzzle : StepPuzzle
{
[Tooltip("The current step in the cycle.")]
[BoxGroup("Step Puzzle")] [Min(0)]
public int cycleStep;
protected override void CheckStep(int step)
{
if (!Solved)
{
if (currentStep == 0)
{
// begin at any step
cycleStep = NextInCycle(step);
Step();
}
else if (step == cycleStep)
{
// next step in cycle
cycleStep = NextInCycle(cycleStep);
Step();
}
else
{
WrongInput();
}
}
}
private int NextInCycle(int step) => (step + 1) % totalSteps;
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 4551ae21288a497dac75931c56f86409
timeCreated: 1669057382

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 748b8c37770b495bb52f2acb59ba5641
timeCreated: 1683591555

View File

@@ -1,6 +1,6 @@
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Modules
namespace EscapeRoomEngine.Engine.Runtime.Modules.Description
{
/// <summary>
/// The <see cref="ModuleDescription"/> for a <see cref="DoorModule"/>. Includes the description of the connected door.

View File

@@ -1,9 +1,10 @@
using System.Collections.Generic;
using EscapeRoomEngine.Engine.Runtime.Modules.State;
using EscapeRoomEngine.Engine.Runtime.Requirements;
using NaughtyAttributes;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Modules
namespace EscapeRoomEngine.Engine.Runtime.Modules.Description
{
/// <summary>
/// The description of a specific module variant. Includes any requirements, the types and the module state that should be initialised with the module.

View File

@@ -1,7 +1,7 @@
using NaughtyAttributes;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Modules
namespace EscapeRoomEngine.Engine.Runtime.Modules.Description
{
/// <summary>
/// The <see cref="ModuleDescription"/> for a <see cref="DoorModule"/>. Includes the description of the connected door.

View File

@@ -1,4 +1,6 @@
using System;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using EscapeRoomEngine.Engine.Runtime.Modules.State;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using UnityEngine;

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using EscapeRoomEngine.Engine.Runtime.Modules.State;
using EscapeRoomEngine.Engine.Runtime.Requirements;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using UnityEngine;

View File

@@ -1,4 +1,6 @@
using EscapeRoomEngine.Engine.Runtime.Utilities;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using EscapeRoomEngine.Engine.Runtime.Modules.State;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Modules

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4cc6fbbfd1284b65841ac814a9936b9f
timeCreated: 1683591527

View File

@@ -1,7 +1,7 @@
using EscapeRoomEngine.Engine.Runtime.Utilities;
using NaughtyAttributes;
namespace EscapeRoomEngine.Engine.Runtime.Modules
namespace EscapeRoomEngine.Engine.Runtime.Modules.State
{
public enum DoorEventType
{

View File

@@ -1,6 +1,6 @@
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Modules
namespace EscapeRoomEngine.Engine.Runtime.Modules.State
{
/// <summary>
/// An abstract module state. Example implementations are <see cref="DoorState"/> and <see cref="PuzzleState"/>.

View File

@@ -2,11 +2,10 @@
using EscapeRoomEngine.Engine.Runtime.Utilities;
using JetBrains.Annotations;
using NaughtyAttributes;
using UnityEngine;
using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger;
using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType;
namespace EscapeRoomEngine.Engine.Runtime.Modules
namespace EscapeRoomEngine.Engine.Runtime.Modules.State
{
public enum PuzzleEventType
{

View File

@@ -1,4 +1,4 @@
namespace EscapeRoomEngine.Engine.Runtime.Modules
namespace EscapeRoomEngine.Engine.Runtime.Modules.State
{
/// <summary>
/// The spawn door is used in the first room.

View File

@@ -1,93 +0,0 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using NaughtyAttributes;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Modules
{
/// <summary>
/// The <see cref="PuzzleState"/> of a puzzle that requires a specific state to be solved.
/// </summary>
public class StatePuzzle : PuzzleState
{
[Tooltip("The state this puzzle starts at.")]
[BoxGroup("State Puzzle")]
[SerializeField]
protected List<int> states;
[Tooltip("The state that needs to be reached for this puzzle to be solved.")]
[BoxGroup("State Puzzle")]
[SerializeField]
protected List<int> solution;
[Tooltip("Set this to the total number of states this puzzle has.")]
[BoxGroup("State Puzzle")]
[SerializeField]
[ValidateInput("CorrectStateCount", "States count must be equal to the number of states and the length of the solution.")]
[Min(0)]
protected int stateCount;
[BoxGroup("State Puzzle")]
[ProgressBar("Correct States", "stateCount", EColor.Orange)]
public int correctStates;
private List<int> _initialStates;
protected virtual void Awake()
{
_initialStates = new List<int>(states);
}
protected override void Start()
{
PuzzleEvent += (_, type) =>
{
switch (type)
{
case PuzzleEventType.Restarted:
for (var i = 0; i < stateCount; i++)
{
SetState(i, _initialStates[i], false);
}
break;
case PuzzleEventType.Solved:
for (var i = 0; i < stateCount; i++)
{
SetState(i, solution[i], false);
}
break;
case PuzzleEventType.WrongInput:
break;
default:
throw new ArgumentOutOfRangeException(nameof(type), type, null);
}
};
base.Start();
}
protected virtual void SetState(int index, int value, bool checkSolution)
{
if (index >= 0 && index < stateCount)
{
states[index] = value;
correctStates = 0;
for (var i = 0; i < stateCount; i++)
{
if (states[i] == solution[i])
{
correctStates++;
}
}
if (checkSolution && correctStates == stateCount && correctStates > 0)
{
Solve();
}
}
}
[UsedImplicitly] // used for field validation
private bool CorrectStateCount(int count) =>
states != null && count == states.Count &&
solution != null && count == solution.Count;
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 713782041b1d40a28cfe199081a4a009
timeCreated: 1669687388

View File

@@ -1,84 +0,0 @@
using System;
using NaughtyAttributes;
using UnityEngine;
using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger;
using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType;
namespace EscapeRoomEngine.Engine.Runtime.Modules
{
/// <summary>
/// The <see cref="PuzzleState"/> of a puzzle that includes a number of steps that need to be completed to solve it.
/// </summary>
public abstract class StepPuzzle : PuzzleState
{
[BoxGroup("Step Puzzle")]
[InfoBox("In easy mode, the step puzzle will not reset if a wrong input is made.")]
public bool easyMode;
[BoxGroup("Step Puzzle")] [Min(0)]
public int totalSteps;
[BoxGroup("Step Puzzle")] [ProgressBar("Step", "totalSteps", EColor.Orange)]
public int currentStep;
protected override void Start()
{
PuzzleEvent += (_, type) =>
{
switch (type)
{
case PuzzleEventType.Restarted:
currentStep = 0;
break;
case PuzzleEventType.Solved:
currentStep = totalSteps;
break;
case PuzzleEventType.WrongInput:
if (!easyMode)
{
currentStep = 0;
}
break;
default:
throw new ArgumentOutOfRangeException(nameof(type), type, null);
}
};
base.Start();
}
protected virtual void CheckStep(int step)
{
if (!Solved)
{
if (step == currentStep)
{
Step();
}
else
{
WrongInput();
}
}
}
#region Debug Buttons
[Button(enabledMode: EButtonEnableMode.Playmode)]
protected void Step()
{
if (!Solved)
{
currentStep++;
if (currentStep >= totalSteps)
{
Solve();
}
else
{
Logger.Log($"{this} step {currentStep}/{totalSteps}", LogType.PuzzleDetail);
}
}
}
#endregion
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 5095ea3f77724269857f7275fbf7159b
timeCreated: 1669052447

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 730542e39b51427399729e60f1405d5c
timeCreated: 1683591635

View File

@@ -1,8 +1,9 @@
using System.Collections.Generic;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Requirements
namespace EscapeRoomEngine.Engine.Runtime.Requirements.Placement
{
/// <summary>
/// This requirement guarantees that the module faces the center of the space.
@@ -10,7 +11,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Requirements
[CreateAssetMenu(menuName = "Requirements/Face Space Center")]
public class FaceSpaceCenter : PlacementRequirement
{
protected override List<Placement> FilterCandidates(List<Placement> candidates, Module module, Space space)
protected override List<Utilities.Placement> FilterCandidates(List<Utilities.Placement> candidates, Module module, Space space)
{
float width = space.rrPlacement.size.x;
float length = space.rrPlacement.size.y;

View File

@@ -1,8 +1,9 @@
using System.Collections.Generic;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Requirements
namespace EscapeRoomEngine.Engine.Runtime.Requirements.Placement
{
/// <summary>
/// This requirement forces a specific orientation.
@@ -12,7 +13,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Requirements
{
public Orientation orientation;
protected override List<Placement> FilterCandidates(List<Placement> candidates, Module module, Space space)
protected override List<Utilities.Placement> FilterCandidates(List<Utilities.Placement> candidates, Module module, Space space)
{
candidates.RemoveAll(candidate => candidate.orientation != orientation);

View File

@@ -2,7 +2,7 @@
using EscapeRoomEngine.Engine.Runtime.Modules;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Requirements
namespace EscapeRoomEngine.Engine.Runtime.Requirements.Placement
{
/// <summary>
/// This requirement prevents modules from overlapping. For two models not to overlap, both of them need this requirement.
@@ -10,7 +10,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Requirements
[CreateAssetMenu(menuName = "Requirements/No Overlap")]
public class NoOverlap : PlacementRequirement
{
protected override List<Placement> FilterCandidates(List<Placement> candidates, Module module, Space space)
protected override List<Utilities.Placement> FilterCandidates(List<Utilities.Placement> candidates, Module module, Space space)
{
space.AllModules.ForEach(other => // for all other module ...
other.srPlacement.ForEachPosition(otherPosition => // ... positions ...

View File

@@ -2,7 +2,7 @@
using EscapeRoomEngine.Engine.Runtime.Modules;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Requirements
namespace EscapeRoomEngine.Engine.Runtime.Requirements.Placement
{
/// <summary>
/// This requirement guarantees that the back side of the module is placed at the edge of the space.
@@ -10,7 +10,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Requirements
[CreateAssetMenu(menuName = "Requirements/Place Along Space Edges")]
public class PlaceAlongSpaceEdges : PlacementRequirement
{
protected override List<Placement> FilterCandidates(List<Placement> candidates, Module module, Space space)
protected override List<Utilities.Placement> FilterCandidates(List<Utilities.Placement> candidates, Module module, Space space)
{
var sizeMinusOne = space.rrPlacement.size - Vector2Int.one;

View File

@@ -2,7 +2,7 @@
using EscapeRoomEngine.Engine.Runtime.Modules;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Requirements
namespace EscapeRoomEngine.Engine.Runtime.Requirements.Placement
{
/// <summary>
/// This requirement allows any placement. Used for testing purposes.
@@ -10,7 +10,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Requirements
[CreateAssetMenu(menuName = "Requirements/Place Anywhere")]
public class PlaceAnywhere : PlacementRequirement
{
protected override List<Placement> FilterCandidates(List<Placement> candidates, Module module, Space space)
protected override List<Utilities.Placement> FilterCandidates(List<Utilities.Placement> candidates, Module module, Space space)
{
return candidates;
}

View File

@@ -2,7 +2,7 @@
using EscapeRoomEngine.Engine.Runtime.Modules;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Requirements
namespace EscapeRoomEngine.Engine.Runtime.Requirements.Placement
{
/// <summary>
/// This requirement places a module exactly in the same position as its first related module.
@@ -10,9 +10,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Requirements
[CreateAssetMenu(menuName = "Requirements/Place With Related Module")]
public class PlaceWithRelatedModule : PlacementRequirement
{
protected override List<Placement> FilterCandidates(List<Placement> candidates, Module module, Space space)
protected override List<Utilities.Placement> FilterCandidates(List<Utilities.Placement> candidates, Module module, Space space)
{
return new List<Placement> { module.relatedModules[0].srPlacement };
return new List<Utilities.Placement> { module.relatedModules[0].srPlacement };
}
}
}

View File

@@ -8,9 +8,9 @@ namespace EscapeRoomEngine.Engine.Runtime.Requirements
/// <summary>
/// The main class any placement requirement inherits from. To place a module, every possible placement inside the space is put into a list of candidates that is then filtered by all placement requirements.
/// </summary>
public abstract class PlacementRequirement : Requirement<Placement>
public abstract class PlacementRequirement : Requirement<Utilities.Placement>
{
protected abstract override List<Placement> FilterCandidates(List<Placement> candidates, Module module, Space space);
protected abstract override List<Utilities.Placement> FilterCandidates(List<Utilities.Placement> candidates, Module module, Space space);
public static bool TryPlacing(Module module, Space space)
{

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e6ea2e0c5bff467b8c9d720e958f87f8
timeCreated: 1683591641

View File

@@ -1,9 +1,10 @@
using System.Collections.Generic;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using NaughtyAttributes;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.Requirements
namespace EscapeRoomEngine.Engine.Runtime.Requirements.Precondition
{
/// <summary>
/// This requirement guarantees that a module is placed in the same space as its related module.

View File

@@ -2,6 +2,8 @@ using System.Collections.Generic;
using System.Linq;
using EscapeRoomEngine.Engine.Runtime.Measurements;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using EscapeRoomEngine.Engine.Runtime.Modules.State;
using UnityEngine;
using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger;
using LogType = EscapeRoomEngine.Engine.Runtime.Utilities.LogType;

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using UnityEngine;
using Logger = EscapeRoomEngine.Engine.Runtime.Utilities.Logger;

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c13c76161df849bfb0bd769d1756a66f
timeCreated: 1683591920

View File

@@ -2,7 +2,7 @@ using NaughtyAttributes;
using UnityEngine;
using UnityEngine.UI;
namespace EscapeRoomEngine.Engine.Runtime.UI
namespace EscapeRoomEngine.Engine.Runtime.UI.Elements
{
/// <summary>
/// This component is responsible to change the icon of the pause button depending on the game state.

View File

@@ -1,9 +1,9 @@
using System.Collections.Generic;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using NaughtyAttributes;
using UnityEngine;
namespace EscapeRoomEngine.Engine.Runtime.UI
namespace EscapeRoomEngine.Engine.Runtime.UI.Elements
{
/// <summary>
/// The puzzle plan UI component that displays the current puzzle plan in the game master window.

View File

@@ -1,11 +1,11 @@
using EscapeRoomEngine.Engine.Runtime.Measurements;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using NaughtyAttributes;
using UnityEngine;
using UnityEngine.UI;
namespace EscapeRoomEngine.Engine.Runtime.UI
namespace EscapeRoomEngine.Engine.Runtime.UI.Elements
{
/// <summary>
/// An entry in the <see cref="PuzzlePlan"/> UI component that displays the name and estimated time for a puzzle.

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using EscapeRoomEngine.Engine.Runtime.Measurements;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Modules.Description;
using EscapeRoomEngine.Engine.Runtime.UI.Elements;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using NaughtyAttributes;
using UnityEngine;

View File

@@ -1,6 +1,6 @@
using System.Collections.Generic;
namespace EscapeRoomEngine.Engine.Runtime
namespace EscapeRoomEngine.Engine.Runtime.Utilities
{
public enum Orientation
{

View File

@@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using Range = EscapeRoomEngine.Engine.Runtime.Utilities.Range;
namespace EscapeRoomEngine.Engine.Runtime
namespace EscapeRoomEngine.Engine.Runtime.Utilities
{
/// <summary>
/// A placement defines the position, size and orientation of a module or space.