CrossingOver/globals/file_globals.gd
2024-03-14 00:53:46 -03:00

149 lines
4.5 KiB
GDScript

extends Node
enum VNLoadSource {
NEW_GAME = 300,
FROM_MANUAL_SAVE = 301,
FROM_AUTOSAVE = 302,
}
enum VNSaveTarget {
MANUAL_SAVE = 401,
AUTOSAVE = 402,
}
const GLOBAL_DATA_PATH = "user://data.json"
const SAVES_DIR = "user://saves"
const MAX_SAVES = 24
signal loaded
signal updated_save_files(save_file_list)
signal new_manual_save(save_file)
signal new_autosave(save_file)
var has_loaded = false
var can_continue = false
var current_load_source: VNLoadSource = VNLoadSource.NEW_GAME
var current_load_path = ""
var current_load_file = null
var save_files = []
var global_data = null
var new_game_save_file = {}
func _ready():
DirAccess.make_dir_recursive_absolute(SAVES_DIR)
# Populate previously saved files
for file_name in DirAccess.get_files_at(SAVES_DIR):
if file_name.length() == 7 and file_name.right(5) == ".json":
can_continue = true
var path = "%s/%s" % [SAVES_DIR, file_name]
var file = FileAccess.open(path, FileAccess.READ)
var data = JSON.parse_string(file.get_as_text())
file.close()
save_files.append({
"idx": int(file_name.left(2)),
"path": path,
"timestamp": data["timestamp"],
"name": data["name"],
"is_autosave": data.get("is_autosave", false),
})
save_files.sort_custom(func (a, b): return Time.get_unix_time_from_datetime_string(a["timestamp"]) > Time.get_unix_time_from_datetime_string(b["timestamp"]))
has_loaded = true
loaded.emit()
func create_save_file(target: VNSaveTarget, data: Variant, save_name: String = "") -> String:
var timestamp = Time.get_datetime_string_from_system(false, true)
var idx = 1
var path = ""
var is_autosave = target == VNSaveTarget.AUTOSAVE
can_continue = true
if save_files.size() > 0:
idx = save_files[0]["idx"] % 99 + 1 # Avoid creating a 00.json file
path = "%s/%02d.json" % [SAVES_DIR, idx]
for i in range(save_files.size() - 1, -1, -1):
# Remove file if MAX_SAVES limit would be exceeded or if "idx" wraps around and overwrites this
if i >= MAX_SAVES - 1 or save_files[i]["idx"] == idx:
# Should be safe to remove, since we're resizing from the right
var save_to_delete = save_files.pop_at(i)
DirAccess.remove_absolute(save_to_delete["path"])
var file = FileAccess.open(path, FileAccess.WRITE)
file.store_string(JSON.stringify({
"timestamp": timestamp,
"name": save_name,
"is_autosave": is_autosave,
"data": data,
}))
file.close()
save_files.push_front({
"idx": idx,
"path": path,
"timestamp": timestamp,
"name": save_name,
"is_autosave": is_autosave,
})
match target:
VNSaveTarget.MANUAL_SAVE:
new_manual_save.emit(save_files[0])
VNSaveTarget.AUTOSAVE:
new_autosave.emit(save_files[0])
_:
assert(false, "Unknown save target %s" % target)
return path
func load_save_file(load_target: VNLoadSource, load_file = null) -> Variant:
current_load_source = load_target
match load_target:
VNLoadSource.NEW_GAME:
return new_game_save_file
#VNLoadSource.FROM_MANUAL_SAVE when not load_file:
# current_load_source = VNLoadSource.FROM_AUTOSAVE
VNLoadSource.FROM_AUTOSAVE:
current_load_path = load_file["path"]
VNLoadSource.FROM_MANUAL_SAVE:
current_load_path = load_file["path"]
_:
assert(false, "Can't figure out where to load saved data from!")
if not FileAccess.file_exists(current_load_path):
push_warning("Load file not found, returning new game data...")
current_load_path = ""
current_load_source = VNLoadSource.NEW_GAME
return {}
return JSON.parse_string(FileAccess.open(current_load_path, FileAccess.READ).get_as_text())["data"]
func delete_save_file(load_file = null):
var i = save_files.find(load_file)
if i == -1:
push_warning("Couldn't locate file for deletion!")
return
DirAccess.remove_absolute(load_file["path"])
save_files.remove_at(i)
updated_save_files.emit(save_files)
func set_global_data(key: String, value: Variant):
if FileAccess.file_exists(GLOBAL_DATA_PATH):
var file = FileAccess.open(GLOBAL_DATA_PATH, FileAccess.READ)
global_data = JSON.parse_string(file.get_as_text())
file.close()
elif not global_data:
global_data = {}
var prev_value = global_data.get(key)
global_data[key] = value
if value != prev_value:
var file = FileAccess.open(GLOBAL_DATA_PATH, FileAccess.WRITE)
file.store_string(JSON.stringify(global_data))
file.close()
return prev_value
func get_global_data(key: String, default = null):
if not global_data:
if FileAccess.file_exists(GLOBAL_DATA_PATH):
var file = FileAccess.open(GLOBAL_DATA_PATH, FileAccess.READ)
global_data = JSON.parse_string(file.get_as_text())
file.close()
else:
global_data = {}
return global_data.get(key, default)