|
|
@ -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) |
|
|
@ -18,9 +17,12 @@ 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 _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 |
|
|
|
|
|
|
|
|
|
|
@ -28,8 +30,9 @@ 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) |
|
|
|
toggle_save_icon_generation.connect(_on_toggle_save_icon_generation) |
|
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void: |
|
|
|
if event.is_action_pressed("quick_save"): |
|
|
@ -71,14 +74,17 @@ 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_icon |
|
|
|
_save_resource.save_icon_texture = _generate_save_icon_texture(save_game_data_path + _save_icon) |
|
|
|
|
|
|
|
save_files.append(_save_resource) |
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
@ -90,7 +96,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() |
|
|
|
|
|
|
@ -99,6 +104,22 @@ func quick_load_game() -> void: |
|
|
|
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 |
|
|
|
|
|
|
|
## 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") |
|
|
@ -110,6 +131,7 @@ func _load_save_level_data_component() -> bool: |
|
|
|
|
|
|
|
func _load_game_resource(resource_filename: String) -> void: |
|
|
|
if not _load_save_level_data_component(): return |
|
|
|
|
|
|
|
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) |
|
|
@ -120,6 +142,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: |
|
|
@ -138,6 +162,8 @@ func _save_game_as_resource(resource_filename: String) -> void: |
|
|
|
if result != OK: |
|
|
|
printerr("Failed to save game (" , result, "): ", 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: |
|
|
|
var nodes: Array = get_tree().get_nodes_in_group("save_data_component") |
|
|
@ -151,6 +177,19 @@ 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: |
|
|
|
if !_enable_save_icon_generation: return |
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
|
|
|
func _on_save_game_as_resource(save_name: String) -> void: |
|
|
|
if not _load_save_level_data_component(): return |
|
|
@ -169,3 +208,7 @@ 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 |