From 44083114ba190adde4c5e4966b001573122b728e Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sun, 1 Dec 2024 21:14:04 +0100 Subject: [PATCH] Refactored Game saving and loading, added simple unit test for it. --- data/recipes/campfire.tres | 2 +- data/recipes/fence_fortified.tres | 4 +- data/recipes/floor.tres | 4 +- data/recipes/shovel.tres | 2 +- data/recipes/stick.tres | 2 +- data/recipes/woodplank.tres | 2 +- data/recipes/workbench.tres | 4 +- data/{items => structures}/campfire_pit.tres | 0 .../fence_fortified.tres | 0 data/{items => structures}/floor.tres | 0 data/{items => structures}/woodplanks.tres | 0 data/{items => structures}/workbench.tres | 0 game_ui.gd | 12 +- root_ui.gd | 89 +------------ root_ui.tscn | 120 +++++++++--------- scenes/game.gd | 109 +++++++++++++++- tests/scenes/game_tests.gd | 28 ++++ 17 files changed, 213 insertions(+), 165 deletions(-) rename data/{items => structures}/campfire_pit.tres (100%) rename data/{items => structures}/fence_fortified.tres (100%) rename data/{items => structures}/floor.tres (100%) rename data/{items => structures}/woodplanks.tres (100%) rename data/{items => structures}/workbench.tres (100%) create mode 100644 tests/scenes/game_tests.gd diff --git a/data/recipes/campfire.tres b/data/recipes/campfire.tres index 45c2613..715656d 100644 --- a/data/recipes/campfire.tres +++ b/data/recipes/campfire.tres @@ -2,7 +2,7 @@ [ext_resource type="Resource" uid="uid://bn5j38jbwlj1f" path="res://data/items/stick.tres" id="1_c6ol1"] [ext_resource type="Script" path="res://model/recipe_resource.gd" id="1_q0xgv"] -[ext_resource type="Resource" uid="uid://qelpkmqsqo5r" path="res://data/items/campfire_pit.tres" id="2_xeckb"] +[ext_resource type="Resource" uid="uid://qelpkmqsqo5r" path="res://data/structures/campfire_pit.tres" id="2_xeckb"] [resource] script = ExtResource("1_q0xgv") diff --git a/data/recipes/fence_fortified.tres b/data/recipes/fence_fortified.tres index 35f7a49..2905bc6 100644 --- a/data/recipes/fence_fortified.tres +++ b/data/recipes/fence_fortified.tres @@ -2,8 +2,8 @@ [ext_resource type="Script" path="res://model/recipe_resource.gd" id="1_h0rj4"] [ext_resource type="Resource" uid="uid://bn5j38jbwlj1f" path="res://data/items/stick.tres" id="1_i6g7d"] -[ext_resource type="Resource" uid="uid://dmjr6pmb17l2y" path="res://data/items/woodplanks.tres" id="2_d54b6"] -[ext_resource type="Resource" uid="uid://c714vj3s6cnqg" path="res://data/items/fence_fortified.tres" id="3_bsd6g"] +[ext_resource type="Resource" uid="uid://dmjr6pmb17l2y" path="res://data/structures/woodplanks.tres" id="2_d54b6"] +[ext_resource type="Resource" uid="uid://c714vj3s6cnqg" path="res://data/structures/fence_fortified.tres" id="3_bsd6g"] [resource] script = ExtResource("1_h0rj4") diff --git a/data/recipes/floor.tres b/data/recipes/floor.tres index 23b0865..885dcda 100644 --- a/data/recipes/floor.tres +++ b/data/recipes/floor.tres @@ -1,8 +1,8 @@ [gd_resource type="Resource" script_class="RecipeResource" load_steps=4 format=3 uid="uid://dbij72n3ia8te"] [ext_resource type="Script" path="res://model/recipe_resource.gd" id="1_sqajm"] -[ext_resource type="Resource" uid="uid://dmjr6pmb17l2y" path="res://data/items/woodplanks.tres" id="1_y7d3a"] -[ext_resource type="Resource" uid="uid://cepy03xrewibs" path="res://data/items/floor.tres" id="2_m3y1r"] +[ext_resource type="Resource" uid="uid://dmjr6pmb17l2y" path="res://data/structures/woodplanks.tres" id="1_y7d3a"] +[ext_resource type="Resource" uid="uid://cepy03xrewibs" path="res://data/structures/floor.tres" id="2_m3y1r"] [resource] script = ExtResource("1_sqajm") diff --git a/data/recipes/shovel.tres b/data/recipes/shovel.tres index 3049a59..c664ea3 100644 --- a/data/recipes/shovel.tres +++ b/data/recipes/shovel.tres @@ -2,7 +2,7 @@ [ext_resource type="Script" path="res://model/recipe_resource.gd" id="1_eqskp"] [ext_resource type="Resource" uid="uid://bn5j38jbwlj1f" path="res://data/items/stick.tres" id="1_w20uq"] -[ext_resource type="Resource" uid="uid://dmjr6pmb17l2y" path="res://data/items/woodplanks.tres" id="3_x6ond"] +[ext_resource type="Resource" uid="uid://dmjr6pmb17l2y" path="res://data/structures/woodplanks.tres" id="3_x6ond"] [ext_resource type="Resource" uid="uid://mkj3oeaxvltq" path="res://data/items/shovel.tres" id="4_j1aun"] [resource] diff --git a/data/recipes/stick.tres b/data/recipes/stick.tres index d12b579..2049ffd 100644 --- a/data/recipes/stick.tres +++ b/data/recipes/stick.tres @@ -1,6 +1,6 @@ [gd_resource type="Resource" script_class="RecipeResource" load_steps=4 format=3 uid="uid://mju8wym58143"] -[ext_resource type="Resource" uid="uid://dmjr6pmb17l2y" path="res://data/items/woodplanks.tres" id="1_7pctr"] +[ext_resource type="Resource" uid="uid://dmjr6pmb17l2y" path="res://data/structures/woodplanks.tres" id="1_7pctr"] [ext_resource type="Resource" uid="uid://bn5j38jbwlj1f" path="res://data/items/stick.tres" id="2_6dang"] [ext_resource type="Script" path="res://model/recipe_resource.gd" id="2_rsitf"] diff --git a/data/recipes/woodplank.tres b/data/recipes/woodplank.tres index 8489f10..e12dbf6 100644 --- a/data/recipes/woodplank.tres +++ b/data/recipes/woodplank.tres @@ -2,7 +2,7 @@ [ext_resource type="Script" path="res://model/recipe_resource.gd" id="1_8rbqv"] [ext_resource type="Resource" uid="uid://c1ll2snhgv3m1" path="res://data/items/treelog.tres" id="1_lfwgj"] -[ext_resource type="Resource" uid="uid://dmjr6pmb17l2y" path="res://data/items/woodplanks.tres" id="2_17d0x"] +[ext_resource type="Resource" uid="uid://dmjr6pmb17l2y" path="res://data/structures/woodplanks.tres" id="2_17d0x"] [resource] script = ExtResource("1_8rbqv") diff --git a/data/recipes/workbench.tres b/data/recipes/workbench.tres index 6bce37a..6f8fe8c 100644 --- a/data/recipes/workbench.tres +++ b/data/recipes/workbench.tres @@ -1,8 +1,8 @@ [gd_resource type="Resource" script_class="RecipeResource" load_steps=4 format=3 uid="uid://dvgxtg3oau0f3"] -[ext_resource type="Resource" uid="uid://dmjr6pmb17l2y" path="res://data/items/woodplanks.tres" id="1_2e1bt"] +[ext_resource type="Resource" uid="uid://dmjr6pmb17l2y" path="res://data/structures/woodplanks.tres" id="1_2e1bt"] [ext_resource type="Script" path="res://model/recipe_resource.gd" id="1_d10rq"] -[ext_resource type="Resource" uid="uid://kywjkeu5tnjp" path="res://data/items/workbench.tres" id="2_a5ecf"] +[ext_resource type="Resource" uid="uid://kywjkeu5tnjp" path="res://data/structures/workbench.tres" id="2_a5ecf"] [resource] script = ExtResource("1_d10rq") diff --git a/data/items/campfire_pit.tres b/data/structures/campfire_pit.tres similarity index 100% rename from data/items/campfire_pit.tres rename to data/structures/campfire_pit.tres diff --git a/data/items/fence_fortified.tres b/data/structures/fence_fortified.tres similarity index 100% rename from data/items/fence_fortified.tres rename to data/structures/fence_fortified.tres diff --git a/data/items/floor.tres b/data/structures/floor.tres similarity index 100% rename from data/items/floor.tres rename to data/structures/floor.tres diff --git a/data/items/woodplanks.tres b/data/structures/woodplanks.tres similarity index 100% rename from data/items/woodplanks.tres rename to data/structures/woodplanks.tres diff --git a/data/items/workbench.tres b/data/structures/workbench.tres similarity index 100% rename from data/items/workbench.tres rename to data/structures/workbench.tres diff --git a/game_ui.gd b/game_ui.gd index 167ec63..f60595c 100644 --- a/game_ui.gd +++ b/game_ui.gd @@ -1,6 +1,8 @@ class_name GameUI extends Control +# Connects the game state to the UI + signal quit_game_scene @onready var tool_slots = %ToolSlots @@ -10,8 +12,6 @@ signal quit_game_scene @onready var build_dialog = %BuildDialog @onready var debug_panel: Panel = %DebugPanel -var picked_up_level_items:Array[NodePath] = [] - var _game_scene:Game var _player:Player var _all_recipes:Array[RecipeResource] = [] @@ -41,10 +41,6 @@ func activate_game_scene(game_scene:Node3D) -> void: tool_slots.show() tool_container.displayStacks(_player.inventory.get_tool_item_stacks()) - - # When saving a game we need to know which items were picked up. - for pickup_item in get_tree().get_nodes_in_group("pickup_item"): - pickup_item.connect("item_picked_up", on_item_pickup) game_menu_ui.hide() @@ -85,10 +81,6 @@ func _on_player_trigger_message(message): print(message) -func on_item_pickup(node_path:NodePath): - picked_up_level_items.append(node_path) - - func disconnect_player_signals(): _player.disconnect("trigger_message", _on_player_trigger_message) diff --git a/root_ui.gd b/root_ui.gd index c3e7920..86bc96b 100644 --- a/root_ui.gd +++ b/root_ui.gd @@ -51,97 +51,20 @@ func load_scene(scene_resource:PackedScene): current_level_resource = scene_resource.resource_path _game_build_system = scene.find_child("BuildSystem", true, false) as BuildSystem - - var player:Player = scene.find_child("Player", true, false) - InteractionSystem.player = player + InteractionSystem.player = scene.find_child("Player", true, false) as Player func save_game(): - var player:Player = scene.find_child("Player", true, false) - - if player == null: - push_error("Cannot load game: no player found!") - return - - var save_data:SaveGameResource = SaveGameResource.new() - - save_data.level = current_level_resource - save_data.level_pickup_items = %GameUI.picked_up_level_items - save_data.player_transform = player.global_transform - - for node:Node in get_tree().get_nodes_in_group("quest_state"): - save_data.quest_states[node.name] = {} - - for property in node.get_property_list(): - if (property.usage & PROPERTY_USAGE_STORAGE != 0) and (property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE) != 0: - save_data.quest_states[node.name][property.name] = node.get(property.name) - - for item_stack in player.inventory.get_item_stacks(): - save_data.inventory.append({"item": item_stack.item, "count": item_stack.count}) - - for structure:BuiltStructure in get_tree().get_nodes_in_group("built_structure"): - var built_structure_resource = BuiltStructureResource.new() - built_structure_resource.global_transform = structure.global_transform - built_structure_resource.item = structure.item - var item_array = save_data.built_structures.find_key(structure.item) - - if item_array == null: - item_array = [] - save_data.built_structures[structure.item] = item_array - - item_array.append(structure.global_transform) - - print("Saving game: " + current_game_profile_directory + "/savegame.tres") - ResourceSaver.save(save_data, current_game_profile_directory + "/savegame.tres") + var game:Game = %Scene.get_child(0) as Game + game.save_game(current_game_profile_directory) activate_ui_panel(%GameUI) func load_game(): set_root_ui_state(RootUI.ROOT_UI_STATE.UNDEFINED) - %GameUI.picked_up_level_items.clear() + load_scene(game_scene) + var game:Game = %Scene.get_child(0) as Game - print("Loading game: " + current_game_profile_directory + "/savegame.tres") - var save_data:SaveGameResource = load(current_game_profile_directory + "/savegame.tres") as SaveGameResource - - var level_resource:PackedScene = load(save_data.level) - load_scene(level_resource) - - var player:Player = scene.find_child("Player", true, false) - - if player == null: - push_error("Cannot load game: no player found!") - return - - player.global_transform = save_data.player_transform - player.init_look_target_direction() - - # Quest state - for quest_state:Node in get_tree().get_nodes_in_group("quest_state"): - for property in quest_state.get_property_list(): - if (property.usage & PROPERTY_USAGE_STORAGE != 0) and (property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE) != 0 and (save_data.quest_states.has(quest_state.name)) and (save_data.quest_states[quest_state.name].has(property.name)): - quest_state.set(property.name, save_data.quest_states[quest_state.name][property.name]) - - # Inventory - player.inventory.clear() - var inventory_item_stacks:Array[ItemStack] = player.inventory.get_item_stacks() - - assert(inventory_item_stacks.size() >= save_data.inventory.size()) - - for i in range(save_data.inventory.size()): - inventory_item_stacks[i].item = save_data.inventory[i]["item"] - inventory_item_stacks[i].count = save_data.inventory[i]["count"] - - # Picked up items - for item_path in save_data.level_pickup_items: - if get_tree().root.has_node(item_path): - var item_node = get_tree().root.get_node(item_path) - %GameUI.picked_up_level_items.append(item_path) - item_node.queue_free() - - # Built structures - for item:ItemResource in save_data.built_structures.keys(): - var item_transform_array = save_data.built_structures[item] as Array[Transform3D] - for structure_transform in item_transform_array: - _game_build_system.build_structure(item, structure_transform) + game.load_game(current_game_profile_directory) set_root_ui_state(RootUI.ROOT_UI_STATE.GAME) diff --git a/root_ui.tscn b/root_ui.tscn index a648b29..753b1e2 100644 --- a/root_ui.tscn +++ b/root_ui.tscn @@ -985,22 +985,22 @@ unique_name_in_owner = true [connection signal="item_selected" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/Recipes/RecipeList" to="GameUI/InventoryDialog" method="_on_recipe_list_item_selected"] [connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/ItemSlot" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/ItemSlot" method="_on_gui_input"] [connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/ItemSlot" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/ItemSlot" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18027" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18027" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18027" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18027" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18028" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18028" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18028" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18028" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18029" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18029" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18029" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18029" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18030" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18030" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18030" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18030" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18031" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18031" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18031" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18031" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18032" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18032" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18032" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18032" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18033" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18033" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18033" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18033" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18034" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18034" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18034" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18034" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18090" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18090" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18090" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18090" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18091" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18091" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18091" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18091" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18092" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18092" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18092" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18092" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18093" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18093" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18093" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18093" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18094" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18094" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18094" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18094" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18095" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18095" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18095" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18095" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18096" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18096" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18096" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18096" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18097" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18097" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18097" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftIngredients/Panel/CenterContainer/IngredientsContainer/@Panel@18097" method="_on_mouse_entered"] [connection signal="gui_input" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftResult/Panel/CenterContainer/ResultsContainer/ItemSlot" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftResult/Panel/CenterContainer/ResultsContainer/ItemSlot" method="_on_gui_input"] [connection signal="mouse_entered" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftResult/Panel/CenterContainer/ResultsContainer/ItemSlot" to="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftResult/Panel/CenterContainer/ResultsContainer/ItemSlot" method="_on_mouse_entered"] [connection signal="pressed" from="GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftResult/HBoxContainer/CraftButton" to="GameUI/InventoryDialog" method="_on_craft_button_pressed"] @@ -1013,49 +1013,49 @@ unique_name_in_owner = true [connection signal="item_selected" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer" to="GameUI/BuildDialog" method="_on_build_items_container_item_selected"] [connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/ItemSlot" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/ItemSlot" method="_on_gui_input"] [connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/ItemSlot" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/ItemSlot" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18035" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18035" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18035" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18035" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18036" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18036" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18036" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18036" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18037" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18037" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18037" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18037" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18038" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18038" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18038" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18038" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18039" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18039" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18039" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18039" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18040" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18040" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18040" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18040" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18041" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18041" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18041" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18041" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18042" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18042" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18042" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18042" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18043" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18043" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18043" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18043" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18044" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18044" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18044" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18044" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18045" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18045" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18045" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18045" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18046" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18046" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18046" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18046" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18047" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18047" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18047" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18047" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18048" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18048" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18048" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18048" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18049" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18049" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18049" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18049" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18098" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18098" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18098" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18098" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18099" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18099" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18099" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18099" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18100" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18100" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18100" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18100" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18101" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18101" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18101" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18101" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18102" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18102" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18102" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18102" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18103" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18103" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18103" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18103" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18104" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18104" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18104" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18104" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18105" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18105" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18105" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18105" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18106" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18106" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18106" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18106" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18107" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18107" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18107" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18107" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18108" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18108" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18108" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18108" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18109" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18109" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18109" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18109" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18110" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18110" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18110" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18110" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18111" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18111" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18111" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18111" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18112" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18112" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18112" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemsContainer/@Panel@18112" method="_on_mouse_entered"] [connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/ItemSlot" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/ItemSlot" method="_on_gui_input"] [connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/ItemSlot" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/ItemSlot" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18050" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18050" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18050" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18050" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18051" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18051" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18051" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18051" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18052" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18052" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18052" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18052" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18053" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18053" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18053" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18053" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18054" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18054" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18054" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18054" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18055" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18055" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18055" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18055" method="_on_mouse_entered"] -[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18056" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18056" method="_on_gui_input"] -[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18056" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18056" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18113" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18113" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18113" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18113" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18114" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18114" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18114" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18114" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18115" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18115" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18115" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18115" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18116" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18116" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18116" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18116" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18117" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18117" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18117" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18117" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18118" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18118" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18118" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18118" method="_on_mouse_entered"] +[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18119" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18119" method="_on_gui_input"] +[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18119" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@18119" method="_on_mouse_entered"] diff --git a/scenes/game.gd b/scenes/game.gd index c7f8db2..0a1f8b1 100644 --- a/scenes/game.gd +++ b/scenes/game.gd @@ -1,16 +1,31 @@ -extends Node3D class_name Game +extends Node3D + +# Takes care of game state including +# * player state +# * current level +# * player-world state (i.e. which items were picked up in the level) + +signal item_picked_up(node_path:NodePath) @onready var camera = %Camera -@onready var player = %Player +@onready var player:Player = %Player @onready var build_system:BuildSystem = %BuildSystem +var picked_up_level_items:Array[NodePath] = [] +var level = null + var _player_camera_offset:Vector3 = Vector3.ZERO # Called when the node enters the scene tree for the first time. func _ready(): _player_camera_offset = camera.global_position - player.global_position + Vector3.UP * 1 + picked_up_level_items.clear() + + level = get_node("Level") + + register_item_pickups() # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(_delta): @@ -21,3 +36,93 @@ func _process(_delta): camera.global_position = player.global_position + _player_camera_offset camera.look_at(player.global_position) + +func register_item_pickups() -> void: + # When saving a game we need to know which items were picked up. + for pickup_item in get_tree().get_nodes_in_group("pickup_item"): + pickup_item.connect("item_picked_up", on_item_pickup) + +func on_item_pickup(node_path:NodePath): + picked_up_level_items.append(node_path) + item_picked_up.emit(node_path) + +func load_level(level_resource_path:String) -> void: + var level_resource = load(level_resource_path) as PackedScene + + var level_node = get_node("Level") as Node3D + assert(level_node != null) + + level_node.queue_free() + remove_child(level_node) + + level = level_resource.instantiate() + name = "Level" + add_child(level) + + register_item_pickups() + +func save_game(game_profile_path:String): + var save_data:SaveGameResource = SaveGameResource.new() + + save_data.level = level.scene_file_path + save_data.level_pickup_items = picked_up_level_items + save_data.player_transform = player.global_transform + + for node:Node in get_tree().get_nodes_in_group("quest_state"): + save_data.quest_states[node.name] = {} + + for property in node.get_property_list(): + if (property.usage & PROPERTY_USAGE_STORAGE != 0) and (property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE) != 0: + save_data.quest_states[node.name][property.name] = node.get(property.name) + + for item_stack in player.inventory.get_item_stacks(): + save_data.inventory.append({"item": item_stack.item, "count": item_stack.count}) + + for structure:BuiltStructure in get_tree().get_nodes_in_group("built_structure"): + var built_structure_resource = BuiltStructureResource.new() + built_structure_resource.global_transform = structure.global_transform + built_structure_resource.item = structure.item + var item_array = save_data.built_structures.get_or_add(structure.item, []) + + item_array.append(structure.global_transform) + + print("Saving game: " + game_profile_path + "/savegame.tres") + ResourceSaver.save(save_data, game_profile_path + "/savegame.tres") + +func load_game(game_profile_path:String) -> void: + print("Loading game: " + game_profile_path + "/savegame.tres") + var save_data:SaveGameResource = load(game_profile_path + "/savegame.tres") as SaveGameResource + + load_level(save_data.level) + + player.global_transform = save_data.player_transform + player.init_look_target_direction() + + # Quest state + for quest_state:Node in get_tree().get_nodes_in_group("quest_state"): + for property in quest_state.get_property_list(): + if (property.usage & PROPERTY_USAGE_STORAGE != 0) and (property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE) != 0 and (save_data.quest_states.has(quest_state.name)) and (save_data.quest_states[quest_state.name].has(property.name)): + quest_state.set(property.name, save_data.quest_states[quest_state.name][property.name]) + + # Inventory + player.inventory.clear() + var inventory_item_stacks:Array[ItemStack] = player.inventory.get_item_stacks() + + assert(inventory_item_stacks.size() >= save_data.inventory.size()) + + for i in range(save_data.inventory.size()): + inventory_item_stacks[i].item = save_data.inventory[i]["item"] + inventory_item_stacks[i].count = save_data.inventory[i]["count"] + + # Picked up items + for item_path in save_data.level_pickup_items: + if get_tree().root.has_node(item_path): + var item_node = get_tree().root.get_node(item_path) + picked_up_level_items.append(item_path) + item_node.queue_free() + + # Built structures + for item:ItemResource in save_data.built_structures.keys(): + var item_transform_array = save_data.built_structures[item] as Array[Transform3D] + for structure_transform in item_transform_array: + build_system.build_structure(item, structure_transform) diff --git a/tests/scenes/game_tests.gd b/tests/scenes/game_tests.gd new file mode 100644 index 0000000..9f70745 --- /dev/null +++ b/tests/scenes/game_tests.gd @@ -0,0 +1,28 @@ +# GdUnit generated TestSuite +class_name GameTest +extends GdUnitTestSuite +@warning_ignore('unused_parameter') +@warning_ignore('return_value_discarded') + +# TestSuite generated from +const __source = 'res://scenes/game.gd' + +var game_scene:PackedScene = preload("res://scenes/game.tscn") +var _unittest_game_profile_path:String = "user://game_profiles/unittest" + +func test_save_game() -> void: + var game:Game = game_scene.instantiate() + add_child(game) + + var floor_resource = load("res://data/structures/floor.tres") + + game.build_system.build_structure(floor_resource, Transform3D.IDENTITY) + game.build_system.build_structure(floor_resource, Transform3D.IDENTITY.translated(Vector3(1, 0, 0))) + + game.save_game(_unittest_game_profile_path) + + var save_data:SaveGameResource = load(_unittest_game_profile_path + "/savegame.tres") as SaveGameResource + assert_that(len(save_data.built_structures.keys())).is_equal(1) + assert_that(save_data.built_structures.has(floor_resource)).is_equal(true) + + assert_that(len(save_data.built_structures[floor_resource])).is_equal(2)