From d841c15fba8ac733b5af7dae836a5142b96b1498 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Wed, 26 Mar 2025 17:16:39 -0400 Subject: [PATCH 01/15] Add icon creation --- save_load/autoloads/save_game_manager.gd | 14 +++++++++++++- save_load/ui/save_file.gd | 11 ++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/save_load/autoloads/save_game_manager.gd b/save_load/autoloads/save_game_manager.gd index 2558117..ac5758f 100644 --- a/save_load/autoloads/save_game_manager.gd +++ b/save_load/autoloads/save_game_manager.gd @@ -72,7 +72,7 @@ func list_saves(include_quick_saves: bool = true, include_auto_saves: bool = tru _save_resource.filesize = _loaded_file.get_length() if FileAccess.file_exists(save_game_data_path + _save_icon): - _save_resource.save_icon = _save_icon + _save_resource.save_icon = save_game_data_path + _save_icon save_files.append(_save_resource) @@ -95,10 +95,20 @@ func quick_load_game() -> void: game_loaded.emit() + ## Sort the save files list by date created, descending func _custom_save_file_sort(a: SaveFileDetailsResource, b: SaveFileDetailsResource) -> bool: return a.date_created > b.date_created +## Generates an icon by taking a screenshot[br] +## The icon utilizes the same filename as the save file, replacing `.tres` with `.png` +func _generate_save_icon(save_game_file_path: String) -> void: + # TODO: Hide the UI before taking the screenshot + var _icon_filepath: String = save_game_file_path.replace(".tres", ".png") + + var _icon: Image = get_viewport().get_texture().get_image() + _icon.save_png(_icon_filepath) + ## Find the SaveLevelDataComponent within the level which stores the save paths and filenames func _load_save_level_data_component() -> bool: _save_level_data_component = get_tree().get_first_node_in_group("save_level_data_component") @@ -138,6 +148,8 @@ func _save_game_as_resource(resource_filename: String) -> void: if result != OK: printerr("Failed to save game (" , result, "): ", save_game_file_path) + _generate_save_icon(save_game_file_path) + ## Save the properties defined on the SaveDataComponents attached to various nodes (such as Block) func _save_node_data() -> void: var nodes: Array = get_tree().get_nodes_in_group("save_data_component") diff --git a/save_load/ui/save_file.gd b/save_load/ui/save_file.gd index 1c82756..6954b52 100644 --- a/save_load/ui/save_file.gd +++ b/save_load/ui/save_file.gd @@ -39,7 +39,16 @@ func set_save_date() -> void: save_date_label.text = save_file_details.date_created func set_save_icon() -> void: - save_icon.texture = load(save_file_details.save_icon) + if !FileAccess.file_exists(save_file_details.save_icon): + return + + var _icon_image: Image = Image.new() + _icon_image.load(save_file_details.save_icon) + + var _icon_texture: ImageTexture = ImageTexture.new() + _icon_texture.set_image(_icon_image) + + save_icon.texture = _icon_texture func set_save_name() -> void: save_name_label.text = save_file_details.save_name From 14990c4305e1635efe217e917e3e8b93d5f1d1bb Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Wed, 26 Mar 2025 18:04:56 -0400 Subject: [PATCH 02/15] Updating how default icon is generated/displayed --- save_load/resources/default_save_icon.tres | 4 ++++ .../resources/save_file_details_resource.gd | 2 +- save_load/ui/save_file.gd | 18 +++++++++++------- save_load/ui/save_file.tscn | 5 +++-- 4 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 save_load/resources/default_save_icon.tres diff --git a/save_load/resources/default_save_icon.tres b/save_load/resources/default_save_icon.tres new file mode 100644 index 0000000..1921e8e --- /dev/null +++ b/save_load/resources/default_save_icon.tres @@ -0,0 +1,4 @@ +[gd_resource type="CompressedTexture2D" format=3 uid="uid://60ib8urc8xjo"] + +[resource] +load_path = "res://.godot/imported/icon.svg-56083ea2a1f1a4f1e49773bdc6d7826c.ctex" diff --git a/save_load/resources/save_file_details_resource.gd b/save_load/resources/save_file_details_resource.gd index dd90d45..fdabb86 100644 --- a/save_load/resources/save_file_details_resource.gd +++ b/save_load/resources/save_file_details_resource.gd @@ -8,4 +8,4 @@ extends Node @export var filename: String = "" @export var date_created: String = "" @export var filesize: int = 0 -@export var save_icon: String = "res://assets/icon.svg" +@export var save_icon: String diff --git a/save_load/ui/save_file.gd b/save_load/ui/save_file.gd index 6954b52..93a4aea 100644 --- a/save_load/ui/save_file.gd +++ b/save_load/ui/save_file.gd @@ -4,6 +4,7 @@ extends Panel @export var save_panel_highlight: StyleBoxFlat @export var save_panel_normal: StyleBoxFlat +@export var default_save_icon_resource: CompressedTexture2D @export_group("Node Exports") @export var save_name_label: Label @@ -39,14 +40,17 @@ func set_save_date() -> void: save_date_label.text = save_file_details.date_created func set_save_icon() -> void: - if !FileAccess.file_exists(save_file_details.save_icon): + var _icon_texture: Texture2D = ImageTexture.new() + if save_file_details.save_icon != null and !FileAccess.file_exists(save_file_details.save_icon): return - - var _icon_image: Image = Image.new() - _icon_image.load(save_file_details.save_icon) - - var _icon_texture: ImageTexture = ImageTexture.new() - _icon_texture.set_image(_icon_image) + elif save_file_details.save_icon == null: + _icon_texture = default_save_icon_resource + else: + var _icon_image: Image = Image.new() + _icon_image.load(save_file_details.save_icon) + + @warning_ignore("unsafe_method_access") + _icon_texture.set_image(_icon_image) save_icon.texture = _icon_texture diff --git a/save_load/ui/save_file.tscn b/save_load/ui/save_file.tscn index 9be91ae..51c6e83 100644 --- a/save_load/ui/save_file.tscn +++ b/save_load/ui/save_file.tscn @@ -1,6 +1,5 @@ [gd_scene load_steps=11 format=3 uid="uid://bb7poutsn4ex2"] -[ext_resource type="Texture2D" uid="uid://dknv7amroftm8" path="res://assets/icon.svg" id="1_714lu"] [ext_resource type="StyleBox" uid="uid://biousyggn7iua" path="res://save_load/resources/save_file_panel_theme.tres" id="1_cqw77"] [ext_resource type="Texture2D" uid="uid://cmq51cgasug81" path="res://save_load/assets/folder-open-normal.png" id="1_k6haa"] [ext_resource type="Script" uid="uid://dcfdyua5gwpw4" path="res://save_load/ui/save_file.gd" id="2_5g2eu"] @@ -8,6 +7,7 @@ [ext_resource type="StyleBox" uid="uid://bwm315lqbbb87" path="res://save_load/resources/save_file_highlight_panel_theme.tres" id="3_om23c"] [ext_resource type="Texture2D" uid="uid://by4w5ll3le7g6" path="res://save_load/assets/folder-open-hover.png" id="3_ubfnn"] [ext_resource type="Texture2D" uid="uid://dvp5yeoqw36yt" path="res://save_load/assets/trash-normal.png" id="4_c2bnc"] +[ext_resource type="Texture2D" uid="uid://60ib8urc8xjo" path="res://save_load/resources/default_save_icon.tres" id="4_jgxci"] [ext_resource type="Texture2D" uid="uid://brwa8yljyrlgy" path="res://save_load/assets/trash-pressed.png" id="5_jgxci"] [ext_resource type="Texture2D" uid="uid://cmrtuy0i5qc01" path="res://save_load/assets/trash-hover.png" id="6_cqw77"] @@ -19,6 +19,7 @@ theme_override_styles/panel = ExtResource("1_cqw77") script = ExtResource("2_5g2eu") save_panel_highlight = ExtResource("3_om23c") save_panel_normal = ExtResource("1_cqw77") +default_save_icon_resource = ExtResource("4_jgxci") save_name_label = NodePath("HBoxContainer/NameDate/SaveName") save_date_label = NodePath("HBoxContainer/NameDate/SaveDate") save_icon = NodePath("HBoxContainer/SaveFileIcon") @@ -46,7 +47,7 @@ size_flags_horizontal = 0 [node name="SaveFileIcon" type="TextureRect" parent="HBoxContainer"] layout_mode = 2 -texture = ExtResource("1_714lu") +texture = ExtResource("4_jgxci") expand_mode = 3 [node name="NameDate" type="VBoxContainer" parent="HBoxContainer"] From 5b4cf461f461c9e93bc003e9340de2c1a3b95cdb Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Wed, 26 Mar 2025 18:15:36 -0400 Subject: [PATCH 03/15] Removing save icon when deleting save --- save_load/autoloads/save_game_manager.gd | 1 + 1 file changed, 1 insertion(+) diff --git a/save_load/autoloads/save_game_manager.gd b/save_load/autoloads/save_game_manager.gd index ac5758f..43aaa2a 100644 --- a/save_load/autoloads/save_game_manager.gd +++ b/save_load/autoloads/save_game_manager.gd @@ -181,3 +181,4 @@ func _on_delete_save_file(filename: String) -> void: var save_file_path: String = _save_level_data_component.settings.save_game_data_path + filename DirAccess.remove_absolute(save_file_path) + DirAccess.remove_absolute(save_file_path.replace(".tres", ".png")) # Delete icon From f618e0c702f25cc8af7ef4536425126e3d563bfa Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Wed, 26 Mar 2025 18:19:21 -0400 Subject: [PATCH 04/15] Checking string instead of null --- save_load/ui/save_file.gd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/save_load/ui/save_file.gd b/save_load/ui/save_file.gd index 93a4aea..823aa94 100644 --- a/save_load/ui/save_file.gd +++ b/save_load/ui/save_file.gd @@ -41,9 +41,9 @@ func set_save_date() -> void: func set_save_icon() -> void: var _icon_texture: Texture2D = ImageTexture.new() - if save_file_details.save_icon != null and !FileAccess.file_exists(save_file_details.save_icon): + if save_file_details.save_icon != "" and !FileAccess.file_exists(save_file_details.save_icon): return - elif save_file_details.save_icon == null: + elif save_file_details.save_icon == "": _icon_texture = default_save_icon_resource else: var _icon_image: Image = Image.new() From 59f834677482d829526d518a0437664394b88e4d Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Wed, 26 Mar 2025 18:57:13 -0400 Subject: [PATCH 05/15] Adding a (hacky) method for generating the save icon and hiding the UI --- save_load/components/save_level_data_component.gd | 2 ++ save_load/ui/save_load_ui.gd | 6 ++++++ scenes/root.tscn | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/save_load/components/save_level_data_component.gd b/save_load/components/save_level_data_component.gd index 10ccc4b..f4f8e78 100644 --- a/save_load/components/save_level_data_component.gd +++ b/save_load/components/save_level_data_component.gd @@ -3,7 +3,9 @@ class_name SaveLevelDataComponent extends Node + @export var settings: SaveGameSettings ## The SaveGameSettings resource +@export var ui_node: CanvasLayer ## The UI to Show/Hide when taking screenshot (e.g. save icon generation) func _ready() -> void: diff --git a/save_load/ui/save_load_ui.gd b/save_load/ui/save_load_ui.gd index 11744cd..f0c3fde 100644 --- a/save_load/ui/save_load_ui.gd +++ b/save_load/ui/save_load_ui.gd @@ -22,8 +22,14 @@ func _on_create_save_button_pressed() -> void: if save_name.strip_edges() == "": save_name = Time.get_datetime_string_from_system().replace(":", "") + var _save_level_data_component: SaveLevelDataComponent = get_tree().get_first_node_in_group("save_level_data_component") + if _save_level_data_component.ui_node != null: + _save_level_data_component.ui_node.visible = false + await get_tree().create_timer(.150).timeout # A hack to delay to allow UI to hide before taking screenshot SaveGameManager.create_save_file.emit(save_name) SaveGameManager.refresh_saves_list.emit() + if _save_level_data_component.ui_node != null: + _save_level_data_component.ui_node.visible = true new_save_ui.hide() SignalManager.resume_game.emit() diff --git a/scenes/root.tscn b/scenes/root.tscn index c2deef4..2d37ade 100644 --- a/scenes/root.tscn +++ b/scenes/root.tscn @@ -9,4 +9,9 @@ script = ExtResource("1_lrqlo") [node name="World" parent="." instance=ExtResource("2_vvh5c")] +[node name="SaveLevelDataComponent" parent="World" index="3" node_paths=PackedStringArray("ui_node")] +ui_node = NodePath("../../UI") + [node name="UI" parent="." instance=ExtResource("3_vvh5c")] + +[editable path="World"] From 71a8b5eed2c1714b13c286e4c844b3f80b27563c Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Wed, 26 Mar 2025 19:06:33 -0400 Subject: [PATCH 06/15] Refreshing the list of saves when opening the save list from the pause menu --- save_load/ui/save_files_list.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/save_load/ui/save_files_list.gd b/save_load/ui/save_files_list.gd index d3f36de..283b109 100644 --- a/save_load/ui/save_files_list.gd +++ b/save_load/ui/save_files_list.gd @@ -5,8 +5,8 @@ extends VBoxContainer func _ready() -> void: + SaveGameManager.open_save_list_ui.connect(_on_refresh_saves_list) SaveGameManager.refresh_saves_list.connect(_on_refresh_saves_list) - refresh_saves_list() ## Clear the SaveFilesList node of all saves and load most recent saves From 15a8a57edaf9ec9bba8f986d9b6d968d4005eba7 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Wed, 26 Mar 2025 19:12:58 -0400 Subject: [PATCH 07/15] Removing need for refresh_saves_list signal --- save_load/autoloads/save_game_manager.gd | 1 - save_load/ui/save_files_list.gd | 5 ++--- save_load/ui/save_load_ui.gd | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/save_load/autoloads/save_game_manager.gd b/save_load/autoloads/save_game_manager.gd index 43aaa2a..abb06b1 100644 --- a/save_load/autoloads/save_game_manager.gd +++ b/save_load/autoloads/save_game_manager.gd @@ -9,7 +9,6 @@ extends Node signal game_saved signal game_loaded -signal refresh_saves_list signal create_auto_save_file signal create_save_file(save_name: String) signal delete_save_file(filename: String) diff --git a/save_load/ui/save_files_list.gd b/save_load/ui/save_files_list.gd index 283b109..b586bab 100644 --- a/save_load/ui/save_files_list.gd +++ b/save_load/ui/save_files_list.gd @@ -5,8 +5,7 @@ extends VBoxContainer func _ready() -> void: - SaveGameManager.open_save_list_ui.connect(_on_refresh_saves_list) - SaveGameManager.refresh_saves_list.connect(_on_refresh_saves_list) + SaveGameManager.open_save_list_ui.connect(_on_open_save_list_ui) ## Clear the SaveFilesList node of all saves and load most recent saves @@ -25,5 +24,5 @@ func _clear_save_files_list() -> void: for _panel: SaveFilePanel in get_children(): _panel.queue_free() -func _on_refresh_saves_list() -> void: +func _on_open_save_list_ui() -> void: refresh_saves_list() diff --git a/save_load/ui/save_load_ui.gd b/save_load/ui/save_load_ui.gd index f0c3fde..1266163 100644 --- a/save_load/ui/save_load_ui.gd +++ b/save_load/ui/save_load_ui.gd @@ -27,7 +27,6 @@ func _on_create_save_button_pressed() -> void: _save_level_data_component.ui_node.visible = false await get_tree().create_timer(.150).timeout # A hack to delay to allow UI to hide before taking screenshot SaveGameManager.create_save_file.emit(save_name) - SaveGameManager.refresh_saves_list.emit() if _save_level_data_component.ui_node != null: _save_level_data_component.ui_node.visible = true new_save_ui.hide() From 8ea3b727f3bb71e6e8275ff3ebba7e3ef04ac181 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Wed, 26 Mar 2025 19:27:05 -0400 Subject: [PATCH 08/15] Moving icon texture into SaveGameManager --- save_load/autoloads/save_game_manager.gd | 20 ++++++++++++++++--- .../components/save_level_data_component.gd | 1 + .../components/save_level_data_component.tscn | 4 +++- .../resources/save_file_details_resource.gd | 2 +- save_load/ui/save_file.gd | 15 +------------- save_load/ui/save_file.tscn | 1 - 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/save_load/autoloads/save_game_manager.gd b/save_load/autoloads/save_game_manager.gd index abb06b1..ac5b7e5 100644 --- a/save_load/autoloads/save_game_manager.gd +++ b/save_load/autoloads/save_game_manager.gd @@ -70,8 +70,7 @@ func list_saves(include_quick_saves: bool = true, include_auto_saves: bool = tru var _loaded_file: FileAccess = FileAccess.open(_save_path, FileAccess.READ) _save_resource.filesize = _loaded_file.get_length() - if FileAccess.file_exists(save_game_data_path + _save_icon): - _save_resource.save_icon = save_game_data_path + _save_icon + _save_resource.save_icon_texture = _generate_save_icon_texture(save_game_data_path + _save_icon) save_files.append(_save_resource) @@ -94,11 +93,26 @@ func quick_load_game() -> void: game_loaded.emit() - ## Sort the save files list by date created, descending func _custom_save_file_sort(a: SaveFileDetailsResource, b: SaveFileDetailsResource) -> bool: return a.date_created > b.date_created +## Generate the texture for use in the save file listing +func _generate_save_icon_texture(save_icon: String) -> Texture2D: + var _icon_texture: Texture2D = ImageTexture.new() + if save_icon != null and !FileAccess.file_exists(save_icon): + _icon_texture = _save_level_data_component.default_save_icon_resource + elif save_icon == null: + _icon_texture = _save_level_data_component.default_save_icon_resource + else: + var _icon_image: Image = Image.new() + _icon_image.load(save_icon) + + @warning_ignore("unsafe_method_access") + _icon_texture.set_image(_icon_image) + + return _icon_texture + ## Generates an icon by taking a screenshot[br] ## The icon utilizes the same filename as the save file, replacing `.tres` with `.png` func _generate_save_icon(save_game_file_path: String) -> void: diff --git a/save_load/components/save_level_data_component.gd b/save_load/components/save_level_data_component.gd index f4f8e78..d5fbc1b 100644 --- a/save_load/components/save_level_data_component.gd +++ b/save_load/components/save_level_data_component.gd @@ -4,6 +4,7 @@ class_name SaveLevelDataComponent extends Node +@export var default_save_icon_resource: CompressedTexture2D @export var settings: SaveGameSettings ## The SaveGameSettings resource @export var ui_node: CanvasLayer ## The UI to Show/Hide when taking screenshot (e.g. save icon generation) diff --git a/save_load/components/save_level_data_component.tscn b/save_load/components/save_level_data_component.tscn index 570dc3a..32421fe 100644 --- a/save_load/components/save_level_data_component.tscn +++ b/save_load/components/save_level_data_component.tscn @@ -1,8 +1,10 @@ -[gd_scene load_steps=3 format=3 uid="uid://c3pqilb6yh5kc"] +[gd_scene load_steps=4 format=3 uid="uid://c3pqilb6yh5kc"] [ext_resource type="Script" uid="uid://c7x2qvyu62230" path="res://save_load/components/save_level_data_component.gd" id="1_exguq"] +[ext_resource type="Texture2D" uid="uid://60ib8urc8xjo" path="res://save_load/resources/default_save_icon.tres" id="2_hd7aa"] [ext_resource type="Resource" uid="uid://o32fooj1lxg7" path="res://save_load/resources/save_game_settings_resource.tres" id="2_rkr1f"] [node name="SaveLevelDataComponent" type="Node"] script = ExtResource("1_exguq") +default_save_icon_resource = ExtResource("2_hd7aa") settings = ExtResource("2_rkr1f") diff --git a/save_load/resources/save_file_details_resource.gd b/save_load/resources/save_file_details_resource.gd index fdabb86..882ebd9 100644 --- a/save_load/resources/save_file_details_resource.gd +++ b/save_load/resources/save_file_details_resource.gd @@ -8,4 +8,4 @@ extends Node @export var filename: String = "" @export var date_created: String = "" @export var filesize: int = 0 -@export var save_icon: String +@export var save_icon_texture: Texture2D diff --git a/save_load/ui/save_file.gd b/save_load/ui/save_file.gd index 823aa94..386be40 100644 --- a/save_load/ui/save_file.gd +++ b/save_load/ui/save_file.gd @@ -4,7 +4,6 @@ extends Panel @export var save_panel_highlight: StyleBoxFlat @export var save_panel_normal: StyleBoxFlat -@export var default_save_icon_resource: CompressedTexture2D @export_group("Node Exports") @export var save_name_label: Label @@ -40,19 +39,7 @@ func set_save_date() -> void: save_date_label.text = save_file_details.date_created func set_save_icon() -> void: - var _icon_texture: Texture2D = ImageTexture.new() - if save_file_details.save_icon != "" and !FileAccess.file_exists(save_file_details.save_icon): - return - elif save_file_details.save_icon == "": - _icon_texture = default_save_icon_resource - else: - var _icon_image: Image = Image.new() - _icon_image.load(save_file_details.save_icon) - - @warning_ignore("unsafe_method_access") - _icon_texture.set_image(_icon_image) - - save_icon.texture = _icon_texture + save_icon.texture = save_file_details.save_icon_texture func set_save_name() -> void: save_name_label.text = save_file_details.save_name diff --git a/save_load/ui/save_file.tscn b/save_load/ui/save_file.tscn index 51c6e83..274c12a 100644 --- a/save_load/ui/save_file.tscn +++ b/save_load/ui/save_file.tscn @@ -19,7 +19,6 @@ theme_override_styles/panel = ExtResource("1_cqw77") script = ExtResource("2_5g2eu") save_panel_highlight = ExtResource("3_om23c") save_panel_normal = ExtResource("1_cqw77") -default_save_icon_resource = ExtResource("4_jgxci") save_name_label = NodePath("HBoxContainer/NameDate/SaveName") save_date_label = NodePath("HBoxContainer/NameDate/SaveDate") save_icon = NodePath("HBoxContainer/SaveFileIcon") From 260e168179c0f7b2f4bdbfcdab4ebf1be72d16e4 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Wed, 26 Mar 2025 19:29:17 -0400 Subject: [PATCH 09/15] Comment update --- save_load/ui/save_load_ui.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/save_load/ui/save_load_ui.gd b/save_load/ui/save_load_ui.gd index 1266163..0ce2936 100644 --- a/save_load/ui/save_load_ui.gd +++ b/save_load/ui/save_load_ui.gd @@ -25,7 +25,7 @@ func _on_create_save_button_pressed() -> void: var _save_level_data_component: SaveLevelDataComponent = get_tree().get_first_node_in_group("save_level_data_component") if _save_level_data_component.ui_node != null: _save_level_data_component.ui_node.visible = false - await get_tree().create_timer(.150).timeout # A hack to delay to allow UI to hide before taking screenshot + await get_tree().create_timer(.150).timeout # A hack to allow time for UI to hide before taking screenshot SaveGameManager.create_save_file.emit(save_name) if _save_level_data_component.ui_node != null: _save_level_data_component.ui_node.visible = true From 8d42e81c6164550d6c3e88153d6958722cdaa50c Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Wed, 26 Mar 2025 19:47:37 -0400 Subject: [PATCH 10/15] Correcting resetting world and hiding UI on game load --- save_load/autoloads/save_game_manager.gd | 12 ++++++++++-- scenes/ui/ui.gd | 4 ++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/save_load/autoloads/save_game_manager.gd b/save_load/autoloads/save_game_manager.gd index ac5b7e5..7ea9c41 100644 --- a/save_load/autoloads/save_game_manager.gd +++ b/save_load/autoloads/save_game_manager.gd @@ -27,7 +27,7 @@ func _ready() -> void: quick_load.connect(quick_load_game) quick_save.connect(quick_load_game) create_save_file.connect(_on_save_game_as_resource) - load_save_file.connect(_load_game_resource) + load_save_file.connect(load_game_save) delete_save_file.connect(_on_delete_save_file) func _unhandled_input(event: InputEvent) -> void: @@ -77,6 +77,10 @@ func list_saves(include_quick_saves: bool = true, include_auto_saves: bool = tru save_files.sort_custom(_custom_save_file_sort) return save_files +func load_game_save(resource_filename: String) -> void: + _load_game_resource(resource_filename) + game_loaded.emit() + func quick_save_game() -> void: if not _load_save_level_data_component(): return @@ -88,7 +92,6 @@ func quick_load_game() -> void: if not _load_save_level_data_component(): return # TODO: Don't reset world if quicksave not found - EntityManager.reset_world.emit() _load_game_resource(_save_level_data_component.settings.quicksave_file_name) game_loaded.emit() @@ -133,6 +136,9 @@ func _load_save_level_data_component() -> bool: func _load_game_resource(resource_filename: String) -> void: if not _load_save_level_data_component(): return + + EntityManager.reset_world.emit() + var save_game_file_path: String = _save_level_data_component.settings.save_game_data_path + resource_filename if !FileAccess.file_exists(save_game_file_path): printerr("Failed to load save. File does not exist: ", save_game_file_path) @@ -148,6 +154,8 @@ func _load_game_resource(resource_filename: String) -> void: if resource is Node3DDataResource: (resource as Node3DDataResource)._load_data(root_node) + game_loaded.emit() + func _save_game_as_resource(resource_filename: String) -> void: if not _load_save_level_data_component(): return diff --git a/scenes/ui/ui.gd b/scenes/ui/ui.gd index ea9b1db..11fbecc 100644 --- a/scenes/ui/ui.gd +++ b/scenes/ui/ui.gd @@ -18,6 +18,7 @@ func _ready() -> void: SignalManager.resume_game.connect(_on_resume_game) SaveGameManager.close_save_list_ui.connect(_on_close_save_list_ui) SaveGameManager.open_save_list_ui.connect(_on_open_save_list_ui) + SaveGameManager.game_loaded.connect(_on_game_loaded) _on_resume_game() @@ -42,6 +43,9 @@ func _on_close_save_list_ui() -> void: func _on_close_settings_menu() -> void: SignalManager.resume_game.emit() +func _on_game_loaded() -> void: + _on_resume_game() + func _on_open_pause_menu() -> void: Input.mouse_mode = Input.MOUSE_MODE_VISIBLE From 257002dc90f70f4ac0e8de264cade92b08127e91 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Wed, 26 Mar 2025 20:02:32 -0400 Subject: [PATCH 11/15] Renaming function for clarity --- save_load/autoloads/save_game_manager.gd | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/save_load/autoloads/save_game_manager.gd b/save_load/autoloads/save_game_manager.gd index 7ea9c41..e97bf1a 100644 --- a/save_load/autoloads/save_game_manager.gd +++ b/save_load/autoloads/save_game_manager.gd @@ -116,15 +116,6 @@ func _generate_save_icon_texture(save_icon: String) -> Texture2D: return _icon_texture -## Generates an icon by taking a screenshot[br] -## The icon utilizes the same filename as the save file, replacing `.tres` with `.png` -func _generate_save_icon(save_game_file_path: String) -> void: - # TODO: Hide the UI before taking the screenshot - var _icon_filepath: String = save_game_file_path.replace(".tres", ".png") - - var _icon: Image = get_viewport().get_texture().get_image() - _icon.save_png(_icon_filepath) - ## Find the SaveLevelDataComponent within the level which stores the save paths and filenames func _load_save_level_data_component() -> bool: _save_level_data_component = get_tree().get_first_node_in_group("save_level_data_component") @@ -169,7 +160,7 @@ func _save_game_as_resource(resource_filename: String) -> void: if result != OK: printerr("Failed to save game (" , result, "): ", save_game_file_path) - _generate_save_icon(save_game_file_path) + _take_save_screenshot(save_game_file_path) ## Save the properties defined on the SaveDataComponents attached to various nodes (such as Block) func _save_node_data() -> void: @@ -184,6 +175,15 @@ func _save_node_data() -> void: var save_final_resource: Node3DDataResource = save_data_resource.duplicate() _game_data_resource.save_data_nodes.append(save_final_resource) +## Takes a screenshot and saves next to the save file[br] +## The icon utilizes the same filename as the save file, replacing `.tres` with `.png` +func _take_save_screenshot(save_game_file_path: String) -> void: + # TODO: Hide the UI before taking the screenshot + var _icon_filepath: String = save_game_file_path.replace(".tres", ".png") + + var _icon: Image = get_viewport().get_texture().get_image() + _icon.save_png(_icon_filepath) + func _on_save_game_as_resource(save_name: String) -> void: if not _load_save_level_data_component(): return From 2df15febad507c41fa89c9fbfb9d6cb8577c7aad Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Wed, 26 Mar 2025 21:07:08 -0400 Subject: [PATCH 12/15] Removing duplicate signal emit() --- save_load/autoloads/save_game_manager.gd | 2 -- 1 file changed, 2 deletions(-) diff --git a/save_load/autoloads/save_game_manager.gd b/save_load/autoloads/save_game_manager.gd index e97bf1a..1e2b290 100644 --- a/save_load/autoloads/save_game_manager.gd +++ b/save_load/autoloads/save_game_manager.gd @@ -145,8 +145,6 @@ func _load_game_resource(resource_filename: String) -> void: if resource is Node3DDataResource: (resource as Node3DDataResource)._load_data(root_node) - game_loaded.emit() - func _save_game_as_resource(resource_filename: String) -> void: if not _load_save_level_data_component(): return From a8b30f2657c4f027d44e9a2a3a755f026a2742e1 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Thu, 27 Mar 2025 09:43:29 -0400 Subject: [PATCH 13/15] Allow defining the save icon size --- save_load/autoloads/save_game_manager.gd | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/save_load/autoloads/save_game_manager.gd b/save_load/autoloads/save_game_manager.gd index 1e2b290..96c64b8 100644 --- a/save_load/autoloads/save_game_manager.gd +++ b/save_load/autoloads/save_game_manager.gd @@ -20,6 +20,7 @@ signal close_save_list_ui var _game_data_resource: SaveGameDataResource = SaveGameDataResource.new() +var _save_icon_size: Vector2i = Vector2i(896, 504) ## If Vector2.ZERO, uses the user's resolution var _save_level_data_component: SaveLevelDataComponent ## Contains the save paths and filenames @@ -128,8 +129,6 @@ func _load_save_level_data_component() -> bool: func _load_game_resource(resource_filename: String) -> void: if not _load_save_level_data_component(): return - EntityManager.reset_world.emit() - var save_game_file_path: String = _save_level_data_component.settings.save_game_data_path + resource_filename if !FileAccess.file_exists(save_game_file_path): printerr("Failed to load save. File does not exist: ", save_game_file_path) @@ -140,6 +139,8 @@ func _load_game_resource(resource_filename: String) -> void: printerr("Failed to load save. Unknown format? ", save_game_file_path) return + EntityManager.reset_world.emit() + var root_node: Window = get_tree().root for resource: Resource in _game_data_resource.save_data_nodes: if resource is Node3DDataResource: @@ -180,6 +181,9 @@ func _take_save_screenshot(save_game_file_path: String) -> void: var _icon_filepath: String = save_game_file_path.replace(".tres", ".png") var _icon: Image = get_viewport().get_texture().get_image() + if _save_icon_size != Vector2i.ZERO: + _icon.resize(_save_icon_size.x, _save_icon_size.y) + _icon.save_png(_icon_filepath) From f47367dfdf295ddfc6e7e620214d5c3ba36310d8 Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Thu, 27 Mar 2025 09:58:45 -0400 Subject: [PATCH 14/15] Adding setting for disabling/enabling save screenshots --- autoloads/game_settings_manager.gd | 6 ++++++ .../game_options_settings_resource.gd | 1 + save_load/autoloads/save_game_manager.gd | 13 ++++++++++++- scenes/ui/menus/settings_menu.gd | 6 ++++++ scenes/ui/menus/settings_menu.tscn | 19 ++++++++++++++++++- 5 files changed, 43 insertions(+), 2 deletions(-) diff --git a/autoloads/game_settings_manager.gd b/autoloads/game_settings_manager.gd index c17bc8f..cdf377f 100644 --- a/autoloads/game_settings_manager.gd +++ b/autoloads/game_settings_manager.gd @@ -5,6 +5,7 @@ extends Node signal game_options_block_highlight_changed(block_highlight_enabled: bool) signal game_options_held_block_ui_changed(held_block_enabled: bool) signal game_options_quickslots_ui_changed(quickslots_enabled: bool) +signal game_options_screenshot_saves_changed(screenshots_enabled: bool) signal game_options_waila_changed(waila_enabled: bool) #endregion @@ -36,6 +37,7 @@ func _init() -> void: game_options_block_highlight_changed.connect(_on_game_options_block_highlight_changed) game_options_held_block_ui_changed.connect(_on_game_options_held_block_ui_changed) game_options_quickslots_ui_changed.connect(_on_game_options_quickslots_ui_changed) + game_options_screenshot_saves_changed.connect(_on_game_options_screenshot_saves_changed) game_options_waila_changed.connect(_on_game_options_waila_changed) graphics_fov_changed.connect(_on_graphics_fov_changed) @@ -61,6 +63,10 @@ func _on_game_options_quickslots_ui_changed(quickslots_enabled: bool) -> void: settings.game_options.enable_quickslots_ui = quickslots_enabled save_settings() +func _on_game_options_screenshot_saves_changed(screenshots_enabled: bool) -> void: + settings.game_options.enable_save_screenshots = screenshots_enabled + save_settings() + func _on_game_options_waila_changed(waila_enabled: bool) -> void: settings.game_options.enable_waila = waila_enabled save_settings() diff --git a/resources/game_settings/game_options_settings_resource.gd b/resources/game_settings/game_options_settings_resource.gd index bd78936..7c9a5c6 100644 --- a/resources/game_settings/game_options_settings_resource.gd +++ b/resources/game_settings/game_options_settings_resource.gd @@ -6,3 +6,4 @@ extends Resource @export var enable_block_highlight: bool = true @export var enable_quickslots_ui: bool = true @export var enable_held_block: bool = true +@export var enable_save_screenshots: bool = true ## Take a screenshot during save to use as the save icon diff --git a/save_load/autoloads/save_game_manager.gd b/save_load/autoloads/save_game_manager.gd index 96c64b8..86d1274 100644 --- a/save_load/autoloads/save_game_manager.gd +++ b/save_load/autoloads/save_game_manager.gd @@ -17,12 +17,15 @@ signal quick_save signal quick_load signal open_save_list_ui signal close_save_list_ui +signal toggle_save_icon_generation(toggled: bool) ## Enable/Disable the generation of a screenshot during save for the save icon. var _game_data_resource: SaveGameDataResource = SaveGameDataResource.new() var _save_icon_size: Vector2i = Vector2i(896, 504) ## If Vector2.ZERO, uses the user's resolution var _save_level_data_component: SaveLevelDataComponent ## Contains the save paths and filenames +var _enable_save_icon_generation: bool = true + func _ready() -> void: quick_load.connect(quick_load_game) @@ -30,6 +33,7 @@ func _ready() -> void: create_save_file.connect(_on_save_game_as_resource) load_save_file.connect(load_game_save) delete_save_file.connect(_on_delete_save_file) + toggle_save_icon_generation.connect(_on_toggle_save_icon_generation) func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("quick_save"): @@ -177,10 +181,14 @@ func _save_node_data() -> void: ## Takes a screenshot and saves next to the save file[br] ## The icon utilizes the same filename as the save file, replacing `.tres` with `.png` func _take_save_screenshot(save_game_file_path: String) -> void: - # TODO: Hide the UI before taking the screenshot + if !_enable_save_icon_generation: return + var _icon_filepath: String = save_game_file_path.replace(".tres", ".png") + # TODO: Hide the UI before taking the screenshot var _icon: Image = get_viewport().get_texture().get_image() + # TODO: Show the UI after taking the screenshot + if _save_icon_size != Vector2i.ZERO: _icon.resize(_save_icon_size.x, _save_icon_size.y) @@ -205,3 +213,6 @@ func _on_delete_save_file(filename: String) -> void: var save_file_path: String = _save_level_data_component.settings.save_game_data_path + filename DirAccess.remove_absolute(save_file_path) DirAccess.remove_absolute(save_file_path.replace(".tres", ".png")) # Delete icon + +func _on_toggle_save_icon_generation(toggled: bool) -> void: + _enable_save_icon_generation = toggled diff --git a/scenes/ui/menus/settings_menu.gd b/scenes/ui/menus/settings_menu.gd index b192ce9..f1369ec 100644 --- a/scenes/ui/menus/settings_menu.gd +++ b/scenes/ui/menus/settings_menu.gd @@ -6,6 +6,7 @@ extends Panel @export var block_highlight_input: CheckButton @export var held_block_ui_input: CheckButton @export var quick_slots_ui_input: CheckButton +@export var screenshot_icon_input: CheckButton @export var waila_input: CheckButton @export_group("Graphics Settings Nodes") @@ -26,6 +27,7 @@ func apply_default_values() -> void: block_highlight_input.set_pressed_no_signal(GameSettingsManager.settings.game_options.enable_block_highlight) held_block_ui_input.set_pressed_no_signal(GameSettingsManager.settings.game_options.enable_held_block) quick_slots_ui_input.set_pressed_no_signal(GameSettingsManager.settings.game_options.enable_quickslots_ui) + screenshot_icon_input.set_pressed_no_signal(GameSettingsManager.settings.game_options.enable_save_screenshots) waila_input.set_pressed_no_signal(GameSettingsManager.settings.game_options.enable_waila) #endregion @@ -52,6 +54,10 @@ func _on_quickslots_ui_toggled(toggled_on: bool) -> void: func _on_enable_waila_toggled(toggled_on: bool) -> void: GameSettingsManager.game_options_waila_changed.emit(toggled_on) + +func _on_screenshot_icon_button_toggled(toggled_on: bool) -> void: + GameSettingsManager.game_options_screenshot_saves_changed.emit(toggled_on) + SaveGameManager.toggle_save_icon_generation.emit(toggled_on) #endregion #region Graphics Settings diff --git a/scenes/ui/menus/settings_menu.tscn b/scenes/ui/menus/settings_menu.tscn index 9a6250e..6db6aa4 100644 --- a/scenes/ui/menus/settings_menu.tscn +++ b/scenes/ui/menus/settings_menu.tscn @@ -14,7 +14,7 @@ corner_radius_top_right = 2 corner_radius_bottom_right = 2 corner_radius_bottom_left = 2 -[node name="SettingsMenu" type="Panel" node_paths=PackedStringArray("block_highlight_input", "held_block_ui_input", "quick_slots_ui_input", "waila_input", "resolution_input", "fullscreen_input", "vsync_input", "fov_slider", "fov_value_label")] +[node name="SettingsMenu" type="Panel" node_paths=PackedStringArray("block_highlight_input", "held_block_ui_input", "quick_slots_ui_input", "screenshot_icon_input", "waila_input", "resolution_input", "fullscreen_input", "vsync_input", "fov_slider", "fov_value_label")] process_mode = 3 anchors_preset = 15 anchor_right = 1.0 @@ -25,6 +25,7 @@ script = ExtResource("1_qwcqe") block_highlight_input = NodePath("Background/MarginContainer/VBoxContainer/TabContainer/Game/BlockHighlight/CheckButton") held_block_ui_input = NodePath("Background/MarginContainer/VBoxContainer/TabContainer/Game/HeldBlockUI/CheckButton") quick_slots_ui_input = NodePath("Background/MarginContainer/VBoxContainer/TabContainer/Game/QuickslotsUI/CheckButton") +screenshot_icon_input = NodePath("Background/MarginContainer/VBoxContainer/TabContainer/Game/ScreenshotIcon/CheckButton") waila_input = NodePath("Background/MarginContainer/VBoxContainer/TabContainer/Game/Waila/CheckButton") resolution_input = NodePath("Background/MarginContainer/VBoxContainer/TabContainer/Graphics/Resolution/OptionButton") fullscreen_input = NodePath("Background/MarginContainer/VBoxContainer/TabContainer/Graphics/Fullscreen/CheckBox") @@ -126,6 +127,21 @@ text = "Enable Player Held Block" layout_mode = 2 button_pressed = true +[node name="ScreenshotIcon" type="HBoxContainer" parent="Background/MarginContainer/VBoxContainer/TabContainer/Game"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Background/MarginContainer/VBoxContainer/TabContainer/Game/ScreenshotIcon"] +layout_mode = 2 +size_flags_horizontal = 3 +tooltip_text = "Enable/Disable the taking of a screenshot to utilize as the save icon." +mouse_filter = 1 +text = "Enable Save Screenshot" + +[node name="CheckButton" type="CheckButton" parent="Background/MarginContainer/VBoxContainer/TabContainer/Game/ScreenshotIcon"] +layout_mode = 2 +tooltip_text = "Enable/Disable the taking of a screenshot to utilize as the save icon." +button_pressed = true + [node name="Graphics" type="VBoxContainer" parent="Background/MarginContainer/VBoxContainer/TabContainer"] visible = false layout_mode = 2 @@ -244,6 +260,7 @@ text = "Close Settings" [connection signal="toggled" from="Background/MarginContainer/VBoxContainer/TabContainer/Game/Waila/CheckButton" to="." method="_on_enable_waila_toggled"] [connection signal="toggled" from="Background/MarginContainer/VBoxContainer/TabContainer/Game/QuickslotsUI/CheckButton" to="." method="_on_quickslots_ui_toggled"] [connection signal="toggled" from="Background/MarginContainer/VBoxContainer/TabContainer/Game/HeldBlockUI/CheckButton" to="." method="_on_held_block_ui_toggled"] +[connection signal="toggled" from="Background/MarginContainer/VBoxContainer/TabContainer/Game/ScreenshotIcon/CheckButton" to="." method="_on_screenshot_icon_button_toggled"] [connection signal="value_changed" from="Background/MarginContainer/VBoxContainer/TabContainer/Graphics/FOV/HSlider" to="." method="_on_fov_slider_changed"] [connection signal="pressed" from="Background/MarginContainer/VBoxContainer/TabContainer/Graphics/CenterContainer/ApplyButton" to="." method="_on_graphics_apply_button_pressed"] [connection signal="pressed" from="Background/BottomRow/CloseButton" to="." method="_on_close_button_pressed"] From 68afe1dce8e1cf5737c2043b419ecb610e89e70d Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Thu, 27 Mar 2025 10:07:45 -0400 Subject: [PATCH 15/15] Removing unnecessary comments --- save_load/autoloads/save_game_manager.gd | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/save_load/autoloads/save_game_manager.gd b/save_load/autoloads/save_game_manager.gd index 86d1274..d99053d 100644 --- a/save_load/autoloads/save_game_manager.gd +++ b/save_load/autoloads/save_game_manager.gd @@ -20,12 +20,11 @@ signal close_save_list_ui signal toggle_save_icon_generation(toggled: bool) ## Enable/Disable the generation of a screenshot during save for the save icon. +var _enable_save_icon_generation: bool = true var _game_data_resource: SaveGameDataResource = SaveGameDataResource.new() var _save_icon_size: Vector2i = Vector2i(896, 504) ## If Vector2.ZERO, uses the user's resolution var _save_level_data_component: SaveLevelDataComponent ## Contains the save paths and filenames -var _enable_save_icon_generation: bool = true - func _ready() -> void: quick_load.connect(quick_load_game) @@ -184,10 +183,7 @@ func _take_save_screenshot(save_game_file_path: String) -> void: if !_enable_save_icon_generation: return var _icon_filepath: String = save_game_file_path.replace(".tres", ".png") - - # TODO: Hide the UI before taking the screenshot var _icon: Image = get_viewport().get_texture().get_image() - # TODO: Show the UI after taking the screenshot if _save_icon_size != Vector2i.ZERO: _icon.resize(_save_icon_size.x, _save_icon_size.y)