using System.Collections;
using System.Collections.Generic;
using EscapeRoomEngine.Desert.Runtime.Dispenser;
using EscapeRoomEngine.Engine.Runtime.Modules;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using NaughtyAttributes;
using UnityEngine;
namespace EscapeRoomEngine.Desert.Runtime
{
///
/// The main component for the orb throwing module.
///
[RequireComponent(typeof(Collider))]
public class Hoop : StatePuzzle
{
[Tooltip("How long to wait in seconds until the state is updated. Orbs that do not stay in the hoop should not be counted.")]
public float updateDelay;
[BoxGroup("Internal")] [SerializeField]
private List rings;
private readonly HashSet _orbs = new();
private Dispenser.Dispenser _dispenser;
protected override void Start()
{
base.Start();
PuzzleEvent += (_, type) =>
{
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
switch (type)
{
case PuzzleEventType.Restarted:
var color = Engine.Runtime.Engine.Theme.puzzleColor;
rings.ForEach(ring => ring.color = color.hdr);
_dispenser.Reset();
break;
case PuzzleEventType.Solved:
color = Engine.Runtime.Engine.Theme.solvedColor;
rings.ForEach(ring => ring.color = color.hdr);
_dispenser.Solve();
break;
}
};
}
protected override void SetState(int index, int value, bool checkSolution)
{
base.SetState(index, value, checkSolution);
for (var i = 0; i < rings.Count; i++)
{
rings[i].active = i < value;
}
}
private IEnumerator SetOrbCount()
{
if (!Solved)
{
yield return new WaitForSeconds(updateDelay);
SetState(0, _orbs.Count, true);
}
}
private void OnTriggerEnter(Collider other)
{
var orb = other.GetComponent();
if (orb)
{
_orbs.Add(orb.gameObject);
StartCoroutine(SetOrbCount());
}
}
private void OnTriggerExit(Collider other)
{
var orb = other.GetComponent();
if (orb)
{
_orbs.Remove(orb.gameObject);
StartCoroutine(SetOrbCount());
}
}
public override void SetModule(Module module)
{
base.SetModule(module);
// The hoop requires a related dispenser module
var firstRelatedModule = Module.relatedModules[0];
if (firstRelatedModule.State is Dispenser.Dispenser dispenser)
{
_dispenser = dispenser;
}
else
{
throw new EngineException("Hoop was not assigned a related Dispenser.");
}
}
}
}