diff --git a/Code/Grid/InventoryCell.cs b/Code/Grid/InventoryCell.cs index c96199e..7e9ca47 100644 --- a/Code/Grid/InventoryCell.cs +++ b/Code/Grid/InventoryCell.cs @@ -3,12 +3,13 @@ using GodotGridInventory.Code.Grid.Enums; namespace GodotGridInventory.Code.Grid; +#nullable enable public class InventoryCell { private readonly InventoryGrid _parentGrid; public Vector2 Position { get; set; } public EnumInventoryGridCellState State { get; set; } - public ItemConfiguration? Item { get; set; } = null; + public Item? Item { get; set; } = null; public InventoryCell(Vector2 position, InventoryGrid parentGrid) @@ -17,5 +18,6 @@ public class InventoryCell State = EnumInventoryGridCellState.Available; Item = null; Position = position; + GD.Print($"Inventory cell created at position {position.X}, {position.Y}"); } } \ No newline at end of file diff --git a/Code/Grid/InventoryGrid.cs b/Code/Grid/InventoryGrid.cs index 7ecc751..4a3e969 100644 --- a/Code/Grid/InventoryGrid.cs +++ b/Code/Grid/InventoryGrid.cs @@ -5,29 +5,36 @@ using GodotGridInventory.Code.Grid.Enums; namespace GodotGridInventory.Code.Grid; +#nullable enable public class InventoryGrid { - private readonly int _gridWidth; - private readonly int _gridHeight; + private readonly InventoryController _inventoryController; + public readonly Vector2 GridSize; - private readonly List _gridCells = new(); + public List GridCells = new(); - public InventoryGrid(int width, int height) + public InventoryGrid(InventoryController inventoryController, Vector2 size) { - _gridWidth = width; - _gridHeight = height; + _inventoryController = inventoryController; + GridSize = size; InitializeGrid(); } + + public InventoryGrid(InventoryController inventoryController, List gridCells) + { + _inventoryController = inventoryController; + GridCells = gridCells; + } private void InitializeGrid() { - for(var x = 0; x < _gridWidth; x++) + for(var x = 0; x < GridSize.X; x++) { - for(var y = 0; y < _gridHeight; y++) + for(var y = 0; y < GridSize.Y; y++) { var cellPosition = new Vector2(x, y); var cell = new InventoryCell(cellPosition, this); - _gridCells.Add(cell); + GridCells.Add(cell); } } } @@ -38,9 +45,9 @@ public class InventoryGrid /// /// The position of the cell to update. /// The item to set the cell to. - private void SetCellItem(Vector2 position, ItemConfiguration item) + private void SetCellItem(Vector2 position, Item item) { - var cell = _gridCells.FirstOrDefault(cell => cell.Position == position); + var cell = GridCells.FirstOrDefault(cell => cell.Position == position); if(cell != null) { cell.Item = item; @@ -53,7 +60,7 @@ public class InventoryGrid /// The position of the cell to update. private void ClearCellItem(Vector2 position) { - var cell = _gridCells.FirstOrDefault(cell => cell.Position == position); + var cell = GridCells.FirstOrDefault(cell => cell.Position == position); if(cell != null) { cell.Item = null; @@ -67,7 +74,7 @@ public class InventoryGrid /// The state to set the cell private void SetCellState(Vector2 position, EnumInventoryGridCellState state) { - var cell = _gridCells.FirstOrDefault(cell => cell.Position == position); + var cell = GridCells.FirstOrDefault(cell => cell.Position == position); if(cell != null) { cell.State = state; @@ -82,7 +89,7 @@ public class InventoryGrid /// The state to set the cells private void SetCellAreaState(Vector2 position, Vector2 size, EnumInventoryGridCellState state) { - foreach (var cell in _gridCells.Where(cell => cell.Position.X >= position.X && cell.Position.X < position.X + size.X && cell.Position.Y >= position.Y && cell.Position.Y < position.Y + size.Y)) + foreach (var cell in GridCells.Where(cell => cell.Position.X >= position.X && cell.Position.X < position.X + size.X && cell.Position.Y >= position.Y && cell.Position.Y < position.Y + size.Y)) { cell.State = state; } @@ -95,16 +102,16 @@ public class InventoryGrid /// The first coordinates available for something of the given size, or null if no space available. private Vector2? GetAvailableCellPosition(Vector2 size) { - var availableCells = _gridCells.Where(cell => cell.State == EnumInventoryGridCellState.Available); + var availableCells = GridCells.Where(cell => cell.State == EnumInventoryGridCellState.Available); var cell = availableCells.FirstOrDefault(); if(cell != null) { return cell.Position; } - for (int x = 0; x <= _gridWidth - size.X; x++) + for (int x = 0; x <= GridSize.X - size.X; x++) { - for (int y = 0; y <= _gridHeight - size.Y; y++) + for (int y = 0; y <= GridSize.Y - size.Y; y++) { // Check if the area is available if (IsSpaceAvailable(new Vector2(x, y), size)) @@ -125,7 +132,7 @@ public class InventoryGrid /// A List of cells that are available for the item to be placed in. private bool IsSpaceAvailable(Vector2 position, Vector2 size) { - var cells = _gridCells.Where( cell => cell.Position.X >= position.X && cell.Position.X < position.X + size.X && cell.Position.Y >= position.Y && cell.Position.Y < position.Y + size.Y); + var cells = GridCells.Where( cell => cell.Position.X >= position.X && cell.Position.X < position.X + size.X && cell.Position.Y >= position.Y && cell.Position.Y < position.Y + size.Y); return cells.All(cell => cell.State == EnumInventoryGridCellState.Available); } #endregion @@ -138,7 +145,7 @@ public class InventoryGrid /// The ID of the item to add. /// The position to add the item at in inventory grid space. If null then will insert at first available place. /// - public bool AddItem(string itemId, Vector2? position) + public bool AddItem(string itemId, Vector2? position = null) { var item = ItemDatabase.Instance.GetItemConfiguration(itemId); if(item == null) @@ -166,10 +173,10 @@ public class InventoryGrid /// Gets the cell at the given location in inventory grid space. /// /// The position you want to get the cell of. - /// The inventory cell. + /// The inventory cell at the given location in inventory grid space. public InventoryCell? GetCell(Vector2 position) { - return _gridCells.FirstOrDefault(cell => cell.Position == position); + return GridCells.FirstOrDefault(cell => cell.Position == position); } #endregion diff --git a/Code/Grid/InventoryModel.cs b/Code/Grid/InventoryModel.cs new file mode 100644 index 0000000..ed8a410 --- /dev/null +++ b/Code/Grid/InventoryModel.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using System.Linq; +using Godot; + +namespace GodotGridInventory.Code.Grid; +public class InventoryModel +{ + public int Id { get; set; } + public string Name { get; set; } + public int GridWidth { get; set; } + public int GridHeight { get; set; } + + public List Items { get; set; } + + public List Cells { get; set; } = new List(); + public InventoryGrid? Grid { get; set; } + public bool Open { get; set; } = false; +} \ No newline at end of file diff --git a/Code/InventoryController.cs b/Code/InventoryController.cs index e5c40e3..fb7e179 100644 --- a/Code/InventoryController.cs +++ b/Code/InventoryController.cs @@ -1,8 +1,127 @@ +using System.Collections.Generic; +using System.Linq; using Godot; +using GodotGridInventory.Code.Grid; namespace GodotGridInventory.Code; -public class InventoryController : Node +public partial class InventoryController : Node { + private int _inventoryIdCounter = 0; + private readonly ItemDatabase _itemDatabase = ItemDatabase.Instance; + [Export] public float CellSize { get; set; } = 32; + private Dictionary _inventories { get; set; } = new Dictionary(); + public override void _Ready() + { + base._Ready(); + } + + public bool UpdateInventory(int id, InventoryModel inventoryModel) + { + var inventory = _inventories[id]; + if(inventory == null) + { + GD.PrintErr($"Inventory not found with id {id}."); + return false; + } + + _inventories[id] = inventoryModel; + return true; + } + + public InventoryModel GetInventory(int id) + { + var inventory = _inventories[id]; + if(inventory == null) + { + GD.PrintErr($"Inventory not found with id {id}."); + return null; + } + + var result = _inventories[id]; + return result; + } + + public void AddInventory(string name, Vector2 size, string[] items) + { + var inventoryGrid = new InventoryGrid(this, size); + + foreach (var item in items) + { + inventoryGrid.AddItem(item); + } + + _inventories.Add(_inventoryIdCounter, new InventoryModel() + { + Id = _inventoryIdCounter, + Name = name, + Items = items.Select( item=> _itemDatabase.GetItemConfiguration(item)).ToList(), + Cells = inventoryGrid.GridCells, + Open = false + }); + + _inventoryIdCounter++; + } + + public bool RemoveInventory(int Id) + { + var inventory = _inventories[Id]; + if(inventory == null) + { + GD.PrintErr($"Inventory not found with id {Id}."); + return false; + } + + _inventories.Remove(Id); + GD.Print($"Inventory {inventory.Name} with id {inventory.Id} removed."); + return true; + } + + public bool OpenInventory(int Id) + { + var inventory = _inventories[Id]; + if(inventory == null) + { + GD.PrintErr($"Inventory not found with id {Id}."); + return false; + } + + if (inventory.Open == true) + { + GD.PrintErr($"Inventory with {Id} is already open."); + return false; + } + _inventories[Id].Open = true; + GD.Print($"Opened inventory {inventory.Name} with id {inventory.Id}."); + return true; + } + + public bool CloseInventory(int Id) + { + if(!_inventories.ContainsKey(Id)) + { + GD.PrintErr("Inventory not found with id " + Id + "."); + return false; + } + + var inventory = _inventories[Id]; + if (inventory.Open == false) + { + GD.PrintErr($"Inventory with {Id} is already closed."); + return false; + } + + _inventories[Id].Open = false; + _inventories.Remove(Id); + GD.Print("Closed inventory " + inventory.Name + " with id " + inventory.Id + "."); + return true; + } + + public List GetInventoriesLoaded() + { + var result = _inventories.Values.ToList(); + GD.Print($"Getting list of all _inventoriesLoaded loaded into memory ({result.Count})."); + return result; + } } \ No newline at end of file diff --git a/Code/ItemDatabase/ItemDatabase.cs b/Code/ItemDatabase/ItemDatabase.cs index fe8f7d0..67af19b 100644 --- a/Code/ItemDatabase/ItemDatabase.cs +++ b/Code/ItemDatabase/ItemDatabase.cs @@ -7,11 +7,14 @@ namespace GodotGridInventory.Code; public class ItemDatabase { public static ItemDatabase Instance { get; } = new(); - private readonly Dictionary _itemDatabase = new(); + private readonly Dictionary _itemDatabase = new(); + public ItemDatabase() + { + InitializeItemDatabase(); + } - - public ItemConfiguration GetItemConfiguration(string id) + public Item GetItemConfiguration(string id) { return _itemDatabase[id]; } @@ -22,7 +25,7 @@ public class ItemDatabase var items = DirAccess.GetFilesAt(ItemDatabaseConstants.ITEMS_PATH).Where(filePath => filePath.EndsWith(ItemDatabaseConstants.ITEM_EXTENSION)); foreach (var item in items) { - var itemResource = GD.Load(item); + var itemResource = GD.Load(item); if (itemResource != null) { _itemDatabase.Add(itemResource.Id, itemResource); diff --git a/Code/Items/ItemConfiguration.cs b/Code/Items/Item.cs similarity index 90% rename from Code/Items/ItemConfiguration.cs rename to Code/Items/Item.cs index 8238d73..256bcec 100644 --- a/Code/Items/ItemConfiguration.cs +++ b/Code/Items/Item.cs @@ -3,7 +3,7 @@ using System; using GodotGridInventory.Code.Items.Enums; [GlobalClass, Icon("res://icon.svg")] -public partial class ItemConfiguration : Resource +public partial class Item : Resource { [Export] public string Id { get; set; } [Export] public string Name { get; set; } diff --git a/Code/UI/InventoryGridInterface.cs b/Code/UI/InventoryGridInterface.cs new file mode 100644 index 0000000..80ce747 --- /dev/null +++ b/Code/UI/InventoryGridInterface.cs @@ -0,0 +1,38 @@ +using Godot; +using GodotGridInventory.Code.Grid; + +namespace GodotGridInventory.Code.UI; + +public partial class InventoryGridInterface:Control +{ + [Export] public Control GridContainer { get; set; } + [Export] public string GridSlotPath { get; set; } + + private PackedScene _gridSlotResource; + private InventoryGrid _inventoryGrid; + private InventoryController _inventoryController; + + public override void _Ready() + { + _gridSlotResource = GD.Load(GridSlotPath); + base._Ready(); + } + + public void InitializeInventoryGrid(InventoryGrid inventoryGrid, InventoryController inventoryController) + { + _inventoryGrid = inventoryGrid; + _inventoryController = inventoryController; + + for (var x = 0; x < _inventoryGrid.GridSize.X; x++) + { + for (var y = 0; y < _inventoryGrid.GridSize.Y; y++) + { + var cellPosition = new Vector2(x, y); + var cell = _inventoryGrid.GetCell(cellPosition); + var gridSlot = _gridSlotResource.Instantiate() as InventoryGridSlot; + gridSlot.Position = new Vector2(x * _inventoryController.CellSize, y * _inventoryController.CellSize); + GridContainer.AddChild(gridSlot); + } + } + } +} \ No newline at end of file diff --git a/Code/UI/InventoryGridSlot.cs b/Code/UI/InventoryGridSlot.cs new file mode 100644 index 0000000..a915595 --- /dev/null +++ b/Code/UI/InventoryGridSlot.cs @@ -0,0 +1,8 @@ +using Godot; + +namespace GodotGridInventory.Code.UI; + +public partial class InventoryGridSlot : Control +{ + +} \ No newline at end of file diff --git a/debug.cs b/debug.cs new file mode 100644 index 0000000..a4e14cb --- /dev/null +++ b/debug.cs @@ -0,0 +1,7 @@ +using Godot; +using System; + +public partial class debug : Node +{ + +} diff --git a/main.tscn b/main.tscn index 9963955..b797a1a 100644 --- a/main.tscn +++ b/main.tscn @@ -1,3 +1,12 @@ -[gd_scene format=3 uid="uid://cc8f5p1w5xdyx"] +[gd_scene load_steps=3 format=3 uid="uid://cc8f5p1w5xdyx"] -[node name="Node" type="Node"] +[ext_resource type="Script" path="res://debug.cs" id="1_al802"] +[ext_resource type="Script" path="res://Code/InventoryController.cs" id="2_0yu34"] + +[node name="UI" type="CanvasLayer"] + +[node name="Debug" type="Node" parent="."] +script = ExtResource("1_al802") + +[node name="Inventory Controller" type="Node" parent="."] +script = ExtResource("2_0yu34")