diff --git a/autoloads/inventory_manager.gd b/autoloads/inventory_manager.gd index 5384c5b..9548fab 100644 --- a/autoloads/inventory_manager.gd +++ b/autoloads/inventory_manager.gd @@ -4,7 +4,10 @@ signal next_quick_slot signal previous_quick_slot signal select_quick_slot(slot_index: int) signal quick_slot_item_changed(item_id: String) -signal item_picked_up(item_id: String, amount: int) +signal item_picked_up(item: ItemResource) +signal item_dropped(item: ItemResource) +signal inventory_opened +signal inventory_closed var quick_slot_item_id: String = "001" diff --git a/project.godot b/project.godot index ed4e80c..76d988c 100644 --- a/project.godot +++ b/project.godot @@ -134,6 +134,11 @@ quickslot_previous={ "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":16,"position":Vector2(173, 17),"global_position":Vector2(182, 63),"factor":1.0,"button_index":5,"canceled":false,"pressed":true,"double_click":false,"script":null) ] } +open_inventory={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":73,"key_label":0,"unicode":105,"location":0,"echo":false,"script":null) +] +} [layer_names] diff --git a/resources/blocks/001_dirt.tres b/resources/blocks/001_dirt.tres index 405f023..efd0ad1 100644 --- a/resources/blocks/001_dirt.tres +++ b/resources/blocks/001_dirt.tres @@ -8,5 +8,7 @@ script = ExtResource("1_ljghb") material_east = ExtResource("1_n1cq6") id = "001" name = "Dirt" +amount = 0 description = "Block of dirt" +item_texture = "uid://li36txj7oweq" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" diff --git a/resources/blocks/002_stone.tres b/resources/blocks/002_stone.tres index 3aa0d3f..8e5d3d1 100644 --- a/resources/blocks/002_stone.tres +++ b/resources/blocks/002_stone.tres @@ -8,5 +8,7 @@ script = ExtResource("1_63t5s") material_east = ExtResource("1_6chm7") id = "002" name = "Stone" +amount = 0 description = "Block of stone" +item_texture = "uid://ct1iawpfkdf5l" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" diff --git a/resources/blocks/003_wood.tres b/resources/blocks/003_wood.tres index 3e1c06e..ae533ae 100644 --- a/resources/blocks/003_wood.tres +++ b/resources/blocks/003_wood.tres @@ -14,5 +14,7 @@ material_top = ExtResource("1_1n8h6") material_bottom = ExtResource("1_1n8h6") id = "003" name = "Wood" +amount = 0 description = "Wood log" +item_texture = "uid://0mw651622h01" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" diff --git a/resources/blocks/004_leaves.tres b/resources/blocks/004_leaves.tres index 5e69168..7a32786 100644 --- a/resources/blocks/004_leaves.tres +++ b/resources/blocks/004_leaves.tres @@ -8,5 +8,7 @@ script = ExtResource("3_kuops") material_east = ExtResource("1_dbmit") id = "004" name = "Leaves" +amount = 0 description = "Tree leaves" +item_texture = "uid://goygbpyqhych" metadata/_custom_type_script = "uid://dwrmy4mx0mw18" diff --git a/resources/inventory/player_inventory_empty.tres b/resources/inventory/player_inventory_empty.tres new file mode 100644 index 0000000..36e5ed7 --- /dev/null +++ b/resources/inventory/player_inventory_empty.tres @@ -0,0 +1,10 @@ +[gd_resource type="Resource" script_class="InventoryResource" load_steps=3 format=3 uid="uid://cnpw7y1csu774"] + +[ext_resource type="Script" uid="uid://becun6dj78v8d" path="res://resources/inventory_resource.gd" id="1_o2th4"] +[ext_resource type="Script" uid="uid://bdx4q355l5ugl" path="res://resources/item_resource.gd" id="1_udg6i"] + +[resource] +script = ExtResource("1_o2th4") +inventory = Array[ExtResource("1_udg6i")]([]) +max_stack_size = 999 +metadata/_custom_type_script = "uid://becun6dj78v8d" diff --git a/resources/inventory/player_inventory_testing.tres b/resources/inventory/player_inventory_testing.tres new file mode 100644 index 0000000..87921a6 --- /dev/null +++ b/resources/inventory/player_inventory_testing.tres @@ -0,0 +1,61 @@ +[gd_resource type="Resource" script_class="InventoryResource" load_steps=13 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/item_resource.gd" id="1_gg8jx"] +[ext_resource type="Material" uid="uid://uex0dq00xomt" path="res://assets/materials/dirt.tres" id="2_8w148"] +[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://bnqiumcb3ixan" path="res://assets/materials/wood_ends.tres" id="5_viap3"] +[ext_resource type="Material" uid="uid://h0naiw6swfkl" path="res://assets/materials/wood_side.tres" id="6_wqat2"] +[ext_resource type="Material" uid="uid://d15n1p3spu3jg" path="res://assets/materials/leaves.tres" id="7_xd1nd"] + +[sub_resource type="Resource" id="Resource_jaam2"] +script = ExtResource("3_vgvac") +material_east = ExtResource("2_8w148") +id = "001" +name = "Dirt" +amount = 100 +description = "Block of dirt" +item_texture = "uid://li36txj7oweq" +metadata/_custom_type_script = "uid://dwrmy4mx0mw18" + +[sub_resource type="Resource" id="Resource_4kby3"] +script = ExtResource("3_vgvac") +material_east = ExtResource("4_7yuhn") +id = "002" +name = "Stone" +amount = 100 +description = "Block of stone" +item_texture = "uid://ct1iawpfkdf5l" +metadata/_custom_type_script = "uid://dwrmy4mx0mw18" + +[sub_resource type="Resource" id="Resource_byct5"] +script = ExtResource("3_vgvac") +material_east = ExtResource("6_wqat2") +material_west = ExtResource("6_wqat2") +material_north = ExtResource("6_wqat2") +material_south = ExtResource("6_wqat2") +material_top = ExtResource("5_viap3") +material_bottom = ExtResource("5_viap3") +id = "003" +name = "Wood" +amount = 100 +description = "Wood log" +item_texture = "uid://0mw651622h01" +metadata/_custom_type_script = "uid://dwrmy4mx0mw18" + +[sub_resource type="Resource" id="Resource_qycqj"] +script = ExtResource("3_vgvac") +material_east = ExtResource("7_xd1nd") +id = "004" +name = "Leaves" +amount = 100 +description = "Tree leaves" +item_texture = "uid://goygbpyqhych" +metadata/_custom_type_script = "uid://dwrmy4mx0mw18" + +[resource] +script = ExtResource("1_4v6mg") +inventory = Array[ExtResource("1_gg8jx")]([SubResource("Resource_jaam2"), SubResource("Resource_4kby3"), SubResource("Resource_byct5"), SubResource("Resource_qycqj")]) +max_stack_size = 999 +metadata/_custom_type_script = "uid://becun6dj78v8d" diff --git a/resources/inventory_resource.gd b/resources/inventory_resource.gd new file mode 100644 index 0000000..4f7a6de --- /dev/null +++ b/resources/inventory_resource.gd @@ -0,0 +1,6 @@ +class_name InventoryResource +extends Resource + + +@export var inventory: Array[ItemResource] = [] +@export var max_stack_size: int = 999 diff --git a/resources/inventory_resource.gd.uid b/resources/inventory_resource.gd.uid new file mode 100644 index 0000000..e347559 --- /dev/null +++ b/resources/inventory_resource.gd.uid @@ -0,0 +1 @@ +uid://becun6dj78v8d diff --git a/resources/item_resource.gd b/resources/item_resource.gd index 2cabbc3..a481462 100644 --- a/resources/item_resource.gd +++ b/resources/item_resource.gd @@ -4,4 +4,6 @@ extends Resource @export var id: String = "000" @export var name: String = "Item Name" +@export var amount: int = 0 @export var description: String = "Item Description" +@export_file var item_texture: String = "res://icon.svg" diff --git a/scenes/blocks/dropped_block.gd b/scenes/blocks/dropped_block.gd index b222b91..a82a456 100644 --- a/scenes/blocks/dropped_block.gd +++ b/scenes/blocks/dropped_block.gd @@ -22,7 +22,9 @@ func initialize(id: String, _position: Vector3) -> void: func _on_pickup_area_body_entered(body: Node3D) -> void: if not body is Player: return - # TODO: Update stack_count when we start storing that information + # TODO: Update stack count dynamically var stack_count: int = 1 - InventoryManager.item_picked_up.emit(block.get_id(), stack_count) + var item: ItemResource = (DBItems.data[block.get_id()] as Resource).duplicate() + item.amount = stack_count + InventoryManager.item_picked_up.emit(item) queue_free() diff --git a/scenes/ui/inventory/inventory.gd b/scenes/ui/inventory/inventory.gd new file mode 100644 index 0000000..017079f --- /dev/null +++ b/scenes/ui/inventory/inventory.gd @@ -0,0 +1,69 @@ +class_name Inventory +extends Control + + +@export var inventory_resource: InventoryResource +@export var item_rect_scene: PackedScene +@export var grid_container: GridContainer + + +func _input(event: InputEvent) -> void: + if event.is_action_pressed("open_inventory"): + toggle_inventory() + +func _ready() -> void: + InventoryManager.item_picked_up.connect(add_item.bind()) + InventoryManager.item_dropped.connect(subtract_item.bind()) + for item_resource: ItemResource in inventory_resource.inventory: + add_item(item_resource) + + +func add_item(item_resource: ItemResource, 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.item_resource = item_resource + item_rect.update_rect() + +func find_item_rect(item_resource: ItemResource) -> InventoryItemRect: + var rect: InventoryItemRect = null + + for container: InventoryItemRect in grid_container.get_children(): + if container.item_resource.id == item_resource.id: + rect = container + break + + return rect + +func subtract_item(item_resource: ItemResource) -> 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.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 toggle_inventory() -> void: + visible = not visible + + if visible: + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + InventoryManager.inventory_opened.emit() + get_tree().paused = true + else: + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + InventoryManager.inventory_closed.emit() + get_tree().paused = false diff --git a/scenes/ui/inventory/inventory.gd.uid b/scenes/ui/inventory/inventory.gd.uid new file mode 100644 index 0000000..967e94c --- /dev/null +++ b/scenes/ui/inventory/inventory.gd.uid @@ -0,0 +1 @@ +uid://dybecq130mxhn diff --git a/scenes/ui/inventory/inventory.tscn b/scenes/ui/inventory/inventory.tscn new file mode 100644 index 0000000..3870443 --- /dev/null +++ b/scenes/ui/inventory/inventory.tscn @@ -0,0 +1,60 @@ +[gd_scene load_steps=4 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="PackedScene" uid="uid://boueuk2hnfvg" path="res://scenes/ui/inventory/item_rect.tscn" id="3_xeaml"] + +[node name="Inventory" type="Control" node_paths=PackedStringArray("grid_container")] +process_mode = 3 +custom_minimum_size = Vector2(860, 400) +layout_mode = 3 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -410.0 +offset_top = -200.0 +offset_right = 410.0 +offset_bottom = 200.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_s6ek7") +inventory_resource = ExtResource("2_avmd0") +item_rect_scene = ExtResource("3_xeaml") +grid_container = NodePath("Background/MarginContainer/VBoxContainer/GridContainer") + +[node name="Background" type="Panel" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="MarginContainer" type="MarginContainer" parent="Background"] +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 = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 + +[node name="VBoxContainer" type="VBoxContainer" parent="Background/MarginContainer"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Background/MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_type_variation = &"HeaderLarge" +text = "Inventory" + +[node name="GridContainer" type="GridContainer" parent="Background/MarginContainer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +theme_override_constants/h_separation = 20 +theme_override_constants/v_separation = 20 +columns = 10 diff --git a/scenes/ui/inventory/item_rect.gd b/scenes/ui/inventory/item_rect.gd new file mode 100644 index 0000000..f6d1199 --- /dev/null +++ b/scenes/ui/inventory/item_rect.gd @@ -0,0 +1,19 @@ +class_name InventoryItemRect +extends Panel + + +@export var amount_label: Label +@export var item_resource: ItemResource +@export var item_texture: TextureRect + + +func update_rect() -> void: + item_texture.texture = load(item_resource.item_texture) + amount_label.text = "x" + str(item_resource.amount) + 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)) diff --git a/scenes/ui/inventory/item_rect.gd.uid b/scenes/ui/inventory/item_rect.gd.uid new file mode 100644 index 0000000..285c4ac --- /dev/null +++ b/scenes/ui/inventory/item_rect.gd.uid @@ -0,0 +1 @@ +uid://cknl6i0jce5jr diff --git a/scenes/ui/inventory/item_rect.tscn b/scenes/ui/inventory/item_rect.tscn new file mode 100644 index 0000000..fe9fb36 --- /dev/null +++ b/scenes/ui/inventory/item_rect.tscn @@ -0,0 +1,41 @@ +[gd_scene load_steps=4 format=3 uid="uid://boueuk2hnfvg"] + +[ext_resource type="Texture2D" uid="uid://dknv7amroftm8" path="res://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"] +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) +offset_right = 64.0 +offset_bottom = 64.0 +script = ExtResource("1_oderi") +amount_label = NodePath("AmountLabel") +item_texture = NodePath("ItemTexture") +metadata/_edit_use_anchors_ = true + +[node name="ItemTexture" type="TextureRect" parent="."] +texture_filter = 1 +layout_mode = 0 +offset_right = 64.0 +offset_bottom = 64.0 +texture = ExtResource("1_o0kom") +expand_mode = 1 +stretch_mode = 4 + +[node name="AmountLabel" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -40.0 +offset_top = -23.0 +offset_right = -3.0 +grow_horizontal = 0 +grow_vertical = 0 +text = "x100" +label_settings = SubResource("LabelSettings_oderi") diff --git a/scenes/ui/options_menu.tscn b/scenes/ui/options_menu.tscn index 555cb01..9a8fd08 100644 --- a/scenes/ui/options_menu.tscn +++ b/scenes/ui/options_menu.tscn @@ -27,7 +27,7 @@ size_flags_horizontal = 3 [node name="Label" type="Label" parent="PanelContainer/MarginContainer/LeftContainer/VBoxContainer"] layout_mode = 2 size_flags_vertical = 0 -theme_type_variation = &"HeaderMedium" +theme_type_variation = &"HeaderLarge" text = "Options Menu" horizontal_alignment = 1 diff --git a/scenes/ui/ui.gd b/scenes/ui/ui.gd index 165669b..5c99e97 100644 --- a/scenes/ui/ui.gd +++ b/scenes/ui/ui.gd @@ -3,6 +3,7 @@ extends CanvasLayer @onready var crosshair: CenterContainer = $Crosshair +@onready var inventory: Inventory = $Inventory @onready var options_menu: MarginContainer = $OptionsMenu @onready var quick_slots: MarginContainer = $QuickSlots @onready var waila: Waila = $Waila diff --git a/scenes/ui/ui.tscn b/scenes/ui/ui.tscn index df6740d..a1c506d 100644 --- a/scenes/ui/ui.tscn +++ b/scenes/ui/ui.tscn @@ -1,9 +1,11 @@ -[gd_scene load_steps=5 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://w6wtjosjn1qu" path="res://scenes/ui/options_menu.tscn" id="2_f5cxw"] [ext_resource type="PackedScene" uid="uid://cbiygbgpfk220" path="res://scenes/ui/quick_slots.tscn" id="4_g5kmx"] +[ext_resource type="PackedScene" uid="uid://dcr25y1lw4wjp" path="res://scenes/ui/inventory/inventory.tscn" id="5_0dwhk"] +[ext_resource type="Resource" uid="uid://blfp6tiir282o" path="res://resources/inventory/player_inventory_testing.tres" id="6_pfayw"] [node name="UI" type="CanvasLayer"] script = ExtResource("1_aac20") @@ -32,6 +34,10 @@ visible = false [node name="QuickSlots" parent="." instance=ExtResource("4_g5kmx")] +[node name="Inventory" parent="." instance=ExtResource("5_0dwhk")] +visible = false +inventory_resource = ExtResource("6_pfayw") + [connection signal="toggled" from="OptionsMenu/PanelContainer/MarginContainer/LeftContainer/VBoxContainer/BlockHighlights/CheckButton" to="." method="_on_block_highlights_toggled"] [connection signal="toggled" from="OptionsMenu/PanelContainer/MarginContainer/LeftContainer/VBoxContainer/Waila/CheckButton" to="." method="_on_waila_toggled"] [connection signal="pressed" from="OptionsMenu/PanelContainer/MarginContainer/CenterContainer/HBoxContainer/CloseButton" to="." method="_on_close_button_pressed"]