projectEli/Assets/Inventory System/Scripts/UI/GridUI.cs
2023-01-26 18:16:31 -08:00

453 lines
15 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using static SimpleInventorySystem.InventorySystem;
namespace SimpleInventorySystem
{
[RequireComponent(typeof (GridLayoutGroup))]
public class GridUI : MonoBehaviour
{
private LayoutElement layoutElement;
private GridLayoutGroup gridLayout;
public GameObject CellPrefab;
public bool generateCells; // will autopopulate grid
public SlotUI[] slots;
[HideInInspector] public ItemUI associatedItemUI;
[SerializeField] public Size gridSize;
internal void ChangeGridLayoutSize(int rows, int columns)
{
gridSize.Width = rows;
gridSize.Height = columns;
}
private Cell[,] cells;
public GameObject testItem;
public GameObject[] testItems;
private Size cellSize;
public Size CellSize { get { return cellSize; } }
private Vector2 nextAvailableCellCoords;
private void Awake()
{
if(cells == null)
{
SetUpCellsArray();
}
}
private bool cellsInitialized;
public void SetAssociatedItemUI(ItemUI itemUI)
{
associatedItemUI = itemUI;
}
public bool IsAssociatedItem(ItemUI itemUI)
{
return associatedItemUI == itemUI;
}
void SetUpCellsArray()
{
gridLayout = GetComponent<GridLayoutGroup>();
if (gridSize.Width == 0 && gridLayout.constraint == GridLayoutGroup.Constraint.FixedColumnCount)
{
gridSize.Width = gridLayout.constraintCount;
}
else if (gridSize.Height == 0 && gridLayout.constraint == GridLayoutGroup.Constraint.FixedRowCount)
{
gridSize.Height = gridLayout.constraintCount;
}
if (gridSize.Width == 0 || gridSize.Height == 0)
{
Debug.LogError("GridUI needs a defined width and height, or width or height needs to be constrained through the GridLayoutGroup component.");
}
//Debug.Log("GridUI: GridSize: " + gridSize.Width + ", " + gridSize.Height);
cells = new Cell[gridSize.Height, gridSize.Width];
}
void GenerateCells()
{
SetUpCellsArray();
if (CellPrefab != null)
{
/*foreach(Transform child in transform)
{
// TODO: make sure to unequip items currently in the grid
Destroy(child);
}*/
Debug.Log(gridSize.Width + ", " + gridSize.Height);
for (int y = 0; y < gridSize.Height; y++)
{
for (int x = 0; x < gridSize.Width; x++)
{
// TODO: load inventory from data here upon intialization
GameObject cell = GameObject.Instantiate(CellPrefab, this.transform);
cell.transform.localScale = new Vector3(1f, 1f, 1f);
SlotUI slot = cell.GetComponentInChildren<SlotUI>();
// WARNING: All cell prefabs must now have a slot
//if (cell.GetComponentInChildren<SlotUI>() != null)
//{
slot.grid = this;
slot.AllowedItemTags = new List<ItemTags>();
slot.AllowedItemTags.Add(ItemTags.Any);
cells[y, x] = new Cell(x, y, slot, false);
//cells[y, x].GetSlot().SetCell(cells[y, x]);
//Debug.Log("Foo: " + (slot == null));
//Debug.Log("Bar: " + (cells[y, x].GetSlot().cell == null));
//cells[y, x].inUse = false;
//}
}
}
cellsInitialized = true;
/*if (cells != null && cells[0, 0] != null && testItem != null)
{
Debug.Log("Add item");
Cell cell = cells[0, 0];
GameObject item = Instantiate(testItem);
cell.slot.DropOntoSlot(item);
//item.transform.SetParent(.gameObject.transform);
}*/
/*if (testItems != null)
{
int i = 0;
int x = 0, y = 0;
int lootCount = 1;
foreach (GameObject testItem in testItems)
{
bool dropped = false;
GameObject item = null;
try
{
do
{
x = i % gridSize.Width;
y = i / gridSize.Width;
item = Instantiate(testItem);
item.name = item.name + " " + lootCount;
dropped = cells[y, x].slot.DropOntoSlot(item);
if (!dropped)
{
Destroy(item);
}
else
{
lootCount++;
item.transform.localScale = new Vector3(1, 1, 1);
}
i++;
} while (!dropped);
}
catch (IndexOutOfRangeException err)
{
Debug.LogWarning("GridUI: " + x + ", " + y);
}
if (item == null)
{
Debug.LogWarning("Could not add all test items");
break;
}
// TODO: Make sure this works as expected
nextAvailableCellCoords = new Vector2(i % gridSize.Width, i / gridSize.Width);
}
}*/
}
}
public IEnumerator PopulateItemsWithNewInventory(List<ItemUI> items)
{
Debug.Log("Populating Inventory");
yield return new WaitForFixedUpdate();
//InitializeCells();
int i = 0;
int x = 0, y = 0;
foreach (ItemUI item in items)
{
Debug.Log(item.itemName);
bool dropped = false;
try
{
do
{
x = i % gridSize.Width;
y = i / gridSize.Width;
dropped = cells[y, x].slot.DropOntoSlot(item.gameObject);
if (!dropped)
{
//Destroy(item);
}
else
{
item.transform.localScale = new Vector3(1, 1, 1);
}
i++;
} while (!dropped);
}
catch (IndexOutOfRangeException err)
{
Debug.LogWarning("GridUI: " + x + ", " + y);
}
if (item == null)
{
Debug.LogWarning("Could not add all test items");
break;
}
// TODO: Make sure this works as expected
nextAvailableCellCoords = new Vector2(i % gridSize.Width, i / gridSize.Width);
}
}
public bool DropItemOnGrid(GameObject item)
{
if (item != null)
{
int i = 0;
int limit = 100000;
int x = (int)nextAvailableCellCoords.x, y = (int)nextAvailableCellCoords.y;
bool dropped = false;
try
{
do
{
x = i % gridSize.Width;
y = i / gridSize.Width;
if (cells == null)
{
if (generateCells)
{
GenerateCells();
}
else if (!cellsInitialized)
{
SetUpCellsArray();
LocateSlotsForCells();
}
}
Debug.Log($"GridUI: Is Slot null? {cells[y, x] == null}");
dropped = cells[y, x].slot.DropOntoSlot(item);
if (!dropped)
{
}
else
{
item.transform.localScale = new Vector3(1, 1, 1);
// TODO: Make sure this works as expected
nextAvailableCellCoords = new Vector2(i % gridSize.Width, i / gridSize.Width);
return true;
}
i++;
if(i == limit)
{
Debug.Log("Limit reached");
}
} while (!dropped && i < cells.Length && i < limit); // TODO: perhaps add a check to make sure i has not exceeded the total number of slots
}
catch (IndexOutOfRangeException err)
{
Debug.LogWarning("GridUI: " + x + ", " + y);
return false;
}
return false;
}
else
{
Debug.LogWarning("GridUI: Could not add item to grid.");
return false;
}
}
// Start is called before the first frame update
void Start()
{
InitializeCells();
}
void InitializeCells()
{
if (!generateCells)
{
if (!cellsInitialized)
{
LocateSlotsForCells();
}
}
else
{
GenerateCells();
}
}
void LocateSlotsForCells()
{
//if (slots != null)
for (int i = 0; i < gridLayout.transform.childCount; i++)
{
int x = i % gridSize.Width;
int y = (i - x) / gridSize.Width;
if (cells[y, x] != null)
{
continue;
}
Transform child = gridLayout.transform.GetChild(i);
SlotUI slot = child.GetComponentInChildren<SlotUI>();
if (slot != null)
{
cells[y, x] = new Cell(x, y, slot, true);
slot.SetCell(cells[y, x]);
slot.grid = this;
if (slot.width > 1 || slot.height > 1)
{
for (int j = 0; j < slot.height; j++)
{
for (int k = 1; k < slot.width; k++)
{
cells[y + j, x + k] = new Cell(x + k, y + j, slot, false);
}
}
}
Debug.Log("START: " + (slot.cell == null));
}
else
{
cells[y, x] = null;// new Cell(null, false, false); // Setting null so that we can reserve memory
}
}
cellsInitialized = true;
}
internal void HideSlotsOfItem(ItemUI itemDrop)
{
if(itemDrop != null)
{
itemDrop.HideSlots();
}
}
public bool CanMoveInCells(ItemUI item, SlotUI slot, List<Cell> occupiedCells = null)
{
if (slot == null || slot.cell == null || (slot.cell.inUse && (slot.GetItemUI() != null && !slot.GetItemUI().Stackable)) || (associatedItemUI == item))
{
Debug.Log("GridUI: CanMoveInCells(): " + slot.gameObject.name + ": A" + (slot.cell == null));
return false;
}
else if (slot.IsSingleCellSlot() && item.IsSingleCellItem() && (!slot.cell.inUse || (slot.StackItemsOnSlot && slot.GetItemUI().name == item.name)))
{
Debug.Log("GridUI: CanMoveInCells(): " + slot.gameObject.name + ": B");
//if (!slot.cell.inUse)
return true;
//else
// return false;
}
else if (cells != null)
{
List<Cell> oCells = new List<Cell>();
if(occupiedCells != null)
{
oCells = occupiedCells;
}
Size size = item.SizeAfterOrientation();
// for (int h = 0; h < slot.height; h++){
// for (int w = 0; w < slot.width; w++)
for (int h = 0; h < size.Height; h++)
{
for (int w = 0; w < size.Width; w++)
{
if(slot.cell.Y + h >= gridSize.Height || slot.cell.X + w >= gridSize.Width)
{
Debug.Log("GridUI: CanMoveInCells(): " + slot.gameObject.name + ": D");
return false;
}
Cell cell = cells[slot.cell.Y + h, slot.cell.X + w];
if (cell != null && cell.inUse)
{
Debug.Log(cell != null);
Debug.Log(cell.inUse);
Debug.Log("GridUI: CanMoveInCells(): " + slot.gameObject.name + ": E");
return false;
}
oCells.Add(cell);
}
}
//Debug.Log(occupiedCells.Count);
Debug.Log("GridUI: CanMoveInCells(): " + slot.gameObject.name + ": F");
Debug.Log(oCells.Count);
return true;
}
Debug.Log("GridUI: CanMoveInCells(): " + slot.gameObject.name + ": G");
return false;
}
// Update is called once per frame
void Update()
{
}
public class Cell
{
protected int x, y;
public int X { get { return x; } }
public int Y { get { return y; } }
public SlotUI slot;
public bool ownsSlot;
public bool inUse;
public ItemUI item;
public Cell(int x, int y, SlotUI slot, bool ownsSlot)
{
this.x = x;
this.y = y;
this.slot = slot;
slot.SetCell(this);
inUse = false;
this.ownsSlot = ownsSlot;
}
public bool HasSlot()
{
return slot != null;
}
public SlotUI GetSlot()
{
return slot;
}
}
}
}