using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using static SimpleInventorySystem.GridUI; using System; namespace SimpleInventorySystem { [RequireComponent(typeof(RectTransform), typeof(CanvasGroup))] public class ItemUI : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler { private RectTransform rectTransform; public Image image; [HideInInspector] public Canvas canvas; private CanvasGroup canvasGroup; private float scale = 1f; public SlotUI previousSlot { get; private set; } private SlotUI slot; private Cell[] cells; private bool isDragging; public int width; public int height; private Size imageSizeOnGrid; private Orientation imageOrientation = Orientation.Portrait; public ItemTags ItemTag = ItemTags.Any; [HideInInspector] public List ContainedItems = new List(); [HideInInspector] public ItemUI ParentContainer; [HideInInspector] public GameObject container; public GameObject containerUIPrefab; public Item itemPrefab; [HideInInspector] public bool Equipped; private Vector2 oldImageSizeDelta; private Vector2 oldSizeDelta; public bool Stackable { get { return StackLimit > 1; } } private int count; public int StackLimit = 1; public int Count { get { return count; } set { if (!Stackable) { count = 1; } else { count = value; } SetRenderItemUIPropertyValue(); } } private RenderItemUIProperty renderProp; [HideInInspector] public bool PickedUpOnFrame; [HideInInspector] public List ContextWindows = new List(); [HideInInspector] public bool IsLinkedSlotClone; public bool PointerIsHoveredOver { get { return InventorySystem.IsMouseOverItemUITop(this); } } [HideInInspector] public LimitStackSlotCapacity limitStackSlotCapacity; [HideInInspector] public PickUp pickUp; [HideInInspector] public TargetAttachment targetAttachment; //public Item item; private void Awake() { rectTransform = GetComponent(); if(image == null) { Image[] images = transform.GetComponentsInChildren(); for(int i = 0; i < images.Length; i++) { if(images[i] == GetComponent()) { continue; } image = transform.GetComponentInChildren(); break; } } if(image == null) { Debug.LogError("ItemUI: Item needs an Image component."); } canvasGroup = GetComponent(); renderProp = GetComponent(); limitStackSlotCapacity = GetComponent(); if (width <= 0 || height <= 0) { Debug.LogError("Inventory ItemUI must contain a positive integer value for Width and Height: " + name); } int eulerAngle = Mathf.Abs(Mathf.CeilToInt(transform.rotation.eulerAngles.z)); switch (eulerAngle) { case 270: imageOrientation = (height > width) ? Orientation.Portrait : Orientation.Landscape; break; case 180: imageOrientation = (width > height) ? Orientation.Landscape : Orientation.Portrait; break; case 90: imageOrientation = (height > width) ? Orientation.Portrait : Orientation.Landscape; break; default: imageOrientation = (width > height) ? Orientation.Landscape : Orientation.Portrait; break; } //InstantiateItem(); } /// /// Returns an integer number if it has a container with a GridUI. the number returned is either -1 if no gridUI exists, or the capacity in terms of 1x1 cells. /// /// public int ContainerCapacity() { GridUI gridUI = null; if(container != null && container.TryGetComponent(out gridUI)) { return gridUI.gridSize.Width * gridUI.gridSize.Height; } return -1; } private void SetRenderItemUIPropertyValue() { if (renderProp != null) { renderProp.value = Count.ToString(); } } public void InstantiateItem() { //if (item == null && itemPrefab != null) //{ // item = Instantiate(itemPrefab); //} } public SlotUI GetSlotUI() { return slot; } public void OnBeginDrag(PointerEventData eventData) { } public void OnDrag(PointerEventData eventData) { } public void OnEndDrag(PointerEventData eventData) { //rectTransform.localPosition = new Vector3(0, 0); } public void Drop() { //Debug.Log("OnEndDrag"); if (image != null) { canvasGroup.alpha = 1f; image.maskable = true; } canvasGroup.blocksRaycasts = true; isDragging = false; InventorySystem.instance.DraggedItem = null; if (slot == null) { Debug.Log("ItemUI: OnEndDrag: Returning to parent"); //ReturnToSlot(); } else { // TODO: this need improvement Equipped = slot.EquipSlot; } } public void GrabAndDragItem() { if (!isDragging) { Debug.Log("GRAB AND DRAG"); //Debug.Log("OnPointerDown"); //Debug.Log("OnBeginDrag"); canvasGroup.alpha = .7f; canvasGroup.blocksRaycasts = false; image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, oldImageSizeDelta.x); image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, oldImageSizeDelta.y); rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, oldSizeDelta.x); rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, oldSizeDelta.y); if (slot != null) previousSlot = slot; transform.SetParent(canvas.transform); //rectTransform.pivot = new Vector2(.5f, .5f); //rectTransform.position += new Vector3(50, -50, 0); if (slot != null) { slot.RemoveDragDropItem(); slot = null; } if (cells != null) { foreach (Cell c in cells) { if (c != null) { c.inUse = false; //c.overlapped = false; //s.ShowImage(); if (c.GetSlot() != null && c.GetSlot() != this.slot) { c.GetSlot().UnsetCell();// RemoveDragDropItem(true); } } } cells = null; } isDragging = true; InventorySystem.instance.DraggedItem = this; PickedUpOnFrame = true; // Destroy each associated window, since we won't rely on windows if we are moving this item for(int i = ContextWindows.Count - 1; i >= 0; i--) { ContextWindows[i].SetActive(true); } ContextWindows.Clear(); } } public void AddToContainedItems(ItemUI item) { ContainedItems.Add(item); item.ParentContainer = this; } public void RemoveFromContainedItems(ItemUI item) { ContainedItems.Remove(item); item.ParentContainer = null; } public void OnPointerDown(PointerEventData eventData) { if (eventData.button == PointerEventData.InputButton.Left) { GrabAndDragItem(); } } public void OnPointerClick(PointerEventData eventData) { if(eventData.button == PointerEventData.InputButton.Left) { GrabAndDragItem(); } else if (eventData.button == PointerEventData.InputButton.Right) { InventorySystem.instance.OpenContextMenu(this); } /*else if (eventData.button == PointerEventData.InputButton.Right) { InventorySystem.instance.OpenContextMenu(this); }*/ } public void FitImageInSlot(Vector2 size) { Debug.Log("FitImageInSlot: " + image.transform.name); float ratio = size.y / image.rectTransform.sizeDelta.y; rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, size.x); rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, size.y); image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, size.y); image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, size.y); /* image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, size.y);// = new Vector2(image.rectTransform.sizeDelta.x * ratio, size.y); Debug.Log(oldImageSizeDelta + ", " + oldSizeDelta); this.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, size.y); ;*/ //image.transform.localScale *= ratio; //this.scale = scale; //image.transform.localScale *= scale; } public void SetSlot(SlotUI slot) { this.slot = slot; } // TODO: Make sure it was dropped somewhere, if not, return it to the original parent public void ReturnToSlot() { if (previousSlot != null && !isDragging) { Debug.Log("RETURNED: " + previousSlot.gameObject.name); previousSlot.DropOntoSlot(this.gameObject); } } // Start is called\ before the first frame update void Start() { oldImageSizeDelta = image.rectTransform.sizeDelta; oldSizeDelta = this.rectTransform.sizeDelta; // TODO: Possibly have item image scale into slot here. imageSizeOnGrid = new Size(width * InventorySystem.instance.DefaultSizeOnGrid.Width, height * InventorySystem.instance.DefaultSizeOnGrid.Height); if (canvas == null) { canvas = SimpleInventorySystem.InventorySystem.instance.inventoryUI; } if (Count == 0) { Count = 1; } SetRenderItemUIPropertyValue(); } public Orientation ImageOrientation() { return imageOrientation; } public Size SizeAfterOrientation() { Debug.Log(imageOrientation); if (imageOrientation == Orientation.Landscape) { if (width >= height) { return new Size(width, height); } else { return new Size(height, width); } } else { if (height >= width) { return new Size(width, height); } else { return new Size(height, width); } } } public void HideSlots() { if (cells != null) { foreach (Cell cell in cells) { if (cell != null) { SlotUI slot = cell.GetSlot(); if (slot != null) slot.HideImage(); } } } } public void SetSlots(List cellList) { cells = new Cell[cellList.Count]; for (int i = 0; i < cellList.Count; i++) { if (cellList[i] != null) { cells[i] = cellList[i]; cells[i].inUse = true; } } } public bool IsSingleCellItem() { return width == 1 && height == 1; } public bool AddToStack(int value = 1) { if (Stackable && Count < StackLimit) { Count+=value; return true; } return false; } public bool RemoveFromStack(int value = 1) { if (Stackable && Count > 0) { Count-= value; return true; } return false; } public void UnsetSlots() { cells = null; } void FixedUpdate() { } // Update is called once per frame void Update() { if (isDragging) { // TODO: fix this rectTransform.position = InventorySystem.instance.MouseInCanvasPosition; } if (PointerIsHoveredOver && InventorySystem.instance.DraggedItem == null) { if (Input.GetMouseButtonDown(0) && !isDragging && InventorySystem.instance.DraggedItem == null && !slot.DroppedOnFrame) { GrabAndDragItem(); } if (Input.GetMouseButtonDown(1) && InventorySystem.instance.DraggedItem == null) { InventorySystem.instance.OpenContextMenu(this); } } if (Input.GetMouseButtonUp(0)) { PickedUpOnFrame = false; } if (isDragging) { if (image != null) { image.maskable = false; } if (InventorySystem.instance.PressedKeyRotation(true)) { Debug.Log("Rotate"); RectTransform handler = (RectTransform)transform; int eulerAngle = Mathf.Abs(Mathf.CeilToInt(handler.rotation.eulerAngles.z)) - 90; Debug.Log("euler" + eulerAngle); switch (eulerAngle) { case -90: rectTransform.pivot = new Vector2(0,0); rectTransform.Rotate(new Vector3(0, 0, 1), -90); imageOrientation = (width > height) ? Orientation.Portrait : Orientation.Landscape; break; case 180: rectTransform.pivot = new Vector2(1, 0); handler.Rotate(new Vector3(0, 0, 1), -90); imageOrientation = (width > height) ? Orientation.Landscape : Orientation.Portrait; break; case 90: rectTransform.pivot = new Vector2(1, 1); handler.Rotate(new Vector3(0, 0, 1), -90); imageOrientation = (width > height) ? Orientation.Portrait : Orientation.Landscape; break; default: handler.Rotate(new Vector3(0, 0, 1), -90); handler.localPosition = new Vector3(0, 0, 0); handler.pivot = new Vector2(0, 1); imageOrientation = (width > height) ? Orientation.Landscape : Orientation.Portrait; break; } } if (InventorySystem.instance.PressedDropItemKey(true)) { if(pickUp == null) { // TODO: Create a new pickup for items without a gameobject attached throw new NotImplementedException(); } isDragging = false; InventorySystem.instance.DraggedItem = null; InventorySystem.instance.player.DetachItemGameObject(pickUp.ItemGameObject, this); } } } public void OnPointerExit(PointerEventData eventData) { //PointerIsHoveredOver = false; } public void OnPointerEnter(PointerEventData eventData) { //PointerIsHoveredOver = true; } } }