using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; namespace Beyond { public class ActionTriggerEvent : MonoBehaviour { public bool debugPrint; public Button ActionButton; public Button LadderButton; public Button CrouchButton; public Button BlockButton; public GameObject AttackButton; public GameObject SpellButton; public GameObject ComsumableButton; public GameObject ComsumableFaithButton; public GameObject powerButtonsParent; public Button DashButton; public Button RunButton; public Button TargetButton; public Button JumpButton; public bool disableRun = false; public bool disableCrouch = false; public static Action ActionTriggerEnter; public static Action ActionTriggerExit; private bool usingFootbridge; private TriggerDescriptor m_currentDesc; private List m_Triggers = new List(); // NEW: Dictionary for reference counting to handle multiple colliders private Dictionary m_TriggerCounts = new Dictionary(); private GameStateManager.State m_prevGameState = GameStateManager.State.NORMAL; private void Initialize() { if (LadderButton) LadderButton.gameObject.SetActive(false); if (ActionButton) ActionButton.gameObject.SetActive(false); if (CrouchButton) CrouchButton.gameObject.SetActive(!disableCrouch); if (AttackButton) AttackButton.gameObject.SetActive(true); if (SpellButton) SpellButton.gameObject.SetActive(true); if (ComsumableButton) ComsumableButton.gameObject.SetActive(true); if (ComsumableFaithButton) ComsumableFaithButton.gameObject.SetActive(true); if (powerButtonsParent) { powerButtonsParent.SetActive(true); } if (RunButton) RunButton.gameObject.SetActive(!disableRun); } private void OnActionTrigger(bool activate, TriggerDescriptor.TriggerType type) { if (type == TriggerDescriptor.TriggerType.Ladder) { if (LadderButton) LadderButton.gameObject.SetActive(activate); if (ActionButton) ActionButton.gameObject.SetActive(false); } else { if (LadderButton) LadderButton.gameObject.SetActive(false); if (ActionButton) ActionButton.gameObject.SetActive(activate); } if (CrouchButton && !disableCrouch) CrouchButton.interactable = !activate; if (AttackButton) AttackButton.gameObject.SetActive(!activate); if (SpellButton) SpellButton.gameObject.SetActive(!activate); if (powerButtonsParent) { powerButtonsParent.SetActive(!activate); } if (RunButton && !disableRun) RunButton.interactable = !activate; } private void Start() { ActionTriggerEnter += OnInvokeActionTriggerEnter; ActionTriggerExit += OnInvokeActionTriggerExit; if (GameStateManager.Instance) GameStateManager.Instance.m_OnStateChanged.AddListener(OnGameStateChanged); Initialize(); } private void OnDestroy() { ActionTriggerEnter -= OnInvokeActionTriggerEnter; ActionTriggerExit -= OnInvokeActionTriggerExit; if (GameStateManager.Instance) GameStateManager.Instance.m_OnStateChanged.RemoveListener(OnGameStateChanged); } void OnGameStateChanged(GameStateManager.State state) { if (state == GameStateManager.State.COMBAT) { DashButton.gameObject.SetActive(true); BlockButton.gameObject.SetActive(true); } else if (state == GameStateManager.State.NORMAL) { DashButton.gameObject.SetActive(false); BlockButton.gameObject.SetActive(false); } } private void DebugLog(string text) { if (debugPrint) { Debug.Log(text); } } // CORRECTED: Handles multiple colliders entering the same trigger. private void OnInvokeActionTriggerEnter(TriggerDescriptor to) { DebugLog("OnInvokeActionTriggerEnter for: " + to.obj.name); if (!m_TriggerCounts.ContainsKey(to)) { m_Triggers.Add(to); m_TriggerCounts.Add(to, 1); // Add to dictionary with a count of 1. } else { m_TriggerCounts[to]++; // If already present, just increment the count. } } // CORRECTED: Handles multiple colliders exiting the same trigger. private void OnInvokeActionTriggerExit(TriggerDescriptor to) { DebugLog("OnInvokeActionTriggerExit for: " + to.obj.name); if (m_TriggerCounts.ContainsKey(to)) { m_TriggerCounts[to]--; // Decrement the reference count. // Only remove the trigger completely if this was the last collider to exit. if (m_TriggerCounts[to] <= 0) { m_TriggerCounts.Remove(to); // Clean up the dictionary. m_Triggers.Remove(to); if (to == m_currentDesc) { OnActionTrigger(false, to.type); m_currentDesc = null; } } } else { // This error should no longer occur with the new logic. Debug.LogError("Exitting trigger that is not on the list! " + to.obj.name, this); } } private void Update() { var gameState = GameStateManager.Instance.CurrentState; if (GameStateManager.Instance.CurrentState != m_prevGameState && m_currentDesc != null) { if (gameState == GameStateManager.State.COMBAT) { if (m_currentDesc != null) { OnActionTrigger(false, m_currentDesc.type); } m_prevGameState = gameState; return; } else if (gameState == GameStateManager.State.NORMAL) { OnActionTrigger(true, m_currentDesc.type); } } m_prevGameState = gameState; if (m_Triggers.Count > 0) { if (m_Triggers.Count > 1) { m_Triggers.Sort(); } if (m_currentDesc != m_Triggers[0]) { if (m_currentDesc != null) { OnActionTrigger(false, m_currentDesc.type); } m_currentDesc = null; if (gameState != GameStateManager.State.COMBAT) { m_currentDesc = m_Triggers[0]; OnActionTrigger(true, m_currentDesc.type); } } } // This handles the case where the last trigger was removed from the list else if (m_currentDesc != null) { OnActionTrigger(false, m_currentDesc.type); m_currentDesc = null; } } } }