From 1062193785eb96616c59106c7b1f2924c7dc5ed2 Mon Sep 17 00:00:00 2001 From: cblech Date: Mon, 14 Apr 2025 16:49:29 +0200 Subject: [PATCH 1/5] item on ground and pickup --- prefabs/UI/Inventory/Inventory.tscn | 2 +- .../interactions/generic_item_on_ground.tscn | 22 ++++++++ project.godot | 2 +- .../Babushka_scene_item_pickup_testing.tscn | 53 +++++++++++++++++++ .../Common/Inventory/InventoryManager.cs | 4 ++ .../CSharp/Common/Inventory/InventoryUi.cs | 3 +- .../CSharp/Common/Inventory/ItemOnGround.cs | 46 ++++++++++++++++ .../Common/Inventory/ItemOnGround.cs.uid | 1 + .../Common/Inventory/ItemOnGroundSpawnWith.cs | 16 ++++++ .../Inventory/ItemOnGroundSpawnWith.cs.uid | 1 + 10 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 prefabs/interactions/generic_item_on_ground.tscn create mode 100644 scenes/testing/Babushka_scene_item_pickup_testing.tscn create mode 100644 scripts/CSharp/Common/Inventory/ItemOnGround.cs create mode 100644 scripts/CSharp/Common/Inventory/ItemOnGround.cs.uid create mode 100644 scripts/CSharp/Common/Inventory/ItemOnGroundSpawnWith.cs create mode 100644 scripts/CSharp/Common/Inventory/ItemOnGroundSpawnWith.cs.uid diff --git a/prefabs/UI/Inventory/Inventory.tscn b/prefabs/UI/Inventory/Inventory.tscn index 5435acc..5d59d26 100644 --- a/prefabs/UI/Inventory/Inventory.tscn +++ b/prefabs/UI/Inventory/Inventory.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=5 format=3 uid="uid://cgjc4wurbgimy"] -[ext_resource type="Script" uid="uid://hg7jay2kt441" path="res://scripts/CSharp/Common/Inventory/InventoryUi.cs" id="1_6wusm"] +[ext_resource type="Script" uid="uid://b7vlkecrn0t5c" path="res://scripts/CSharp/Common/Inventory/InventoryUi.cs" id="1_6wusm"] [ext_resource type="Script" uid="uid://b2jhdxcrhtm2d" path="res://scripts/CSharp/Common/Inventory/InventoryTestScript.cs" id="3_exrk4"] [ext_resource type="Resource" uid="uid://datee0flk1e84" path="res://resources/items/pickaxe.tres" id="4_5fdxq"] [ext_resource type="Texture2D" uid="uid://c7wqla0mbu3np" path="res://graphics/ui/babushka_ui_tmp_inventory_select.png" id="4_tiss4"] diff --git a/prefabs/interactions/generic_item_on_ground.tscn b/prefabs/interactions/generic_item_on_ground.tscn new file mode 100644 index 0000000..576e96d --- /dev/null +++ b/prefabs/interactions/generic_item_on_ground.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=5 format=3 uid="uid://5hltxpdxmqcq"] + +[ext_resource type="Script" uid="uid://udhigottc8rg" path="res://scripts/CSharp/Common/Inventory/ItemOnGround.cs" id="1_mnomu"] +[ext_resource type="PackedScene" uid="uid://ob04y3syvo0e" path="res://prefabs/interaction_area.tscn" id="2_ue6ub"] +[ext_resource type="Script" uid="uid://c8suoi3i6kqai" path="res://scripts/CSharp/Common/Inventory/ItemOnGroundSpawnWith.cs" id="3_ue6ub"] +[ext_resource type="Resource" uid="uid://c7viddcd3kywp" path="res://resources/items/axe.tres" id="4_sfad0"] + +[node name="GenericItemOnGround" type="Node3D"] +script = ExtResource("1_mnomu") + +[node name="InteractionArea" parent="." instance=ExtResource("2_ue6ub")] + +[node name="SpawnWithItem" type="Node" parent="."] +script = ExtResource("3_ue6ub") +_blueprint = ExtResource("4_sfad0") + +[node name="ItemLabel" type="Label3D" parent="."] +offset = Vector2(0, 55.64) +billboard = 1 +text = "test" + +[connection signal="Interacted" from="InteractionArea" to="." method="TryPickUp"] diff --git a/project.godot b/project.godot index d61222a..0cc2d20 100644 --- a/project.godot +++ b/project.godot @@ -11,7 +11,7 @@ config_version=5 [application] config/name="Babushka" -run/main_scene="uid://br7yq757cawts" +run/main_scene="uid://dbxy2y85r1d8x" config/features=PackedStringArray("4.4", "C#", "Forward Plus") config/icon="res://icon.svg" diff --git a/scenes/testing/Babushka_scene_item_pickup_testing.tscn b/scenes/testing/Babushka_scene_item_pickup_testing.tscn new file mode 100644 index 0000000..6ca85ff --- /dev/null +++ b/scenes/testing/Babushka_scene_item_pickup_testing.tscn @@ -0,0 +1,53 @@ +[gd_scene load_steps=10 format=3 uid="uid://dbxy2y85r1d8x"] + +[ext_resource type="PackedScene" uid="uid://dbd1niu3tp8y5" path="res://prefabs/Player3D.tscn" id="1_pdc5e"] +[ext_resource type="PackedScene" uid="uid://biwd3jj65qrlh" path="res://prefabs/farming/base_field.tscn" id="2_741gk"] +[ext_resource type="PackedScene" uid="uid://5hltxpdxmqcq" path="res://prefabs/interactions/generic_item_on_ground.tscn" id="5_sjt6k"] +[ext_resource type="PackedScene" uid="uid://cgjc4wurbgimy" path="res://prefabs/UI/Inventory/Inventory.tscn" id="6_876p1"] +[ext_resource type="Resource" uid="uid://cndd64batns31" path="res://resources/items/bucket.tres" id="6_nvnpb"] +[ext_resource type="Script" uid="uid://d178x7agr603o" path="res://scripts/CSharp/Common/Farming/FieldService.cs" id="7_3rkjv"] + +[sub_resource type="PlaneMesh" id="PlaneMesh_8yprl"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_8tgff"] +albedo_color = Color(0.505882, 0.588235, 0.494118, 1) + +[sub_resource type="BoxShape3D" id="BoxShape3D_t58di"] +size = Vector3(2.01563, 0.160522, 2.00824) + +[node name="SceneFarmVesna" type="Node3D"] + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +transform = Transform3D(10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0) +mesh = SubResource("PlaneMesh_8yprl") +skeleton = NodePath("") +surface_material_override/0 = SubResource("StandardMaterial3D_8tgff") + +[node name="StaticBody3D" type="StaticBody3D" parent="MeshInstance3D"] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="MeshInstance3D/StaticBody3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.000976563, -0.0739136, -0.00112915) +shape = SubResource("BoxShape3D_t58di") + +[node name="Player3d" parent="." node_paths=PackedStringArray("_fieldParent") instance=ExtResource("1_pdc5e")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.51633, 0.725631, 3.57249) +_fieldParent = NodePath("../FieldService") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.618408, 0.785857, 0, -0.785857, 0.618408, -0.802612, 0, 4.73262) + +[node name="BaseField" parent="." instance=ExtResource("2_741gk")] +transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0.0574723, 0) +visible = false + +[node name="Inventory" parent="." instance=ExtResource("6_876p1")] + +[node name="FieldService" type="Node3D" parent="."] +script = ExtResource("7_3rkjv") + +[node name="GenericItemOnGround" parent="." instance=ExtResource("5_sjt6k")] + +[node name="SpawnWithItem" parent="GenericItemOnGround" index="1"] +_blueprint = ExtResource("6_nvnpb") + +[editable path="GenericItemOnGround"] diff --git a/scripts/CSharp/Common/Inventory/InventoryManager.cs b/scripts/CSharp/Common/Inventory/InventoryManager.cs index cd024aa..ed44999 100644 --- a/scripts/CSharp/Common/Inventory/InventoryManager.cs +++ b/scripts/CSharp/Common/Inventory/InventoryManager.cs @@ -60,4 +60,8 @@ public partial class InventoryManager : Node { return inventory.RemoveItem(inventorySlot); } + public InventoryActionResult CollectItem(ItemInstance itemInstance) + { + return playerInventory.AddItem(itemInstance); + } } diff --git a/scripts/CSharp/Common/Inventory/InventoryUi.cs b/scripts/CSharp/Common/Inventory/InventoryUi.cs index f9241be..3b8ed7d 100644 --- a/scripts/CSharp/Common/Inventory/InventoryUi.cs +++ b/scripts/CSharp/Common/Inventory/InventoryUi.cs @@ -25,6 +25,7 @@ public partial class InventoryUi : Control PopulateSlots(); SetSlotContent(); SetSlotSelectPosition(); + InventoryManager.Instance.playerInventory.InventoryContentsChanged += SetSlotContent; } public override void _ExitTree() @@ -88,7 +89,7 @@ public partial class InventoryUi : Control var destinationSlot = index; InventoryManager.Instance.MoveItem(_playerInventory, sourceSlot, _playerInventory, destinationSlot); _slotOnMouse = null; - SetSlotContent(); + //SetSlotContent(); } } diff --git a/scripts/CSharp/Common/Inventory/ItemOnGround.cs b/scripts/CSharp/Common/Inventory/ItemOnGround.cs new file mode 100644 index 0000000..714174c --- /dev/null +++ b/scripts/CSharp/Common/Inventory/ItemOnGround.cs @@ -0,0 +1,46 @@ +using Godot; +namespace Babushka.scripts.CSharp.Common.Inventory; + +public partial class ItemOnGround : Node3D +{ + private ItemInstance _itemInstance; + + public ItemInstance itemInstance + { + get => _itemInstance; + set + { + _itemInstance = value; + UpdateVisuals(); + } + } + + public void TryPickUp() + { + GD.Print("Trying to pick up item"); + + var result = InventoryManager.Instance.CollectItem(itemInstance); + if (result == InventoryActionResult.Success) + { + QueueFree(); + } + else + { + GD.Print("Inventory is full"); + // TODO: player message + } + } + + public void UpdateVisuals() + { + var label = GetNode("ItemLabel"); + if (itemInstance.blueprint != null) + { + label.Text = itemInstance.blueprint.name; + } + else + { + label.Text = "Error Item"; + } + } +} diff --git a/scripts/CSharp/Common/Inventory/ItemOnGround.cs.uid b/scripts/CSharp/Common/Inventory/ItemOnGround.cs.uid new file mode 100644 index 0000000..c2313d3 --- /dev/null +++ b/scripts/CSharp/Common/Inventory/ItemOnGround.cs.uid @@ -0,0 +1 @@ +uid://udhigottc8rg diff --git a/scripts/CSharp/Common/Inventory/ItemOnGroundSpawnWith.cs b/scripts/CSharp/Common/Inventory/ItemOnGroundSpawnWith.cs new file mode 100644 index 0000000..3f530ea --- /dev/null +++ b/scripts/CSharp/Common/Inventory/ItemOnGroundSpawnWith.cs @@ -0,0 +1,16 @@ +#nullable enable +using Godot; +namespace Babushka.scripts.CSharp.Common.Inventory; + +public partial class ItemOnGroundSpawnWith : Node +{ + [Export] private ItemResource? _blueprint = null; + + public override void _EnterTree() + { + if(_blueprint == null) return; + + var parent = GetParent(); + parent.itemInstance = new ItemInstance { blueprint = _blueprint }; + } +} diff --git a/scripts/CSharp/Common/Inventory/ItemOnGroundSpawnWith.cs.uid b/scripts/CSharp/Common/Inventory/ItemOnGroundSpawnWith.cs.uid new file mode 100644 index 0000000..bd0685f --- /dev/null +++ b/scripts/CSharp/Common/Inventory/ItemOnGroundSpawnWith.cs.uid @@ -0,0 +1 @@ +uid://c8suoi3i6kqai From e99b574d1f9a84ca7238214da76cfe64803c039e Mon Sep 17 00:00:00 2001 From: cblech Date: Mon, 14 Apr 2025 17:36:29 +0200 Subject: [PATCH 2/5] Added pickup error text --- .../interactions/generic_item_on_ground.tscn | 4 +++ .../Babushka_scene_item_pickup_testing.tscn | 26 ++++++++++++++++-- .../CSharp/Common/Inventory/ItemOnGround.cs | 27 ++++++++++--------- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/prefabs/interactions/generic_item_on_ground.tscn b/prefabs/interactions/generic_item_on_ground.tscn index 576e96d..42f3b14 100644 --- a/prefabs/interactions/generic_item_on_ground.tscn +++ b/prefabs/interactions/generic_item_on_ground.tscn @@ -19,4 +19,8 @@ offset = Vector2(0, 55.64) billboard = 1 text = "test" +[node name="PickupErrorLabel" type="Label3D" parent="."] +offset = Vector2(0, 150) +billboard = 1 + [connection signal="Interacted" from="InteractionArea" to="." method="TryPickUp"] diff --git a/scenes/testing/Babushka_scene_item_pickup_testing.tscn b/scenes/testing/Babushka_scene_item_pickup_testing.tscn index 6ca85ff..7b0fa00 100644 --- a/scenes/testing/Babushka_scene_item_pickup_testing.tscn +++ b/scenes/testing/Babushka_scene_item_pickup_testing.tscn @@ -1,11 +1,13 @@ -[gd_scene load_steps=10 format=3 uid="uid://dbxy2y85r1d8x"] +[gd_scene load_steps=12 format=3 uid="uid://dbxy2y85r1d8x"] [ext_resource type="PackedScene" uid="uid://dbd1niu3tp8y5" path="res://prefabs/Player3D.tscn" id="1_pdc5e"] [ext_resource type="PackedScene" uid="uid://biwd3jj65qrlh" path="res://prefabs/farming/base_field.tscn" id="2_741gk"] [ext_resource type="PackedScene" uid="uid://5hltxpdxmqcq" path="res://prefabs/interactions/generic_item_on_ground.tscn" id="5_sjt6k"] [ext_resource type="PackedScene" uid="uid://cgjc4wurbgimy" path="res://prefabs/UI/Inventory/Inventory.tscn" id="6_876p1"] [ext_resource type="Resource" uid="uid://cndd64batns31" path="res://resources/items/bucket.tres" id="6_nvnpb"] -[ext_resource type="Script" uid="uid://d178x7agr603o" path="res://scripts/CSharp/Common/Farming/FieldService.cs" id="7_3rkjv"] +[ext_resource type="Script" uid="uid://cywyym5l7ymhr" path="res://scripts/CSharp/Common/Farming/FieldService.cs" id="7_3rkjv"] +[ext_resource type="Resource" uid="uid://c5yg3lx756v4v" path="res://resources/items/hoe.tres" id="7_hv2km"] +[ext_resource type="Resource" uid="uid://datee0flk1e84" path="res://resources/items/pickaxe.tres" id="8_hae25"] [sub_resource type="PlaneMesh" id="PlaneMesh_8yprl"] @@ -46,8 +48,28 @@ visible = false script = ExtResource("7_3rkjv") [node name="GenericItemOnGround" parent="." instance=ExtResource("5_sjt6k")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.53971, -4.76837e-07, -3.81996) [node name="SpawnWithItem" parent="GenericItemOnGround" index="1"] _blueprint = ExtResource("6_nvnpb") +[node name="GenericItemOnGround2" parent="." instance=ExtResource("5_sjt6k")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.73646, -9.53674e-07, -3.96783) + +[node name="GenericItemOnGround3" parent="." instance=ExtResource("5_sjt6k")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.43861, -4.76837e-07, -3.93506) + +[node name="SpawnWithItem" parent="GenericItemOnGround3" index="1"] +_blueprint = ExtResource("7_hv2km") + +[node name="GenericItemOnGround4" parent="." instance=ExtResource("5_sjt6k")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.1678, -4.76837e-07, -3.94977) +_infiniteSupply = true + +[node name="SpawnWithItem" parent="GenericItemOnGround4" index="1"] +_blueprint = ExtResource("8_hae25") + [editable path="GenericItemOnGround"] +[editable path="GenericItemOnGround2"] +[editable path="GenericItemOnGround3"] +[editable path="GenericItemOnGround4"] diff --git a/scripts/CSharp/Common/Inventory/ItemOnGround.cs b/scripts/CSharp/Common/Inventory/ItemOnGround.cs index 714174c..75ba3d8 100644 --- a/scripts/CSharp/Common/Inventory/ItemOnGround.cs +++ b/scripts/CSharp/Common/Inventory/ItemOnGround.cs @@ -5,6 +5,12 @@ public partial class ItemOnGround : Node3D { private ItemInstance _itemInstance; + [Export] + private bool _infiniteSupply = false; + + private Label3D _itemLabel => GetNode("ItemLabel"); + private Label3D _pickupErrorLabel => GetNode("PickupErrorLabel"); + public ItemInstance itemInstance { get => _itemInstance; @@ -22,25 +28,22 @@ public partial class ItemOnGround : Node3D var result = InventoryManager.Instance.CollectItem(itemInstance); if (result == InventoryActionResult.Success) { - QueueFree(); + if (!_infiniteSupply) + { + QueueFree(); + } } else { - GD.Print("Inventory is full"); - // TODO: player message + _pickupErrorLabel.Text = "Inventory Full"; + var tween = GetTree().CreateTween(); + tween.TweenInterval(2); + tween.TweenCallback(Callable.From(() => _pickupErrorLabel.Text = "")); } } public void UpdateVisuals() { - var label = GetNode("ItemLabel"); - if (itemInstance.blueprint != null) - { - label.Text = itemInstance.blueprint.name; - } - else - { - label.Text = "Error Item"; - } + _itemLabel.Text = itemInstance.blueprint?.name ?? "Error Item"; } } From fb362e10adecf6664937744b2302d85b64a6edaa Mon Sep 17 00:00:00 2001 From: cblech Date: Thu, 17 Apr 2025 03:24:31 +0200 Subject: [PATCH 3/5] item count WIP --- resources/items/axe.tres | 1 + resources/items/bucket.tres | 1 + resources/items/hoe.tres | 1 + resources/items/pickaxe.tres | 1 + resources/items/tomato_seed.tres | 10 ++++++++++ scenes/testing/Babushka_scene_item_pickup_testing.tscn | 6 +++--- scripts/CSharp/Common/Inventory/ItemInstance.cs | 1 + scripts/CSharp/Common/Inventory/ItemResource.cs | 8 ++++++-- 8 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 resources/items/tomato_seed.tres diff --git a/resources/items/axe.tres b/resources/items/axe.tres index 0770130..cbac4ae 100644 --- a/resources/items/axe.tres +++ b/resources/items/axe.tres @@ -6,4 +6,5 @@ script = ExtResource("1_t485b") name = "Axe Deo" color = Color(0.643898, 0.4587, 0.294335, 1) +maxStack = 1 metadata/_custom_type_script = "uid://cbskymrxs6ksu" diff --git a/resources/items/bucket.tres b/resources/items/bucket.tres index b323f49..2005ad5 100644 --- a/resources/items/bucket.tres +++ b/resources/items/bucket.tres @@ -6,4 +6,5 @@ script = ExtResource("1_8k5aa") name = "Buck the Bucket" color = Color(0.336269, 0.489145, 0.825324, 1) +maxStack = 1 metadata/_custom_type_script = "uid://cbskymrxs6ksu" diff --git a/resources/items/hoe.tres b/resources/items/hoe.tres index e7c0e27..a7960d7 100644 --- a/resources/items/hoe.tres +++ b/resources/items/hoe.tres @@ -6,4 +6,5 @@ script = ExtResource("1_06nef") name = "Your Mom" color = Color(0.751421, 0.329615, 0.570911, 1) +maxStack = 1 metadata/_custom_type_script = "uid://cbskymrxs6ksu" diff --git a/resources/items/pickaxe.tres b/resources/items/pickaxe.tres index afc788d..31870c8 100644 --- a/resources/items/pickaxe.tres +++ b/resources/items/pickaxe.tres @@ -6,4 +6,5 @@ script = ExtResource("1_07aya") name = "Pick Axe" color = Color(0.589014, 0.823353, 0.998475, 1) +maxStack = 1 metadata/_custom_type_script = "uid://cbskymrxs6ksu" diff --git a/resources/items/tomato_seed.tres b/resources/items/tomato_seed.tres new file mode 100644 index 0000000..79abe3e --- /dev/null +++ b/resources/items/tomato_seed.tres @@ -0,0 +1,10 @@ +[gd_resource type="Resource" script_class="ItemResource" load_steps=2 format=3 uid="uid://d1uuxp1lp4aro"] + +[ext_resource type="Script" uid="uid://cbskymrxs6ksu" path="res://scripts/CSharp/Common/Inventory/ItemResource.cs" id="1_dustj"] + +[resource] +script = ExtResource("1_dustj") +name = "Tomato Seed" +color = Color(0.135039, 0.307214, 0.333128, 1) +maxStack = 20 +metadata/_custom_type_script = "uid://cbskymrxs6ksu" diff --git a/scenes/testing/Babushka_scene_item_pickup_testing.tscn b/scenes/testing/Babushka_scene_item_pickup_testing.tscn index 7b0fa00..f3efd13 100644 --- a/scenes/testing/Babushka_scene_item_pickup_testing.tscn +++ b/scenes/testing/Babushka_scene_item_pickup_testing.tscn @@ -5,9 +5,9 @@ [ext_resource type="PackedScene" uid="uid://5hltxpdxmqcq" path="res://prefabs/interactions/generic_item_on_ground.tscn" id="5_sjt6k"] [ext_resource type="PackedScene" uid="uid://cgjc4wurbgimy" path="res://prefabs/UI/Inventory/Inventory.tscn" id="6_876p1"] [ext_resource type="Resource" uid="uid://cndd64batns31" path="res://resources/items/bucket.tres" id="6_nvnpb"] -[ext_resource type="Script" uid="uid://cywyym5l7ymhr" path="res://scripts/CSharp/Common/Farming/FieldService.cs" id="7_3rkjv"] +[ext_resource type="Script" uid="uid://dbkkeo3gw2xgy" path="res://scripts/CSharp/Common/Farming/FieldService.cs" id="7_3rkjv"] [ext_resource type="Resource" uid="uid://c5yg3lx756v4v" path="res://resources/items/hoe.tres" id="7_hv2km"] -[ext_resource type="Resource" uid="uid://datee0flk1e84" path="res://resources/items/pickaxe.tres" id="8_hae25"] +[ext_resource type="Resource" uid="uid://d1uuxp1lp4aro" path="res://resources/items/tomato_seed.tres" id="8_hv2km"] [sub_resource type="PlaneMesh" id="PlaneMesh_8yprl"] @@ -67,7 +67,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.1678, -4.76837e-07, -3.9497 _infiniteSupply = true [node name="SpawnWithItem" parent="GenericItemOnGround4" index="1"] -_blueprint = ExtResource("8_hae25") +_blueprint = ExtResource("8_hv2km") [editable path="GenericItemOnGround"] [editable path="GenericItemOnGround2"] diff --git a/scripts/CSharp/Common/Inventory/ItemInstance.cs b/scripts/CSharp/Common/Inventory/ItemInstance.cs index 83eed75..abf6e4f 100644 --- a/scripts/CSharp/Common/Inventory/ItemInstance.cs +++ b/scripts/CSharp/Common/Inventory/ItemInstance.cs @@ -3,4 +3,5 @@ public class ItemInstance { public ItemResource blueprint; + public int amount = 1; } diff --git a/scripts/CSharp/Common/Inventory/ItemResource.cs b/scripts/CSharp/Common/Inventory/ItemResource.cs index f696046..c6c8b88 100644 --- a/scripts/CSharp/Common/Inventory/ItemResource.cs +++ b/scripts/CSharp/Common/Inventory/ItemResource.cs @@ -2,17 +2,21 @@ namespace Babushka.scripts.CSharp.Common.Inventory; [GlobalClass] -public partial class ItemResource: Resource +public partial class ItemResource : Resource { [Export] public string name; [Export] public Color color; - + + [Export] + public int maxStack; + public ItemResource() { name = ""; color = Colors.Red; + maxStack = 1; } } From fb0c14c3f1cb0895370d15a5be30e4e827ac67ad Mon Sep 17 00:00:00 2001 From: cblech Date: Thu, 17 Apr 2025 16:10:12 +0200 Subject: [PATCH 4/5] Added item stacking --- prefabs/UI/Inventory/Slot.tscn | 18 ++++ .../Common/Inventory/InventoryInstance.cs | 86 ++++++++++++++----- .../Common/Inventory/InventoryManager.cs | 20 +++-- .../CSharp/Common/Inventory/InventoryUi.cs | 12 ++- .../CSharp/Common/Inventory/ItemInstance.cs | 9 ++ .../CSharp/Common/Inventory/ItemOnGround.cs | 2 +- scripts/CSharp/Common/Inventory/SlotUi.cs | 2 + 7 files changed, 118 insertions(+), 31 deletions(-) diff --git a/prefabs/UI/Inventory/Slot.tscn b/prefabs/UI/Inventory/Slot.tscn index 8e7c2ac..cb8252c 100644 --- a/prefabs/UI/Inventory/Slot.tscn +++ b/prefabs/UI/Inventory/Slot.tscn @@ -41,4 +41,22 @@ label_settings = SubResource("LabelSettings_7emux") horizontal_alignment = 1 vertical_alignment = 1 +[node name="AmountLabel" type="Label" parent="."] +layout_mode = 1 +anchors_preset = -1 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -409.0 +offset_top = -329.0 +offset_right = -10.0 +offset_bottom = -10.0 +grow_horizontal = 0 +grow_vertical = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) +text = "999" +horizontal_alignment = 2 +vertical_alignment = 2 + [connection signal="gui_input" from="." to="." method="_on_gui_input"] diff --git a/scripts/CSharp/Common/Inventory/InventoryInstance.cs b/scripts/CSharp/Common/Inventory/InventoryInstance.cs index 0991199..5070b69 100644 --- a/scripts/CSharp/Common/Inventory/InventoryInstance.cs +++ b/scripts/CSharp/Common/Inventory/InventoryInstance.cs @@ -12,6 +12,7 @@ public partial class InventoryInstance : Node [Signal] public delegate void SlotAmountChangedEventHandler(); + [Signal] public delegate void InventoryContentsChangedEventHandler(); @@ -32,54 +33,99 @@ public partial class InventoryInstance : Node _slots.Add(new InventorySlot()); } } + EmitSignal(SignalName.SlotAmountChanged); } } - - public InventoryActionResult AddItem(ItemInstance newItem, int inventorySlot = -1) + + public InventoryActionResult AddItem(ItemInstance newItem) { - if (inventorySlot < 0) + var result = AddItemAndStackRecursive(newItem, 0); + EmitSignal(SignalName.InventoryContentsChanged); + return result; + } + + private InventoryActionResult AddItemAndStackRecursive(ItemInstance newItem, int slotSearch) + { + if (newItem.blueprint == null || newItem.amount == 0) + return InventoryActionResult.SourceDoesNotExists; + + var slotIndex = -1; + // find stackable slot + for (var i = slotSearch; i < _slots.Count; i++) { - inventorySlot = _slots.FindIndex(slot => slot.IsEmpty()); + if (_slots[i].itemInstance?.blueprint == newItem.blueprint) + { + slotIndex = i; + break; + } } - - if (inventorySlot < 0 || !_slots[inventorySlot].IsEmpty()) + + if (slotIndex < 0) { - return InventoryActionResult.DestinationFull; + // find empty slot + for (var i = slotSearch; i < _slots.Count; i++) + { + if (_slots[i].IsEmpty()) + { + slotIndex = i; + break; + } + } } - - if (inventorySlot >= _slots.Count) + + if (slotIndex < 0) { - return InventoryActionResult.DestinationDoesNotExists; + return InventoryActionResult.DestinationFull; } - - _slots[inventorySlot].itemInstance = newItem; - EmitSignal(SignalName.InventoryContentsChanged); - return InventoryActionResult.Success; + + var itemInstance = _slots[slotIndex].itemInstance ?? new ItemInstance { blueprint = newItem.blueprint, amount = 0 }; + var maxStack = itemInstance!.blueprint.maxStack; + var freeOnStack = maxStack - itemInstance.amount; + var moveAmount = Math.Min(freeOnStack, newItem.amount); + itemInstance.amount += moveAmount; + newItem.amount -= moveAmount; + _slots[slotIndex].itemInstance = itemInstance; + return newItem.amount <= 0 + ? InventoryActionResult.Success + : AddItemAndStackRecursive(newItem, slotIndex + 1); } - - public InventoryActionResult RemoveItem(int inventorySlot, out ItemInstance? itemInstance ) + + public InventoryActionResult RemoveItem(int inventorySlot, out ItemInstance? itemInstance) { if (inventorySlot < 0 || inventorySlot >= _slots.Count) { itemInstance = null; return InventoryActionResult.SourceDoesNotExists; } - + if (_slots[inventorySlot].IsEmpty()) { itemInstance = null; return InventoryActionResult.SourceIsEmpty; } - + itemInstance = _slots[inventorySlot].itemInstance; _slots[inventorySlot].itemInstance = null; EmitSignal(SignalName.InventoryContentsChanged); return InventoryActionResult.Success; } - + public InventoryActionResult RemoveItem(int inventorySlot) { return RemoveItem(inventorySlot, out _); } -} + + public InventoryActionResult AddItemToSlot(ItemInstance itemInstance, int destinationSlot) + { + if (destinationSlot < 0 || destinationSlot >= _slots.Count) + return InventoryActionResult.DestinationDoesNotExists; + + if (!_slots[destinationSlot].IsEmpty()) + return InventoryActionResult.DestinationFull; + + _slots[destinationSlot].itemInstance = itemInstance; + EmitSignal(SignalName.InventoryContentsChanged); + return InventoryActionResult.Success; + } +} \ No newline at end of file diff --git a/scripts/CSharp/Common/Inventory/InventoryManager.cs b/scripts/CSharp/Common/Inventory/InventoryManager.cs index ed44999..b191e98 100644 --- a/scripts/CSharp/Common/Inventory/InventoryManager.cs +++ b/scripts/CSharp/Common/Inventory/InventoryManager.cs @@ -6,7 +6,7 @@ namespace Babushka.scripts.CSharp.Common.Inventory; public partial class InventoryManager : Node { public static InventoryManager Instance { get; private set; } - + public InventoryInstance playerInventory; public override void _EnterTree() @@ -23,11 +23,13 @@ public partial class InventoryManager : Node public InventoryActionResult CreateItem( ItemResource itemBlueprint, InventoryInstance inventory, + int amount = 1, int inventorySlot = -1) { - var newItem = new ItemInstance { blueprint = itemBlueprint }; - var addResult = inventory.AddItem(newItem, inventorySlot); - return addResult; + var newItem = new ItemInstance { blueprint = itemBlueprint, amount = amount }; + return inventorySlot < 0 + ? inventory.AddItem(newItem) + : inventory.AddItemToSlot(newItem, inventorySlot); } public InventoryActionResult MoveItem( @@ -39,10 +41,11 @@ public partial class InventoryManager : Node var remResult = sourceInventory.RemoveItem(sourceSlot, out var item); if (remResult != InventoryActionResult.Success) return remResult; - var addResult = destinationInventory.AddItem(item!, destinationSlot); - if(addResult == InventoryActionResult.Success) return InventoryActionResult.Success; + var addResult = destinationInventory.AddItemToSlot(item!, destinationSlot); + if (addResult == InventoryActionResult.Success) return InventoryActionResult.Success; - sourceInventory.AddItem(item!, sourceSlot); // can not fail ... in theory + // if adding in the destination failed, re-add the item into the source + sourceInventory.AddItemToSlot(item!, sourceSlot); // can not fail ... in theory return addResult; } @@ -60,8 +63,9 @@ public partial class InventoryManager : Node { return inventory.RemoveItem(inventorySlot); } + public InventoryActionResult CollectItem(ItemInstance itemInstance) { return playerInventory.AddItem(itemInstance); } -} +} \ No newline at end of file diff --git a/scripts/CSharp/Common/Inventory/InventoryUi.cs b/scripts/CSharp/Common/Inventory/InventoryUi.cs index 3b8ed7d..eb92b91 100644 --- a/scripts/CSharp/Common/Inventory/InventoryUi.cs +++ b/scripts/CSharp/Common/Inventory/InventoryUi.cs @@ -43,6 +43,12 @@ public partial class InventoryUi : Control uiSlot!.nameLabel.Text = inventorySlot.itemInstance?.blueprint.name ?? ""; uiSlot!.nameLabel.LabelSettings = uiSlot!.nameLabel.LabelSettings.Duplicate() as LabelSettings; uiSlot!.nameLabel.LabelSettings!.FontColor = inventorySlot.itemInstance?.blueprint.color ?? Colors.White; + + var amountText = inventorySlot.itemInstance != null && + inventorySlot.itemInstance.amount != 1 + ? inventorySlot.itemInstance.amount.ToString() + : ""; + uiSlot!.amountLabel.Text = amountText; } } @@ -99,6 +105,7 @@ public partial class InventoryUi : Control { InputInventoryOpenClose(); } + if (Input.IsActionJustPressed("ui_inventory_disadvance")) { _selectedSlot++; @@ -106,7 +113,8 @@ public partial class InventoryUi : Control _selectedSlot = 0; SetSlotSelectPosition(); } - if(Input.IsActionJustPressed("ui_inventory_advance")) + + if (Input.IsActionJustPressed("ui_inventory_advance")) { _selectedSlot--; if (_selectedSlot < 0) @@ -143,4 +151,4 @@ public partial class InventoryUi : Control _slotOnMouse = null; } } -} +} \ No newline at end of file diff --git a/scripts/CSharp/Common/Inventory/ItemInstance.cs b/scripts/CSharp/Common/Inventory/ItemInstance.cs index abf6e4f..0aaa528 100644 --- a/scripts/CSharp/Common/Inventory/ItemInstance.cs +++ b/scripts/CSharp/Common/Inventory/ItemInstance.cs @@ -4,4 +4,13 @@ public class ItemInstance { public ItemResource blueprint; public int amount = 1; + + public ItemInstance Clone() + { + return new ItemInstance + { + blueprint = blueprint, + amount = amount + }; + } } diff --git a/scripts/CSharp/Common/Inventory/ItemOnGround.cs b/scripts/CSharp/Common/Inventory/ItemOnGround.cs index 75ba3d8..d9c7cbe 100644 --- a/scripts/CSharp/Common/Inventory/ItemOnGround.cs +++ b/scripts/CSharp/Common/Inventory/ItemOnGround.cs @@ -25,7 +25,7 @@ public partial class ItemOnGround : Node3D { GD.Print("Trying to pick up item"); - var result = InventoryManager.Instance.CollectItem(itemInstance); + var result = InventoryManager.Instance.CollectItem(itemInstance.Clone()); if (result == InventoryActionResult.Success) { if (!_infiniteSupply) diff --git a/scripts/CSharp/Common/Inventory/SlotUi.cs b/scripts/CSharp/Common/Inventory/SlotUi.cs index 2c174b2..753447d 100644 --- a/scripts/CSharp/Common/Inventory/SlotUi.cs +++ b/scripts/CSharp/Common/Inventory/SlotUi.cs @@ -7,12 +7,14 @@ public partial class SlotUi : Control { public Label nameLabel; public int index; + public Label amountLabel; [Signal] public delegate void ClickedEventHandler(int index); public override void _EnterTree() { nameLabel = GetNode