using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using System; using static SimpleInventorySystem.GridUI; namespace SimpleInventorySystem { public class SlotUI : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler { public int width; public int height; public bool useImageAsSlotHolder; public Image image; public GridUI grid; public GridUI.Cell cell; public bool CellInUse; public ItemUI itemUI; [HideInInspector] public GroupSlotUI groupSlot; private AppendUI appendUI; [SerializeField] public int cellX; [SerializeField] public int cellY; public bool EquipSlot; public List LinkedSlots = new List(); private LinkedSlotUI linkedSlotUI; public bool PointerIsHoveredOver; private bool droppedStackOntoEmptySlot; internal ItemUI GetItemUI() { return itemUI; } public float imageScale = 1f; public List AllowedItemTags; /*public void OnDrop(PointerEventData eventData) { // //("OnDrop"); if (eventData.pointerDrag != null && AllowedDraggable(eventData.pointerDrag)) { DropOntoSlot(eventData.pointerDrag); } }*/ public bool AllowedDraggable(GameObject gameObject) { return gameObject.GetComponent() != null; } public bool IsLinkedSlot() { return linkedSlotUI != null; } public bool DropOntoSlot(GameObject item, bool dropStack = true) { ItemUI itemDrop = item.GetComponent(); if (IsLinkedSlot()) { GameObject newItemDrop = Instantiate(item); itemDrop = newItemDrop.GetComponent(); itemDrop.IsLinkedSlotClone = true; } List occupiedCells = new List(); if (!itemDrop.IsLinkedSlotClone && ((HasStack() && itemUI != null && itemUI.itemPrefab == itemDrop.itemPrefab) || !dropStack)) { Debug.Log("Handling Stack"); // TODO: HANDLE STACKING HERE int maxStackDrop = 1; if (dropStack) { maxStackDrop = itemDrop.Count; if (maxStackDrop > itemUI.StackLimit - itemUI.Count) { maxStackDrop = itemDrop.Count - itemUI.Count; } } if(itemUI != null) { if (itemUI.AddToStack(maxStackDrop)) { Debug.Log("Add to stack"); itemDrop.RemoveFromStack(maxStackDrop); return true; } } else { GameObject GO = Instantiate(item, transform, false); GO.transform.localPosition = new Vector3(0, 0, 0); ItemUI oldItemDrop = itemDrop; itemDrop = GO.GetComponent(); if (itemDrop.AddToStack(maxStackDrop)) { oldItemDrop.RemoveFromStack(maxStackDrop); } else { return false; } } } bool dropCheck = (grid != null && grid.CanMoveInCells(itemDrop, this, occupiedCells) || (grid == null && !cell.inUse)); ItemTags itemTag = itemDrop.ItemTag; bool allowed = AllowedItemTags == null || AllowedItemTags.Count == 0 || AllowedItemTags.Contains(ItemTags.Any) || AllowedItemTags.Contains(itemTag); /*Debug.Log("GridUI: DropOntoSlot(): " + gameObject.name + ": " + "dropCheck: " + dropCheck); Debug.Log("GridUI: DropOntoSlot(): " + gameObject.name + ": " + "allowed: " + allowed);*/ if (dropCheck && allowed) { if (occupiedCells != null && occupiedCells.Count > 1) { //Debug.Log("SlotUI: " + occupiedCells.Count); itemDrop.SetSlots(occupiedCells); } else { Debug.Log("In Use"); cell.inUse = true; CellInUse = cell.inUse; } Transform parent = transform; if (useImageAsSlotHolder && image != null) { parent = image.gameObject.transform; } item.GetComponent().SetParent(parent); item.GetComponent().anchoredPosition = GetComponent().anchoredPosition; //item.GetComponent().pivot = new Vector2(0, 1); itemDrop.SetImageScale(imageScale); itemDrop.SetSlot(this); this.itemUI = itemDrop; itemUI.Drop(); if (itemUI.Stackable) { droppedStackOntoEmptySlot = true; } if (!IsLinkedSlot()) { foreach (SlotUI ls in LinkedSlots) { if (ls == this) { Debug.LogWarning("No self-referencing for this array ;)"); continue; } //ls.DropOntoSlot(item); } } if (grid != null) { grid.HideSlotsOfItem(itemDrop); } HideImage(); if (groupSlot != null) { groupSlot.OnItemDropped(); } if (appendUI != null) { appendUI.AppendUIToTransform(itemUI); } return true; } else if (itemDrop.previousSlot != this) { // TODO: See why this is outputting at beginning, probably from test objects in Loot //Debug.LogWarning("SlotUI: Failed to drop. dropCheck: " + dropCheck + ", allowed: " + allowed); // return item to previous parent itemDrop.ReturnToSlot(); return false; //Debug.Log("Resetting parent"); } else { //Debug.LogWarning("SlotUI: Failed to drop. dropCheck: " + dropCheck + ", allowed: " + allowed); Debug.LogError("SlotUI: Something wrong has happened."); return false; } } void Awake() { if (image == null) { Image[] images = GetComponentsInChildren(); // This will retrieve the first instance of an image in the FIRST child with the component //Debug.Log(images.Length); if (images.Length > 0) { if (images[0].transform == transform) { if (images.Length > 1) { image = images[1]; } } else { image = images[0]; } } } if (grid == null) grid = GetComponentInParent(); // Check again if (grid == null) { cell = new Cell(0, 0, this, true); } if (TryGetComponent(out AppendUI aui)) { appendUI = aui; } if (TryGetComponent(out LinkedSlotUI lui)) { linkedSlotUI = lui; } } public void RemoveDragDropItem() { ShowImage(); if (appendUI != null) { appendUI.RemoveUIFromTransform(itemUI); } foreach (SlotUI linked in LinkedSlots) { linked.RemoveDragDropItem(); } itemUI = null; if (cell != null) { cell.inUse = false; CellInUse = cell.inUse; } if (groupSlot != null) { groupSlot.OnItemRemoved(); } } public bool IsSingleCellSlot() { return width == 1 && height == 1; } public bool HasStack() { return itemUI != null && itemUI.Stackable; } // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { if (PointerIsHoveredOver) { ItemUI droppedItem = InventorySystem.instance.DraggedItem; if (droppedItem != null && !droppedItem.PickedUpOnFrame) { if (Input.GetMouseButtonDown(0)) { bool callback = DropOntoSlot(droppedItem.gameObject); if (callback && droppedItem.Stackable) { if (droppedItem.Count <= 0) Destroy(droppedItem.gameObject); else if (itemUI.Count < droppedItem.Count && !droppedStackOntoEmptySlot) { InventorySystem.instance.DraggedItem = droppedItem; droppedStackOntoEmptySlot = false; } } } else if (Input.GetMouseButtonDown(1) && droppedItem.Stackable) { Debug.Log("Right Click"); if(DropOntoSlot(droppedItem.gameObject, false)) { if (droppedItem.Count <= 0) Destroy(droppedItem.gameObject); else { InventorySystem.instance.DraggedItem = droppedItem; droppedItem.transform.SetParent(InventorySystem.instance.inventoryUI.transform); droppedStackOntoEmptySlot = false; } } } } } } public void SetCell(Cell cell) { this.cell = cell; cellX = this.cell.X; cellY = this.cell.Y; } internal void HideImage() { if(image != null) { image.color = new Color(image.color.r, image.color.g, image.color.b, 0); } } internal void ShowImage() { if (image != null) { image.color = new Color(image.color.r, image.color.g, image.color.b, 1); } } public void OnPointerClick(PointerEventData eventData) { } public void OnPointerDown(PointerEventData eventData) { ItemUI droppedItem = InventorySystem.instance.DraggedItem; if (droppedItem != null && !droppedItem.PickedUpOnFrame) { DropOntoSlot(droppedItem.gameObject); } } public void OnPointerExit(PointerEventData eventData) { PointerIsHoveredOver = false; } public void OnPointerEnter(PointerEventData eventData) { PointerIsHoveredOver = true; } } }