using System.Collections; using System.Collections.Generic; using UnityEngine; using UHFPS.Input; using ThunderWire.Attributes; namespace UHFPS.Runtime { [Docs("https://docs.twgamesdev.com/uhfps/guides/player-items")] public class PlayerItemsManager : PlayerComponent { public List PlayerItems = new(); public float AntiSpamDelay = 0.5f; public bool IsItemsUsable = true; private PlayerItemBehaviour currentItem; private PlayerItemBehaviour previousItem; private PlayerItemBehaviour nextItem; private bool canSwitch = true; private bool wasDeactivated = false; public bool CanInteract => isEnabled && IsItemsUsable; public bool IsAnyEquipped => CurrentItemIndex != -1; public PlayerItemBehaviour CurrentItem => currentItem; public int CurrentItemIndex => PlayerItems.IndexOf(currentItem); public PlayerItemBehaviour PreviousItem => previousItem; public int PreviousItemIndex => PlayerItems.IndexOf(previousItem); private void Awake() { InputManager.Performed(Controls.ITEM_UNEQUIP, _ => DeselectCurrent()); canSwitch = true; } /// /// Switch or select a player item. /// /// Index of the player item in the PlayerItems list. public void SwitchPlayerItem(int itemID) { if (currentItem != null && currentItem.IsBusy() || !canSwitch || !IsItemsUsable || ExamineController.IsExamining) return; StopAllCoroutines(); nextItem = PlayerItems[itemID]; wasDeactivated = false; canSwitch = false; if (nextItem != currentItem) { if (currentItem != null && currentItem.IsEquipped()) { StartCoroutine(SwitchItem()); } else { previousItem = currentItem; currentItem = nextItem; nextItem = null; StartCoroutine(SelectItem()); } } else { DeselectCurrent(); nextItem = null; } } /// /// Activate player item. /// /// Index of the player item in the PlayerItems list. public void ActivateItem(int itemID) { nextItem = PlayerItems[itemID]; if (currentItem == null || nextItem != currentItem) return; previousItem = currentItem; currentItem = nextItem; nextItem = null; previousItem.OnItemDeactivate(); currentItem.OnItemActivate(); wasDeactivated = false; canSwitch = true; } /// /// Activate a player item that was previously deselected. /// public void ActivatePreviousItem() { if (previousItem == null) return; var current = currentItem; currentItem = previousItem; previousItem = current; currentItem.OnItemActivate(); wasDeactivated = false; canSwitch = true; } /// /// Select a previously deselected player item. /// public void SelectPreviousItem() { if (previousItem == null) return; var current = currentItem; currentItem = previousItem; previousItem = current; StopAllCoroutines(); StartCoroutine(SelectItem()); wasDeactivated = false; canSwitch = false; } /// /// Activate a player item that was previously deactivated. /// public void ActivatePreviouslyDeactivatedItem() { if (previousItem == null || !wasDeactivated) return; var current = currentItem; currentItem = previousItem; previousItem = current; currentItem.OnItemActivate(); wasDeactivated = false; canSwitch = true; } /// /// Select a player item that was previously deactivated. /// public void SelectPreviouslyDeactivatedItem() { if (previousItem == null || !wasDeactivated) return; var current = currentItem; currentItem = previousItem; previousItem = current; StopAllCoroutines(); StartCoroutine(SelectItem()); wasDeactivated = false; canSwitch = false; } /// /// Deselect the currently equipped player item. /// public void DeselectCurrent() { if (currentItem == null) return; previousItem = currentItem; StopAllCoroutines(); StartCoroutine(DeselectItem()); } /// /// Deactivate the currently equipped player item. /// public void DeactivateCurrentItem() { if (currentItem == null) return; previousItem = currentItem; currentItem = null; wasDeactivated = true; canSwitch = true; StopAllCoroutines(); previousItem.OnItemDeactivate(); } /// /// Register the current item as a previously deactivated item. /// public void RegisterPreviousItem() { if (currentItem == null) return; previousItem = currentItem; wasDeactivated = true; } IEnumerator SwitchItem() { currentItem.OnItemDeselect(); yield return new WaitUntil(() => !currentItem.IsEquipped()); previousItem = currentItem; currentItem = nextItem; nextItem = null; currentItem.OnItemSelect(); yield return AntiSpam(); } IEnumerator SelectItem() { currentItem.OnItemSelect(); yield return AntiSpam(); } IEnumerator DeselectItem() { currentItem.OnItemDeselect(); yield return new WaitUntil(() => !currentItem.IsEquipped()); yield return AntiSpam(); currentItem = null; nextItem = null; } IEnumerator AntiSpam() { yield return new WaitForSeconds(AntiSpamDelay); canSwitch = true; } } }