475 lines
16 KiB
C#
475 lines
16 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;
|
|
[HideInInspector] public GameObject testItem;
|
|
[HideInInspector] public GameObject[] testItems;
|
|
[HideInInspector] public List<ItemUI> itemsOnGrid;
|
|
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;
|
|
}
|
|
}
|
|
|
|
public void AddItemToGrid(ItemUI item)
|
|
{
|
|
if (!itemsOnGrid.Contains(item))
|
|
{
|
|
itemsOnGrid.Add(item.GetComponent<ItemUI>());
|
|
}
|
|
}
|
|
|
|
public bool ContainsItemFromGrid(ItemUI item)
|
|
{
|
|
return itemsOnGrid.Contains(item);
|
|
}
|
|
|
|
public void RemoveItemFromGrid(ItemUI item)
|
|
{
|
|
if (itemsOnGrid.Contains(item))
|
|
{
|
|
itemsOnGrid.Remove(item.GetComponent<ItemUI>());
|
|
}
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
}
|