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