using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; /// <summary> /// Handles dragging functionality for items for better GUI inventory managament /// </summary> public class DraggableItem : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { public enum DraggableItemType { ItemScreenInventory, ActiveItemSpot, ShopStock, InventoryInShop, LootStock, InventoryInLootScreen } public DraggableItemType Type; [SerializeField] private Image image; private Transform parentAfterDrag; private Transform refOldParent; /// <summary> /// Sets the new drag location of this object for reference /// </summary> /// <param name="t">The new parent transform</param> public void SetParentDrag(Transform t) => parentAfterDrag = t; private bool DecipherNewLocation(RectTransform transformHovered) { DropBox db = parentAfterDrag.GetComponent<DropBox>(); ItemGUI gui = GetComponent<ItemGUI>(); InventoryManipulator manipulator = InventoryManipulator.Instance; // Moves active item to the general inventory, and marks it with necessary attributes for // the inventory spot location if (db.Type == DropBox.DropLocations.GeneralItemInventory && Type == DraggableItemType.ActiveItemSpot) return manipulator.SwitchActiveToInventory(this.gameObject, db.transform); else if (db.Type == DropBox.DropLocations.ActiveItemNecklace && gui.GetAspect() is Apparel neck) { bool neckCheck = false; if (neck.ApparelLocation is ApparelSO.Location.Neck) neckCheck = manipulator.SwitchInventoryToActive(this.gameObject, DropBox.DropLocations.ActiveItemNecklace); return neckCheck; } else if (db.Type == DropBox.DropLocations.ActiveItemRingOne && gui.GetAspect() is Apparel ring1) { bool ringOneCheck = false; if (ring1.ApparelLocation is ApparelSO.Location.RingLocOne || ring1.ApparelLocation is ApparelSO.Location.RingLocTwo) ringOneCheck = manipulator.SwitchInventoryToActive(this.gameObject, DropBox.DropLocations.ActiveItemRingOne); return ringOneCheck; } else if (db.Type == DropBox.DropLocations.ActiveItemRingTwo && gui.GetAspect() is Apparel ring2) { bool ringTwoCheck = false; if (ring2.ApparelLocation is ApparelSO.Location.RingLocOne || ring2.ApparelLocation is ApparelSO.Location.RingLocTwo) ringTwoCheck = manipulator.SwitchInventoryToActive(this.gameObject, DropBox.DropLocations.ActiveItemRingTwo); return ringTwoCheck; } else if (db.Type == DropBox.DropLocations.ActiveItemHelmet && gui.GetAspect() is Apparel headPiece) { bool headCheck = false; if (headPiece.ApparelLocation is ApparelSO.Location.Head) headCheck = manipulator.SwitchInventoryToActive(this.gameObject, DropBox.DropLocations.ActiveItemHelmet); return headCheck; } else if (db.Type == DropBox.DropLocations.ActiveItemChest && gui.GetAspect() is Apparel chestPiece) { bool chestCheck = false; if (chestPiece.ApparelLocation is ApparelSO.Location.Chest) chestCheck = manipulator.SwitchInventoryToActive(this.gameObject, DropBox.DropLocations.ActiveItemChest); return chestCheck; } else if (db.Type == DropBox.DropLocations.ActiveItemBoots && gui.GetAspect() is Apparel boots) { bool bootCheck = false; if (boots.ApparelLocation is ApparelSO.Location.Leggings) bootCheck = manipulator.SwitchInventoryToActive(this.gameObject, DropBox.DropLocations.ActiveItemBoots); return bootCheck; } else if (db.Type == DropBox.DropLocations.ActiveItemWeapon && gui.GetAspect() is Weapon) return manipulator.SwitchInventoryToActive(this.gameObject, DropBox.DropLocations.ActiveItemWeapon); else if (db.Type == DropBox.DropLocations.ActiveItemSecWeapon && gui.GetAspect() is Weapon) return manipulator.SwitchInventoryToActive(this.gameObject, DropBox.DropLocations.ActiveItemSecWeapon); else if (db.Type == DropBox.DropLocations.ActiveItemRelic && gui.GetAspect() is Relic) return manipulator.SwitchInventoryToActive(this.gameObject, DropBox.DropLocations.ActiveItemRelic); else if ((db.Type == DropBox.DropLocations.ShopStock || transformHovered == db.transform.parent) && !gui.GetAspect().CantBeSold) { // This guard clause catches if the player attempts to buy their own items or sell the shops items if (parentAfterDrag == refOldParent) return false; TownUI.Instance.SellToVendor(gui.GetItemName()); // If the indicator of if the object successfully was sold to the vendor is marked as false // then this object won't be destroyed and will go back to its old parent if (parentAfterDrag != db.transform) Destroy(this.gameObject); else parentAfterDrag = refOldParent; } else if (db.Type == DropBox.DropLocations.ShopInventory || transformHovered == db.transform.parent) { // This guard clause catches if the player attempts to buy their own items or sell the shops items if (parentAfterDrag == refOldParent) return false; TownUI.Instance.SellToPlayer(gui.GetItemName()); // If the indicator of if the object was successfully bought is marked as false // then the object won't be destroyed and be transferred back to its old parent if (parentAfterDrag != db.transform) Destroy(this.gameObject); else parentAfterDrag = refOldParent; } else if (db.Type == DropBox.DropLocations.LootStock) { if (transformHovered.name != "InvenViewport") throw new NullReferenceException(); else EnemyUI.Instance.MoveToActiveInven(this.gameObject, gui.GetAspect(), gui.GetItemAmount()); } else if (db.Type == DropBox.DropLocations.LootInventory) { if (transformHovered.name != "LootViewport") throw new NullReferenceException(); else EnemyUI.Instance.MoveToLootingInven(gui.GetAspect(), gui.GetItemAmount()); } else return false; return true; } #region Drag Handlers public void OnBeginDrag(PointerEventData eventData) { parentAfterDrag = transform.parent; refOldParent = transform.parent; if ((int)Type is 1 || (int)Type is 0 || (int)Type is 4 || (int)Type is 5) transform.SetParent(transform.root.GetChild(1), false); else if ((int)Type is 2 || (int)Type is 3) transform.SetParent(transform.root.GetChild(0), false); else transform.SetParent(transform.root, false); transform.SetAsLastSibling(); image.raycastTarget = false; } public void OnDrag(PointerEventData eventData) { Vector3 vector = Camera.main.ScreenToWorldPoint(Input.mousePosition); transform.position = new Vector3(vector.x, vector.y, 1f); } public void OnEndDrag(PointerEventData eventData) { RectTransform rectTrans; try { rectTrans = eventData.pointerEnter.TryGetComponent(out RectTransform rect) ? rect : null; bool deciphered = DecipherNewLocation(rectTrans); if (!deciphered) throw new NullReferenceException(); } catch (NullReferenceException) { parentAfterDrag = refOldParent; } catch (InvalidOperationException) { parentAfterDrag = refOldParent; } finally { // For if the clone object is destroyed try { transform.SetParent(parentAfterDrag, false); this.transform.position = new Vector3(this.transform.position.x, this.transform.parent.position.y, 1f); if (InventoryManipulator.Instance.IsNaked || Globals.InventoryOpened) InventoryManipulator.Instance.CheckNude(); image.raycastTarget = true; } catch { } } } #endregion }