From 09487de05a6944936b603f4f765dbb044c3476ea Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sat, 5 Apr 2025 18:41:49 -0400 Subject: [PATCH 01/23] feat: Add initial ItemResource type and basic torch --- resources/item_resource.gd | 5 +++++ resources/item_resource.gd.uid | 1 + resources/items/007_torch.tres | 14 ++++++++++++++ scenes/items/torch.tscn | 23 +++++++++++++++++++++++ 4 files changed, 43 insertions(+) create mode 100644 resources/item_resource.gd create mode 100644 resources/item_resource.gd.uid create mode 100644 resources/items/007_torch.tres create mode 100644 scenes/items/torch.tscn diff --git a/resources/item_resource.gd b/resources/item_resource.gd new file mode 100644 index 0000000..1bffa6a --- /dev/null +++ b/resources/item_resource.gd @@ -0,0 +1,5 @@ +class_name ItemResource +extends DBItemResource + + +@export var resource_scene: PackedScene = null diff --git a/resources/item_resource.gd.uid b/resources/item_resource.gd.uid new file mode 100644 index 0000000..84183a7 --- /dev/null +++ b/resources/item_resource.gd.uid @@ -0,0 +1 @@ +uid://m32ytcig5ha5 diff --git a/resources/items/007_torch.tres b/resources/items/007_torch.tres new file mode 100644 index 0000000..47c9197 --- /dev/null +++ b/resources/items/007_torch.tres @@ -0,0 +1,14 @@ +[gd_resource type="Resource" script_class="ItemResource" load_steps=3 format=3 uid="uid://dqkdgxdjb8sk5"] + +[ext_resource type="PackedScene" uid="uid://ccky0w7brcf1l" path="res://scenes/items/torch.tscn" id="1_7h82o"] +[ext_resource type="Script" uid="uid://m32ytcig5ha5" path="res://resources/item_resource.gd" id="2_e6rfx"] + +[resource] +script = ExtResource("2_e6rfx") +resource_scene = ExtResource("1_7h82o") +id = "007" +name = "Torch" +amount = 1 +description = "A torch to light the way" +item_texture = "uid://dknv7amroftm8" +metadata/_custom_type_script = "uid://m32ytcig5ha5" diff --git a/scenes/items/torch.tscn b/scenes/items/torch.tscn new file mode 100644 index 0000000..a9e776e --- /dev/null +++ b/scenes/items/torch.tscn @@ -0,0 +1,23 @@ +[gd_scene load_steps=4 format=3 uid="uid://ccky0w7brcf1l"] + +[sub_resource type="BoxMesh" id="BoxMesh_ctvck"] +size = Vector3(0.1, 0.1, 0.1) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ctvck"] +emission_enabled = true +emission = Color(0.846334, 0.776792, 0.275847, 1) +emission_energy_multiplier = 8.23 + +[sub_resource type="BoxMesh" id="BoxMesh_vkm4o"] +size = Vector3(0.1, 0.4, 0.1) + +[node name="Torch" type="Node3D"] + +[node name="Head" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.449571, 0) +mesh = SubResource("BoxMesh_ctvck") +surface_material_override/0 = SubResource("StandardMaterial3D_ctvck") + +[node name="Base" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.19988, 0) +mesh = SubResource("BoxMesh_vkm4o") -- 2.30.1 From 943b44c6467a7e0f147ba1fd781071da43f0c32f Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sat, 5 Apr 2025 18:42:26 -0400 Subject: [PATCH 02/23] config: Update testing inventory with high amounts and additional blocks --- .../inventory/player_inventory_testing.tres | 46 ++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/resources/inventory/player_inventory_testing.tres b/resources/inventory/player_inventory_testing.tres index b36ba8c..5479790 100644 --- a/resources/inventory/player_inventory_testing.tres +++ b/resources/inventory/player_inventory_testing.tres @@ -1,4 +1,4 @@ -[gd_resource type="Resource" script_class="InventoryResource" load_steps=12 format=3 uid="uid://blfp6tiir282o"] +[gd_resource type="Resource" script_class="InventoryResource" load_steps=19 format=3 uid="uid://blfp6tiir282o"] [ext_resource type="Script" uid="uid://becun6dj78v8d" path="res://resources/inventory_resource.gd" id="1_4v6mg"] [ext_resource type="Script" uid="uid://bdx4q355l5ugl" path="res://resources/db_item_resource.gd" id="1_gg8jx"] @@ -6,14 +6,18 @@ [ext_resource type="Script" uid="uid://dwrmy4mx0mw18" path="res://resources/block_resource.gd" id="3_vgvac"] [ext_resource type="Material" uid="uid://cx7m27qa4ds4s" path="res://assets/materials/stone.tres" id="4_7yuhn"] [ext_resource type="Material" uid="uid://jearv8lmwhec" path="res://assets/materials/wood.tres" id="5_p27bu"] +[ext_resource type="Material" uid="uid://b4wrf3quiaa1b" path="res://assets/materials/grass.tres" id="7_vgvac"] [ext_resource type="Material" uid="uid://d15n1p3spu3jg" path="res://assets/materials/leaves.tres" id="7_xd1nd"] +[ext_resource type="Material" uid="uid://b2w5ybx51vuwf" path="res://assets/materials/glass.tres" id="8_7yuhn"] +[ext_resource type="PackedScene" uid="uid://ccky0w7brcf1l" path="res://scenes/items/torch.tscn" id="9_viap3"] +[ext_resource type="Script" uid="uid://m32ytcig5ha5" path="res://resources/item_resource.gd" id="10_wqat2"] [sub_resource type="Resource" id="Resource_jaam2"] script = ExtResource("3_vgvac") material_texture = ExtResource("2_8w148") id = "001" name = "Dirt" -amount = 100 +amount = 999 description = "Block of dirt" item_texture = "uid://li36txj7oweq" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" @@ -23,7 +27,7 @@ script = ExtResource("3_vgvac") material_texture = ExtResource("4_7yuhn") id = "002" name = "Stone" -amount = 100 +amount = 999 description = "Block of stone" item_texture = "uid://ct1iawpfkdf5l" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" @@ -33,7 +37,7 @@ script = ExtResource("3_vgvac") material_texture = ExtResource("5_p27bu") id = "003" name = "Wood" -amount = 100 +amount = 999 description = "Wood log" item_texture = "uid://0mw651622h01" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" @@ -43,13 +47,43 @@ script = ExtResource("3_vgvac") material_texture = ExtResource("7_xd1nd") id = "004" name = "Leaves" -amount = 100 +amount = 999 description = "Tree leaves" item_texture = "uid://goygbpyqhych" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" +[sub_resource type="Resource" id="Resource_viap3"] +script = ExtResource("3_vgvac") +material_texture = ExtResource("7_vgvac") +id = "005" +name = "Grass" +amount = 999 +description = "Block of grass and dirt" +item_texture = "uid://li36txj7oweq" +metadata/_custom_type_script = "uid://dwrmy4mx0mw18" + +[sub_resource type="Resource" id="Resource_wqat2"] +script = ExtResource("3_vgvac") +material_texture = ExtResource("8_7yuhn") +id = "006" +name = "Glass" +amount = 999 +description = "Glass block" +item_texture = "uid://cpllegyqnfnrh" +metadata/_custom_type_script = "uid://dwrmy4mx0mw18" + +[sub_resource type="Resource" id="Resource_xd1nd"] +script = ExtResource("10_wqat2") +resource_scene = ExtResource("9_viap3") +id = "007" +name = "Torch" +amount = 999 +description = "A torch to light the way" +item_texture = "uid://dknv7amroftm8" +metadata/_custom_type_script = "uid://m32ytcig5ha5" + [resource] script = ExtResource("1_4v6mg") -inventory = Array[ExtResource("1_gg8jx")]([SubResource("Resource_jaam2"), SubResource("Resource_4kby3"), SubResource("Resource_byct5"), SubResource("Resource_qycqj")]) +inventory = Array[ExtResource("1_gg8jx")]([SubResource("Resource_jaam2"), SubResource("Resource_4kby3"), SubResource("Resource_byct5"), SubResource("Resource_qycqj"), SubResource("Resource_viap3"), SubResource("Resource_wqat2"), SubResource("Resource_xd1nd")]) max_stack_size = 999 metadata/_custom_type_script = "uid://becun6dj78v8d" -- 2.30.1 From f63cfb0ca83321d298c424359f5dd0459358e1f9 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sat, 5 Apr 2025 18:43:58 -0400 Subject: [PATCH 03/23] wip: Initialize the item rects and add highlighting on mouse over --- scenes/ui/inventory/inventory.gd | 17 +++++++++++++++-- scenes/ui/inventory/inventory.tscn | 17 ++++++++++++++--- scenes/ui/inventory/item_rect.gd | 24 +++++++++++++++++++++--- scenes/ui/inventory/item_rect.tscn | 26 ++++++++++++++++++-------- 4 files changed, 68 insertions(+), 16 deletions(-) diff --git a/scenes/ui/inventory/inventory.gd b/scenes/ui/inventory/inventory.gd index d20f035..5eeb103 100644 --- a/scenes/ui/inventory/inventory.gd +++ b/scenes/ui/inventory/inventory.gd @@ -6,6 +6,11 @@ extends Control @export var item_rect_scene: PackedScene @export var grid_container: GridContainer +@export var highlight_theme: Resource + +var items: Array[Node] = [] +var selected_item: int = 0 + func _input(event: InputEvent) -> void: if event.is_action_pressed("open_inventory"): @@ -14,9 +19,15 @@ func _input(event: InputEvent) -> void: func _ready() -> void: InventoryManager.item_picked_up.connect(add_item) InventoryManager.item_dropped.connect(subtract_item) + + for item: InventoryItemRect in grid_container.get_children(): + item.queue_free() + for item_resource: DBItemResource in inventory_resource.inventory: add_item(item_resource) + refresh_items() + func add_item(item_resource: DBItemResource, amount: int = 1) -> void: var item_rect: InventoryItemRect = find_item_rect(item_resource) @@ -29,8 +40,7 @@ func add_item(item_resource: DBItemResource, amount: int = 1) -> void: else: item_rect = item_rect_scene.instantiate() grid_container.add_child(item_rect) - item_rect.item_resource = item_resource - item_rect.update_rect() + item_rect.init(item_resource, highlight_theme) func find_item_rect(item_resource: DBItemResource) -> InventoryItemRect: var rect: InventoryItemRect = null @@ -56,6 +66,9 @@ func subtract_item(item_resource: DBItemResource) -> void: else: push_error("Attempting to subtract amount (" + str(item_resource.amount) + " from nonexistent inventory item (" + str(item_resource.name) + ")") +func refresh_items() -> void: + items = grid_container.get_children() + func toggle_inventory() -> void: visible = not visible diff --git a/scenes/ui/inventory/inventory.tscn b/scenes/ui/inventory/inventory.tscn index 3870443..e6b16b2 100644 --- a/scenes/ui/inventory/inventory.tscn +++ b/scenes/ui/inventory/inventory.tscn @@ -1,8 +1,10 @@ -[gd_scene load_steps=4 format=3 uid="uid://dcr25y1lw4wjp"] +[gd_scene load_steps=6 format=3 uid="uid://dcr25y1lw4wjp"] [ext_resource type="Script" uid="uid://dybecq130mxhn" path="res://scenes/ui/inventory/inventory.gd" id="1_s6ek7"] -[ext_resource type="Resource" uid="uid://cnpw7y1csu774" path="res://resources/inventory/player_inventory_empty.tres" id="2_avmd0"] +[ext_resource type="Resource" uid="uid://blfp6tiir282o" path="res://resources/inventory/player_inventory_testing.tres" id="2_pefhr"] [ext_resource type="PackedScene" uid="uid://boueuk2hnfvg" path="res://scenes/ui/inventory/item_rect.tscn" id="3_xeaml"] +[ext_resource type="StyleBox" uid="uid://dlaswvta2mvim" path="res://resources/inventory/quickslot-panel-highlight-stylebox.tres" id="4_8ndef"] +[ext_resource type="Resource" uid="uid://b50yyok6ddux4" path="res://resources/blocks/005_grass.tres" id="4_lobmi"] [node name="Inventory" type="Control" node_paths=PackedStringArray("grid_container")] process_mode = 3 @@ -20,9 +22,10 @@ offset_bottom = 200.0 grow_horizontal = 2 grow_vertical = 2 script = ExtResource("1_s6ek7") -inventory_resource = ExtResource("2_avmd0") +inventory_resource = ExtResource("2_pefhr") item_rect_scene = ExtResource("3_xeaml") grid_container = NodePath("Background/MarginContainer/VBoxContainer/GridContainer") +highlight_theme = ExtResource("4_8ndef") [node name="Background" type="Panel" parent="."] layout_mode = 1 @@ -58,3 +61,11 @@ size_flags_vertical = 3 theme_override_constants/h_separation = 20 theme_override_constants/v_separation = 20 columns = 10 + +[node name="ItemRect" parent="Background/MarginContainer/VBoxContainer/GridContainer" instance=ExtResource("3_xeaml")] +layout_mode = 2 +item_resource = ExtResource("4_lobmi") + +[node name="ItemRect2" parent="Background/MarginContainer/VBoxContainer/GridContainer" instance=ExtResource("3_xeaml")] +layout_mode = 2 +item_resource = ExtResource("4_lobmi") diff --git a/scenes/ui/inventory/item_rect.gd b/scenes/ui/inventory/item_rect.gd index be07ddc..a3ecab9 100644 --- a/scenes/ui/inventory/item_rect.gd +++ b/scenes/ui/inventory/item_rect.gd @@ -4,16 +4,34 @@ extends Panel @export var amount_label: Label @export var item_resource: DBItemResource -@export var item_texture: TextureRect +@export var item_texture: TextureButton + +var highlight_theme: Resource + + +func init(_item_resource: DBItemResource, _highlight_theme: Resource) -> void: + item_texture.mouse_entered.connect(_on_mouse_entered) + item_texture.mouse_exited.connect(_on_mouse_exited) + + highlight_theme = _highlight_theme + item_resource = _item_resource + update_rect() func update_rect() -> void: - item_texture.texture = load(item_resource.item_texture) + item_texture.texture_normal = load(item_resource.item_texture) amount_label.text = "x" + str(item_resource.amount) - tooltip_text = item_resource.name + "\n" + item_resource.description + item_texture.tooltip_text = item_resource.name + "\n" + item_resource.description func on_stack_full(is_full: bool) -> void: if is_full: amount_label.add_theme_color_override("font_color", Color(1, 0, 0)) else: amount_label.add_theme_color_override("font_color", Color(1, 1, 1)) + + +func _on_mouse_entered() -> void: + set("theme_override_styles/panel", highlight_theme) + +func _on_mouse_exited() -> void: + set("theme_override_styles/panel", null) diff --git a/scenes/ui/inventory/item_rect.tscn b/scenes/ui/inventory/item_rect.tscn index fd62238..2d21f0a 100644 --- a/scenes/ui/inventory/item_rect.tscn +++ b/scenes/ui/inventory/item_rect.tscn @@ -8,21 +8,31 @@ outline_size = 3 outline_color = Color(0, 0, 0, 1) [node name="ItemRect" type="Panel" node_paths=PackedStringArray("amount_label", "item_texture")] -custom_minimum_size = Vector2(64, 64) +custom_minimum_size = Vector2(72, 72) offset_right = 64.0 offset_bottom = 64.0 script = ExtResource("1_oderi") amount_label = NodePath("AmountLabel") -item_texture = NodePath("ItemTexture") +item_texture = NodePath("TextureButton") metadata/_edit_use_anchors_ = true -[node name="ItemTexture" type="TextureRect" parent="."] +[node name="TextureButton" type="TextureButton" parent="."] texture_filter = 1 -layout_mode = 0 -offset_right = 64.0 -offset_bottom = 64.0 -texture = ExtResource("1_o0kom") -expand_mode = 1 +custom_minimum_size = Vector2(64, 64) +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -32.0 +offset_top = -32.0 +offset_right = 32.0 +offset_bottom = 32.0 +grow_horizontal = 2 +grow_vertical = 2 +texture_normal = ExtResource("1_o0kom") +ignore_texture_size = true stretch_mode = 4 [node name="AmountLabel" type="Label" parent="."] -- 2.30.1 From c0fc13ecca09c11cd939e1034122d6a3593b4cd7 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sat, 5 Apr 2025 19:52:07 -0400 Subject: [PATCH 04/23] config: Add 007_torch to DBItems.data --- autoloads/db_items.gd | 1 + 1 file changed, 1 insertion(+) diff --git a/autoloads/db_items.gd b/autoloads/db_items.gd index 30347b9..0d6b740 100644 --- a/autoloads/db_items.gd +++ b/autoloads/db_items.gd @@ -8,4 +8,5 @@ extends Node "004": preload("res://resources/blocks/004_leaves.tres"), "005": preload("res://resources/blocks/005_grass.tres"), "006": preload("res://resources/blocks/006_glass.tres"), + "007": preload("res://resources/items/007_torch.tres"), } -- 2.30.1 From 077143a32cc6a2b33084818a2b2b62eaa753cf7d Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sat, 5 Apr 2025 19:56:48 -0400 Subject: [PATCH 05/23] wip: Create empty cells and move inventory into InventoryManager --- autoloads/inventory_manager.gd | 29 ++++++++++++++++ scenes/ui/inventory/inventory.gd | 54 +++++++++++++++++++++--------- scenes/ui/inventory/inventory.tscn | 16 +++------ scenes/ui/inventory/item_rect.gd | 14 ++++++-- scenes/ui/inventory/item_rect.tscn | 4 +-- 5 files changed, 83 insertions(+), 34 deletions(-) diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index 9277acd..6e779b1 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -9,12 +9,41 @@ signal item_dropped(item: DBItemResource) signal inventory_opened signal inventory_closed +signal add_to_inventory(item_id: String, amount: int) +signal remove_from_inventory(item_id: String, amount: int) +signal item_added(item_id: String, amount: int) +signal item_removed(item_id: String, amount: int) + var quick_slot_item_id: String = "001" +var inventory: Dictionary[String, DBItemResource] + func _ready() -> void: self.quick_slot_item_changed.connect(_on_quick_slot_item_changed) + self.item_picked_up.connect(_on_item_picked_up) + self.item_dropped.connect(_on_item_dropped) + + self.add_to_inventory.connect(_on_add_to_inventory) + self.remove_from_inventory.connect(_on_remove_from_inventory) + + +func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: + if not inventory.has(item_id): + inventory[item_id] = DBItems.data[item_id] + + inventory[item_id].amount += amount + +func _on_remove_from_inventory(item_id: String, amount: int = 1) -> void: + if not inventory.has(item_id): return + + inventory[item_id].amount -= amount + +func _on_item_dropped(item_id: String) -> void: + _on_remove_from_inventory(item_id, 1) +func _on_item_picked_up(item_id: String) -> void: + _on_add_to_inventory(item_id, 1) func _on_quick_slot_item_changed(item_id: String) -> void: quick_slot_item_id = item_id diff --git a/scenes/ui/inventory/inventory.gd b/scenes/ui/inventory/inventory.gd index 5eeb103..32c8904 100644 --- a/scenes/ui/inventory/inventory.gd +++ b/scenes/ui/inventory/inventory.gd @@ -5,10 +5,10 @@ extends Control @export var inventory_resource: InventoryResource @export var item_rect_scene: PackedScene @export var grid_container: GridContainer +@export var max_items: int = 40 # 4 rows of 10 @export var highlight_theme: Resource -var items: Array[Node] = [] var selected_item: int = 0 @@ -17,16 +17,12 @@ func _input(event: InputEvent) -> void: toggle_inventory() func _ready() -> void: - InventoryManager.item_picked_up.connect(add_item) - InventoryManager.item_dropped.connect(subtract_item) + InventoryManager.item_picked_up.connect(_on_item_picked_up) + InventoryManager.item_dropped.connect(_on_item_dropped) + InventoryManager.add_to_inventory.connect(_on_add_to_inventory) + InventoryManager.remove_from_inventory.connect(_on_remove_from_inventory) - for item: InventoryItemRect in grid_container.get_children(): - item.queue_free() - - for item_resource: DBItemResource in inventory_resource.inventory: - add_item(item_resource) - - refresh_items() + generate_inventory_grid() func add_item(item_resource: DBItemResource, amount: int = 1) -> void: @@ -52,22 +48,35 @@ func find_item_rect(item_resource: DBItemResource) -> InventoryItemRect: return rect -func subtract_item(item_resource: DBItemResource) -> void: +func generate_inventory_grid() -> void: + for item: InventoryItemRect in grid_container.get_children(): + item.queue_free() + + # Add any items from the existing inventory resource + for item_resource: DBItemResource in inventory_resource.inventory: + InventoryManager.add_to_inventory.emit(item_resource.id, item_resource.amount) + + var empty_cells: int = max_items - inventory_resource.inventory.size() + + # Add empty item cells + for _i: int in range(empty_cells): + var item_rect: InventoryItemRect = item_rect_scene.instantiate() + grid_container.add_child(item_rect) + item_rect.clear_rect() + +func subtract_item(item_resource: DBItemResource, amount: int =1) -> void: var item_rect: InventoryItemRect = find_item_rect(item_resource) if item_rect != null: if item_rect.item_resource.amount >= inventory_resource.max_stack_size: item_rect.on_stack_full(false) - item_rect.item_resource.amount -= item_resource.amount + item_rect.item_resource.amount -= amount item_rect.update_rect() if item_rect.item_resource.amount < 1: # Empty stack item_rect.queue_free() else: - push_error("Attempting to subtract amount (" + str(item_resource.amount) + " from nonexistent inventory item (" + str(item_resource.name) + ")") - -func refresh_items() -> void: - items = grid_container.get_children() + push_error("Attempting to subtract amount (" + str(amount) + " from nonexistent inventory item (" + str(item_resource.name) + ")") func toggle_inventory() -> void: visible = not visible @@ -80,3 +89,16 @@ func toggle_inventory() -> void: Input.mouse_mode = Input.MOUSE_MODE_CAPTURED InventoryManager.inventory_closed.emit() get_tree().paused = false + + +func _on_add_to_inventory(item_id: String, amount: int) -> void: + add_item(DBItems.data[item_id], amount) + +func _on_remove_from_inventory(item_id: String, amount: int) -> void: + subtract_item(DBItems.data[item_id], amount) + +func _on_item_picked_up(item_resource: DBItemResource, amount: int) -> void: + add_item(item_resource, amount) + +func _on_item_dropped(item_resource: DBItemResource) -> void: + subtract_item(item_resource, 1) diff --git a/scenes/ui/inventory/inventory.tscn b/scenes/ui/inventory/inventory.tscn index e6b16b2..f853a89 100644 --- a/scenes/ui/inventory/inventory.tscn +++ b/scenes/ui/inventory/inventory.tscn @@ -1,10 +1,9 @@ -[gd_scene load_steps=6 format=3 uid="uid://dcr25y1lw4wjp"] +[gd_scene load_steps=5 format=3 uid="uid://dcr25y1lw4wjp"] [ext_resource type="Script" uid="uid://dybecq130mxhn" path="res://scenes/ui/inventory/inventory.gd" id="1_s6ek7"] [ext_resource type="Resource" uid="uid://blfp6tiir282o" path="res://resources/inventory/player_inventory_testing.tres" id="2_pefhr"] [ext_resource type="PackedScene" uid="uid://boueuk2hnfvg" path="res://scenes/ui/inventory/item_rect.tscn" id="3_xeaml"] [ext_resource type="StyleBox" uid="uid://dlaswvta2mvim" path="res://resources/inventory/quickslot-panel-highlight-stylebox.tres" id="4_8ndef"] -[ext_resource type="Resource" uid="uid://b50yyok6ddux4" path="res://resources/blocks/005_grass.tres" id="4_lobmi"] [node name="Inventory" type="Control" node_paths=PackedStringArray("grid_container")] process_mode = 3 @@ -57,15 +56,8 @@ text = "Inventory" [node name="GridContainer" type="GridContainer" parent="Background/MarginContainer/VBoxContainer"] layout_mode = 2 +size_flags_horizontal = 4 size_flags_vertical = 3 -theme_override_constants/h_separation = 20 -theme_override_constants/v_separation = 20 +theme_override_constants/h_separation = 5 +theme_override_constants/v_separation = 5 columns = 10 - -[node name="ItemRect" parent="Background/MarginContainer/VBoxContainer/GridContainer" instance=ExtResource("3_xeaml")] -layout_mode = 2 -item_resource = ExtResource("4_lobmi") - -[node name="ItemRect2" parent="Background/MarginContainer/VBoxContainer/GridContainer" instance=ExtResource("3_xeaml")] -layout_mode = 2 -item_resource = ExtResource("4_lobmi") diff --git a/scenes/ui/inventory/item_rect.gd b/scenes/ui/inventory/item_rect.gd index a3ecab9..f4968d8 100644 --- a/scenes/ui/inventory/item_rect.gd +++ b/scenes/ui/inventory/item_rect.gd @@ -18,10 +18,18 @@ func init(_item_resource: DBItemResource, _highlight_theme: Resource) -> void: update_rect() +func clear_rect() -> void: + item_texture.texture_normal = null + amount_label.text = "" + item_texture.tooltip_text = "" + func update_rect() -> void: - item_texture.texture_normal = load(item_resource.item_texture) - amount_label.text = "x" + str(item_resource.amount) - item_texture.tooltip_text = item_resource.name + "\n" + item_resource.description + if not item_resource: + clear_rect() + else: + item_texture.texture_normal = load(item_resource.item_texture) + amount_label.text = "x" + str(item_resource.amount) + item_texture.tooltip_text = item_resource.name + "\n" + item_resource.description func on_stack_full(is_full: bool) -> void: if is_full: diff --git a/scenes/ui/inventory/item_rect.tscn b/scenes/ui/inventory/item_rect.tscn index 2d21f0a..7593f1a 100644 --- a/scenes/ui/inventory/item_rect.tscn +++ b/scenes/ui/inventory/item_rect.tscn @@ -1,6 +1,5 @@ -[gd_scene load_steps=4 format=3 uid="uid://boueuk2hnfvg"] +[gd_scene load_steps=3 format=3 uid="uid://boueuk2hnfvg"] -[ext_resource type="Texture2D" uid="uid://dknv7amroftm8" path="res://assets/godot-icon.svg" id="1_o0kom"] [ext_resource type="Script" uid="uid://cknl6i0jce5jr" path="res://scenes/ui/inventory/item_rect.gd" id="1_oderi"] [sub_resource type="LabelSettings" id="LabelSettings_oderi"] @@ -31,7 +30,6 @@ offset_right = 32.0 offset_bottom = 32.0 grow_horizontal = 2 grow_vertical = 2 -texture_normal = ExtResource("1_o0kom") ignore_texture_size = true stretch_mode = 4 -- 2.30.1 From 2db6edae06b62433085eb7222a3349e1c6a79c3f Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sat, 5 Apr 2025 22:57:19 -0400 Subject: [PATCH 06/23] wip: Reworking how inventory is generated (still non-functional) --- autoloads/inventory_manager.gd | 53 ++++++++++-- resources/db_item_resource.gd | 2 + .../inventory/player_inventory_testing.tres | 15 +++- resources/inventory_resource.gd | 1 - scenes/ui/inventory/inventory.gd | 84 +++++++------------ 5 files changed, 92 insertions(+), 63 deletions(-) diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index 6e779b1..c539b00 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -16,7 +16,9 @@ signal item_removed(item_id: String, amount: int) var quick_slot_item_id: String = "001" -var inventory: Dictionary[String, DBItemResource] +var max_inventory_items: int = 40 # 4 rows of 10 + +var inventory: Array[DBItemResource] = [] func _ready() -> void: @@ -28,16 +30,57 @@ func _ready() -> void: self.remove_from_inventory.connect(_on_remove_from_inventory) + +# TODO: REMOVE ME +func _unhandled_input(event: InputEvent) -> void: + if event.is_action_pressed("ui_cancel"): + add_to_inventory.emit("003", 1) + + +func _find_first_stack(item_resource: DBItemResource, item_id: String) -> bool: + return ( + item_resource.id == item_id and + item_resource.amount < item_resource.max_stack_size + ) + + func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: - if not inventory.has(item_id): - inventory[item_id] = DBItems.data[item_id] + var item_resource: DBItemResource = DBItems.data[item_id] + + # The logic below is a mess and needs to be reworked + var amount_remaining: int = amount + while amount_remaining > 0: + var first_stack_index: int = inventory.find_custom(_find_first_stack.bind(item_id)) + + if first_stack_index == -1 and inventory.size() < max_inventory_items: + inventory.append(item_resource) + + if amount_remaining <= item_resource.max_stack_size: + inventory[-1].amount += amount_remaining + amount_remaining = 0 + else: + inventory[-1].amount = item_resource.max_stack_size + amount_remaining -= item_resource.max_stack_size + + item_added.emit(item_id, amount - amount_remaining) + elif first_stack_index > -1: + var current_amount: int = inventory[first_stack_index].amount + var total_amount: int = current_amount + amount_remaining + if item_resource.max_stack_size - total_amount < 0: + inventory[first_stack_index].amount += amount_remaining + amount_remaining = 0 + else: + inventory[first_stack_index].amount = item_resource.max_stack_size + amount_remaining -= item_resource.max_stack_size - inventory[item_id].amount += amount + item_added.emit(item_id, amount - amount_remaining) func _on_remove_from_inventory(item_id: String, amount: int = 1) -> void: if not inventory.has(item_id): return - inventory[item_id].amount -= amount + #if inventory[item_id].amount > 0: + #inventory[item_id].amount -= amount + #item_removed.emit(item_id, max(0, amount)) func _on_item_dropped(item_id: String) -> void: _on_remove_from_inventory(item_id, 1) diff --git a/resources/db_item_resource.gd b/resources/db_item_resource.gd index 89a511f..0dc123d 100644 --- a/resources/db_item_resource.gd +++ b/resources/db_item_resource.gd @@ -5,5 +5,7 @@ extends Resource @export var id: String = "000" @export var name: String = "Item Name" @export var amount: int = 0 +@export var max_stack_size: int = 999 +@export var max_number_stacks: int = 0 ## 0 for unlimited stacks @export var description: String = "Item Description" @export_file var item_texture: String = "res://assets/godot-icon.svg" diff --git a/resources/inventory/player_inventory_testing.tres b/resources/inventory/player_inventory_testing.tres index 5479790..7327d10 100644 --- a/resources/inventory/player_inventory_testing.tres +++ b/resources/inventory/player_inventory_testing.tres @@ -18,6 +18,8 @@ material_texture = ExtResource("2_8w148") id = "001" name = "Dirt" amount = 999 +max_stack_size = 999 +max_number_stacks = 0 description = "Block of dirt" item_texture = "uid://li36txj7oweq" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" @@ -28,6 +30,8 @@ material_texture = ExtResource("4_7yuhn") id = "002" name = "Stone" amount = 999 +max_stack_size = 999 +max_number_stacks = 0 description = "Block of stone" item_texture = "uid://ct1iawpfkdf5l" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" @@ -38,6 +42,8 @@ material_texture = ExtResource("5_p27bu") id = "003" name = "Wood" amount = 999 +max_stack_size = 999 +max_number_stacks = 0 description = "Wood log" item_texture = "uid://0mw651622h01" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" @@ -48,6 +54,8 @@ material_texture = ExtResource("7_xd1nd") id = "004" name = "Leaves" amount = 999 +max_stack_size = 999 +max_number_stacks = 0 description = "Tree leaves" item_texture = "uid://goygbpyqhych" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" @@ -58,6 +66,8 @@ material_texture = ExtResource("7_vgvac") id = "005" name = "Grass" amount = 999 +max_stack_size = 999 +max_number_stacks = 0 description = "Block of grass and dirt" item_texture = "uid://li36txj7oweq" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" @@ -68,6 +78,8 @@ material_texture = ExtResource("8_7yuhn") id = "006" name = "Glass" amount = 999 +max_stack_size = 999 +max_number_stacks = 0 description = "Glass block" item_texture = "uid://cpllegyqnfnrh" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" @@ -78,6 +90,8 @@ resource_scene = ExtResource("9_viap3") id = "007" name = "Torch" amount = 999 +max_stack_size = 999 +max_number_stacks = 0 description = "A torch to light the way" item_texture = "uid://dknv7amroftm8" metadata/_custom_type_script = "uid://m32ytcig5ha5" @@ -85,5 +99,4 @@ metadata/_custom_type_script = "uid://m32ytcig5ha5" [resource] script = ExtResource("1_4v6mg") inventory = Array[ExtResource("1_gg8jx")]([SubResource("Resource_jaam2"), SubResource("Resource_4kby3"), SubResource("Resource_byct5"), SubResource("Resource_qycqj"), SubResource("Resource_viap3"), SubResource("Resource_wqat2"), SubResource("Resource_xd1nd")]) -max_stack_size = 999 metadata/_custom_type_script = "uid://becun6dj78v8d" diff --git a/resources/inventory_resource.gd b/resources/inventory_resource.gd index 1d8712e..039db74 100644 --- a/resources/inventory_resource.gd +++ b/resources/inventory_resource.gd @@ -3,4 +3,3 @@ extends Resource @export var inventory: Array[DBItemResource] = [] -@export var max_stack_size: int = 999 diff --git a/scenes/ui/inventory/inventory.gd b/scenes/ui/inventory/inventory.gd index 32c8904..fa7d08e 100644 --- a/scenes/ui/inventory/inventory.gd +++ b/scenes/ui/inventory/inventory.gd @@ -17,66 +17,39 @@ func _input(event: InputEvent) -> void: toggle_inventory() func _ready() -> void: - InventoryManager.item_picked_up.connect(_on_item_picked_up) - InventoryManager.item_dropped.connect(_on_item_dropped) - InventoryManager.add_to_inventory.connect(_on_add_to_inventory) - InventoryManager.remove_from_inventory.connect(_on_remove_from_inventory) - - generate_inventory_grid() - - -func add_item(item_resource: DBItemResource, amount: int = 1) -> void: - var item_rect: InventoryItemRect = find_item_rect(item_resource) - if item_rect != null: - if item_rect.item_resource.amount + item_resource.amount >= inventory_resource.max_stack_size: - item_rect.on_stack_full(true) - return - item_rect.item_resource.amount += item_resource.amount - item_rect.update_rect() - else: - item_rect = item_rect_scene.instantiate() - grid_container.add_child(item_rect) - item_rect.init(item_resource, highlight_theme) + update_inventory_with_resource() + refresh_inventory_grid() + + InventoryManager.item_added.connect(_on_item_added) # Should be added after update_inventory_with_resource() + InventoryManager.item_removed.connect(_on_item_removed) # Should be added after update_inventory_with_resource() + + +func create_item_cell(item_resource: DBItemResource) -> void: + var item_rect: InventoryItemRect = item_rect_scene.instantiate() + grid_container.add_child(item_rect) + item_rect.init(item_resource, highlight_theme) func find_item_rect(item_resource: DBItemResource) -> InventoryItemRect: var rect: InventoryItemRect = null - for container: InventoryItemRect in grid_container.get_children(): - if container.item_resource.id == item_resource.id: - rect = container + for item_rect: InventoryItemRect in grid_container.get_children(): + if item_rect.item_resource == null: continue + if item_rect.item_resource.id == item_resource.id: + rect = item_rect break return rect -func generate_inventory_grid() -> void: +func refresh_inventory_grid() -> void: for item: InventoryItemRect in grid_container.get_children(): item.queue_free() - # Add any items from the existing inventory resource - for item_resource: DBItemResource in inventory_resource.inventory: - InventoryManager.add_to_inventory.emit(item_resource.id, item_resource.amount) - - var empty_cells: int = max_items - inventory_resource.inventory.size() + for item: DBItemResource in InventoryManager.inventory: + create_item_cell(item) - # Add empty item cells + var empty_cells: int = InventoryManager.max_inventory_items - inventory_resource.inventory.size() for _i: int in range(empty_cells): - var item_rect: InventoryItemRect = item_rect_scene.instantiate() - grid_container.add_child(item_rect) - item_rect.clear_rect() - -func subtract_item(item_resource: DBItemResource, amount: int =1) -> void: - var item_rect: InventoryItemRect = find_item_rect(item_resource) - - if item_rect != null: - if item_rect.item_resource.amount >= inventory_resource.max_stack_size: - item_rect.on_stack_full(false) - item_rect.item_resource.amount -= amount - item_rect.update_rect() - - if item_rect.item_resource.amount < 1: # Empty stack - item_rect.queue_free() - else: - push_error("Attempting to subtract amount (" + str(amount) + " from nonexistent inventory item (" + str(item_resource.name) + ")") + create_item_cell(null) func toggle_inventory() -> void: visible = not visible @@ -90,15 +63,14 @@ func toggle_inventory() -> void: InventoryManager.inventory_closed.emit() get_tree().paused = false +func update_inventory_with_resource() -> void: + # Add any items from the existing inventory resource + for item_resource: DBItemResource in inventory_resource.inventory: + InventoryManager.add_to_inventory.emit(item_resource.id, item_resource.amount) -func _on_add_to_inventory(item_id: String, amount: int) -> void: - add_item(DBItems.data[item_id], amount) - -func _on_remove_from_inventory(item_id: String, amount: int) -> void: - subtract_item(DBItems.data[item_id], amount) -func _on_item_picked_up(item_resource: DBItemResource, amount: int) -> void: - add_item(item_resource, amount) +func _on_item_added(_item_id: String, _amount: int) -> void: + refresh_inventory_grid() -func _on_item_dropped(item_resource: DBItemResource) -> void: - subtract_item(item_resource, 1) +func _on_item_removed(_item_id: String, _amount: int) -> void: + refresh_inventory_grid() -- 2.30.1 From 7460b8a5b25933f42fa210af9ea64af43a36ba06 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sun, 6 Apr 2025 10:34:52 -0400 Subject: [PATCH 07/23] Fixing adding of items to inventory --- autoloads/inventory_manager.gd | 34 +++++++++++++++++++++----------- scenes/ui/inventory/inventory.gd | 7 +++++-- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index c539b00..a18029b 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -37,7 +37,7 @@ func _unhandled_input(event: InputEvent) -> void: add_to_inventory.emit("003", 1) -func _find_first_stack(item_resource: DBItemResource, item_id: String) -> bool: +func _find_first_available_stack(item_resource: DBItemResource, item_id: String) -> bool: return ( item_resource.id == item_id and item_resource.amount < item_resource.max_stack_size @@ -45,33 +45,43 @@ func _find_first_stack(item_resource: DBItemResource, item_id: String) -> bool: func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: + if not DBItems.data.get(item_id): + printerr("Cannot add item, ", item_id, ", to inventory. Could not find item within DBItems.data.") + return + if amount < 1: + printerr("Cannot add item, ", item_id, ", to inventory. Amount to add cannot be less then 1.") + return + var item_resource: DBItemResource = DBItems.data[item_id] - # The logic below is a mess and needs to be reworked + # This logic seems overly complicated and is a mess. + # Should look into fixing/simplifying this in the future var amount_remaining: int = amount while amount_remaining > 0: - var first_stack_index: int = inventory.find_custom(_find_first_stack.bind(item_id)) + var first_stack_index: int = inventory.find_custom(_find_first_available_stack.bind(item_id)) if first_stack_index == -1 and inventory.size() < max_inventory_items: - inventory.append(item_resource) + var stack_resource: DBItemResource = item_resource.duplicate() + inventory.append(stack_resource) - if amount_remaining <= item_resource.max_stack_size: + if amount_remaining <= stack_resource.max_stack_size: inventory[-1].amount += amount_remaining amount_remaining = 0 else: - inventory[-1].amount = item_resource.max_stack_size - amount_remaining -= item_resource.max_stack_size + inventory[-1].amount = stack_resource.max_stack_size + amount_remaining -= stack_resource.max_stack_size item_added.emit(item_id, amount - amount_remaining) elif first_stack_index > -1: - var current_amount: int = inventory[first_stack_index].amount + var stack_resource: DBItemResource = inventory[first_stack_index] + var current_amount: int = stack_resource.amount var total_amount: int = current_amount + amount_remaining - if item_resource.max_stack_size - total_amount < 0: - inventory[first_stack_index].amount += amount_remaining + if total_amount < stack_resource.max_stack_size: # Stack not full and can hold + inventory[first_stack_index].amount = total_amount amount_remaining = 0 else: - inventory[first_stack_index].amount = item_resource.max_stack_size - amount_remaining -= item_resource.max_stack_size + inventory[first_stack_index].amount = stack_resource.max_stack_size + amount_remaining -= stack_resource.max_stack_size item_added.emit(item_id, amount - amount_remaining) diff --git a/scenes/ui/inventory/inventory.gd b/scenes/ui/inventory/inventory.gd index fa7d08e..12c5390 100644 --- a/scenes/ui/inventory/inventory.gd +++ b/scenes/ui/inventory/inventory.gd @@ -47,7 +47,7 @@ func refresh_inventory_grid() -> void: for item: DBItemResource in InventoryManager.inventory: create_item_cell(item) - var empty_cells: int = InventoryManager.max_inventory_items - inventory_resource.inventory.size() + var empty_cells: int = InventoryManager.max_inventory_items - InventoryManager.inventory.size() for _i: int in range(empty_cells): create_item_cell(null) @@ -63,8 +63,11 @@ func toggle_inventory() -> void: InventoryManager.inventory_closed.emit() get_tree().paused = false +## Add any items from the existing inventory resource func update_inventory_with_resource() -> void: - # Add any items from the existing inventory resource + if inventory_resource == null: + return + for item_resource: DBItemResource in inventory_resource.inventory: InventoryManager.add_to_inventory.emit(item_resource.id, item_resource.amount) -- 2.30.1 From 9077c66a943e05a0919bb3bb2437b8ebe7c79547 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sun, 6 Apr 2025 12:41:49 -0400 Subject: [PATCH 08/23] wip: Add support for removing an item from inventory --- autoloads/inventory_manager.gd | 41 +++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index a18029b..610c180 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -30,19 +30,26 @@ func _ready() -> void: self.remove_from_inventory.connect(_on_remove_from_inventory) - # TODO: REMOVE ME func _unhandled_input(event: InputEvent) -> void: - if event.is_action_pressed("ui_cancel"): + if event.is_action_pressed("ui_up"): add_to_inventory.emit("003", 1) + elif event.is_action_pressed("ui_down"): + remove_from_inventory.emit("003", 1) -func _find_first_available_stack(item_resource: DBItemResource, item_id: String) -> bool: +## Find the stack where at least one item can be added +func _find_available_stack(item_resource: DBItemResource, item_id: String) -> bool: return ( item_resource.id == item_id and item_resource.amount < item_resource.max_stack_size ) +## Find the stack in which we can remove a specific item +## The inventory has a stack, then it should have at least 1 item. Empty stacks are not kept in the inventory. +func _find_removable_stack(item_resource: DBItemResource, item_id: String) -> bool: + return item_resource.id == item_id + func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: if not DBItems.data.get(item_id): @@ -58,7 +65,7 @@ func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: # Should look into fixing/simplifying this in the future var amount_remaining: int = amount while amount_remaining > 0: - var first_stack_index: int = inventory.find_custom(_find_first_available_stack.bind(item_id)) + var first_stack_index: int = inventory.find_custom(_find_available_stack.bind(item_id)) if first_stack_index == -1 and inventory.size() < max_inventory_items: var stack_resource: DBItemResource = item_resource.duplicate() @@ -71,7 +78,6 @@ func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: inventory[-1].amount = stack_resource.max_stack_size amount_remaining -= stack_resource.max_stack_size - item_added.emit(item_id, amount - amount_remaining) elif first_stack_index > -1: var stack_resource: DBItemResource = inventory[first_stack_index] var current_amount: int = stack_resource.amount @@ -83,14 +89,29 @@ func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: inventory[first_stack_index].amount = stack_resource.max_stack_size amount_remaining -= stack_resource.max_stack_size - item_added.emit(item_id, amount - amount_remaining) + item_added.emit(item_id, amount - amount_remaining) func _on_remove_from_inventory(item_id: String, amount: int = 1) -> void: - if not inventory.has(item_id): return + var amount_remaining: int = amount + while amount_remaining > 0: + var last_stack_index: int = inventory.rfind_custom(_find_removable_stack.bind(item_id)) + + if last_stack_index > -1: + var stack_resource: DBItemResource = inventory[last_stack_index] + var current_stack_amount: int = stack_resource.amount + var total_amount: int = current_stack_amount - amount_remaining + + if total_amount > 0: # Stack will not be empty after removing + inventory[last_stack_index].amount -= amount_remaining + amount_remaining = 0 + else: + var remaining: int = stack_resource.max_stack_size - current_stack_amount + inventory.remove_at(last_stack_index) + amount_remaining -= remaining + else: # Received more to remove than we had stacks of + amount_remaining = 0 - #if inventory[item_id].amount > 0: - #inventory[item_id].amount -= amount - #item_removed.emit(item_id, max(0, amount)) + item_removed.emit(item_id, amount - amount_remaining) func _on_item_dropped(item_id: String) -> void: _on_remove_from_inventory(item_id, 1) -- 2.30.1 From c195dbc8f6dc598090ecbcd17789bd2823160ca5 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sun, 6 Apr 2025 14:47:25 -0400 Subject: [PATCH 09/23] wip: Add _inventory_cache and available_space() --- autoloads/inventory_manager.gd | 50 +++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index 610c180..cf15668 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -19,7 +19,7 @@ var quick_slot_item_id: String = "001" var max_inventory_items: int = 40 # 4 rows of 10 var inventory: Array[DBItemResource] = [] - +var _inventory_cache: Dictionary[String, Dictionary] = {} ## Used for caching certain information func _ready() -> void: self.quick_slot_item_changed.connect(_on_quick_slot_item_changed) @@ -38,17 +38,36 @@ func _unhandled_input(event: InputEvent) -> void: remove_from_inventory.emit("003", 1) +func available_space(item_id: String) -> int: + var full_stacks: int = floor(_inventory_cache[item_id].total / DBItems.data[item_id].max_stack_size) + var space_in_stacks: int = ( + DBItems.data[item_id].max_stack_size - abs( + _inventory_cache[item_id].total - (DBItems.data[item_id].max_stack_size * full_stacks) + ) + ) + + # This is a bit of a hack because I'm a math/logic noob + if space_in_stacks == DBItems.data[item_id].max_stack_size: + space_in_stacks = 0 + + var open_stack_amount: int = (max_inventory_items - inventory.size()) * DBItems.data[item_id].max_stack_size + return open_stack_amount + space_in_stacks + + +func _find_stacks_by_id(item_resource: DBItemResource, item_id: String) -> bool: + return item_resource.id == item_id + ## Find the stack where at least one item can be added -func _find_available_stack(item_resource: DBItemResource, item_id: String) -> bool: +func _find_stacks_with_space(item_resource: DBItemResource, item_id: String) -> bool: return ( item_resource.id == item_id and item_resource.amount < item_resource.max_stack_size ) -## Find the stack in which we can remove a specific item -## The inventory has a stack, then it should have at least 1 item. Empty stacks are not kept in the inventory. -func _find_removable_stack(item_resource: DBItemResource, item_id: String) -> bool: - return item_resource.id == item_id +func _update_cache_total(item_id: String, amount: int) -> void: + if not _inventory_cache.get(item_id): + _inventory_cache[item_id] = {"total": 0} + _inventory_cache[item_id].total += amount func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: @@ -65,27 +84,30 @@ func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: # Should look into fixing/simplifying this in the future var amount_remaining: int = amount while amount_remaining > 0: - var first_stack_index: int = inventory.find_custom(_find_available_stack.bind(item_id)) + var first_stack_index: int = inventory.find_custom(_find_stacks_with_space.bind(item_id)) - if first_stack_index == -1 and inventory.size() < max_inventory_items: + if first_stack_index == -1 and inventory.size() < max_inventory_items: # No existing stack and empty slots available var stack_resource: DBItemResource = item_resource.duplicate() inventory.append(stack_resource) if amount_remaining <= stack_resource.max_stack_size: + _update_cache_total(item_id, amount_remaining) inventory[-1].amount += amount_remaining amount_remaining = 0 else: + _update_cache_total(item_id, stack_resource.max_stack_size) inventory[-1].amount = stack_resource.max_stack_size amount_remaining -= stack_resource.max_stack_size - elif first_stack_index > -1: var stack_resource: DBItemResource = inventory[first_stack_index] var current_amount: int = stack_resource.amount var total_amount: int = current_amount + amount_remaining - if total_amount < stack_resource.max_stack_size: # Stack not full and can hold + if total_amount < stack_resource.max_stack_size: # Stack not full and has space + _update_cache_total(item_id, amount_remaining) inventory[first_stack_index].amount = total_amount amount_remaining = 0 else: + _update_cache_total(item_id, stack_resource.max_stack_size - current_amount) inventory[first_stack_index].amount = stack_resource.max_stack_size amount_remaining -= stack_resource.max_stack_size @@ -94,7 +116,7 @@ func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: func _on_remove_from_inventory(item_id: String, amount: int = 1) -> void: var amount_remaining: int = amount while amount_remaining > 0: - var last_stack_index: int = inventory.rfind_custom(_find_removable_stack.bind(item_id)) + var last_stack_index: int = inventory.rfind_custom(_find_stacks_by_id.bind(item_id)) if last_stack_index > -1: var stack_resource: DBItemResource = inventory[last_stack_index] @@ -102,12 +124,14 @@ func _on_remove_from_inventory(item_id: String, amount: int = 1) -> void: var total_amount: int = current_stack_amount - amount_remaining if total_amount > 0: # Stack will not be empty after removing + _update_cache_total(item_id, -amount_remaining) inventory[last_stack_index].amount -= amount_remaining amount_remaining = 0 else: - var remaining: int = stack_resource.max_stack_size - current_stack_amount + var to_remove: int = stack_resource.max_stack_size - current_stack_amount + _update_cache_total(item_id, -amount_remaining) inventory.remove_at(last_stack_index) - amount_remaining -= remaining + amount_remaining -= to_remove else: # Received more to remove than we had stacks of amount_remaining = 0 -- 2.30.1 From e3a987e1a80707e75724c870c9cb50a298d4034e Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sun, 6 Apr 2025 14:53:06 -0400 Subject: [PATCH 10/23] cleanup: Removing testing hotkeys --- autoloads/inventory_manager.gd | 8 -------- 1 file changed, 8 deletions(-) diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index cf15668..8a3da19 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -30,14 +30,6 @@ func _ready() -> void: self.remove_from_inventory.connect(_on_remove_from_inventory) -# TODO: REMOVE ME -func _unhandled_input(event: InputEvent) -> void: - if event.is_action_pressed("ui_up"): - add_to_inventory.emit("003", 1) - elif event.is_action_pressed("ui_down"): - remove_from_inventory.emit("003", 1) - - func available_space(item_id: String) -> int: var full_stacks: int = floor(_inventory_cache[item_id].total / DBItems.data[item_id].max_stack_size) var space_in_stacks: int = ( -- 2.30.1 From fc46230dbadffdef4664300dc844fde17aab566c Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sun, 6 Apr 2025 14:54:49 -0400 Subject: [PATCH 11/23] chore: Split toggle_inventory() for convenience --- scenes/ui/inventory/inventory.gd | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/scenes/ui/inventory/inventory.gd b/scenes/ui/inventory/inventory.gd index 12c5390..00a1c8c 100644 --- a/scenes/ui/inventory/inventory.gd +++ b/scenes/ui/inventory/inventory.gd @@ -2,12 +2,12 @@ class_name Inventory extends Control -@export var inventory_resource: InventoryResource -@export var item_rect_scene: PackedScene -@export var grid_container: GridContainer +@export var inventory_resource: InventoryResource ## A starting inventory to initialize the inventory with +@export var item_rect_scene: PackedScene ## The scene to use for each individual item stack in the inventory +@export var grid_container: GridContainer ## Container for inventory items @export var max_items: int = 40 # 4 rows of 10 -@export var highlight_theme: Resource +@export var highlight_theme: Resource ## The theme to apply on mouse_enter of the InventoryItemRect var selected_item: int = 0 @@ -52,16 +52,11 @@ func refresh_inventory_grid() -> void: create_item_cell(null) func toggle_inventory() -> void: - visible = not visible - if visible: - Input.mouse_mode = Input.MOUSE_MODE_VISIBLE - InventoryManager.inventory_opened.emit() - get_tree().paused = true + _close_inventory() else: - Input.mouse_mode = Input.MOUSE_MODE_CAPTURED - InventoryManager.inventory_closed.emit() - get_tree().paused = false + _open_inventory() + ## Add any items from the existing inventory resource func update_inventory_with_resource() -> void: @@ -72,6 +67,18 @@ func update_inventory_with_resource() -> void: InventoryManager.add_to_inventory.emit(item_resource.id, item_resource.amount) +func _close_inventory() -> void: + visible = false + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + InventoryManager.inventory_closed.emit() + +func _open_inventory() -> void: + refresh_inventory_grid() + visible = true + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + InventoryManager.inventory_opened.emit() + + func _on_item_added(_item_id: String, _amount: int) -> void: refresh_inventory_grid() -- 2.30.1 From c833c0947ef67bdba48c8719f17391e7f8f94134 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sun, 6 Apr 2025 15:00:51 -0400 Subject: [PATCH 12/23] feat: Clear inventory when loading inventory resource --- autoloads/inventory_manager.gd | 7 +++++++ scenes/ui/inventory/inventory.gd | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index 8a3da19..8434d6b 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -9,6 +9,7 @@ signal item_dropped(item: DBItemResource) signal inventory_opened signal inventory_closed +signal clear_inventory signal add_to_inventory(item_id: String, amount: int) signal remove_from_inventory(item_id: String, amount: int) signal item_added(item_id: String, amount: int) @@ -21,6 +22,7 @@ var max_inventory_items: int = 40 # 4 rows of 10 var inventory: Array[DBItemResource] = [] var _inventory_cache: Dictionary[String, Dictionary] = {} ## Used for caching certain information + func _ready() -> void: self.quick_slot_item_changed.connect(_on_quick_slot_item_changed) self.item_picked_up.connect(_on_item_picked_up) @@ -28,6 +30,7 @@ func _ready() -> void: self.add_to_inventory.connect(_on_add_to_inventory) self.remove_from_inventory.connect(_on_remove_from_inventory) + self.clear_inventory.connect(_on_clear_inventory) func available_space(item_id: String) -> int: @@ -129,6 +132,10 @@ func _on_remove_from_inventory(item_id: String, amount: int = 1) -> void: item_removed.emit(item_id, amount - amount_remaining) +func _on_clear_inventory() -> void: + inventory.clear() + _inventory_cache.clear() + func _on_item_dropped(item_id: String) -> void: _on_remove_from_inventory(item_id, 1) diff --git a/scenes/ui/inventory/inventory.gd b/scenes/ui/inventory/inventory.gd index 00a1c8c..874042a 100644 --- a/scenes/ui/inventory/inventory.gd +++ b/scenes/ui/inventory/inventory.gd @@ -57,12 +57,12 @@ func toggle_inventory() -> void: else: _open_inventory() - ## Add any items from the existing inventory resource func update_inventory_with_resource() -> void: if inventory_resource == null: return + InventoryManager.clear_inventory.emit() for item_resource: DBItemResource in inventory_resource.inventory: InventoryManager.add_to_inventory.emit(item_resource.id, item_resource.amount) -- 2.30.1 From 2f1ce26bdc2eb9da4e252322fe049195841530a2 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sun, 6 Apr 2025 15:55:26 -0400 Subject: [PATCH 13/23] wip: Clear Inventory when InventoryManager.clear_inventory emitted --- scenes/ui/inventory/inventory.gd | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/scenes/ui/inventory/inventory.gd b/scenes/ui/inventory/inventory.gd index 874042a..7173b24 100644 --- a/scenes/ui/inventory/inventory.gd +++ b/scenes/ui/inventory/inventory.gd @@ -5,12 +5,9 @@ extends Control @export var inventory_resource: InventoryResource ## A starting inventory to initialize the inventory with @export var item_rect_scene: PackedScene ## The scene to use for each individual item stack in the inventory @export var grid_container: GridContainer ## Container for inventory items -@export var max_items: int = 40 # 4 rows of 10 @export var highlight_theme: Resource ## The theme to apply on mouse_enter of the InventoryItemRect -var selected_item: int = 0 - func _input(event: InputEvent) -> void: if event.is_action_pressed("open_inventory"): @@ -22,6 +19,7 @@ func _ready() -> void: InventoryManager.item_added.connect(_on_item_added) # Should be added after update_inventory_with_resource() InventoryManager.item_removed.connect(_on_item_removed) # Should be added after update_inventory_with_resource() + InventoryManager.clear_inventory.connect(_on_clear_inventory) func create_item_cell(item_resource: DBItemResource) -> void: @@ -29,7 +27,7 @@ func create_item_cell(item_resource: DBItemResource) -> void: grid_container.add_child(item_rect) item_rect.init(item_resource, highlight_theme) -func find_item_rect(item_resource: DBItemResource) -> InventoryItemRect: +func find_item_cell(item_resource: DBItemResource) -> InventoryItemRect: var rect: InventoryItemRect = null for item_rect: InventoryItemRect in grid_container.get_children(): @@ -79,6 +77,13 @@ func _open_inventory() -> void: InventoryManager.inventory_opened.emit() +func _on_clear_inventory() -> void: + for item: InventoryItemRect in grid_container.get_children(): + item.queue_free() + + for _i: int in range(InventoryManager.max_inventory_items): + create_item_cell(null) + func _on_item_added(_item_id: String, _amount: int) -> void: refresh_inventory_grid() -- 2.30.1 From ac92c7501f4890f45909f7d4c542182b8dc1b9a9 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sun, 6 Apr 2025 16:26:57 -0400 Subject: [PATCH 14/23] feat: Use null to indicate empty slots to keep inventory order --- autoloads/inventory_manager.gd | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index 8434d6b..738ad44 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -14,12 +14,14 @@ signal add_to_inventory(item_id: String, amount: int) signal remove_from_inventory(item_id: String, amount: int) signal item_added(item_id: String, amount: int) signal item_removed(item_id: String, amount: int) +signal inventory_slot_cleared(slot_index: int) + var quick_slot_item_id: String = "001" var max_inventory_items: int = 40 # 4 rows of 10 -var inventory: Array[DBItemResource] = [] +var inventory: Array[DBItemResource] = [] ## To ensure inventory is automatically sorted, "empty" inventory cells will be replaced with null to keep positions var _inventory_cache: Dictionary[String, Dictionary] = {} ## Used for caching certain information @@ -50,13 +52,15 @@ func available_space(item_id: String) -> int: func _find_stacks_by_id(item_resource: DBItemResource, item_id: String) -> bool: - return item_resource.id == item_id + return item_resource != null and item_resource.id == item_id ## Find the stack where at least one item can be added func _find_stacks_with_space(item_resource: DBItemResource, item_id: String) -> bool: return ( - item_resource.id == item_id and - item_resource.amount < item_resource.max_stack_size + item_resource == null or ( + item_resource.id == item_id and + item_resource.amount < item_resource.max_stack_size + ) ) func _update_cache_total(item_id: String, amount: int) -> void: @@ -81,8 +85,9 @@ func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: while amount_remaining > 0: var first_stack_index: int = inventory.find_custom(_find_stacks_with_space.bind(item_id)) + var stack_resource: DBItemResource if first_stack_index == -1 and inventory.size() < max_inventory_items: # No existing stack and empty slots available - var stack_resource: DBItemResource = item_resource.duplicate() + stack_resource = item_resource.duplicate() inventory.append(stack_resource) if amount_remaining <= stack_resource.max_stack_size: @@ -94,7 +99,10 @@ func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: inventory[-1].amount = stack_resource.max_stack_size amount_remaining -= stack_resource.max_stack_size elif first_stack_index > -1: - var stack_resource: DBItemResource = inventory[first_stack_index] + if inventory[first_stack_index] == null: # Empty slot + inventory[first_stack_index] = item_resource.duplicate() + + stack_resource = inventory[first_stack_index] var current_amount: int = stack_resource.amount var total_amount: int = current_amount + amount_remaining if total_amount < stack_resource.max_stack_size: # Stack not full and has space @@ -125,8 +133,9 @@ func _on_remove_from_inventory(item_id: String, amount: int = 1) -> void: else: var to_remove: int = stack_resource.max_stack_size - current_stack_amount _update_cache_total(item_id, -amount_remaining) - inventory.remove_at(last_stack_index) + inventory[last_stack_index] = null amount_remaining -= to_remove + inventory_slot_cleared.emit(last_stack_index) else: # Received more to remove than we had stacks of amount_remaining = 0 -- 2.30.1 From 34a56a09dbe6bd1c20518e596ccc8d86c939db42 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sun, 6 Apr 2025 22:07:51 -0400 Subject: [PATCH 15/23] wip: Reworked Quickslots and wired up inventory --- autoloads/inventory_manager.gd | 39 +++-- .../inventory/player_inventory_testing.tres | 18 +-- scenes/player/player.gd | 32 +++- scenes/player/player.tscn | 2 +- scenes/player/ray_cast_look.gd | 2 +- scenes/ui/inventory/quickslots_slot.gd | 39 +++++ scenes/ui/inventory/quickslots_slot.gd.uid | 1 + scenes/ui/inventory/quickslots_slot.tscn | 36 +++++ scenes/ui/quick_slots.gd | 48 +++--- scenes/ui/quick_slots.tscn | 152 ++++-------------- scenes/ui/ui.tscn | 6 +- 11 files changed, 191 insertions(+), 184 deletions(-) create mode 100644 scenes/ui/inventory/quickslots_slot.gd create mode 100644 scenes/ui/inventory/quickslots_slot.gd.uid create mode 100644 scenes/ui/inventory/quickslots_slot.tscn diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index 738ad44..da18998 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -3,7 +3,7 @@ extends Node signal next_quick_slot signal previous_quick_slot signal select_quick_slot(slot_index: int) -signal quick_slot_item_changed(item_id: String) +signal quick_slot_selected(slot_index: int) signal item_picked_up(item: DBItemResource) signal item_dropped(item: DBItemResource) signal inventory_opened @@ -14,11 +14,11 @@ signal add_to_inventory(item_id: String, amount: int) signal remove_from_inventory(item_id: String, amount: int) signal item_added(item_id: String, amount: int) signal item_removed(item_id: String, amount: int) -signal inventory_slot_cleared(slot_index: int) +signal inventory_slot_updated(slot_index: int) -var quick_slot_item_id: String = "001" - +var quick_slot_count: int = 10 +var selected_quick_slot: int = 0 var max_inventory_items: int = 40 # 4 rows of 10 var inventory: Array[DBItemResource] = [] ## To ensure inventory is automatically sorted, "empty" inventory cells will be replaced with null to keep positions @@ -26,13 +26,14 @@ var _inventory_cache: Dictionary[String, Dictionary] = {} ## Used for caching ce func _ready() -> void: - self.quick_slot_item_changed.connect(_on_quick_slot_item_changed) self.item_picked_up.connect(_on_item_picked_up) self.item_dropped.connect(_on_item_dropped) self.add_to_inventory.connect(_on_add_to_inventory) self.remove_from_inventory.connect(_on_remove_from_inventory) self.clear_inventory.connect(_on_clear_inventory) + self.quick_slot_selected.connect(_on_quick_slot_selected) + func available_space(item_id: String) -> int: @@ -50,6 +51,13 @@ func available_space(item_id: String) -> int: var open_stack_amount: int = (max_inventory_items - inventory.size()) * DBItems.data[item_id].max_stack_size return open_stack_amount + space_in_stacks +func get_inventory_item(item_slot: int = selected_quick_slot) -> DBItemResource: + if item_slot >= inventory.size() or item_slot < 0: + return null + return inventory.get(item_slot) + +func get_quick_slot_item_id(item_slot: int = selected_quick_slot) -> String: + return inventory[item_slot].id func _find_stacks_by_id(item_resource: DBItemResource, item_id: String) -> bool: return item_resource != null and item_resource.id == item_id @@ -98,6 +106,8 @@ func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: _update_cache_total(item_id, stack_resource.max_stack_size) inventory[-1].amount = stack_resource.max_stack_size amount_remaining -= stack_resource.max_stack_size + + inventory_slot_updated.emit(inventory.size() - 1) elif first_stack_index > -1: if inventory[first_stack_index] == null: # Empty slot inventory[first_stack_index] = item_resource.duplicate() @@ -114,6 +124,8 @@ func _on_add_to_inventory(item_id: String, amount: int = 1) -> void: inventory[first_stack_index].amount = stack_resource.max_stack_size amount_remaining -= stack_resource.max_stack_size + inventory_slot_updated.emit(first_stack_index) + item_added.emit(item_id, amount - amount_remaining) func _on_remove_from_inventory(item_id: String, amount: int = 1) -> void: @@ -135,8 +147,9 @@ func _on_remove_from_inventory(item_id: String, amount: int = 1) -> void: _update_cache_total(item_id, -amount_remaining) inventory[last_stack_index] = null amount_remaining -= to_remove - inventory_slot_cleared.emit(last_stack_index) - else: # Received more to remove than we had stacks of + + inventory_slot_updated.emit(last_stack_index) + else: # Received more to remove than we have stacks for amount_remaining = 0 item_removed.emit(item_id, amount - amount_remaining) @@ -145,11 +158,11 @@ func _on_clear_inventory() -> void: inventory.clear() _inventory_cache.clear() -func _on_item_dropped(item_id: String) -> void: - _on_remove_from_inventory(item_id, 1) +func _on_item_dropped(item: DBItemResource) -> void: + _on_remove_from_inventory(item.id, 1) -func _on_item_picked_up(item_id: String) -> void: - _on_add_to_inventory(item_id, 1) +func _on_item_picked_up(item: DBItemResource) -> void: + _on_add_to_inventory(item.id, 1) -func _on_quick_slot_item_changed(item_id: String) -> void: - quick_slot_item_id = item_id +func _on_quick_slot_selected(slot_index: int) -> void: + selected_quick_slot = slot_index diff --git a/resources/inventory/player_inventory_testing.tres b/resources/inventory/player_inventory_testing.tres index 7327d10..f2831e7 100644 --- a/resources/inventory/player_inventory_testing.tres +++ b/resources/inventory/player_inventory_testing.tres @@ -1,4 +1,4 @@ -[gd_resource type="Resource" script_class="InventoryResource" load_steps=19 format=3 uid="uid://blfp6tiir282o"] +[gd_resource type="Resource" script_class="InventoryResource" load_steps=16 format=3 uid="uid://blfp6tiir282o"] [ext_resource type="Script" uid="uid://becun6dj78v8d" path="res://resources/inventory_resource.gd" id="1_4v6mg"] [ext_resource type="Script" uid="uid://bdx4q355l5ugl" path="res://resources/db_item_resource.gd" id="1_gg8jx"] @@ -9,8 +9,6 @@ [ext_resource type="Material" uid="uid://b4wrf3quiaa1b" path="res://assets/materials/grass.tres" id="7_vgvac"] [ext_resource type="Material" uid="uid://d15n1p3spu3jg" path="res://assets/materials/leaves.tres" id="7_xd1nd"] [ext_resource type="Material" uid="uid://b2w5ybx51vuwf" path="res://assets/materials/glass.tres" id="8_7yuhn"] -[ext_resource type="PackedScene" uid="uid://ccky0w7brcf1l" path="res://scenes/items/torch.tscn" id="9_viap3"] -[ext_resource type="Script" uid="uid://m32ytcig5ha5" path="res://resources/item_resource.gd" id="10_wqat2"] [sub_resource type="Resource" id="Resource_jaam2"] script = ExtResource("3_vgvac") @@ -84,19 +82,7 @@ description = "Glass block" item_texture = "uid://cpllegyqnfnrh" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" -[sub_resource type="Resource" id="Resource_xd1nd"] -script = ExtResource("10_wqat2") -resource_scene = ExtResource("9_viap3") -id = "007" -name = "Torch" -amount = 999 -max_stack_size = 999 -max_number_stacks = 0 -description = "A torch to light the way" -item_texture = "uid://dknv7amroftm8" -metadata/_custom_type_script = "uid://m32ytcig5ha5" - [resource] script = ExtResource("1_4v6mg") -inventory = Array[ExtResource("1_gg8jx")]([SubResource("Resource_jaam2"), SubResource("Resource_4kby3"), SubResource("Resource_byct5"), SubResource("Resource_qycqj"), SubResource("Resource_viap3"), SubResource("Resource_wqat2"), SubResource("Resource_xd1nd")]) +inventory = Array[ExtResource("1_gg8jx")]([SubResource("Resource_jaam2"), SubResource("Resource_4kby3"), SubResource("Resource_byct5"), SubResource("Resource_qycqj"), SubResource("Resource_viap3"), SubResource("Resource_wqat2")]) metadata/_custom_type_script = "uid://becun6dj78v8d" diff --git a/scenes/player/player.gd b/scenes/player/player.gd index c7777f4..223eed5 100644 --- a/scenes/player/player.gd +++ b/scenes/player/player.gd @@ -37,7 +37,9 @@ func _input(event: InputEvent) -> void: if event is InputEventMouseMotion: _handle_mouse_movement(event.relative) elif event.is_action_pressed("throw_item"): # TODO: Move to state? - EntityManager.drop_block.emit(InventoryManager.quick_slot_item_id, head.global_position, -head.global_basis.z, throw_velocity) + if InventoryManager.get_inventory_item() != null: + EntityManager.drop_block.emit(InventoryManager.get_quick_slot_item_id(), head.global_position, -head.global_basis.z, throw_velocity) + InventoryManager.remove_from_inventory.emit(InventoryManager.get_quick_slot_item_id(), 1) func _physics_process(delta: float) -> void: is_crouching = Input.is_action_pressed("crouch") or ray_cast_crouch.is_colliding() @@ -56,14 +58,15 @@ func _physics_process(delta: float) -> void: func _ready() -> void: GameSettingsManager.graphics_fov_changed.connect(_on_graphics_fov_changed) GameSettingsManager.game_options_held_block_ui_changed.connect(_on_game_options_held_block_ui_changed) - InventoryManager.quick_slot_item_changed.connect(_on_quick_slot_item_changed) + InventoryManager.quick_slot_selected.connect(_on_quick_slot_selected) + InventoryManager.add_to_inventory.connect(_on_add_to_inventory) + InventoryManager.remove_from_inventory.connect(_on_remove_from_inventory) + InventoryManager.item_picked_up.connect(_on_item_picked_up) SignalManager.resume_game.connect(_on_resume_game) SignalManager.open_pause_menu.connect(_on_open_pause_menu) SignalManager.hide_ui.connect(_on_hide_ui) SignalManager.show_ui.connect(_on_show_ui) - _update_held_block_mesh(InventoryManager.quick_slot_item_id) - func _apply_gravity(delta: float) -> void: if is_on_floor(): return @@ -133,10 +136,15 @@ func _set_is_sprinting() -> void: else: is_sprinting = Input.is_action_pressed("run") -func _update_held_block_mesh(item_id: String) -> void: +func _update_held_block_mesh() -> void: + var current_item: DBItemResource = InventoryManager.get_inventory_item() + if current_item == null: + block_mesh.visible = false + return + block_mesh.visible = GameSettingsManager.settings.game_options.enable_held_block if GameSettingsManager.settings.game_options.enable_held_block: - block_mesh.apply_material(DBItems.data[item_id].material_texture) + block_mesh.apply_material(current_item.material_texture) func _on_game_options_held_block_ui_changed(toggled: bool) -> void: @@ -145,8 +153,8 @@ func _on_game_options_held_block_ui_changed(toggled: bool) -> void: func _on_graphics_fov_changed(fov: int) -> void: camera.fov = fov -func _on_quick_slot_item_changed(item_id: String) -> void: - _update_held_block_mesh(item_id) +func _on_quick_slot_selected(_slot_index: int) -> void: + _update_held_block_mesh() func _on_open_pause_menu() -> void: block_mesh.visible = false @@ -154,6 +162,14 @@ func _on_open_pause_menu() -> void: func _on_resume_game() -> void: block_mesh.visible = GameSettingsManager.settings.game_options.enable_held_block +func _on_add_to_inventory(_item_id: String, _amount: int) -> void: + _update_held_block_mesh() + +func _on_item_picked_up(_item: DBItemResource) -> void: + _update_held_block_mesh() + +func _on_remove_from_inventory(_item_id: String, _amount: int) -> void: + _update_held_block_mesh() func _on_hide_ui() -> void: block_mesh.visible = false diff --git a/scenes/player/player.tscn b/scenes/player/player.tscn index 942fdff..ccce050 100644 --- a/scenes/player/player.tscn +++ b/scenes/player/player.tscn @@ -35,7 +35,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.8, 0) [node name="Camera3D" type="Camera3D" parent="Head"] [node name="BlockMesh" parent="Head/Camera3D" instance=ExtResource("2_p47bc")] -transform = Transform3D(1, 0, 0, 0, 0.965926, -0.258819, 0, 0.258819, 0.965926, 0, -0.680035, -1.7196) +transform = Transform3D(1, 0, 0, 0, 0.965926, -0.258819, 0, 0.258819, 0.965926, 1.15474, -0.680035, -1.35803) [node name="RayCastLook" type="RayCast3D" parent="Head" node_paths=PackedStringArray("player")] target_position = Vector3(0, 0, -10) diff --git a/scenes/player/ray_cast_look.gd b/scenes/player/ray_cast_look.gd index ea92373..c035de3 100644 --- a/scenes/player/ray_cast_look.gd +++ b/scenes/player/ray_cast_look.gd @@ -17,7 +17,7 @@ func _process(_delta: float) -> void: if !is_valid_placement_target(block_pos): return - EntityManager.create_block.emit(InventoryManager.quick_slot_item_id, block_pos) + EntityManager.create_block.emit(InventoryManager.get_quick_slot_item_id(), block_pos) if Waila.ref.get_target() == collider: return diff --git a/scenes/ui/inventory/quickslots_slot.gd b/scenes/ui/inventory/quickslots_slot.gd new file mode 100644 index 0000000..135fa19 --- /dev/null +++ b/scenes/ui/inventory/quickslots_slot.gd @@ -0,0 +1,39 @@ +class_name QuickSlotsSlot +extends Panel + + +@export var amount_label: Label +@export var slot_texture: TextureRect + +var slot_index: int = 0 + +func _ready() -> void: + InventoryManager.inventory_slot_updated.connect(_on_inventory_slot_updated) + + +func init(_slot_index: int) -> void: + slot_index = _slot_index + refresh() + +func clear() -> void: + slot_texture.texture = null + amount_label.text = "" + slot_texture.tooltip_text = "" + +func refresh() -> void: + if InventoryManager.inventory.size() < 1: + return clear() + elif not InventoryManager.inventory.get(slot_index): + return clear() + elif InventoryManager.inventory[slot_index] == null: + return clear() + + slot_texture.texture = load(InventoryManager.inventory[slot_index].item_texture) + amount_label.text = "x" + str(InventoryManager.inventory[slot_index].amount) + slot_texture.tooltip_text = InventoryManager.inventory[slot_index].name + "\n" + InventoryManager.inventory[slot_index].description + + +func _on_inventory_slot_updated(_slot_index: int) -> void: + if _slot_index != slot_index: return + + refresh() diff --git a/scenes/ui/inventory/quickslots_slot.gd.uid b/scenes/ui/inventory/quickslots_slot.gd.uid new file mode 100644 index 0000000..c962a41 --- /dev/null +++ b/scenes/ui/inventory/quickslots_slot.gd.uid @@ -0,0 +1 @@ +uid://cq3yb4beq5f4s diff --git a/scenes/ui/inventory/quickslots_slot.tscn b/scenes/ui/inventory/quickslots_slot.tscn new file mode 100644 index 0000000..fcfc1f2 --- /dev/null +++ b/scenes/ui/inventory/quickslots_slot.tscn @@ -0,0 +1,36 @@ +[gd_scene load_steps=3 format=3 uid="uid://c40k8ey6e54v1"] + +[ext_resource type="Script" uid="uid://cq3yb4beq5f4s" path="res://scenes/ui/inventory/quickslots_slot.gd" id="1_l6jhe"] + +[sub_resource type="LabelSettings" id="LabelSettings_7oxdy"] +outline_size = 3 +outline_color = Color(0, 0, 0, 1) + +[node name="Slot" type="Panel" node_paths=PackedStringArray("amount_label", "slot_texture")] +custom_minimum_size = Vector2(64, 64) +script = ExtResource("1_l6jhe") +amount_label = NodePath("MarginContainer/AmountLabel") +slot_texture = NodePath("MarginContainer/TextureRect") + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 4 +theme_override_constants/margin_top = 4 +theme_override_constants/margin_right = 4 +theme_override_constants/margin_bottom = 4 + +[node name="TextureRect" type="TextureRect" parent="MarginContainer"] +texture_filter = 1 +layout_mode = 2 +expand_mode = 2 + +[node name="AmountLabel" type="Label" parent="MarginContainer"] +layout_mode = 2 +size_flags_horizontal = 8 +size_flags_vertical = 8 +label_settings = SubResource("LabelSettings_7oxdy") diff --git a/scenes/ui/quick_slots.gd b/scenes/ui/quick_slots.gd index c7baf3e..be1e08a 100644 --- a/scenes/ui/quick_slots.gd +++ b/scenes/ui/quick_slots.gd @@ -3,28 +3,29 @@ extends Node @export var highlight_theme: Resource +@export var slots_container: GridContainer +@export var quickslots_slot: PackedScene -@onready var slots_container: GridContainer = $GridContainer - -var _items: Array[String] = ["001", "005", "002", "003", "004", "006"] var _previous_selected_item: int = 0 var _selected_item: int = 0 : set(new_item_index): if new_item_index < 0: - new_item_index = _items.size() - 1 - elif new_item_index >= _items.size(): + new_item_index = InventoryManager.quick_slot_count - 1 + elif new_item_index >= InventoryManager.quick_slot_count: new_item_index = 0 _previous_selected_item = _selected_item _selected_item = new_item_index + func _init() -> void: InventoryManager.next_quick_slot.connect(select_next_item) InventoryManager.previous_quick_slot.connect(select_previous_item) InventoryManager.select_quick_slot.connect(select_quick_slot) func _ready() -> void: - var current_slot: Panel = slots_container.get_child(_selected_item) - current_slot.set("theme_override_styles/panel", highlight_theme) + clear_slots() + generate_quick_slots() + update_highlighted_slot() func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("quickslot1"): @@ -53,26 +54,31 @@ func _unhandled_input(event: InputEvent) -> void: select_previous_item() -func get_quickslot_index() -> int: - return _selected_item +func clear_slots() -> void: + for slot: QuickSlotsSlot in slots_container.get_children(): + slot.queue_free() -func get_selected_item() -> String: - return _items[_selected_item] - -func select_quick_slot(slot_index: int) -> void: - _selected_item = slot_index - update_highlighted_slot() - InventoryManager.quick_slot_item_changed.emit(get_selected_item()) +func generate_quick_slots() -> void: + for slot_index: int in range(InventoryManager.quick_slot_count): + var slot: QuickSlotsSlot = quickslots_slot.instantiate() + slots_container.add_child(slot) + slot.init(slot_index) func select_previous_item() -> void: - select_quick_slot(_selected_item + 1) + select_quick_slot(_selected_item - 1) func select_next_item() -> void: - select_quick_slot(_selected_item - 1) + select_quick_slot(_selected_item + 1) + +func select_quick_slot(slot_index: int) -> void: + _selected_item = slot_index + InventoryManager.quick_slot_selected.emit(slot_index) + update_highlighted_slot() func update_highlighted_slot() -> void: - var previous_slot: Panel = slots_container.get_child(_previous_selected_item) - var current_slot: Panel = slots_container.get_child(_selected_item) + if _previous_selected_item != _selected_item: + var previous_slot: Panel = slots_container.get_child(_previous_selected_item) + previous_slot.set("theme_override_styles/panel", null) - previous_slot.set("theme_override_styles/panel", null) + var current_slot: Panel = slots_container.get_child(_selected_item) current_slot.set("theme_override_styles/panel", highlight_theme) diff --git a/scenes/ui/quick_slots.tscn b/scenes/ui/quick_slots.tscn index 1f00638..e9f083e 100644 --- a/scenes/ui/quick_slots.tscn +++ b/scenes/ui/quick_slots.tscn @@ -1,157 +1,63 @@ -[gd_scene load_steps=9 format=3 uid="uid://cbiygbgpfk220"] +[gd_scene load_steps=4 format=3 uid="uid://cbiygbgpfk220"] [ext_resource type="Script" uid="uid://bcq6vexsmyeol" path="res://scenes/ui/quick_slots.gd" id="1_cqw2g"] -[ext_resource type="Texture2D" uid="uid://li36txj7oweq" path="res://assets/textures/dirt.png" id="2_kotkb"] [ext_resource type="StyleBox" uid="uid://dlaswvta2mvim" path="res://resources/inventory/quickslot-panel-highlight-stylebox.tres" id="2_ps55n"] -[ext_resource type="Texture2D" uid="uid://ct1iawpfkdf5l" path="res://assets/textures/stone.png" id="3_cqw2g"] -[ext_resource type="Texture2D" uid="uid://bgo4mb3atmbot" path="res://assets/textures/grass.png" id="3_yyyxx"] -[ext_resource type="Texture2D" uid="uid://0mw651622h01" path="res://assets/textures/wood.png" id="4_yyyxx"] -[ext_resource type="Texture2D" uid="uid://goygbpyqhych" path="res://assets/textures/leaves.png" id="5_ps55n"] -[ext_resource type="Texture2D" uid="uid://cpllegyqnfnrh" path="res://assets/textures/glass.png" id="8_bup65"] +[ext_resource type="PackedScene" uid="uid://c40k8ey6e54v1" path="res://scenes/ui/inventory/quickslots_slot.tscn" id="3_bup65"] -[node name="QuickSlots" type="MarginContainer"] -anchors_preset = 4 -anchor_top = 0.5 -anchor_bottom = 0.5 -offset_top = -220.0 -offset_right = 80.0 -offset_bottom = 220.0 -grow_vertical = 2 -size_flags_horizontal = 0 +[node name="QuickSlots" type="MarginContainer" node_paths=PackedStringArray("slots_container")] +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -364.0 +offset_top = -80.0 +offset_right = 364.0 +grow_horizontal = 2 +grow_vertical = 0 theme_override_constants/margin_left = 8 theme_override_constants/margin_top = 8 theme_override_constants/margin_right = 8 theme_override_constants/margin_bottom = 8 script = ExtResource("1_cqw2g") highlight_theme = ExtResource("2_ps55n") +slots_container = NodePath("SlotsContainer") +quickslots_slot = ExtResource("3_bup65") -[node name="GridContainer" type="GridContainer" parent="."] +[node name="SlotsContainer" type="GridContainer" parent="."] layout_mode = 2 +size_flags_horizontal = 4 +size_flags_vertical = 4 theme_override_constants/h_separation = 8 theme_override_constants/v_separation = 8 +columns = 10 -[node name="Slot0" type="Panel" parent="GridContainer"] -custom_minimum_size = Vector2(64, 64) -layout_mode = 2 - -[node name="MarginContainer" type="MarginContainer" parent="GridContainer/Slot0"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_constants/margin_left = 4 -theme_override_constants/margin_top = 4 -theme_override_constants/margin_right = 4 -theme_override_constants/margin_bottom = 4 - -[node name="TextureRect" type="TextureRect" parent="GridContainer/Slot0/MarginContainer"] -texture_filter = 1 -layout_mode = 2 -texture = ExtResource("2_kotkb") - -[node name="Slot1" type="Panel" parent="GridContainer"] -custom_minimum_size = Vector2(64, 64) +[node name="Slot0" parent="SlotsContainer" instance=ExtResource("3_bup65")] layout_mode = 2 -[node name="MarginContainer" type="MarginContainer" parent="GridContainer/Slot1"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_constants/margin_left = 4 -theme_override_constants/margin_top = 4 -theme_override_constants/margin_right = 4 -theme_override_constants/margin_bottom = 4 - -[node name="TextureRect" type="TextureRect" parent="GridContainer/Slot1/MarginContainer"] -texture_filter = 1 +[node name="Slot1" parent="SlotsContainer" instance=ExtResource("3_bup65")] layout_mode = 2 -texture = ExtResource("3_yyyxx") -[node name="Slot3" type="Panel" parent="GridContainer"] -custom_minimum_size = Vector2(64, 64) +[node name="Slot2" parent="SlotsContainer" instance=ExtResource("3_bup65")] layout_mode = 2 -[node name="MarginContainer" type="MarginContainer" parent="GridContainer/Slot3"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_constants/margin_left = 4 -theme_override_constants/margin_top = 4 -theme_override_constants/margin_right = 4 -theme_override_constants/margin_bottom = 4 - -[node name="TextureRect" type="TextureRect" parent="GridContainer/Slot3/MarginContainer"] -texture_filter = 1 +[node name="Slot3" parent="SlotsContainer" instance=ExtResource("3_bup65")] layout_mode = 2 -texture = ExtResource("3_cqw2g") -[node name="Slot4" type="Panel" parent="GridContainer"] -custom_minimum_size = Vector2(64, 64) +[node name="Slot4" parent="SlotsContainer" instance=ExtResource("3_bup65")] layout_mode = 2 -[node name="MarginContainer" type="MarginContainer" parent="GridContainer/Slot4"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_constants/margin_left = 4 -theme_override_constants/margin_top = 4 -theme_override_constants/margin_right = 4 -theme_override_constants/margin_bottom = 4 - -[node name="TextureRect" type="TextureRect" parent="GridContainer/Slot4/MarginContainer"] -texture_filter = 1 +[node name="Slot5" parent="SlotsContainer" instance=ExtResource("3_bup65")] layout_mode = 2 -texture = ExtResource("4_yyyxx") -[node name="Slot5" type="Panel" parent="GridContainer"] -custom_minimum_size = Vector2(64, 64) +[node name="Slot6" parent="SlotsContainer" instance=ExtResource("3_bup65")] layout_mode = 2 -[node name="MarginContainer" type="MarginContainer" parent="GridContainer/Slot5"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_constants/margin_left = 4 -theme_override_constants/margin_top = 4 -theme_override_constants/margin_right = 4 -theme_override_constants/margin_bottom = 4 - -[node name="TextureRect" type="TextureRect" parent="GridContainer/Slot5/MarginContainer"] -texture_filter = 1 +[node name="Slot7" parent="SlotsContainer" instance=ExtResource("3_bup65")] layout_mode = 2 -texture = ExtResource("5_ps55n") -[node name="Slot6" type="Panel" parent="GridContainer"] -custom_minimum_size = Vector2(64, 64) +[node name="Slot8" parent="SlotsContainer" instance=ExtResource("3_bup65")] layout_mode = 2 -[node name="MarginContainer" type="MarginContainer" parent="GridContainer/Slot6"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_constants/margin_left = 4 -theme_override_constants/margin_top = 4 -theme_override_constants/margin_right = 4 -theme_override_constants/margin_bottom = 4 - -[node name="TextureRect" type="TextureRect" parent="GridContainer/Slot6/MarginContainer"] -texture_filter = 1 +[node name="Slot9" parent="SlotsContainer" instance=ExtResource("3_bup65")] layout_mode = 2 -texture = ExtResource("8_bup65") diff --git a/scenes/ui/ui.tscn b/scenes/ui/ui.tscn index 3109d97..e7c0a44 100644 --- a/scenes/ui/ui.tscn +++ b/scenes/ui/ui.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=6 format=3 uid="uid://c7fj7wla8bd70"] +[gd_scene load_steps=7 format=3 uid="uid://c7fj7wla8bd70"] [ext_resource type="Script" uid="uid://bslimr2y4lnvq" path="res://scenes/ui/ui.gd" id="1_aac20"] [ext_resource type="PackedScene" uid="uid://dvogu3djluqsn" path="res://scenes/ui/waila.tscn" id="1_u7n8c"] [ext_resource type="PackedScene" uid="uid://cbiygbgpfk220" path="res://scenes/ui/quick_slots.tscn" id="4_g5kmx"] [ext_resource type="PackedScene" uid="uid://by0gd600mbcr5" path="res://scenes/ui/pause_menu/pause_menu.tscn" id="5_0dwhk"] +[ext_resource type="PackedScene" uid="uid://dcr25y1lw4wjp" path="res://scenes/ui/inventory/inventory.tscn" id="6_pfayw"] [ext_resource type="PackedScene" uid="uid://rfknvv8b0d4i" path="res://scenes/ui/autosave_notification.tscn" id="7_jcn1r"] [node name="UI" type="CanvasLayer"] @@ -35,3 +36,6 @@ visible = false [node name="PauseMenu" parent="." instance=ExtResource("5_0dwhk")] visible = false + +[node name="Inventory" parent="." instance=ExtResource("6_pfayw")] +visible = false -- 2.30.1 From ce2613215a3a2e38f6dffcfaa3747626b27fc39d Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sun, 6 Apr 2025 22:12:31 -0400 Subject: [PATCH 16/23] refactor: Move quickslots into own dir --- scenes/ui/{ => quickslots}/quick_slots.gd | 0 scenes/ui/{ => quickslots}/quick_slots.gd.uid | 0 scenes/ui/{ => quickslots}/quick_slots.tscn | 4 ++-- scenes/ui/{inventory => quickslots}/quickslots_slot.gd | 0 scenes/ui/{inventory => quickslots}/quickslots_slot.gd.uid | 0 scenes/ui/{inventory => quickslots}/quickslots_slot.tscn | 2 +- scenes/ui/ui.tscn | 2 +- 7 files changed, 4 insertions(+), 4 deletions(-) rename scenes/ui/{ => quickslots}/quick_slots.gd (100%) rename scenes/ui/{ => quickslots}/quick_slots.gd.uid (100%) rename scenes/ui/{ => quickslots}/quick_slots.tscn (94%) rename scenes/ui/{inventory => quickslots}/quickslots_slot.gd (100%) rename scenes/ui/{inventory => quickslots}/quickslots_slot.gd.uid (100%) rename scenes/ui/{inventory => quickslots}/quickslots_slot.tscn (95%) diff --git a/scenes/ui/quick_slots.gd b/scenes/ui/quickslots/quick_slots.gd similarity index 100% rename from scenes/ui/quick_slots.gd rename to scenes/ui/quickslots/quick_slots.gd diff --git a/scenes/ui/quick_slots.gd.uid b/scenes/ui/quickslots/quick_slots.gd.uid similarity index 100% rename from scenes/ui/quick_slots.gd.uid rename to scenes/ui/quickslots/quick_slots.gd.uid diff --git a/scenes/ui/quick_slots.tscn b/scenes/ui/quickslots/quick_slots.tscn similarity index 94% rename from scenes/ui/quick_slots.tscn rename to scenes/ui/quickslots/quick_slots.tscn index e9f083e..1b8d80e 100644 --- a/scenes/ui/quick_slots.tscn +++ b/scenes/ui/quickslots/quick_slots.tscn @@ -1,8 +1,8 @@ [gd_scene load_steps=4 format=3 uid="uid://cbiygbgpfk220"] -[ext_resource type="Script" uid="uid://bcq6vexsmyeol" path="res://scenes/ui/quick_slots.gd" id="1_cqw2g"] +[ext_resource type="Script" uid="uid://bcq6vexsmyeol" path="res://scenes/ui/quickslots/quick_slots.gd" id="1_cqw2g"] [ext_resource type="StyleBox" uid="uid://dlaswvta2mvim" path="res://resources/inventory/quickslot-panel-highlight-stylebox.tres" id="2_ps55n"] -[ext_resource type="PackedScene" uid="uid://c40k8ey6e54v1" path="res://scenes/ui/inventory/quickslots_slot.tscn" id="3_bup65"] +[ext_resource type="PackedScene" uid="uid://c40k8ey6e54v1" path="res://scenes/ui/quickslots/quickslots_slot.tscn" id="3_bup65"] [node name="QuickSlots" type="MarginContainer" node_paths=PackedStringArray("slots_container")] anchors_preset = 7 diff --git a/scenes/ui/inventory/quickslots_slot.gd b/scenes/ui/quickslots/quickslots_slot.gd similarity index 100% rename from scenes/ui/inventory/quickslots_slot.gd rename to scenes/ui/quickslots/quickslots_slot.gd diff --git a/scenes/ui/inventory/quickslots_slot.gd.uid b/scenes/ui/quickslots/quickslots_slot.gd.uid similarity index 100% rename from scenes/ui/inventory/quickslots_slot.gd.uid rename to scenes/ui/quickslots/quickslots_slot.gd.uid diff --git a/scenes/ui/inventory/quickslots_slot.tscn b/scenes/ui/quickslots/quickslots_slot.tscn similarity index 95% rename from scenes/ui/inventory/quickslots_slot.tscn rename to scenes/ui/quickslots/quickslots_slot.tscn index fcfc1f2..7aba6d9 100644 --- a/scenes/ui/inventory/quickslots_slot.tscn +++ b/scenes/ui/quickslots/quickslots_slot.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://c40k8ey6e54v1"] -[ext_resource type="Script" uid="uid://cq3yb4beq5f4s" path="res://scenes/ui/inventory/quickslots_slot.gd" id="1_l6jhe"] +[ext_resource type="Script" uid="uid://cq3yb4beq5f4s" path="res://scenes/ui/quickslots/quickslots_slot.gd" id="1_l6jhe"] [sub_resource type="LabelSettings" id="LabelSettings_7oxdy"] outline_size = 3 diff --git a/scenes/ui/ui.tscn b/scenes/ui/ui.tscn index e7c0a44..31d71c9 100644 --- a/scenes/ui/ui.tscn +++ b/scenes/ui/ui.tscn @@ -2,7 +2,7 @@ [ext_resource type="Script" uid="uid://bslimr2y4lnvq" path="res://scenes/ui/ui.gd" id="1_aac20"] [ext_resource type="PackedScene" uid="uid://dvogu3djluqsn" path="res://scenes/ui/waila.tscn" id="1_u7n8c"] -[ext_resource type="PackedScene" uid="uid://cbiygbgpfk220" path="res://scenes/ui/quick_slots.tscn" id="4_g5kmx"] +[ext_resource type="PackedScene" uid="uid://cbiygbgpfk220" path="res://scenes/ui/quickslots/quick_slots.tscn" id="4_g5kmx"] [ext_resource type="PackedScene" uid="uid://by0gd600mbcr5" path="res://scenes/ui/pause_menu/pause_menu.tscn" id="5_0dwhk"] [ext_resource type="PackedScene" uid="uid://dcr25y1lw4wjp" path="res://scenes/ui/inventory/inventory.tscn" id="6_pfayw"] [ext_resource type="PackedScene" uid="uid://rfknvv8b0d4i" path="res://scenes/ui/autosave_notification.tscn" id="7_jcn1r"] -- 2.30.1 From af0fc8d3fad2d91acb0d10d6092acecc697baa2a Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sun, 6 Apr 2025 22:16:41 -0400 Subject: [PATCH 17/23] fix: Set grass item texture --- resources/blocks/005_grass.tres | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/blocks/005_grass.tres b/resources/blocks/005_grass.tres index 3be7b92..009ec48 100644 --- a/resources/blocks/005_grass.tres +++ b/resources/blocks/005_grass.tres @@ -9,6 +9,8 @@ material_texture = ExtResource("1_n4fyn") id = "005" name = "Grass" amount = 0 +max_stack_size = 999 +max_number_stacks = 0 description = "Block of grass and dirt" -item_texture = "uid://li36txj7oweq" +item_texture = "uid://bgo4mb3atmbot" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" -- 2.30.1 From 52baddf417a88aabf339ca275d9a152a78746bd0 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Mon, 7 Apr 2025 10:56:07 -0400 Subject: [PATCH 18/23] wip: Remove from inventory when placing block --- autoloads/inventory_manager.gd | 21 +++++++++++++++++---- scenes/player/player.gd | 4 ++++ scenes/player/ray_cast_look.gd | 1 + scenes/ui/quickslots/quick_slots.gd | 6 +++--- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index da18998..e2ca1f8 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -9,9 +9,10 @@ signal item_dropped(item: DBItemResource) signal inventory_opened signal inventory_closed -signal clear_inventory +signal clear_inventory ## Remove all items in inventory signal add_to_inventory(item_id: String, amount: int) signal remove_from_inventory(item_id: String, amount: int) +signal remove_from_slot(slot_index: int, amount: int) signal item_added(item_id: String, amount: int) signal item_removed(item_id: String, amount: int) signal inventory_slot_updated(slot_index: int) @@ -30,11 +31,10 @@ func _ready() -> void: self.item_dropped.connect(_on_item_dropped) self.add_to_inventory.connect(_on_add_to_inventory) - self.remove_from_inventory.connect(_on_remove_from_inventory) self.clear_inventory.connect(_on_clear_inventory) self.quick_slot_selected.connect(_on_quick_slot_selected) - - + self.remove_from_inventory.connect(_on_remove_from_inventory) + self.remove_from_slot.connect(_on_remove_from_slot) func available_space(item_id: String) -> int: var full_stacks: int = floor(_inventory_cache[item_id].total / DBItems.data[item_id].max_stack_size) @@ -166,3 +166,16 @@ func _on_item_picked_up(item: DBItemResource) -> void: func _on_quick_slot_selected(slot_index: int) -> void: selected_quick_slot = slot_index + +## Removes an amount of items from a specific slot +## If the amount exceeds the amount of the slot, will NOT remove from other stacks +func _on_remove_from_slot(slot_index: int, amount: int) -> void: + if slot_index >= max_inventory_items: + printerr("Slot Index ", slot_index, " out of inventory range") + return + + inventory[slot_index].amount -= amount + if inventory[slot_index].amount <= 0: + inventory[slot_index] = null + + inventory_slot_updated.emit(slot_index) diff --git a/scenes/player/player.gd b/scenes/player/player.gd index 223eed5..d5a13a4 100644 --- a/scenes/player/player.gd +++ b/scenes/player/player.gd @@ -62,6 +62,7 @@ func _ready() -> void: InventoryManager.add_to_inventory.connect(_on_add_to_inventory) InventoryManager.remove_from_inventory.connect(_on_remove_from_inventory) InventoryManager.item_picked_up.connect(_on_item_picked_up) + InventoryManager.inventory_slot_updated.connect(_on_inventory_slot_updated) SignalManager.resume_game.connect(_on_resume_game) SignalManager.open_pause_menu.connect(_on_open_pause_menu) SignalManager.hide_ui.connect(_on_hide_ui) @@ -165,6 +166,9 @@ func _on_resume_game() -> void: func _on_add_to_inventory(_item_id: String, _amount: int) -> void: _update_held_block_mesh() +func _on_inventory_slot_updated(_slot_index: int) -> void: + _update_held_block_mesh() + func _on_item_picked_up(_item: DBItemResource) -> void: _update_held_block_mesh() diff --git a/scenes/player/ray_cast_look.gd b/scenes/player/ray_cast_look.gd index c035de3..f2a433c 100644 --- a/scenes/player/ray_cast_look.gd +++ b/scenes/player/ray_cast_look.gd @@ -18,6 +18,7 @@ func _process(_delta: float) -> void: return EntityManager.create_block.emit(InventoryManager.get_quick_slot_item_id(), block_pos) + InventoryManager.remove_from_slot.emit(InventoryManager.selected_quick_slot, 1) if Waila.ref.get_target() == collider: return diff --git a/scenes/ui/quickslots/quick_slots.gd b/scenes/ui/quickslots/quick_slots.gd index be1e08a..03d586f 100644 --- a/scenes/ui/quickslots/quick_slots.gd +++ b/scenes/ui/quickslots/quick_slots.gd @@ -64,12 +64,12 @@ func generate_quick_slots() -> void: slots_container.add_child(slot) slot.init(slot_index) -func select_previous_item() -> void: - select_quick_slot(_selected_item - 1) - func select_next_item() -> void: select_quick_slot(_selected_item + 1) +func select_previous_item() -> void: + select_quick_slot(_selected_item - 1) + func select_quick_slot(slot_index: int) -> void: _selected_item = slot_index InventoryManager.quick_slot_selected.emit(slot_index) -- 2.30.1 From a3ccf9a23ae86e9f85555e34fcf82427c062eee4 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Mon, 7 Apr 2025 11:00:04 -0400 Subject: [PATCH 19/23] cleanup: Minor formatting --- autoloads/inventory_manager.gd | 28 +++++++++++++++---------- scenes/ui/quickslots/quickslots_slot.gd | 3 ++- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index e2ca1f8..4adffd6 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -1,26 +1,32 @@ extends Node -signal next_quick_slot -signal previous_quick_slot -signal select_quick_slot(slot_index: int) -signal quick_slot_selected(slot_index: int) -signal item_picked_up(item: DBItemResource) + signal item_dropped(item: DBItemResource) -signal inventory_opened -signal inventory_closed +signal item_picked_up(item: DBItemResource) -signal clear_inventory ## Remove all items in inventory +#region Inventory Specific signal add_to_inventory(item_id: String, amount: int) -signal remove_from_inventory(item_id: String, amount: int) -signal remove_from_slot(slot_index: int, amount: int) +signal clear_inventory ## Remove all items in inventory signal item_added(item_id: String, amount: int) signal item_removed(item_id: String, amount: int) +signal inventory_closed +signal inventory_opened signal inventory_slot_updated(slot_index: int) +signal remove_from_inventory(item_id: String, amount: int) +signal remove_from_slot(slot_index: int, amount: int) +#endregion + +#region Quickslots +signal next_quick_slot +signal previous_quick_slot +signal quick_slot_selected(slot_index: int) +signal select_quick_slot(slot_index: int) +#endregion +var max_inventory_items: int = 40 # 4 rows of 10 var quick_slot_count: int = 10 var selected_quick_slot: int = 0 -var max_inventory_items: int = 40 # 4 rows of 10 var inventory: Array[DBItemResource] = [] ## To ensure inventory is automatically sorted, "empty" inventory cells will be replaced with null to keep positions var _inventory_cache: Dictionary[String, Dictionary] = {} ## Used for caching certain information diff --git a/scenes/ui/quickslots/quickslots_slot.gd b/scenes/ui/quickslots/quickslots_slot.gd index 135fa19..c7923ec 100644 --- a/scenes/ui/quickslots/quickslots_slot.gd +++ b/scenes/ui/quickslots/quickslots_slot.gd @@ -7,8 +7,9 @@ extends Panel var slot_index: int = 0 + func _ready() -> void: - InventoryManager.inventory_slot_updated.connect(_on_inventory_slot_updated) + InventoryManager.inventory_slot_updated.connect(_on_inventory_slot_updated) func init(_slot_index: int) -> void: -- 2.30.1 From 1a857f3d0abbfb6c62acb7c1cb2f00bb0703336b Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Mon, 7 Apr 2025 11:29:59 -0400 Subject: [PATCH 20/23] wip: Add signal InventoryManager.remove_from_quickslot to simplify removing from quickslot --- autoloads/inventory_manager.gd | 24 ++++++++++++++++-------- scenes/player/player.gd | 2 +- scenes/player/ray_cast_look.gd | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index 4adffd6..08fb202 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -13,6 +13,7 @@ signal inventory_closed signal inventory_opened signal inventory_slot_updated(slot_index: int) signal remove_from_inventory(item_id: String, amount: int) +signal remove_from_quickslot(amount: int) signal remove_from_slot(slot_index: int, amount: int) #endregion @@ -40,6 +41,7 @@ func _ready() -> void: self.clear_inventory.connect(_on_clear_inventory) self.quick_slot_selected.connect(_on_quick_slot_selected) self.remove_from_inventory.connect(_on_remove_from_inventory) + self.remove_from_quickslot.connect(_on_remove_from_quickslot) self.remove_from_slot.connect(_on_remove_from_slot) func available_space(item_id: String) -> int: @@ -77,6 +79,17 @@ func _find_stacks_with_space(item_resource: DBItemResource, item_id: String) -> ) ) +func _remove_from_slot(slot_index: int, amount: int) -> void: + if slot_index >= max_inventory_items: + printerr("Slot Index ", slot_index, " out of inventory range") + return + + inventory[slot_index].amount -= amount + if inventory[slot_index].amount <= 0: + inventory[slot_index] = null + + inventory_slot_updated.emit(slot_index) + func _update_cache_total(item_id: String, amount: int) -> void: if not _inventory_cache.get(item_id): _inventory_cache[item_id] = {"total": 0} @@ -176,12 +189,7 @@ func _on_quick_slot_selected(slot_index: int) -> void: ## Removes an amount of items from a specific slot ## If the amount exceeds the amount of the slot, will NOT remove from other stacks func _on_remove_from_slot(slot_index: int, amount: int) -> void: - if slot_index >= max_inventory_items: - printerr("Slot Index ", slot_index, " out of inventory range") - return + _remove_from_slot(slot_index, amount) - inventory[slot_index].amount -= amount - if inventory[slot_index].amount <= 0: - inventory[slot_index] = null - - inventory_slot_updated.emit(slot_index) +func _on_remove_from_quickslot(amount: int) -> void: + _remove_from_slot(selected_quick_slot, amount) diff --git a/scenes/player/player.gd b/scenes/player/player.gd index d5a13a4..9495e8d 100644 --- a/scenes/player/player.gd +++ b/scenes/player/player.gd @@ -39,7 +39,7 @@ func _input(event: InputEvent) -> void: elif event.is_action_pressed("throw_item"): # TODO: Move to state? if InventoryManager.get_inventory_item() != null: EntityManager.drop_block.emit(InventoryManager.get_quick_slot_item_id(), head.global_position, -head.global_basis.z, throw_velocity) - InventoryManager.remove_from_inventory.emit(InventoryManager.get_quick_slot_item_id(), 1) + InventoryManager.remove_from_quickslot.emit(1) func _physics_process(delta: float) -> void: is_crouching = Input.is_action_pressed("crouch") or ray_cast_crouch.is_colliding() diff --git a/scenes/player/ray_cast_look.gd b/scenes/player/ray_cast_look.gd index f2a433c..73cbf0f 100644 --- a/scenes/player/ray_cast_look.gd +++ b/scenes/player/ray_cast_look.gd @@ -18,7 +18,7 @@ func _process(_delta: float) -> void: return EntityManager.create_block.emit(InventoryManager.get_quick_slot_item_id(), block_pos) - InventoryManager.remove_from_slot.emit(InventoryManager.selected_quick_slot, 1) + InventoryManager.remove_from_quickslot.emit(1) if Waila.ref.get_target() == collider: return -- 2.30.1 From 2a7291e9dab942472498db246444d24be9e23827 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Mon, 7 Apr 2025 11:35:01 -0400 Subject: [PATCH 21/23] docs: Comment update --- autoloads/inventory_manager.gd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index 08fb202..64f63b9 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -79,6 +79,8 @@ func _find_stacks_with_space(item_resource: DBItemResource, item_id: String) -> ) ) +## Removes an amount of items from a specific slot +## If the amount exceeds the amount of the slot, will NOT remove from other stacks func _remove_from_slot(slot_index: int, amount: int) -> void: if slot_index >= max_inventory_items: printerr("Slot Index ", slot_index, " out of inventory range") @@ -186,8 +188,6 @@ func _on_item_picked_up(item: DBItemResource) -> void: func _on_quick_slot_selected(slot_index: int) -> void: selected_quick_slot = slot_index -## Removes an amount of items from a specific slot -## If the amount exceeds the amount of the slot, will NOT remove from other stacks func _on_remove_from_slot(slot_index: int, amount: int) -> void: _remove_from_slot(slot_index, amount) -- 2.30.1 From bfc3071a7075371e2da5396d0c83c056c9789d68 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Mon, 7 Apr 2025 11:55:47 -0400 Subject: [PATCH 22/23] fix: Correct changing quickslot on rollover --- scenes/ui/quickslots/quick_slots.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scenes/ui/quickslots/quick_slots.gd b/scenes/ui/quickslots/quick_slots.gd index 03d586f..ea7c438 100644 --- a/scenes/ui/quickslots/quick_slots.gd +++ b/scenes/ui/quickslots/quick_slots.gd @@ -72,7 +72,7 @@ func select_previous_item() -> void: func select_quick_slot(slot_index: int) -> void: _selected_item = slot_index - InventoryManager.quick_slot_selected.emit(slot_index) + InventoryManager.quick_slot_selected.emit(_selected_item) update_highlighted_slot() func update_highlighted_slot() -> void: -- 2.30.1 From 60a71f07e2e4564ac9a56bab13c7497eac142501 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Mon, 7 Apr 2025 12:12:51 -0400 Subject: [PATCH 23/23] wip: Add notes about the inital quickslot highlight and create remove_slots() --- autoloads/inventory_manager.gd | 2 ++ scenes/ui/quickslots/quick_slots.gd | 14 +++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index 64f63b9..9710a9e 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -44,6 +44,7 @@ func _ready() -> void: self.remove_from_quickslot.connect(_on_remove_from_quickslot) self.remove_from_slot.connect(_on_remove_from_slot) + func available_space(item_id: String) -> int: var full_stacks: int = floor(_inventory_cache[item_id].total / DBItems.data[item_id].max_stack_size) var space_in_stacks: int = ( @@ -67,6 +68,7 @@ func get_inventory_item(item_slot: int = selected_quick_slot) -> DBItemResource: func get_quick_slot_item_id(item_slot: int = selected_quick_slot) -> String: return inventory[item_slot].id + func _find_stacks_by_id(item_resource: DBItemResource, item_id: String) -> bool: return item_resource != null and item_resource.id == item_id diff --git a/scenes/ui/quickslots/quick_slots.gd b/scenes/ui/quickslots/quick_slots.gd index ea7c438..acb48ad 100644 --- a/scenes/ui/quickslots/quick_slots.gd +++ b/scenes/ui/quickslots/quick_slots.gd @@ -23,9 +23,13 @@ func _init() -> void: InventoryManager.select_quick_slot.connect(select_quick_slot) func _ready() -> void: - clear_slots() + remove_slots() generate_quick_slots() - update_highlighted_slot() + + # This doesn't quite work on ready as, for some reason, it will select + # Slot0 (one of the slots BEFORE remove_slots()) instead of the first slot + # create in generate_quick_slots() + select_quick_slot(0) func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("quickslot1"): @@ -56,7 +60,7 @@ func _unhandled_input(event: InputEvent) -> void: func clear_slots() -> void: for slot: QuickSlotsSlot in slots_container.get_children(): - slot.queue_free() + slot.clear() func generate_quick_slots() -> void: for slot_index: int in range(InventoryManager.quick_slot_count): @@ -64,6 +68,10 @@ func generate_quick_slots() -> void: slots_container.add_child(slot) slot.init(slot_index) +func remove_slots() -> void: + for slot: QuickSlotsSlot in slots_container.get_children(): + slot.queue_free() + func select_next_item() -> void: select_quick_slot(_selected_item + 1) -- 2.30.1