Browse Source

Moving saving/loading management into SaveGameManager

pull/15/head
Ryan Reed 1 month ago
parent
commit
57b81c3604
2 changed files with 111 additions and 90 deletions
  1. +105
    -10
      save_load/autoloads/save_game_manager.gd
  2. +6
    -80
      save_load/components/save_level_data_component.gd

+ 105
- 10
save_load/autoloads/save_game_manager.gd View File

@ -18,9 +18,18 @@ signal quick_save
signal quick_load
var _game_data_resource: SaveGameDataResource
var _save_level_data_component: SaveLevelDataComponent ## Contains the save paths and filenames
func _ready() -> void:
quick_load.connect(quick_load_game)
quick_save.connect(quick_load_game)
create_save_file.connect(_save_game_as_resource)
load_save_file.connect(_load_game_resource)
_load_save_level_data_component()
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("quick_save"):
@ -29,22 +38,108 @@ func _unhandled_input(event: InputEvent) -> void:
quick_load_game()
func list_saves() -> Array[SaveFileDetailsResource]:
var save_files: Array[SaveFileDetailsResource] = []
if not _load_save_level_data_component():
return save_files
var save_game_data_path: String = _save_level_data_component.save_game_data_path
if !DirAccess.dir_exists_absolute(save_game_data_path):
return save_files
for filename: String in ResourceLoader.list_directory(save_game_data_path):
if !filename.begins_with("save_"): continue
if !filename.ends_with(".tres"): continue # Screenshots, etc
var _save_path: String = save_game_data_path + filename
var _save_icon: String = filename.replace(".tres", ".png")
var _save_resource: SaveFileDetailsResource = SaveFileDetailsResource.new()
# TODO: Reconsider loading the save to get the name
# This could be a large save making opening each one slow
# Should work out a better method for getting the save name (filename != save name)
var _save_file: SaveGameDataResource = ResourceLoader.load(_save_path)
_save_resource.save_name = _save_file.save_name
_save_resource.filename = filename
_save_resource.date_created = Time.get_datetime_string_from_unix_time(FileAccess.get_modified_time(_save_path))
## In 4.5, this can probably be replaced with FileAccess.get_size(_save_path)
## This should reduce the need for opening the file here
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_files.append(_save_resource)
return save_files
func quick_save_game() -> void:
var save_level_data_component: SaveLevelDataComponent = get_tree().get_first_node_in_group("save_level_data_component")
if save_level_data_component == null:
push_error("Could not find SaveLevelDataComponent node in level")
return
if not _load_save_level_data_component(): return
save_level_data_component.quick_save_game()
_save_game_as_resource(_save_level_data_component.quicksave_file_name)
game_saved.emit()
func quick_load_game() -> void:
var save_level_data_component: SaveLevelDataComponent = get_tree().get_first_node_in_group("save_level_data_component")
if save_level_data_component == null:
push_error("Could not find SaveLevelDataComponent node in level")
return
if not _load_save_level_data_component(): return
# TODO: Don't reset world if quicksave not found
EntityManager.reset_world.emit()
save_level_data_component.quick_load_game()
_load_game_resource(_save_level_data_component.quicksave_file_name)
game_loaded.emit()
## 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")
if _save_level_data_component == null:
push_error("Could not find SaveLevelDataComponent node in level")
return false
return true
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.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)
return
_game_data_resource = ResourceLoader.load(save_game_file_path)
if _game_data_resource == null:
printerr("Failed to load save. Unknown format? ", save_game_file_path)
return
var root_node: Window = get_tree().root
for resource: Resource in _game_data_resource.save_data_nodes:
if resource is Node3DDataResource:
(resource as Node3DDataResource)._load_data(root_node)
func _save_game_as_resource(resource_filename: String) -> void:
if not _load_save_level_data_component(): return
if !DirAccess.dir_exists_absolute(_save_level_data_component.save_game_data_path):
DirAccess.make_dir_absolute(_save_level_data_component.save_game_data_path)
var save_game_file_path: String = _save_level_data_component.save_game_data_path + resource_filename
_save_node_data()
var result: int = ResourceSaver.save(_game_data_resource, save_game_file_path)
if result != OK:
printerr("Failed to save game: ", result)
## 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")
if nodes == null: return
_game_data_resource = SaveGameDataResource.new()
for node: Node in nodes:
if node is SaveDataComponent:
@warning_ignore("unsafe_method_access")
var save_data_resource: Node3DDataResource = node._save_data()
var save_final_resource: Node3DDataResource = save_data_resource.duplicate()
_game_data_resource.save_data_nodes.append(save_final_resource)

+ 6
- 80
save_load/components/save_level_data_component.gd View File

@ -27,94 +27,20 @@ func _ready() -> void:
SaveGameManager.create_auto_save_file.connect(_on_create_auto_save_file)
func list_saves() -> Array[SaveFileDetailsResource]: # TODO: Update hints
var save_files: Array[SaveFileDetailsResource] = []
if !DirAccess.dir_exists_absolute(save_game_data_path):
return save_files
for filename: String in ResourceLoader.list_directory(save_game_data_path):
if !filename.begins_with("save_"): continue
if !filename.ends_with(".tres"): continue # Screenshots, etc
var _save_path: String = save_game_data_path + filename
var _save_icon: String = filename.replace(".tres", ".png")
var _save_resource: SaveFileDetailsResource = SaveFileDetailsResource.new()
# TODO: Reconsider loading the save to get the name
# This could be a large save making opening each one slow
# Should work out a better method for getting the save name (filename != save name)
var _save_file: SaveGameDataResource = ResourceLoader.load(_save_path)
_save_resource.save_name = _save_file.save_name
_save_resource.filename = filename
_save_resource.date_created = Time.get_datetime_string_from_unix_time(FileAccess.get_modified_time(_save_path))
## In 4.5, this can probably be replaced with FileAccess.get_size(_save_path)
## This should reduce the need for opening the file here
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_files.append(_save_resource)
return save_files
func load_game() -> void:
_load_game_resource(save_file_name % level_scene_name)
SaveGameManager.load_save_file.emit(save_file_name % level_scene_name)
func quick_load_game() -> void:
_load_game_resource(quicksave_file_name)
SaveGameManager.quick_load.emit()
func quick_save_game() -> void:
_save_game_as_resource(quicksave_file_name)
SaveGameManager.quick_save.emit()
func save_game() -> void:
_save_game_as_resource(save_file_name % level_scene_name)
func save_node_data() -> void:
var nodes: Array = get_tree().get_nodes_in_group("save_data_component")
if nodes == null: return
game_data_resource = SaveGameDataResource.new()
for node: Node in nodes:
if node is SaveDataComponent:
@warning_ignore("unsafe_method_access")
var save_data_resource: Node3DDataResource = node._save_data()
var save_final_resource: Node3DDataResource = save_data_resource.duplicate()
game_data_resource.save_data_nodes.append(save_final_resource)
func _save_game_as_resource(resource_filename: String) -> void:
if !DirAccess.dir_exists_absolute(save_game_data_path):
DirAccess.make_dir_absolute(save_game_data_path)
var save_game_file_path: String = save_game_data_path + resource_filename
save_node_data()
var result: int = ResourceSaver.save(game_data_resource, save_game_file_path)
if result != OK:
printerr("Failed to save game: ", result)
func _load_game_resource(resource_filename: String) -> void:
var save_game_file_path: String = 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)
return
game_data_resource = ResourceLoader.load(save_game_file_path)
if game_data_resource == null:
printerr("Failed to load save. Unknown format? ", save_game_file_path)
return
var root_node: Window = get_tree().root
for resource: Resource in game_data_resource.save_data_nodes:
if resource is Node3DDataResource:
(resource as Node3DDataResource)._load_data(root_node)
SaveGameManager.create_save_file.emit(save_file_name % level_scene_name)
func _on_create_auto_save_file() -> void:
# TODO: Check max number of autosaves, increment existing autosaves, etc
_save_game_as_resource(autosave_file_name % "01")
#_save_game_as_resource(autosave_file_name % "01")
pass

Loading…
Cancel
Save