using System;
using System.Collections.Generic;
using EscapeRoomEngine.Engine.Runtime.Modules.State;
using JetBrains.Annotations;
using NaughtyAttributes;
using UnityEngine;
namespace Station46.Scripts
{
///
/// 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;
}
}