estimate ui
This commit is contained in:
@@ -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.UI;
|
||||
using EscapeRoomEngine.Engine.Runtime.Utilities;
|
||||
using NaughtyAttributes;
|
||||
using UnityEngine;
|
||||
@@ -27,9 +28,10 @@ namespace EscapeRoomEngine.Engine.Runtime
|
||||
|
||||
public int NumberOfRooms => _rooms.Count;
|
||||
public IOption<Room> CurrentRoom => NumberOfRooms > 0 ? Some<Room>.Of(_rooms[^1]) : None<Room>.New();
|
||||
public float EstimatedTimeRemaining { get; private set; }
|
||||
|
||||
private readonly List<Room> _rooms = new();
|
||||
private List<PuzzleModuleDescription> _puzzles;
|
||||
private List<PuzzleModuleDescription> _availablePuzzles, _plannedPuzzles;
|
||||
private GameObject _playSpaceOrigin;
|
||||
|
||||
private void Awake()
|
||||
@@ -38,7 +40,8 @@ namespace EscapeRoomEngine.Engine.Runtime
|
||||
|
||||
Measure.Clear();
|
||||
|
||||
_puzzles = new List<PuzzleModuleDescription>(theme.puzzleTypes);
|
||||
_availablePuzzles = new List<PuzzleModuleDescription>(theme.puzzleTypes);
|
||||
_plannedPuzzles = new List<PuzzleModuleDescription>(_availablePuzzles);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
@@ -70,6 +73,7 @@ namespace EscapeRoomEngine.Engine.Runtime
|
||||
Instantiate(theme.environment, room.roomObject.transform, false);
|
||||
}
|
||||
|
||||
GameControl.Instance.TimeInRoom = 0;
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
@@ -79,9 +83,8 @@ namespace EscapeRoomEngine.Engine.Runtime
|
||||
var tries = 0;
|
||||
Space space;
|
||||
Passage exit = null;
|
||||
var puzzle = PlanPuzzles();
|
||||
|
||||
var puzzle = _puzzles.PopRandomElement();
|
||||
|
||||
do
|
||||
{
|
||||
tries++;
|
||||
@@ -91,7 +94,7 @@ namespace EscapeRoomEngine.Engine.Runtime
|
||||
space = new Space(room, entrance);
|
||||
|
||||
// add exit
|
||||
if (_puzzles.Count > 0)
|
||||
if (_plannedPuzzles.Count > 0)
|
||||
{
|
||||
var exitDoor = new DoorModule(space, theme.exitDoorTypes.RandomElement());
|
||||
if (!space.AddModuleWithRequirements(exitDoor))
|
||||
@@ -116,6 +119,19 @@ namespace EscapeRoomEngine.Engine.Runtime
|
||||
room.AddSpace(space, exit);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the list of puzzles planned for this run and returns the puzzle to put in the next room.
|
||||
/// </summary>
|
||||
private PuzzleModuleDescription PlanPuzzles()
|
||||
{
|
||||
|
||||
var nextPuzzle = _plannedPuzzles.PopRandomElement();
|
||||
|
||||
EstimatedTimeRemaining = Measure.AverageTime(_plannedPuzzles);
|
||||
|
||||
return nextPuzzle;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void HidePreviousRoom(bool destroy = true)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using EscapeRoomEngine.Engine.Runtime.Modules;
|
||||
using EscapeRoomEngine.Engine.Runtime.Utilities;
|
||||
using UnityEngine;
|
||||
@@ -17,6 +18,13 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements
|
||||
private static Dictionary<int, PuzzleMeasurement> _runningMeasurements;
|
||||
private static Session _currentSession;
|
||||
|
||||
public static float AverageTime(IEnumerable<PuzzleModuleDescription> puzzles) =>
|
||||
puzzles.Sum(puzzle => PuzzleStorage.Instance.Load(puzzle).AverageTimeToSolve);
|
||||
public static float AverageTime(PuzzleModuleDescription puzzle) =>
|
||||
PuzzleStorage.Instance.Load(puzzle).AverageTimeToSolve;
|
||||
public static float AverageTime(Room room) =>
|
||||
room.puzzles.Sum(puzzle => AverageTime((PuzzleModuleDescription)puzzle.description));
|
||||
|
||||
public static void StartMeasuring(PuzzleModuleDescription puzzle)
|
||||
{
|
||||
_runningMeasurements[puzzle.Id] = new PuzzleMeasurement
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace EscapeRoomEngine.Engine.Runtime.Measurements
|
||||
|
||||
private Puzzle LoadOrNew(PuzzleModuleDescription puzzle) => _realm.Find<Puzzle>(puzzle.Id) ?? New(puzzle);
|
||||
|
||||
private Puzzle Load(PuzzleModuleDescription puzzle) => _realm.Find<Puzzle>(puzzle.Id);
|
||||
public Puzzle Load(PuzzleModuleDescription puzzle) => _realm.Find<Puzzle>(puzzle.Id);
|
||||
|
||||
public void Delete(PuzzleModuleDescription puzzle)
|
||||
{
|
||||
|
||||
@@ -13,11 +13,11 @@ namespace EscapeRoomEngine.Engine.Runtime
|
||||
{
|
||||
internal Passage entrance, exit;
|
||||
internal GameObject roomObject;
|
||||
internal readonly List<PuzzleModule> puzzles = new();
|
||||
|
||||
internal bool LastRoom => exit == null;
|
||||
|
||||
private readonly List<Space> _spaces = new();
|
||||
private readonly List<PuzzleModule> _puzzles = new();
|
||||
private readonly List<DoorModule> _doors = new();
|
||||
|
||||
internal Room(Passage entrance)
|
||||
@@ -38,8 +38,8 @@ namespace EscapeRoomEngine.Engine.Runtime
|
||||
{
|
||||
Logger.Log($"Skipping {this}...", LogType.PuzzleFlow);
|
||||
|
||||
_puzzles.ForEach(puzzle => puzzle.PuzzleState.Solve());
|
||||
if (_puzzles.Count == 0 && !LastRoom)
|
||||
puzzles.ForEach(puzzle => puzzle.PuzzleState.Solve());
|
||||
if (puzzles.Count == 0 && !LastRoom)
|
||||
{
|
||||
exit.fromOut.DoorState.Unlock();
|
||||
}
|
||||
@@ -52,7 +52,7 @@ namespace EscapeRoomEngine.Engine.Runtime
|
||||
|
||||
internal void AddPuzzle(PuzzleModule puzzle)
|
||||
{
|
||||
_puzzles.Add(puzzle);
|
||||
puzzles.Add(puzzle);
|
||||
puzzle.PuzzleState.PuzzleEvent += OnPuzzleEvent;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace EscapeRoomEngine.Engine.Runtime
|
||||
{
|
||||
GameControl.Instance.StopGame();
|
||||
}
|
||||
else if (_puzzles.All(p => p.PuzzleState.Solved))
|
||||
else if (puzzles.All(p => p.PuzzleState.Solved))
|
||||
{
|
||||
exit.fromOut.DoorState.Unlock();
|
||||
}
|
||||
@@ -87,7 +87,7 @@ namespace EscapeRoomEngine.Engine.Runtime
|
||||
break;
|
||||
// start measurements on every puzzle as soon as the player enters the last room
|
||||
case DoorEventType.ExitedFrom when door.Equals(entrance.toIn) && Engine.Instance.CurrentRoom.Contains(this):
|
||||
_puzzles.ForEach(puzzle => Measure.StartMeasuring((PuzzleModuleDescription)puzzle.description));
|
||||
puzzles.ForEach(puzzle => Measure.StartMeasuring((PuzzleModuleDescription)puzzle.description));
|
||||
Engine.Instance.HidePreviousRoom();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -19,24 +19,27 @@ namespace EscapeRoomEngine.Engine.Runtime.UI
|
||||
[BoxGroup("Internal")] [SerializeField]
|
||||
private Button startButton, stopButton, pauseButton, addTimeButton, removeTimeButton;
|
||||
[BoxGroup("Internal")] [SerializeField]
|
||||
private Text timeText, targetTimeText, estimateTimeText;
|
||||
private Text timeText, roomTimeText, estimateTimeText, targetTimeText;
|
||||
[BoxGroup("Internal")] [SerializeField]
|
||||
private float uiUpdateInterval = 1;
|
||||
|
||||
[HideInInspector] public GameState gameState = GameState.Stopped;
|
||||
|
||||
private float _timeElapsed, _targetTime;
|
||||
public float TimeElapsed { get; private set; }
|
||||
public float TimeInRoom { get; set; }
|
||||
public float TargetTime { get; private set; }
|
||||
|
||||
private float _previousUIUpdate;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
|
||||
_targetTime = Engine.Instance.initialTargetTime;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
TargetTime = Engine.Instance.initialTargetTime;
|
||||
|
||||
SetTimeText();
|
||||
}
|
||||
|
||||
@@ -45,7 +48,8 @@ namespace EscapeRoomEngine.Engine.Runtime.UI
|
||||
// update time
|
||||
if (gameState == GameState.Running)
|
||||
{
|
||||
_timeElapsed += Time.deltaTime;
|
||||
TimeElapsed += Time.deltaTime;
|
||||
TimeInRoom += Time.deltaTime;
|
||||
}
|
||||
|
||||
// update ui
|
||||
@@ -61,7 +65,7 @@ namespace EscapeRoomEngine.Engine.Runtime.UI
|
||||
stopButton.interactable = gameState != GameState.Stopped;
|
||||
pauseButton.interactable = gameState is GameState.Running or GameState.Paused;
|
||||
addTimeButton.interactable = gameState != GameState.Stopped;
|
||||
removeTimeButton.interactable = gameState != GameState.Stopped && _targetTime >= _timeElapsed + 60;
|
||||
removeTimeButton.interactable = gameState != GameState.Stopped && TargetTime >= TimeElapsed + 60;
|
||||
}
|
||||
|
||||
#region Time Controls
|
||||
@@ -70,7 +74,7 @@ namespace EscapeRoomEngine.Engine.Runtime.UI
|
||||
{
|
||||
gameState = GameState.Running;
|
||||
|
||||
_timeElapsed = 0;
|
||||
TimeElapsed = 0;
|
||||
|
||||
// generate the first room if it hasn't been generated yet
|
||||
Engine.Instance.CurrentRoom.Match(none: () => Engine.Instance.GenerateRoom());
|
||||
@@ -84,7 +88,7 @@ namespace EscapeRoomEngine.Engine.Runtime.UI
|
||||
if (gameState != GameState.Stopped)
|
||||
{
|
||||
// was running
|
||||
Measure.EndSession(_timeElapsed);
|
||||
Measure.EndSession(TimeElapsed);
|
||||
}
|
||||
|
||||
gameState = GameState.Stopped;
|
||||
@@ -112,17 +116,25 @@ namespace EscapeRoomEngine.Engine.Runtime.UI
|
||||
/// <param name="seconds">The amount of seconds that will be added to the time. Can be negative to remove time.</param>
|
||||
public void ChangeTime(int seconds)
|
||||
{
|
||||
if (_targetTime + seconds >= _timeElapsed)
|
||||
if (TargetTime + seconds >= TimeElapsed)
|
||||
{
|
||||
_targetTime += seconds;
|
||||
TargetTime += seconds;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetTimeText()
|
||||
{
|
||||
timeText.text = TimeToText(_timeElapsed);
|
||||
targetTimeText.text = TimeToText(_targetTime);
|
||||
estimateTimeText.text = TimeToText(_timeElapsed);
|
||||
timeText.text = TimeToText(TimeElapsed);
|
||||
roomTimeText.text = TimeToText(TimeInRoom);
|
||||
targetTimeText.text = TimeToText(TargetTime);
|
||||
|
||||
Engine.Instance.CurrentRoom.Match(some: room =>
|
||||
{
|
||||
estimateTimeText.text = TimeToText(
|
||||
TimeElapsed - TimeInRoom
|
||||
+ Mathf.Max(TimeInRoom, Measure.AverageTime(room))
|
||||
+ Engine.Instance.EstimatedTimeRemaining);
|
||||
});
|
||||
}
|
||||
|
||||
private static string TimeToText(float time) => $"{time.ToTimeSpan():mm':'ss}";
|
||||
|
||||
Reference in New Issue
Block a user