From 635655f7a67dda971c353684fa21dac548ef85e8 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Fri, 6 Sep 2024 12:34:18 +0200 Subject: [PATCH] Refactored inventory such that it can handle stacked items. --- data/items/door.tres | 12 ------ data/items/shovel.tres | 1 + data/items/stick.tres | 1 + data/items/stone.tres | 2 + data/items/treelog.tres | 2 + data/items/woodplanks.tres | 1 + inventory.gd | 59 ++++++++++++++++++++++++---- model/item.gd | 1 + scenes/main.gd | 2 +- scenes/main.tscn | 32 ++++++--------- ui/{item_grid.tscn => ItemGrid.tscn} | 3 ++ ui/game_ui.tscn | 2 +- ui/inventory_dialog.gd | 5 ++- ui/item_grid.gd | 32 +++++++++++++-- ui/item_slot.gd | 14 ++++++- ui/item_slot.tscn | 12 ++++-- ui/item_stack.gd | 9 +++++ ui/tool_container.gd | 13 ++++++ ui/tool_container.tscn | 19 +++++++++ ui/ui_theme.tres | 4 +- 20 files changed, 171 insertions(+), 55 deletions(-) delete mode 100644 data/items/door.tres rename ui/{item_grid.tscn => ItemGrid.tscn} (81%) create mode 100644 ui/item_stack.gd create mode 100644 ui/tool_container.gd create mode 100644 ui/tool_container.tscn diff --git a/data/items/door.tres b/data/items/door.tres deleted file mode 100644 index 377c3aa..0000000 --- a/data/items/door.tres +++ /dev/null @@ -1,12 +0,0 @@ -[gd_resource type="Resource" script_class="Item" load_steps=4 format=3 uid="uid://coser1y1y5unl"] - -[ext_resource type="Texture2D" uid="uid://ojsbkfjeu088" path="res://assets/3rdparty/kenney/survival-kit/Previews/toolPickaxe.png" id="1_ev4xm"] -[ext_resource type="PackedScene" uid="uid://ca2l61b2j3y5b" path="res://assets/tools/Pickaxe.tscn" id="2_diiob"] -[ext_resource type="Script" path="res://model/item.gd" id="3_n4quc"] - -[resource] -resource_name = "Pickaxe" -script = ExtResource("3_n4quc") -name = "Pickaxe" -scene = ExtResource("2_diiob") -icon = ExtResource("1_ev4xm") diff --git a/data/items/shovel.tres b/data/items/shovel.tres index ea3df0f..00c3893 100644 --- a/data/items/shovel.tres +++ b/data/items/shovel.tres @@ -10,3 +10,4 @@ script = ExtResource("1_0t4oi") name = "Shovel" scene = ExtResource("1_fne3r") icon = ExtResource("1_oaqa4") +max_stack_size = 1 diff --git a/data/items/stick.tres b/data/items/stick.tres index be21e79..aed1286 100644 --- a/data/items/stick.tres +++ b/data/items/stick.tres @@ -10,3 +10,4 @@ script = ExtResource("3_45lxd") name = "Stick" scene = ExtResource("2_mrxum") icon = ExtResource("1_c3g8n") +max_stack_size = 64 diff --git a/data/items/stone.tres b/data/items/stone.tres index bdf90f6..f79388f 100644 --- a/data/items/stone.tres +++ b/data/items/stone.tres @@ -9,3 +9,5 @@ script = ExtResource("1_dao2u") name = "Stone" scene = ExtResource("2_6nus0") icon = ExtResource("1_t2qva") +stack_size = 1 +max_stack_size = 64 diff --git a/data/items/treelog.tres b/data/items/treelog.tres index 2e92e17..536db4d 100644 --- a/data/items/treelog.tres +++ b/data/items/treelog.tres @@ -9,3 +9,5 @@ script = ExtResource("1_tlj5a") name = "Tree Log" scene = ExtResource("2_ufvdy") icon = ExtResource("1_ak0y2") +stack_size = 1 +max_stack_size = 64 diff --git a/data/items/woodplanks.tres b/data/items/woodplanks.tres index 186994e..2b96e16 100644 --- a/data/items/woodplanks.tres +++ b/data/items/woodplanks.tres @@ -9,3 +9,4 @@ script = ExtResource("3_c8yxb") name = "Wood Planks" scene = ExtResource("2_4oehn") icon = ExtResource("1_plody") +max_stack_size = 64 diff --git a/inventory.gd b/inventory.gd index 82930e1..a02657a 100644 --- a/inventory.gd +++ b/inventory.gd @@ -1,16 +1,57 @@ class_name Inventory -var _content:Array[Item] = [] +var _content:Array[ItemStack] = [] +const INVENTORY_SIZE:int = 36 -func add_item(item:Item): - _content.append(item) +func _init() -> void: + _content.resize(INVENTORY_SIZE) +func get_free_item_stack_index() -> int: + for i:int in range(_content.size()): + if _content[i] == null: + return i + + return -1 + + +func add_item(item:Item) -> bool: + for item_stack:ItemStack in _content: + if item_stack == null: + continue + + if item_stack.item.resource_path != item.resource_path: + continue + + if item_stack.count < item_stack.item.max_stack_size: + item_stack.count = item_stack.count + 1 + return true + + var item_stack_index:int = get_free_item_stack_index() + if item_stack_index >= 0: + var item_stack:ItemStack = ItemStack.new() + item_stack.item = item + item_stack.count = 1 + _content[item_stack_index] = item_stack + return true + + return false func remove_item(item:Item): - _content.erase(item) + for i in range(_content.size() - 1, -1, -1): + var item_stack:ItemStack = _content[i] + if item_stack == null: + continue + + if item_stack.item.resource_path == item.resource_path: + if item_stack.count > 1: + item_stack.count = item_stack.count - 1 + else: + _content[i] = null + + return -func get_items() -> Array[Item]: +func get_item_stacks() -> Array[ItemStack]: return _content @@ -21,7 +62,11 @@ func clear() -> void: func has_all(items:Array[Item]) -> bool: var needed:Array[Item] = items.duplicate() - for available in _content: - needed.erase(available) + for item_stack:ItemStack in _content: + if item_stack == null: + continue + + for i in range (item_stack.count): + needed.erase(item_stack.item) return needed.is_empty() diff --git a/model/item.gd b/model/item.gd index b7c009f..71d6baf 100644 --- a/model/item.gd +++ b/model/item.gd @@ -4,3 +4,4 @@ extends Resource @export var name:String @export var scene:PackedScene @export var icon:Texture2D +@export var max_stack_size:int = 1 diff --git a/scenes/main.gd b/scenes/main.gd index ab02760..88622f8 100644 --- a/scenes/main.gd +++ b/scenes/main.gd @@ -1,5 +1,5 @@ class_name Main -extends Node3D +extends Node @onready var message_container:Control = %MessagesContainer @onready var message_textedit:TextEdit = %MessageTextEdit diff --git a/scenes/main.tscn b/scenes/main.tscn index 048ee1d..90353ce 100644 --- a/scenes/main.tscn +++ b/scenes/main.tscn @@ -1,20 +1,19 @@ -[gd_scene load_steps=14 format=3 uid="uid://ck104ww8vi7f1"] +[gd_scene load_steps=13 format=3 uid="uid://ck104ww8vi7f1"] [ext_resource type="Script" path="res://scenes/main.gd" id="1_yidnr"] [ext_resource type="PackedScene" uid="uid://bo788o53t4rbq" path="res://scenes/startup_scene.tscn" id="2_imuae"] [ext_resource type="PackedScene" uid="uid://cqie4cy0uy1t0" path="res://scenes/game.tscn" id="2_o3qua"] +[ext_resource type="PackedScene" uid="uid://nob4ibnp0p5u" path="res://ui/tool_container.tscn" id="11_yj24a"] +[ext_resource type="Script" path="res://ui/tool_container.gd" id="12_duobv"] [ext_resource type="Script" path="res://root_ui.gd" id="13_h24kl"] [ext_resource type="Theme" uid="uid://dmk7hc81l8gbw" path="res://ui/ui_theme.tres" id="14_bvivl"] [ext_resource type="Script" path="res://game_ui.gd" id="15_g7bf1"] [ext_resource type="Script" path="res://ui/inventory_dialog.gd" id="16_18k4v"] [ext_resource type="PackedScene" uid="uid://dp3fi0g53qrt2" path="res://ui/item_slot.tscn" id="17_rucv3"] -[ext_resource type="PackedScene" uid="uid://bwui4acukq4x6" path="res://ui/item_grid.tscn" id="18_fihac"] +[ext_resource type="PackedScene" uid="uid://bwui4acukq4x6" path="res://ui/ItemGrid.tscn" id="18_fihac"] [ext_resource type="Script" path="res://ui/game_menu_ui.gd" id="19_krapk"] -[ext_resource type="Texture2D" uid="uid://c7fu3paj3b4e8" path="res://assets/3rdparty/kenney/ui-pack-rpg-expansion/PNG/cursorSword_silver.png" id="20_7s1r5"] -[ext_resource type="Texture2D" uid="uid://drpl0ql1p3pfk" path="res://assets/3rdparty/kenney/ui-pack-rpg-expansion/PNG/cursorSword_gold.png" id="21_663i3"] -[ext_resource type="Texture2D" uid="uid://cq8ypeagpedq" path="res://assets/3rdparty/kenney/ui-pack-rpg-expansion/PNG/cursorSword_bronze.png" id="22_le7qn"] -[node name="Main" type="Node3D"] +[node name="Main" type="Node"] script = ExtResource("1_yidnr") [node name="RootUI" type="CanvasLayer" parent="."] @@ -183,7 +182,6 @@ text = "Start [node name="GameUI" type="Control" parent="RootUI"] unique_name_in_owner = true -visible = false layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 @@ -319,6 +317,8 @@ size_flags_vertical = 3 [node name="IngredientsContainer" parent="RootUI/GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer" instance=ExtResource("18_fihac")] unique_name_in_owner = true layout_mode = 2 +columns = 3 +rows = 3 [node name="HBoxContainer" type="HBoxContainer" parent="RootUI/GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients"] layout_mode = 2 @@ -357,6 +357,7 @@ grow_vertical = 2 [node name="ResultsContainer" parent="RootUI/GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftResult/Panel/CenterContainer" instance=ExtResource("18_fihac")] unique_name_in_owner = true layout_mode = 2 +columns = 1 [node name="HBoxContainer" type="HBoxContainer" parent="RootUI/GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftResult"] layout_mode = 2 @@ -387,6 +388,7 @@ unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 4 size_flags_vertical = 4 +rows = 3 [node name="GameMenuUI" type="PanelContainer" parent="RootUI/GameUI"] unique_name_in_owner = true @@ -494,20 +496,10 @@ theme_override_constants/margin_bottom = 32 [node name="PanelContainer" type="PanelContainer" parent="RootUI/GameUI/ToolSlots"] layout_mode = 2 -[node name="HBoxContainer" type="HBoxContainer" parent="RootUI/GameUI/ToolSlots/PanelContainer"] +[node name="ToolContainer" parent="RootUI/GameUI/ToolSlots/PanelContainer" instance=ExtResource("11_yj24a")] layout_mode = 2 - -[node name="Button2" type="Button" parent="RootUI/GameUI/ToolSlots/PanelContainer/HBoxContainer"] -layout_mode = 2 -icon = ExtResource("20_7s1r5") - -[node name="Button3" type="Button" parent="RootUI/GameUI/ToolSlots/PanelContainer/HBoxContainer"] -layout_mode = 2 -icon = ExtResource("21_663i3") - -[node name="Button" type="Button" parent="RootUI/GameUI/ToolSlots/PanelContainer/HBoxContainer"] -layout_mode = 2 -icon = ExtResource("22_le7qn") +script = ExtResource("12_duobv") +slot_scene = ExtResource("17_rucv3") [node name="Scene" type="Node3D" parent="."] unique_name_in_owner = true diff --git a/ui/item_grid.tscn b/ui/ItemGrid.tscn similarity index 81% rename from ui/item_grid.tscn rename to ui/ItemGrid.tscn index e1d9df2..9834d36 100644 --- a/ui/item_grid.tscn +++ b/ui/ItemGrid.tscn @@ -7,3 +7,6 @@ columns = 9 script = ExtResource("1_c5mg2") slot_scene = ExtResource("2_o52f5") + +[node name="ItemSlot" parent="." instance=ExtResource("2_o52f5")] +layout_mode = 2 diff --git a/ui/game_ui.tscn b/ui/game_ui.tscn index 3b20692..12e2aac 100644 --- a/ui/game_ui.tscn +++ b/ui/game_ui.tscn @@ -7,7 +7,7 @@ [ext_resource type="Texture2D" uid="uid://cq8ypeagpedq" path="res://assets/3rdparty/kenney/ui-pack-rpg-expansion/PNG/cursorSword_bronze.png" id="5_4e7rh"] [ext_resource type="Script" path="res://ui/inventory_dialog.gd" id="6_lssx5"] [ext_resource type="PackedScene" uid="uid://dp3fi0g53qrt2" path="res://ui/item_slot.tscn" id="7_2r38a"] -[ext_resource type="PackedScene" uid="uid://bwui4acukq4x6" path="res://ui/item_grid.tscn" id="8_igemi"] +[ext_resource type="PackedScene" uid="uid://bwui4acukq4x6" path="res://ui/ItemGrid.tscn" id="8_igemi"] [node name="GameUI" type="Control"] layout_mode = 3 diff --git a/ui/inventory_dialog.gd b/ui/inventory_dialog.gd index 2a5be82..14c6327 100644 --- a/ui/inventory_dialog.gd +++ b/ui/inventory_dialog.gd @@ -26,7 +26,8 @@ func open(recipes:Array[Recipe], inventory:Inventory): var index = recipe_list.add_item(recipe.name) recipe_list.set_item_metadata(index, recipe) - inventory_container.display(inventory.get_items()) + inventory_container.displayStacks(inventory.get_item_stacks()) + recipe_list.select(0) _on_recipe_list_item_selected(0) @@ -65,5 +66,5 @@ func _on_craft_button_pressed(): for item in _selected_recipe.results: _inventory.add_item(item) - inventory_container.display(_inventory.get_items()) + inventory_container.displayStacks(_inventory.get_item_stacks()) update_crafting_widgets(_selected_recipe) diff --git a/ui/item_grid.gd b/ui/item_grid.gd index b0c0fce..6a06e48 100644 --- a/ui/item_grid.gd +++ b/ui/item_grid.gd @@ -2,12 +2,36 @@ class_name ItemGrid extends GridContainer @export var slot_scene:PackedScene +@export var rows:int = 1 -func display(items:Array[Item]): +func displayStacks(item_stacks:Array[ItemStack]): for child in get_children(): child.queue_free() - - for item in items: + child.get_parent().remove_child(child) + + for item_stack in item_stacks: var slot:ItemSlot = slot_scene.instantiate() add_child(slot) - slot.display(item) + + if item_stack != null: + slot.display(item_stack.item, item_stack.count) + + var item_count = rows * columns + + while get_child_count() < item_count: + add_child(slot_scene.instantiate()) + +func display(item_stacks:Array[Item]): + for child in get_children(): + child.queue_free() + child.get_parent().remove_child(child) + + for item in item_stacks: + var slot:ItemSlot = slot_scene.instantiate() + add_child(slot) + slot.display(item, 1) + + var item_count = rows * columns + + while get_child_count() < item_count: + add_child(slot_scene.instantiate()) diff --git a/ui/item_slot.gd b/ui/item_slot.gd index 443cdd5..52c292b 100644 --- a/ui/item_slot.gd +++ b/ui/item_slot.gd @@ -2,6 +2,16 @@ class_name ItemSlot extends PanelContainer @onready var texture_rect:TextureRect = %TextureRect +@onready var count_label = %CountLabel -func display(item:Item): - texture_rect.texture = item.icon +func display(item:Item, count:int): + if item != null: + texture_rect.texture = item.icon + update_quantity_text(count) + +func update_quantity_text(stack_size) -> void: + if stack_size <= 1: + count_label.hide() + else: + count_label.text = str(stack_size) + count_label.show() diff --git a/ui/item_slot.tscn b/ui/item_slot.tscn index 5704a6b..f3edd6a 100644 --- a/ui/item_slot.tscn +++ b/ui/item_slot.tscn @@ -1,14 +1,18 @@ -[gd_scene load_steps=3 format=3 uid="uid://dp3fi0g53qrt2"] +[gd_scene load_steps=2 format=3 uid="uid://dp3fi0g53qrt2"] [ext_resource type="Script" path="res://ui/item_slot.gd" id="1_7v5l8"] -[ext_resource type="Texture2D" uid="uid://ojsbkfjeu088" path="res://assets/3rdparty/kenney/survival-kit/Previews/toolPickaxe.png" id="1_mafu0"] -[node name="PanelContainer" type="PanelContainer"] +[node name="ItemSlot" type="PanelContainer"] custom_minimum_size = Vector2(64, 64) script = ExtResource("1_7v5l8") [node name="TextureRect" type="TextureRect" parent="."] unique_name_in_owner = true layout_mode = 2 -texture = ExtResource("1_mafu0") expand_mode = 3 + +[node name="CountLabel" type="Label" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 8 +size_flags_vertical = 8 diff --git a/ui/item_stack.gd b/ui/item_stack.gd new file mode 100644 index 0000000..922771b --- /dev/null +++ b/ui/item_stack.gd @@ -0,0 +1,9 @@ +class_name ItemStack +extends Node + +var item:Item = null +@export var count:int = 1 + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. diff --git a/ui/tool_container.gd b/ui/tool_container.gd new file mode 100644 index 0000000..bb208b9 --- /dev/null +++ b/ui/tool_container.gd @@ -0,0 +1,13 @@ +class_name ToolContainer +extends HBoxContainer + +@export var slot_scene:PackedScene + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass diff --git a/ui/tool_container.tscn b/ui/tool_container.tscn new file mode 100644 index 0000000..cd83727 --- /dev/null +++ b/ui/tool_container.tscn @@ -0,0 +1,19 @@ +[gd_scene load_steps=4 format=3 uid="uid://nob4ibnp0p5u"] + +[ext_resource type="Texture2D" uid="uid://c7fu3paj3b4e8" path="res://assets/3rdparty/kenney/ui-pack-rpg-expansion/PNG/cursorSword_silver.png" id="1_wpvbc"] +[ext_resource type="Texture2D" uid="uid://drpl0ql1p3pfk" path="res://assets/3rdparty/kenney/ui-pack-rpg-expansion/PNG/cursorSword_gold.png" id="2_le4fl"] +[ext_resource type="Texture2D" uid="uid://cq8ypeagpedq" path="res://assets/3rdparty/kenney/ui-pack-rpg-expansion/PNG/cursorSword_bronze.png" id="3_jhcf7"] + +[node name="ToolContainer" type="HBoxContainer"] + +[node name="Button2" type="Button" parent="."] +layout_mode = 2 +icon = ExtResource("1_wpvbc") + +[node name="Button3" type="Button" parent="."] +layout_mode = 2 +icon = ExtResource("2_le4fl") + +[node name="Button" type="Button" parent="."] +layout_mode = 2 +icon = ExtResource("3_jhcf7") diff --git a/ui/ui_theme.tres b/ui/ui_theme.tres index dbb611a..0202215 100644 --- a/ui/ui_theme.tres +++ b/ui/ui_theme.tres @@ -83,9 +83,9 @@ Button/styles/normal = SubResource("StyleBoxTexture_votra") Button/styles/pressed = SubResource("StyleBoxTexture_bpyb5") Control/styles/normal = SubResource("StyleBoxTexture_72pk6") ItemList/styles/normal = SubResource("StyleBoxTexture_kl7i7") -Label/colors/font_color = Color(0.172833, 0.172833, 0.172833, 1) +Label/colors/font_color = Color(1, 1, 1, 1) Label/colors/font_outline_color = Color(1, 1, 1, 1) -Label/colors/font_shadow_color = Color(0, 0, 0, 0) +Label/colors/font_shadow_color = Color(0.223103, 0.223103, 0.223103, 0.843137) Label/constants/line_spacing = 3 Label/constants/outline_size = 0 Label/constants/shadow_offset_x = 1