using System; using System.Collections.Generic; using EscapeRoomEngine.Engine.Runtime.Modules.State; using JetBrains.Annotations; using NaughtyAttributes; using UnityEngine; namespace Station46.Runtime { /// /// The of a puzzle that requires a specific state to be solved. /// public class StatePuzzle : PuzzleState { [Tooltip("The state this puzzle starts at.")] [BoxGroup("State Puzzle")] [SerializeField] protected List states; [Tooltip("The state that needs to be reached for this puzzle to be solved.")] [BoxGroup("State Puzzle")] [SerializeField] protected List 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 _initialStates; protected virtual void Awake() { _initialStates = new List(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; } }