using System.Collections; using System.Collections.Generic; using EscapeRoomEngine.Engine.Runtime.Modules; using EscapeRoomEngine.Engine.Runtime.Modules.State; using EscapeRoomEngine.Engine.Runtime.Utilities; using NaughtyAttributes; using Station46.Modules.Dispenser.Scripts; using Station46.Scripts; using UnityEngine; namespace Station46.Modules.Hoop.Scripts { /// /// The main component for the orb throwing module. /// [RequireComponent(typeof(Collider))] public class FlingHoop : 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.Scripts.Dispenser _dispenser; protected override void Start() { base.Start(); PuzzleEvent += (_, type) => { // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault switch (type) { case PuzzleEventType.Restarted: var color = EscapeRoomEngine.Engine.Runtime.Engine.Theme.puzzleColor; rings.ForEach(ring => ring.color = color.hdr); _dispenser.Reset(); break; case PuzzleEventType.Solved: color = EscapeRoomEngine.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.Scripts.Dispenser dispenser) { _dispenser = dispenser; } else { throw new EngineException("Hoop was not assigned a related Dispenser."); } } } }