Refactored Game saving and loading, added simple unit test for it.

main
Martin Felis 2024-12-01 21:14:04 +01:00
parent 437762b2f6
commit 44083114ba
17 changed files with 213 additions and 165 deletions

View File

@ -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")

View File

@ -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")

View File

@ -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")

View File

@ -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]

View File

@ -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"]

View File

@ -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")

View File

@ -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")

View File

@ -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)

View File

@ -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)

View File

@ -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"]

View File

@ -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)

View File

@ -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)