602 lines
20 KiB
C#
602 lines
20 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using UnityEngine.EventSystems;
|
|
using System;
|
|
using static SimpleInventorySystem.GridUI;
|
|
using TMPro;
|
|
|
|
namespace SimpleInventorySystem
|
|
{
|
|
public class SlotUI : MonoBehaviour
|
|
{
|
|
[Header("Slot Attributes")]
|
|
public int width;
|
|
public int height;
|
|
public Image image;
|
|
public bool useImageAsSlotHolder;
|
|
public bool EquipSlot;
|
|
public bool FitItemImageInSlotImage = false;
|
|
[Header("Slot-to-Item Compatibility")]
|
|
public bool IgnoreItemSize;
|
|
public List<ItemTags> AllowedItemTags;
|
|
public List<ItemTags> DisallowedItemTags;
|
|
public List<SlotUI> HasSlotsBelongingToItem;
|
|
[Header("Required Component Links")]
|
|
public TextMeshProUGUI stackSlotCountText;
|
|
|
|
|
|
// Hidden In Inspector
|
|
[HideInInspector] public Stack<ItemUI> stackedItems = new Stack<ItemUI>(); // WARNING: Stack can give some odd troubles with the raycast, consider revision or consideration.
|
|
[HideInInspector] public LimitStackSlot limitStackSlot;
|
|
[HideInInspector] public LimitStackItemManager limitStackItemManager;
|
|
[HideInInspector] public bool DroppedOnFrame;
|
|
public List<GroupSlotUI> groupSlots;
|
|
[HideInInspector] public GridUI grid;
|
|
[HideInInspector] public GridUI.Cell cell;
|
|
[HideInInspector] public ChangeSlotTitle changeSlotTitle;
|
|
public bool CellInUse;
|
|
[HideInInspector] public float imageScale = 1f; // TODO: See if this is still necessary
|
|
[HideInInspector] public bool StackItemsOnSlot; // TODO: Figure out if this should be kept hidden
|
|
|
|
// private variables
|
|
[SerializeField]
|
|
private ItemUI itemUI
|
|
{
|
|
get
|
|
{
|
|
if (stackedItems.Count == 0)
|
|
{
|
|
return null;
|
|
}
|
|
//// Debug.Log("Peek: " + stackedItems.Peek().gameObject.name);
|
|
return stackedItems.Peek();
|
|
}
|
|
}
|
|
private AppendUI appendUI;
|
|
private bool droppedStackOntoEmptySlot;
|
|
//private RenderItemUIProperty renderProp;
|
|
private SlotUI BelongsToItemInSlot;
|
|
|
|
// public variables
|
|
public bool PointerIsHoveredOver { get { return InventorySystem.IsMouseOverUI(gameObject); } }
|
|
|
|
public ItemUI GetItemUI()
|
|
{
|
|
return itemUI;
|
|
}
|
|
|
|
public bool AllowedDraggable(GameObject gameObject)
|
|
{
|
|
return gameObject.GetComponent<ItemUI>() != null;
|
|
}
|
|
|
|
public bool DropOntoSlot(GameObject item, bool dropStack = true)
|
|
{
|
|
ItemUI itemDrop = item.GetComponent<ItemUI>();
|
|
ItemTags itemTag = itemDrop.ItemTag;
|
|
|
|
bool allowed = AllowedItemTags == null || AllowedItemTags.Count == 0 || AllowedItemTags.Contains(ItemTags.Any) || AllowedItemTags.Contains(itemTag);
|
|
bool disallowed = DisallowedItemTags == null || DisallowedItemTags.Contains(itemTag);
|
|
|
|
if (!allowed || disallowed)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (itemDrop.Stackable && StackItemsOnSlot)
|
|
{
|
|
Debug.LogWarning("Item stacks are incompattible with slot stacking.");
|
|
return false;
|
|
}
|
|
|
|
if (limitStackSlot != null && limitStackSlot.HasReachedLimit(itemDrop))
|
|
{
|
|
return false;
|
|
}
|
|
//Debug.Log($"SlotUI:Is LimitStackItem Manager null? {limitStackItemManager == null}");
|
|
|
|
List<Cell> occupiedCells = new List<Cell>();
|
|
|
|
/// STACKING
|
|
/// This section concerns item stacks, not slot stacking
|
|
if (itemDrop.Stackable && ((HasStack() && itemUI != null /*&& itemUI.itemPrefab == itemDrop.itemPrefab*/ && itemUI.itemName == GetItemUI().itemName) || !dropStack))
|
|
{
|
|
// Debug.Log("Handling Stack");
|
|
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);
|
|
|
|
if (appendUI != null && appendUI.StackAppend)
|
|
{
|
|
appendUI.AppendUIToTransform(itemDrop);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Debug.Log("Stack handling");
|
|
GameObject GO = Instantiate(item, transform, false);
|
|
GO.transform.localPosition = new Vector3(0, 0, 0);
|
|
ItemUI oldItemDrop = itemDrop;
|
|
itemDrop = GO.GetComponent<ItemUI>();
|
|
if (itemDrop.AddToStack(maxStackDrop))
|
|
{
|
|
oldItemDrop.RemoveFromStack(maxStackDrop);
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Debug.Log(grid);
|
|
|
|
bool dropCheck = (grid != null && grid.CanMoveInCells(itemDrop, this, occupiedCells)) ||
|
|
(grid == null && cell != null && !cell.inUse && (IgnoreItemSize || (cell.slot.width >= itemDrop.SizeAfterOrientation().Width && !cell.inUse && cell.slot.height >= itemDrop.SizeAfterOrientation().Height)));
|
|
|
|
// Debug.Log("Drop Check: " + dropCheck);
|
|
|
|
//// Debug.Log("DropCheck" + (grid == null && !cell.inUse && (IgnoreItemSize || (cell.slot.width >= itemDrop.SizeAfterOrientation().Width && !cell.inUse && cell.slot.height >= itemDrop.SizeAfterOrientation().Height))));
|
|
|
|
/*// Debug.Log("GridUI: DropOntoSlot(): " + gameObject.name + ": " + "dropCheck: " + dropCheck);
|
|
// Debug.Log("GridUI: DropOntoSlot(): " + gameObject.name + ": " + "allowed: " + allowed);*/
|
|
|
|
if (dropCheck)
|
|
{
|
|
if ((occupiedCells != null && occupiedCells.Count > 1) || StackItemsOnSlot)
|
|
{
|
|
// Debug.Log("SlotUI: " + occupiedCells.Count);
|
|
itemDrop.SetSlots(occupiedCells);
|
|
}
|
|
else
|
|
{
|
|
// Debug.Log("In Use");
|
|
cell.inUse = true;
|
|
CellInUse = cell.inUse;
|
|
}
|
|
|
|
//Debug.Log($"Using Image as Slot Holder: {useImageAsSlotHolder}");
|
|
Transform parent = transform;
|
|
if (useImageAsSlotHolder && image != null)
|
|
{
|
|
//Debug.Log("Using Image as Slot Holder");
|
|
parent = image.gameObject.transform;
|
|
}
|
|
item.GetComponent<Transform>().SetParent(parent);
|
|
item.GetComponent<RectTransform>().anchoredPosition = GetComponent<RectTransform>().anchoredPosition;
|
|
//item.GetComponent<RectTransform>().pivot = new Vector2(0, 1);
|
|
|
|
itemDrop.SetSlot(this);
|
|
|
|
stackedItems.Push(itemDrop);
|
|
|
|
// Debug.Log("SlotUI:Drop:" + itemUI + ", " + itemDrop);
|
|
|
|
itemUI.DropItemOntoSlot(FitItemImageInSlotImage);
|
|
|
|
if (FitItemImageInSlotImage)
|
|
itemDrop.FitImageInSlot(new Vector2(Math.Abs(image.GetComponent<RectTransform>().sizeDelta.x), Math.Abs(image.GetComponent<RectTransform>().sizeDelta.y)));
|
|
|
|
if (itemUI.Stackable)
|
|
{
|
|
droppedStackOntoEmptySlot = true;
|
|
}
|
|
|
|
if (grid != null)
|
|
{
|
|
grid.HideSlotsOfItem(itemDrop);
|
|
//Debug.Log("Grid is not null");
|
|
grid.AddItemToGrid(item.GetComponent<ItemUI>());
|
|
}
|
|
|
|
if (!useImageAsSlotHolder)
|
|
{
|
|
HideImage();
|
|
}
|
|
else
|
|
{
|
|
}
|
|
|
|
foreach (GroupSlotUI groupSlot in groupSlots)
|
|
{
|
|
|
|
if (groupSlot != null)
|
|
{
|
|
groupSlot.OnItemDropped();
|
|
}
|
|
}
|
|
|
|
if (appendUI != null)
|
|
{
|
|
// Debug.Log("Test");
|
|
appendUI.AppendUIToTransform(itemUI);
|
|
}
|
|
if (limitStackItemManager != null)
|
|
{
|
|
limitStackItemManager.SetStackSlotLimit(itemUI);
|
|
}
|
|
|
|
if (limitStackSlot != null)
|
|
{
|
|
limitStackSlot.Increment(itemUI);
|
|
}
|
|
|
|
if (BelongsToItemInSlot != null && BelongsToItemInSlot.GetItemUI() != null)
|
|
{
|
|
BelongsToItemInSlot.GetItemUI().AddToContainedItems(itemUI);
|
|
}
|
|
|
|
if (changeSlotTitle != null)
|
|
{
|
|
changeSlotTitle.ChangeTitle(itemDrop.ItemTag);
|
|
}
|
|
|
|
if (HasSlotsBelongingToItem != null)
|
|
{
|
|
foreach (ItemUI i in itemUI.NestedItems)
|
|
{
|
|
foreach(SlotUI s in HasSlotsBelongingToItem)
|
|
{
|
|
if (s.AllowedItemTags.Contains(i.ItemTag))
|
|
{
|
|
s.AddContainedItemToSlot(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SetRenderItemUIPropertyValue();
|
|
|
|
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 (grid == null)
|
|
grid = GetComponentInParent<GridUI>();
|
|
|
|
// Check again
|
|
if (grid == null)
|
|
{
|
|
cell = new Cell(0, 0, this, true);
|
|
}
|
|
|
|
if (TryGetComponent(out AppendUI aui))
|
|
{
|
|
appendUI = aui;
|
|
}
|
|
|
|
SetRenderItemUIPropertyValue();
|
|
|
|
if (TryGetComponent(out LimitStackSlot lss))
|
|
{
|
|
limitStackSlot = lss;
|
|
}
|
|
|
|
if (TryGetComponent(out ChangeSlotTitle cst))
|
|
{
|
|
changeSlotTitle = cst;
|
|
}
|
|
}
|
|
|
|
private void SetRenderItemUIPropertyValue()
|
|
{
|
|
if (stackSlotCountText != null)
|
|
{
|
|
stackSlotCountText.text = stackedItems.Count.ToString();
|
|
}
|
|
}
|
|
|
|
public void AddContainedItemToSlot(ItemUI item)
|
|
{
|
|
HideImage();
|
|
|
|
/*if (limitStackSlot != null)
|
|
{
|
|
limitStackSlot.Increment(itemUI);
|
|
}*/
|
|
|
|
//DropOntoSlot(item.gameObject);
|
|
|
|
stackedItems.Push(item);
|
|
if(useImageAsSlotHolder && image != null)
|
|
{
|
|
item.transform.SetParent(image.transform, false);
|
|
}
|
|
else
|
|
{
|
|
item.transform.SetParent(transform, false);
|
|
}
|
|
item.gameObject.SetActive(true);
|
|
/*
|
|
foreach(ItemUI item in )
|
|
{
|
|
itemUI.transform.SetParent(itemUI.ParentContainer.transform, false);
|
|
itemUI.gameObject.SetActive(false);
|
|
stackedItems.Pop();
|
|
}*/
|
|
SetRenderItemUIPropertyValue();
|
|
|
|
if (groupSlots != null)
|
|
{
|
|
foreach (GroupSlotUI gs in groupSlots)
|
|
{
|
|
gs.OnItemDropped();
|
|
}
|
|
}
|
|
}
|
|
public void RemoveContainedItemsFromSlot()
|
|
{
|
|
ShowImage();
|
|
|
|
while (stackedItems.Count > 0)
|
|
{
|
|
|
|
/*if (limitStackSlot != null)
|
|
{
|
|
limitStackSlot.Decrement(itemUI);
|
|
}*/
|
|
|
|
if (itemUI.ParentContainer == null)
|
|
{
|
|
Debug.LogWarning("This should not be null");
|
|
}
|
|
if (itemUI.ParentContainer != null)
|
|
itemUI.transform.SetParent(itemUI.ParentContainer.transform, false);
|
|
itemUI.gameObject.SetActive(false);
|
|
|
|
ItemUI oldItem = stackedItems.Pop();
|
|
oldItem.SetSlot(this);
|
|
}
|
|
|
|
if (groupSlots != null)
|
|
{
|
|
foreach (GroupSlotUI gs in groupSlots)
|
|
{
|
|
gs.OnItemRemoved();
|
|
}
|
|
}
|
|
|
|
SetRenderItemUIPropertyValue();
|
|
}
|
|
|
|
public void RemoveDragDropItem()
|
|
{
|
|
|
|
if (BelongsToItemInSlot != null && BelongsToItemInSlot.GetItemUI() != null)
|
|
{
|
|
BelongsToItemInSlot.GetItemUI().RemoveFromContainedItems(itemUI);
|
|
}
|
|
|
|
if (HasSlotsBelongingToItem != null)
|
|
{
|
|
foreach (SlotUI s in HasSlotsBelongingToItem)
|
|
{
|
|
s.RemoveContainedItemsFromSlot();
|
|
}
|
|
}
|
|
|
|
if (appendUI != null)
|
|
{
|
|
appendUI.RemoveUIFromTransform(itemUI);
|
|
}
|
|
|
|
if (limitStackSlot != null)
|
|
{
|
|
limitStackSlot.Decrement(itemUI);
|
|
}
|
|
|
|
if (limitStackItemManager != null)
|
|
{
|
|
limitStackItemManager.UnsetStackSlotLimit();
|
|
}
|
|
|
|
if(changeSlotTitle != null)
|
|
{
|
|
changeSlotTitle.ResetTitle();
|
|
}
|
|
|
|
stackedItems.Pop();
|
|
|
|
foreach (GroupSlotUI groupSlot in groupSlots)
|
|
{
|
|
groupSlot.OnItemRemoved();
|
|
}
|
|
|
|
UnsetCell();
|
|
|
|
SetRenderItemUIPropertyValue();
|
|
}
|
|
|
|
public void UnsetCell()
|
|
{
|
|
if(itemUI == null)
|
|
{
|
|
ShowImage();
|
|
|
|
if (cell != null)
|
|
{
|
|
cell.inUse = false;
|
|
CellInUse = cell.inUse;
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool CanDropOntoSlot()
|
|
{
|
|
/*bool groupSlotsCheck = false;
|
|
if (groupSlots.Count == 0)
|
|
groupSlotsCheck = true;
|
|
else
|
|
{
|
|
foreach (GroupSlotUI groupSlotUI in groupSlots)
|
|
{
|
|
if (groupSlotUI.IsSlotInShowGameObjects(this) && groupSlotUI.ConditionMet())
|
|
{
|
|
groupSlotsCheck = true;
|
|
break;
|
|
}
|
|
}
|
|
}*/
|
|
// TODO: add check for Limit Slot Stack here
|
|
|
|
return (GetItemUI() == null || IsStacking());// && groupSlotsCheck;
|
|
}
|
|
|
|
public bool IsSingleCellSlot()
|
|
{
|
|
return width == 1 && height == 1;
|
|
}
|
|
|
|
public bool HasStack()
|
|
{
|
|
return itemUI != null && itemUI.Stackable;
|
|
}
|
|
public bool IsStacking()
|
|
{
|
|
return StackItemsOnSlot;
|
|
}
|
|
|
|
// Start is called before the first frame update
|
|
void Start()
|
|
{
|
|
if (HasSlotsBelongingToItem.Count > 0)
|
|
{
|
|
foreach (SlotUI s in HasSlotsBelongingToItem)
|
|
{
|
|
s.BelongsToItemInSlot = this;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HasSlotsBelongingToItem = null;
|
|
}
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
if (InventorySystem.instance.PressedDropItemKey(false) || InventorySystem.instance.PressedEquipItemKey(false))
|
|
{
|
|
//// Debug.Log("pressed");
|
|
return;
|
|
}
|
|
|
|
if (PointerIsHoveredOver)
|
|
{
|
|
ItemUI droppedItem = InventorySystem.instance.DraggedItem;
|
|
if (droppedItem != null && !droppedItem.PickedUpOnFrame)
|
|
{
|
|
if (Input.GetMouseButtonDown(0))
|
|
{
|
|
DroppedOnFrame = true;
|
|
ItemUI potentialContainerItem = cell.item;
|
|
|
|
if (potentialContainerItem != null && potentialContainerItem.DropItemInStorageContainer(droppedItem))
|
|
{
|
|
|
|
// todo: do something, or not, idk
|
|
// Debug.Log("This should have dropped into a storage container");
|
|
}
|
|
else
|
|
{
|
|
bool callback = DropOntoSlot(droppedItem.gameObject, true);
|
|
|
|
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)
|
|
{
|
|
DroppedOnFrame = true;
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO: make sure the key combo works as expected
|
|
if (Input.GetMouseButtonUp(0))
|
|
{
|
|
DroppedOnFrame = false;
|
|
}
|
|
}
|
|
|
|
public void SetCell(Cell cell)
|
|
{
|
|
this.cell = cell;
|
|
}
|
|
|
|
internal void HideImage()
|
|
{
|
|
if (image != null)
|
|
{
|
|
image.color = new Color(image.color.r, image.color.g, image.color.b, 0f);
|
|
}
|
|
}
|
|
internal void ShowImage()
|
|
{
|
|
if (image != null)
|
|
{
|
|
image.color = new Color(image.color.r, image.color.g, image.color.b, 1);
|
|
}
|
|
}
|
|
}
|
|
} |