Untitled
unknown
plain_text
9 months ago
5.1 kB
4
Indexable
Never
extends Node ## This is an autoload. It has a global name `SaveSystem`. const NUM_SAVEABLE_NPCS := 100 # Set this to true if you want to print debug info to console. static var _print_debug_info := false static var savedata := { # Overwritten on: "scene_path": "", # Save. "save_time": "", "npc_fed_status": false_array(NUM_SAVEABLE_NPCS), # Npc feed (NPC.gd). "pan_sens": FryingPan.PAN_SENS_DEFAULT, "mouse_sens": 1.0, # Settings close (Pause.gd). "gamepad_sens": 1.0, "master_vol": 1.0, "music_vol": 1.0, "sfx_vol": 1.0, "fullscreen_status": true } static func false_array(size: int) -> Array[bool]: var arr: Array[bool] = [] arr.resize(size) arr.fill(false) return arr # Externally set on NPC `_ready` for validation. ---------- static var readied_npcs: Array[int] = [] static var npc_loaded_at_least_once_status: Array[bool] = [] # --------------------------------------------------------- static var _has_entered_tree_before := false static var last_saveslot := 1 func _enter_tree() -> void: if _has_entered_tree_before: # TODO: Fix this. It's shit. return _has_entered_tree_before = true @warning_ignore("static_called_on_instance") npc_loaded_at_least_once_status = false_array(NUM_SAVEABLE_NPCS) func savedata_to_disk(saveslot: int) -> void: last_saveslot = saveslot var scene_name = get_tree().current_scene.name savedata["scene_path"] = ( LevelPaths.docks if scene_name == "Docks" else LevelPaths.dome if scene_name == "Dome" else LevelPaths.rooftops if scene_name == "Rooftops" else LevelPaths.closet if scene_name == "Closet" else LevelPaths.rooftops if scene_name == "Main" else "" ) assert(savedata["scene_path"].length() > 0) savedata["save_time"] = Time.get_datetime_string_from_system(true) var save_json := JSON.stringify(savedata, " ", false) var save_file := FileAccess.open("user://save_%d.arctic_eggs_save" %saveslot, FileAccess.WRITE) save_file.store_line(save_json) if _print_debug_info: print("---------------------------------------------") print("Saved:") print(save_json) print("---------------------------------------------") # An almost-pure function which returns the data from disk as JSON. # Notably, if the output is missing keys, they are added and their # values are set to defaults. func get_data_from_disk_as_JSON(saveslot: int) -> JSON: var save_file := FileAccess.open( "user://save_%d.arctic_eggs_save" %saveslot, FileAccess.READ ) var save_file_text : String if (save_file != null): save_file_text = save_file.get_as_text() else: print("`save_file_text` was null when getting from disk.") return null var json := JSON.new() var error := json.parse(save_file_text) if error != OK: print("Failed to parse data: ", json.get_error_message(), " in ", "user://save_%d.arctic_eggs_save" %saveslot, " at line ", json.get_error_line()) return null for savekey in savedata: if !json.data.has(savekey): if _print_debug_info: print("Loaded data was missing key `", savekey, "`. This likely means the save format was changed, or an empty save was peeked. Using default value.") match savekey: "scene_path": json.data[savekey] = "" "save_time": json.data[savekey] = "" "npc_fed_status": var default_false_array: Array[bool] = [] default_false_array.resize(NUM_SAVEABLE_NPCS) default_false_array.fill(false) json.data[savekey] = default_false_array "pan_sens": json.data[savekey] = FryingPan.PAN_SENS_DEFAULT "mouse_sens": json.data[savekey] = 1.0 "gamepad_sens": json.data[savekey] = 1.0 "master_vol": json.data[savekey] = 1.0 "music_vol": json.data[savekey] = 1.0 "sfx_vol": json.data[savekey] = 1.0 "fullscreen_status": json.data[savekey] = true _: print("Load data savekey validation is missing a case.") return json func does_save_exist_on_disk() -> bool: for n in 3: var json = get_data_from_disk_as_JSON(n) if json != null: return true return false # Updates last_saveslot and savedata. After calling, make sure to switch scenes. # Whenever a scene is switch to, _ready gets called in each of it's children. # So, savedata can be read from this global script in each needy child. # In short, loaded data gets "applied" on scene load from the bottom up. # Returns true if data on disk was valid (json exists, isn't empty). func load_from_disk_into_savedata(saveslot: int) -> bool: last_saveslot = saveslot var json := get_data_from_disk_as_JSON(saveslot) if (json == null): print("`json` obtained from disk was null.") return false if json.data.is_empty(): print("Data loaded from disk was empty.") return false if _print_debug_info: print("---------------------------------------------") print("savedata before load:") print(savedata) savedata = json.data if _print_debug_info: print("savedata after load:") print(savedata) print("---------------------------------------------") return true
Leave a Comment