using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; namespace Beyond { using Invector; using Invector.vItemManager; using Sirenix.OdinInspector; using Invector.vCharacterController; [vClassHeader("Inventory")] public class bInventory : vMonoBehaviour { #region Item Variables // delegates to help handle items public delegate List GetItemsDelegate(); public delegate void AddItemDelegate(ItemReference itemReference, bool immediate = true, UnityEngine.Events.UnityAction onFinish = null, bool showPopup = true); public delegate bool LockInventoryInputEvent(); public delegate int GetAllAmountDelegate(int id); public delegate void OnUpdateInventoryDelegate(); /// /// Action to get the current items from your Inventory /// public GetItemsDelegate GetItemsHandler; /// /// Action to get all items from your /// public GetItemsDelegate GetItemsAllHandler; /// /// Action to add items to a Inventory /// public AddItemDelegate AddItemsHandler; /// /// Action to get the same items quantity /// public GetAllAmountDelegate GetAllAmount; /// /// Action to lock the inventory input /// public LockInventoryInputEvent IsLockedEvent; /// /// Action to Update the Inventory methods /// public event OnUpdateInventoryDelegate OnUpdateInventory; [vEditorToolbar("Settings")] [vHelpBox("True: Play Item animation when the timeScale is 0 \n False: Ignore Item animation if timeScale equals 0")] public bool playItemAnimation = true; [Range(0, 1)] public float timeScaleWhileIsOpen = 0; [Tooltip("Check true to not destroy this object when changing scenes")] public bool dontDestroyOnLoad = true; public List changeEquipmentControllers; //[vEditorToolbar("Input Mapping")] //public GenericInput openInventory = new GenericInput("I", "I", "I"); public GenericInput removeEquipment = new GenericInput("Mouse1", "X", "X"); [Header("This fields will override the EventSystem Input")] public GenericInput horizontal = new GenericInput("Horizontal", "D-Pad Horizontal", "Horizontal"); public GenericInput vertical = new GenericInput("Vertical", "D-Pad Vertical", "Vertical"); public GenericInput submit = new GenericInput("Return", "A", "A"); public GenericInput cancel = new GenericInput("Backspace", "B", "B"); [vEditorToolbar("Events")] public OnOpenCloseInventory onOpenCloseInventory; public OnHandleItemEvent onUseItem; public OnChangeItemAmount onDestroyItem, onDropItem; public OnChangeEquipmentEvent onEquipItem, onUnequipItem; public bool isOpen, canEquip, lockInventoryInput; //[HideInInspector] public bEquipArea[] equipAreas; public List items { get { if (GetItemsHandler != null) { return GetItemsHandler(); } return new List(); } } public List allItems { get { if (GetItemsAllHandler != null) { return GetItemsAllHandler(); } return new List(); } } private float originalTimeScale = 1f; private bool updatedTimeScale; private bEquipArea currentEquipArea; // [SerializeField] // private StandaloneInputModule inputModule; #endregion Item Variables private void Start() { // manage if you can equip a item or not canEquip = true; // search for a StandaloneInputModule in the scene // inputModule = FindObjectOfType(); // if there is none, a new EventSystem is created // if (inputModule == null) // { // inputModule = (new GameObject("EventSystem")).AddComponent(); // } // get equipAreas in this Inventory equipAreas = GetComponentsInChildren(true); // initialize every equipArea foreach (bEquipArea equipArea in equipAreas) { equipArea.Init(); equipArea.onEquipItem.AddListener(OnEquipItem); equipArea.onUnequipItem.AddListener(OnUnequipItem); equipArea.onSelectEquipArea.AddListener(SetCurrentSelectedArea); } for (int i = 0; i < changeEquipmentControllers.Count; i++) { if (changeEquipmentControllers[i] != null && changeEquipmentControllers[i].equipArea && changeEquipmentControllers[i].display) { changeEquipmentControllers[i].equipArea.onSetLockToEquip.AddListener(changeEquipmentControllers[i].display.SetLockToEquip); } } //if (dontDestroyOnLoad) // DontDestroyOnLoad(gameObject); //if (vGameController.instance) // vGameController.instance.OnReloadGame.AddListener(OnReloadGame); } private void LateUpdate() { // Debug.Log("late update of inventory"); //if (IsLocked()) //{ // return; //} //OpenCloseInventoryInput(); if (isOpen) { // UpdateEventSystemInput(); } if (!isOpen) { ChangeEquipmentInput(); } else { RemoveEquipmentInput(); } } /// /// This is just an example of saving the current items /// public void SaveItemsExample() { var _itemManager = GetComponentInParent(); _itemManager.SaveInventory(); } /// /// This is just an example of loading the saved items /// public void LoadItemsExample() { var _itemManager = GetComponentInParent(); _itemManager.LoadInventory(); } public void OnReloadGame() { StartCoroutine(ReloadEquipment()); } private IEnumerator ReloadEquipment() { yield return new WaitForEndOfFrame(); // inputModule = FindObjectOfType(); isOpen = true; for (int i = 0; i < equipAreas.Length; i++) { var equipArea = equipAreas[i]; for (int a = 0; a < equipArea.equipSlots.Count; a++) { var slot = equipArea.equipSlots[a]; if (equipArea.currentEquippedItem == null) { OnUnequipItem(equipArea, slot.item); equipArea.UnequipItem(slot); } else { equipArea.UnequipItem(slot); } } } isOpen = false; } /// /// Check if the Inventory Input is Locked /// /// public virtual bool IsLocked() { var _locked = (IsLockedEvent != null ? IsLockedEvent.Invoke() : false); return _locked || lockInventoryInput; } /// /// Update all Inventory elements /// public virtual void UpdateInventory() { OnUpdateInventory?.Invoke(); } /// /// Manage the input to open or close the Inventory /// //public virtual void OpenCloseInventoryInput() //{ // // Debug.Log("trying to open or close inventory: "); // if (openInventory.GetButtonDown() && canEquip) // { // if (!isOpen) // { // Debug.Log("trying to open "); // OpenInventory(); // } // else // { // Debug.Log("trying to close "); // CloseInventory(); // } // } //} /// /// Open the Inventory Window /// /// [Button] public virtual void OpenInventory() { Debug.Log("open inventory"); if (isOpen) { return; } isOpen = true; if (!updatedTimeScale) { updatedTimeScale = true; originalTimeScale = Time.timeScale; Time.timeScale = timeScaleWhileIsOpen; } onOpenCloseInventory.Invoke(true); } /// /// Closes the Inventory Window /// public virtual void CloseInventory() { Debug.Log("close 1 , ia open?: " + isOpen); if (!isOpen) { return; } isOpen = false; if (updatedTimeScale) { Time.timeScale = originalTimeScale; updatedTimeScale = false; } onOpenCloseInventory.Invoke(false); } /// /// Input Button to remove the current selected equipped Item /// protected virtual void RemoveEquipmentInput() { if (currentEquipArea != null && removeEquipment.GetButtonDown()) { currentEquipArea.UnequipCurrentItem(); } } /// /// Assign the EquipArea of the Slot that you're selected /// /// protected virtual void SetCurrentSelectedArea(bEquipArea equipArea) { currentEquipArea = equipArea; } /// /// Input to change the current equipSlot /// protected virtual void ChangeEquipmentInput() { // display equiped itens if (changeEquipmentControllers.Count > 0 && canEquip) { foreach (ChangeEquipmentControl changeEquip in changeEquipmentControllers) { UseItemInput(changeEquip); if (changeEquip.equipArea != null) { if (vInput.instance.inputDevice == InputDevice.MouseKeyboard || vInput.instance.inputDevice == InputDevice.Mobile) { if (changeEquip.previousItemInput.GetButtonDown()) { changeEquip.equipArea.PreviousEquipSlot(); } if (changeEquip.nextItemInput.GetButtonDown()) { changeEquip.equipArea.NextEquipSlot(); } } else if (vInput.instance.inputDevice == InputDevice.Joystick) { if (changeEquip.previousItemInput.GetAxisButtonDown(-1)) { changeEquip.equipArea.PreviousEquipSlot(); } if (changeEquip.nextItemInput.GetAxisButtonDown(1)) { changeEquip.equipArea.NextEquipSlot(); } } } } } } /// /// Check if the items of your inventory still exists /// public virtual void CheckEquipmentChanges() { for (int i = 0; i < equipAreas.Length; i++) { var equipArea = equipAreas[i]; for (int a = 0; a < equipArea.equipSlots.Count; a++) { var slot = equipArea.equipSlots[a]; if (slot.item != null && !items.Contains(slot.item)) { equipArea.UnequipItem(slot); var changeEquip = changeEquipmentControllers.Find(e => e.equipArea.Equals(equipArea)); if (changeEquip != null && changeEquip.display) { changeEquip.display.RemoveItem(); } } } } } /// /// Replace the default input of the EventSystem to a /// //protected virtual void UpdateEventSystemInput() //{ // if (inputModule) // { // inputModule.horizontalAxis = horizontal.buttonName; // inputModule.verticalAxis = vertical.buttonName; // inputModule.submitButton = submit.buttonName; // inputModule.cancelButton = cancel.buttonName; // } // else // { // inputModule = FindObjectOfType(); // } //} /// /// Input to use a equipped and consumable Item /// /// protected virtual void UseItemInput(ChangeEquipmentControl changeEquip) { if (changeEquip.display != null && changeEquip.display.item != null && changeEquip.display.item.type == bItemType.Consumable) { if (changeEquip.useItemInput.GetButtonDown() && changeEquip.display.item.amount > 0) { OnUseItem(changeEquip.display.item); } } } /// /// Event to trigger when using an Item /// /// internal virtual void OnUseItem(bItem item) { onUseItem.Invoke(item); } /// /// Event to trigger when you destroy the item /// /// /// internal virtual void OnDestroyItem(bItem item, int amount) { onDestroyItem.Invoke(item, amount); CheckEquipmentChanges(); } /// /// Event to trigger when you drop the item /// /// /// internal virtual void OnDropItem(bItem item, int amount) { onDropItem.Invoke(item, amount); CheckEquipmentChanges(); } /// /// Event to trigger when you equip an Item /// /// /// public virtual void OnEquipItem(bEquipArea equipArea, bItem item) { onEquipItem.Invoke(equipArea, item); ChangeEquipmentDisplay(equipArea, item, false); } /// /// Event to trigger when you unequip an Item /// /// /// public virtual void OnUnequipItem(bEquipArea equipArea, bItem item) { onUnequipItem.Invoke(equipArea, item); ChangeEquipmentDisplay(equipArea, item); } /// /// Updates the /// /// /// /// protected virtual void ChangeEquipmentDisplay(bEquipArea equipArea, bItem item, bool removeItem = true) { if (changeEquipmentControllers.Count > 0) { var changeEquipControl = changeEquipmentControllers.Find(changeEquip => changeEquip.equipArea != null && changeEquip.equipArea == equipArea && changeEquip.display != null); if (changeEquipControl != null) { if (removeItem && changeEquipControl.display.item == item) { changeEquipControl.display.RemoveItem(); changeEquipControl.display.ItemIdentifier(changeEquipControl.equipArea.indexOfEquippedItem + 1, true); } else if (equipArea.currentEquippedItem == item) { changeEquipControl.display.AddItem(item); changeEquipControl.display.ItemIdentifier(changeEquipControl.equipArea.indexOfEquippedItem + 1, true); } } } } } [System.Serializable] public class ChangeEquipmentControl { public GenericInput useItemInput = new GenericInput("U", "Start", "Start"); public GenericInput previousItemInput = new GenericInput("LeftArrow", "D - Pad Horizontal", "D-Pad Horizontal"); public GenericInput nextItemInput = new GenericInput("RightArrow", "D - Pad Horizontal", "D-Pad Horizontal"); public bEquipArea equipArea; public bEquipmentDisplay display; } }