@tool class_name SaveGameHandle extends CenterContainer signal picked(save_game: SaveGame) var has_stage: bool = false: set(stage): has_stage = stage visible = stage save_buttons[0].grab_focus() @export var saves: Array[SaveGame] var save_buttons: Array[SaveGameDisplay] @export var update_display: bool: set(value): load_games() var scroll_container: ScrollContainer var override_save_slot: bool = false func _validate_property(property: Dictionary) -> void: if property.name == "saves": property.usage = PROPERTY_USAGE_READ_ONLY + PROPERTY_USAGE_SCRIPT_VARIABLE + PROPERTY_USAGE_EDITOR func _ready() -> void: var dir = DirAccess.open(State.user_saves_path) if DirAccess.get_open_error() != OK: printerr("Error while opening User Save Directory: %s" % error_string(DirAccess.get_open_error())) # Invalid Error being raised when Directory does not exist. if DirAccess.get_open_error() == ERR_INVALID_PARAMETER: dir = DirAccess.open("user://") dir.make_dir_recursive(State.user_saves_path) load_games() for i in range(save_buttons.size()): save_buttons[i].pressed.connect(func(): picked.emit(saves[i])) func load_games(): saves = [] var save_game_dir := DirAccess.open(State.user_saves_path) var filepaths: PackedStringArray = save_game_dir.get_files() for path in filepaths: if path.ends_with(".json"): saves.append(SaveGame.new("%s/%s" % [State.user_saves_path, path.get_basename()])) saves.append(SaveGame.new()) #purging the current state save_buttons = [] if scroll_container != null: scroll_container.queue_free() scroll_container = ScrollContainer.new() scroll_container.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED scroll_container.custom_minimum_size = Vector2(0, ProjectSettings.get_setting("display/window/size/viewport_height") - 256) add_child(scroll_container) var save_box := VBoxContainer.new() save_box.add_theme_constant_override("separation", 16) scroll_container.add_child(save_box) for i in range(saves.size()): var new_button := SaveGameDisplay.new(saves[i], i+1) save_box.add_child(new_button) save_buttons.append(new_button) new_button.pressed.connect(func(): _on_game_picked(i)) func _on_game_picked(id: int): if override_save_slot: if saves[id].current_room == 0: picked.emit(id) else: $Popup.show() else: picked.emit(id) # This function is called when the user us supposed to choose a slot to load or create a new game. func pick_save_slot(create_new_game: bool): if saves.size() == 1: picked.emit(saves[0]) else: State.take_stage(self) self.override_save_slot = create_new_game func get_most_recent_save() -> SaveGame: var most_recent_time := 0.0 var most_recent_index:int = 0 for i in range(saves.size()): if saves[i].last_saved > most_recent_time and not saves[i].current_room == 0: most_recent_index = i most_recent_time = saves[i].last_saved return saves[most_recent_index] if most_recent_time > 0 else SaveGame.new() func has_existing_saves() -> bool: return saves.size() > 1 func _input(event: InputEvent) -> void: if event.is_action_pressed("ui_cancel"): State.leave_stage(self)