diff --git a/data/save_game.gd b/data/save_game.gd new file mode 100644 index 0000000..75df9a6 --- /dev/null +++ b/data/save_game.gd @@ -0,0 +1,5 @@ +class_name SaveGame +extends Resource + +@export var player_transform:Transform3D + diff --git a/game.gd b/game.gd index ded3214..8a0516c 100644 --- a/game.gd +++ b/game.gd @@ -3,3 +3,22 @@ extends Node3D @onready var message_container:Control = %MessagesContainer @onready var message_textedit:TextEdit = %MessageTextEdit + +@onready var player = %Player + +@onready var root_ui:RootUI = %RootUI + +func save_game(): + var save_game:SaveGame = SaveGame.new() + + save_game.player_transform = player.global_transform + + ResourceSaver.save(save_game, "user://savegame.tres") + root_ui.activate_ui_panel(%GameUI) + +func load_game(): + var save_game:SaveGame = load("user://savegame.tres") as SaveGame + + player.global_transform = save_game.player_transform + + root_ui.activate_ui_panel(%GameUI) diff --git a/game.tscn b/game.tscn index 369fc54..6457de3 100644 --- a/game.tscn +++ b/game.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=36 format=3 uid="uid://bugqatylloxkl"] +[gd_scene load_steps=37 format=3 uid="uid://bugqatylloxkl"] [ext_resource type="Script" path="res://game.gd" id="1_uwyoo"] [ext_resource type="Texture2D" uid="uid://bq3b1hxl5ojh6" path="res://assets/icons/npc_emotes/attention.tres" id="2_4dxur"] @@ -18,6 +18,7 @@ [ext_resource type="Script" path="res://root_ui.gd" id="16_winq7"] [ext_resource type="Theme" uid="uid://dmk7hc81l8gbw" path="res://ui/ui_theme.tres" id="17_1odts"] [ext_resource type="Script" path="res://game_ui.gd" id="18_i4pxl"] +[ext_resource type="Script" path="res://ui/game_menu_ui.gd" id="18_lr26g"] [ext_resource type="Texture2D" uid="uid://c7fu3paj3b4e8" path="res://assets/3rdparty/kenney/ui-pack-rpg-expansion/PNG/cursorSword_silver.png" id="19_mn7wc"] [ext_resource type="Texture2D" uid="uid://drpl0ql1p3pfk" path="res://assets/3rdparty/kenney/ui-pack-rpg-expansion/PNG/cursorSword_gold.png" id="20_3b2hv"] [ext_resource type="Texture2D" uid="uid://cq8ypeagpedq" path="res://assets/3rdparty/kenney/ui-pack-rpg-expansion/PNG/cursorSword_bronze.png" id="21_act8d"] @@ -171,6 +172,7 @@ collision_mask = 16 shape = SubResource("SphereShape3D_wrkyq") [node name="RootUI" type="CanvasLayer" parent="."] +unique_name_in_owner = true script = ExtResource("16_winq7") [node name="MainMenuUI" type="PanelContainer" parent="RootUI"] @@ -331,80 +333,6 @@ layout_mode = 2 text = "Start " -[node name="GameMenuUI" type="PanelContainer" parent="RootUI"] -unique_name_in_owner = true -visible = false -anchors_preset = 8 -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -offset_left = -199.0 -offset_top = -186.0 -offset_right = 199.0 -offset_bottom = 186.0 -grow_horizontal = 2 -grow_vertical = 2 -theme = ExtResource("17_1odts") - -[node name="MarginContainer" type="MarginContainer" parent="RootUI/GameMenuUI"] -layout_mode = 2 -theme_override_constants/margin_left = 60 -theme_override_constants/margin_top = 60 -theme_override_constants/margin_right = 60 -theme_override_constants/margin_bottom = 60 - -[node name="VBoxContainer" type="VBoxContainer" parent="RootUI/GameMenuUI/MarginContainer"] -layout_mode = 2 - -[node name="MarginContainer4" type="MarginContainer" parent="RootUI/GameMenuUI/MarginContainer/VBoxContainer"] -layout_mode = 2 -theme_override_constants/margin_left = 8 -theme_override_constants/margin_top = 8 -theme_override_constants/margin_right = 8 -theme_override_constants/margin_bottom = 8 - -[node name="SaveGameButton" type="Button" parent="RootUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer4"] -layout_mode = 2 -text = "Save Game -" - -[node name="MarginContainer2" type="MarginContainer" parent="RootUI/GameMenuUI/MarginContainer/VBoxContainer"] -layout_mode = 2 -theme_override_constants/margin_left = 8 -theme_override_constants/margin_top = 8 -theme_override_constants/margin_right = 8 -theme_override_constants/margin_bottom = 8 - -[node name="OptionsButton" type="Button" parent="RootUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer2"] -layout_mode = 2 -text = "Options" - -[node name="MarginContainer3" type="MarginContainer" parent="RootUI/GameMenuUI/MarginContainer/VBoxContainer"] -layout_mode = 2 -theme_override_constants/margin_left = 8 -theme_override_constants/margin_top = 8 -theme_override_constants/margin_right = 8 -theme_override_constants/margin_bottom = 8 - -[node name="BackToGameButton" type="Button" parent="RootUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer3"] -layout_mode = 2 -text = "Return to Game" - -[node name="HSeparator" type="HSeparator" parent="RootUI/GameMenuUI/MarginContainer/VBoxContainer"] -layout_mode = 2 - -[node name="MarginContainer5" type="MarginContainer" parent="RootUI/GameMenuUI/MarginContainer/VBoxContainer"] -layout_mode = 2 -theme_override_constants/margin_left = 8 -theme_override_constants/margin_top = 8 -theme_override_constants/margin_right = 8 -theme_override_constants/margin_bottom = 8 - -[node name="ToMainMenuButton" type="Button" parent="RootUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer5"] -layout_mode = 2 -text = "Back to Main Menu" - [node name="GameUI" type="Control" parent="RootUI"] unique_name_in_owner = true layout_mode = 3 @@ -418,38 +346,6 @@ size_flags_vertical = 3 theme = ExtResource("17_1odts") script = ExtResource("18_i4pxl") -[node name="ToolSlots" type="MarginContainer" parent="RootUI/GameUI"] -layout_mode = 1 -anchors_preset = 7 -anchor_left = 0.5 -anchor_top = 1.0 -anchor_right = 0.5 -anchor_bottom = 1.0 -offset_left = -67.0 -offset_top = -77.0 -offset_right = 67.0 -grow_horizontal = 2 -grow_vertical = 0 -theme_override_constants/margin_bottom = 32 - -[node name="PanelContainer" type="PanelContainer" parent="RootUI/GameUI/ToolSlots"] -layout_mode = 2 - -[node name="HBoxContainer" type="HBoxContainer" parent="RootUI/GameUI/ToolSlots/PanelContainer"] -layout_mode = 2 - -[node name="Button2" type="Button" parent="RootUI/GameUI/ToolSlots/PanelContainer/HBoxContainer"] -layout_mode = 2 -icon = ExtResource("19_mn7wc") - -[node name="Button3" type="Button" parent="RootUI/GameUI/ToolSlots/PanelContainer/HBoxContainer"] -layout_mode = 2 -icon = ExtResource("20_3b2hv") - -[node name="Button" type="Button" parent="RootUI/GameUI/ToolSlots/PanelContainer/HBoxContainer"] -layout_mode = 2 -icon = ExtResource("21_act8d") - [node name="MessagesContainer" type="MarginContainer" parent="RootUI/GameUI"] unique_name_in_owner = true visible = false @@ -643,13 +539,136 @@ layout_mode = 2 size_flags_horizontal = 4 size_flags_vertical = 4 +[node name="GameMenuUI" type="PanelContainer" parent="RootUI/GameUI"] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -199.0 +offset_top = -215.0 +offset_right = 199.0 +offset_bottom = 215.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("17_1odts") +script = ExtResource("18_lr26g") + +[node name="MarginContainer" type="MarginContainer" parent="RootUI/GameUI/GameMenuUI"] +layout_mode = 2 +theme_override_constants/margin_left = 60 +theme_override_constants/margin_top = 60 +theme_override_constants/margin_right = 60 +theme_override_constants/margin_bottom = 60 + +[node name="VBoxContainer" type="VBoxContainer" parent="RootUI/GameUI/GameMenuUI/MarginContainer"] +layout_mode = 2 + +[node name="MarginContainer4" type="MarginContainer" parent="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 8 +theme_override_constants/margin_top = 8 +theme_override_constants/margin_right = 8 +theme_override_constants/margin_bottom = 8 + +[node name="SaveGameButton" type="Button" parent="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer4"] +layout_mode = 2 +text = "Save Game +" + +[node name="MarginContainer6" type="MarginContainer" parent="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 8 +theme_override_constants/margin_top = 8 +theme_override_constants/margin_right = 8 +theme_override_constants/margin_bottom = 8 + +[node name="LoadGameButton" type="Button" parent="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer6"] +layout_mode = 2 +text = "Load Game +" + +[node name="MarginContainer2" type="MarginContainer" parent="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 8 +theme_override_constants/margin_top = 8 +theme_override_constants/margin_right = 8 +theme_override_constants/margin_bottom = 8 + +[node name="OptionsButton" type="Button" parent="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer2"] +layout_mode = 2 +text = "Options" + +[node name="MarginContainer3" type="MarginContainer" parent="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 8 +theme_override_constants/margin_top = 8 +theme_override_constants/margin_right = 8 +theme_override_constants/margin_bottom = 8 + +[node name="BackToGameButton" type="Button" parent="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer3"] +layout_mode = 2 +text = "Return to Game" + +[node name="HSeparator" type="HSeparator" parent="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="MarginContainer5" type="MarginContainer" parent="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 8 +theme_override_constants/margin_top = 8 +theme_override_constants/margin_right = 8 +theme_override_constants/margin_bottom = 8 + +[node name="ToMainMenuButton" type="Button" parent="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer5"] +layout_mode = 2 +text = "Back to Main Menu" + +[node name="ToolSlots" type="MarginContainer" parent="RootUI/GameUI"] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -87.0 +offset_top = -101.0 +offset_right = 87.0 +grow_horizontal = 2 +grow_vertical = 0 +theme_override_constants/margin_bottom = 32 + +[node name="PanelContainer" type="PanelContainer" parent="RootUI/GameUI/ToolSlots"] +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="RootUI/GameUI/ToolSlots/PanelContainer"] +layout_mode = 2 + +[node name="Button2" type="Button" parent="RootUI/GameUI/ToolSlots/PanelContainer/HBoxContainer"] +layout_mode = 2 +icon = ExtResource("19_mn7wc") + +[node name="Button3" type="Button" parent="RootUI/GameUI/ToolSlots/PanelContainer/HBoxContainer"] +layout_mode = 2 +icon = ExtResource("20_3b2hv") + +[node name="Button" type="Button" parent="RootUI/GameUI/ToolSlots/PanelContainer/HBoxContainer"] +layout_mode = 2 +icon = ExtResource("21_act8d") + [connection signal="pressed" from="RootUI/MainMenuUI/MarginContainer/VBoxContainer/MarginContainer/NewGameButton" to="RootUI" method="_on_new_game_button_pressed"] [connection signal="pressed" from="RootUI/MainMenuUI/MarginContainer/VBoxContainer/MarginContainer3/QuitButton" to="RootUI" method="_on_quit_button_pressed"] [connection signal="pressed" from="RootUI/NewGameUI/MarginContainer/VBoxContainer/MarginContainer3/HBoxContainer/BackButton" to="RootUI" method="_to_main_menu_button_pressed"] [connection signal="pressed" from="RootUI/NewGameUI/MarginContainer/VBoxContainer/MarginContainer3/HBoxContainer/StartGameButton" to="RootUI" method="_on_start_game_button_pressed"] -[connection signal="pressed" from="RootUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer3/BackToGameButton" to="RootUI" method="_on_start_game_button_pressed"] -[connection signal="pressed" from="RootUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer5/ToMainMenuButton" to="RootUI" method="_to_main_menu_button_pressed"] [connection signal="timeout" from="RootUI/GameUI/MessagesContainer/MessageTimer" to="RootUI/GameUI" method="_on_message_timer_timeout"] [connection signal="pressed" from="RootUI/GameUI/InventoryDialog/Panel/PanelContainer/Title/CloseButton" to="RootUI/GameUI/InventoryDialog" method="_on_close_button_pressed"] [connection signal="item_selected" from="RootUI/GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/Recipes/RecipeList" to="RootUI/GameUI/InventoryDialog" method="_on_recipe_list_item_selected"] [connection signal="pressed" from="RootUI/GameUI/InventoryDialog/Panel/PanelContainer/CraftingUI/HBoxContainer/CraftResult/HBoxContainer/CraftButton" to="RootUI/GameUI/InventoryDialog" method="_on_craft_button_pressed"] +[connection signal="visibility_changed" from="RootUI/GameUI/GameMenuUI" to="RootUI/GameUI" method="_on_game_menu_ui_visibility_changed"] +[connection signal="pressed" from="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer4/SaveGameButton" to="." method="save_game"] +[connection signal="pressed" from="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer6/LoadGameButton" to="." method="load_game"] +[connection signal="pressed" from="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer3/BackToGameButton" to="RootUI" method="_on_start_game_button_pressed"] +[connection signal="pressed" from="RootUI/GameUI/GameMenuUI/MarginContainer/VBoxContainer/MarginContainer5/ToMainMenuButton" to="RootUI" method="_to_main_menu_button_pressed"] diff --git a/game_ui.gd b/game_ui.gd index 752a9e5..1b0388d 100644 --- a/game_ui.gd +++ b/game_ui.gd @@ -1,5 +1,9 @@ extends Control +@onready var tool_slots = %ToolSlots +@onready var game_menu_ui = %GameMenuUI +@onready var world = %World + func _on_message_timer_timeout(): %MessagesContainer.visible = false @@ -10,3 +14,27 @@ func _on_player_trigger_message(message): %MessagesContainer/MessageTimer.start(1) %MessagesContainer.visible = true + +func _unhandled_key_input(event:InputEvent): + var key_event:InputEventKey = event as InputEventKey + + if key_event and key_event.pressed and key_event.get_keycode_with_modifiers() == KEY_ESCAPE: + if %GameMenuUI.visible: + %GameMenuUI.hide() + else: + %GameMenuUI.show() + + +func _on_game_menu_ui_visibility_changed(): + # Function gets triggered when scene is still in construction. In that + # case just return. + if tool_slots == null: + return + + if %GameMenuUI.visible: + tool_slots.hide() + %World.process_mode = Node.PROCESS_MODE_DISABLED + else: + tool_slots.show() + %World.process_mode = Node.PROCESS_MODE_INHERIT + diff --git a/root_ui.gd b/root_ui.gd index 085f0f7..da091b7 100644 --- a/root_ui.gd +++ b/root_ui.gd @@ -1,3 +1,4 @@ +class_name RootUI extends CanvasLayer @onready var ui_panels:Array = [ %MainMenuUI, %NewGameUI, %GameUI, %GameMenuUI ] @@ -6,9 +7,10 @@ extends CanvasLayer @onready var player = %Player @onready var inventory_dialog:InventoryDialog = %InventoryDialog +enum ROOT_UI_STATE { MENU, GAME } +var _root_ui_state:ROOT_UI_STATE = ROOT_UI_STATE.GAME var _all_recipes:Array[Recipe] = [] - # Called when the node enters the scene tree for the first time. func _ready(): for file in DirAccess.get_files_at("res://data/recipes"): @@ -16,8 +18,10 @@ func _ready(): var recipe:Recipe = load(resource_file) as Recipe _all_recipes.append(recipe) - activate_ui_panel(%GameUI) -# activate_ui_panel(%MainMenuUI) + if _root_ui_state == ROOT_UI_STATE.MENU: + activate_ui_panel(%MainMenuUI) + else: + activate_ui_panel(%GameUI) func activate_ui_panel(ui_panel:Control): @@ -26,22 +30,26 @@ func activate_ui_panel(ui_panel:Control): control.visible = true else: control.visible = false - - if not %GameUI.visible: - %World.process_mode = Node.PROCESS_MODE_DISABLED - else: - %World.process_mode = Node.PROCESS_MODE_INHERIT active_ui_panel = ui_panel +func set_root_ui_state(state:ROOT_UI_STATE): + if state == ROOT_UI_STATE.GAME: + %World.process_mode = Node.PROCESS_MODE_INHERIT + activate_ui_panel(%GameUI) + else: + %GameMenuUI.hide() + %World.process_mode = Node.PROCESS_MODE_DISABLED + activate_ui_panel(%MainMenuUI) + + _root_ui_state = state func _on_start_game_button_pressed(): - activate_ui_panel(%GameUI) + set_root_ui_state(ROOT_UI_STATE.GAME) func _on_quit_button_pressed(): get_tree().quit() - func _on_new_game_button_pressed(): @@ -49,17 +57,7 @@ func _on_new_game_button_pressed(): func _to_main_menu_button_pressed(): - activate_ui_panel(%MainMenuUI) - - -func _unhandled_key_input(event:InputEvent): - if active_ui_panel != %GameUI: - return - - var key_event:InputEventKey = event as InputEventKey - - if key_event and key_event.pressed and key_event.get_keycode_with_modifiers() == KEY_ESCAPE: - activate_ui_panel(%GameMenuUI) + set_root_ui_state(ROOT_UI_STATE.MENU) func _unhandled_input(event): diff --git a/ui/game_menu_ui.gd b/ui/game_menu_ui.gd new file mode 100644 index 0000000..8839776 --- /dev/null +++ b/ui/game_menu_ui.gd @@ -0,0 +1,7 @@ +extends PanelContainer + +func _unhandled_key_input(event:InputEvent): + var key_event:InputEventKey = event as InputEventKey + if visible and key_event.pressed and key_event.get_keycode_with_modifiers() == KEY_ESCAPE: + get_viewport().set_input_as_handled() + hide()