180 lines
5.1 KiB
GDScript
180 lines
5.1 KiB
GDScript
extends Node
|
|
|
|
# currently-used compatible format version
|
|
const FORMAT_VERSION: int = 1
|
|
|
|
# contains the save data for a single level
|
|
class LevelSaveData:
|
|
# save file category to use for this level
|
|
var save_id: String
|
|
# scores
|
|
var score_any: int = 0
|
|
var score_100: int = 0
|
|
# times
|
|
var time_any: float = INF
|
|
var time_100: float = INF
|
|
# times died in that level
|
|
var deaths: int
|
|
# collectibles
|
|
var keys_collected: int = 0
|
|
var shards_collected: Array
|
|
# whether level has been beaten at all
|
|
var completed: bool = false
|
|
|
|
func _init(id: String) -> void:
|
|
save_id = id
|
|
# initialize shards array
|
|
shards_collected = []
|
|
shards_collected.resize(8)
|
|
for i in 8:
|
|
shards_collected[i] = false
|
|
|
|
## save the level data to the given ConfigFile
|
|
func save_to_file(file: ConfigFile) -> void:
|
|
# set scores
|
|
file.set_value(save_id, "score_any", score_any)
|
|
file.set_value(save_id, "score_100", score_100)
|
|
# set times
|
|
file.set_value(save_id, "time_any", time_any)
|
|
file.set_value(save_id, "time_100", time_100)
|
|
# set deaths
|
|
file.set_value(save_id, "deaths", deaths)
|
|
# set collected keys
|
|
file.set_value(save_id, "keys", keys_collected)
|
|
# set collected shards
|
|
for i in 8:
|
|
file.set_value(save_id, "shard_%d" % i, shards_collected[i])
|
|
# set completion status
|
|
file.set_value(save_id, "completed", completed)
|
|
|
|
## loads level data from the given ConfigFile
|
|
func load_from_file(file: ConfigFile) -> void:
|
|
# get scores
|
|
score_any = file.get_value(save_id, "score_any", 0)
|
|
score_100 = file.get_value(save_id, "score_100", 0)
|
|
# get times
|
|
time_any = file.get_value(save_id, "time_any", INF)
|
|
time_100 = file.get_value(save_id, "time_100", INF)
|
|
# get deaths
|
|
deaths = file.get_value(save_id, "deaths", 0)
|
|
# get collected keys
|
|
keys_collected = file.get_value(save_id, "keys", keys_collected)
|
|
# get collected shards
|
|
for i in 8:
|
|
shards_collected[i] = file.get_value(save_id, "shard_%d" % i, false)
|
|
# get completion status
|
|
completed = file.get_value(save_id, "completed", false)
|
|
|
|
# contains data of one save file
|
|
class SaveFile:
|
|
# path of file to load/save from
|
|
var file_path: String
|
|
# version of save file format
|
|
var version: int = FORMAT_VERSION
|
|
# name of the save file
|
|
var name: String = ""
|
|
# difficulty chosen for the file
|
|
var difficulty: int = Game.Difficulty.SPICY
|
|
# total play time
|
|
var play_time: float = 0.0
|
|
# dictionary of levels' save data
|
|
var levels: Dictionary
|
|
# whether is debug save
|
|
var debug: bool = false
|
|
# palette the save file is using
|
|
var palette: String = "default"
|
|
|
|
func _init(path: String, debug_save: bool = false) -> void:
|
|
debug = debug_save
|
|
file_path = path
|
|
# initialize level save data dictionary
|
|
levels = {}
|
|
for level in LevelData.levels:
|
|
var data := LevelSaveData.new(level.save_id)
|
|
if debug:
|
|
data.completed = true
|
|
levels[level.save_id] = data
|
|
|
|
# return total number of shards
|
|
func get_total_shards() -> int:
|
|
if debug:
|
|
return 999
|
|
var total = 0
|
|
for level in levels.values():
|
|
total += level.shards_collected.count(true)
|
|
return total
|
|
|
|
# return total number of keys
|
|
func get_total_keys() -> int:
|
|
var total = 0
|
|
for level in levels.values():
|
|
total += level.keys_collected
|
|
return total
|
|
|
|
# return total number of deaths
|
|
func get_total_deaths() -> int:
|
|
var total = 0
|
|
for level in levels.values():
|
|
total += level.deaths
|
|
return total
|
|
|
|
func is_super_player() -> bool:
|
|
return get_total_shards() >= 72 and levels["boss3"].completed
|
|
|
|
# loads data from the file at `path`
|
|
func load_from_file() -> void:
|
|
var file = ConfigFile.new()
|
|
file.load(file_path)
|
|
# get save format version
|
|
version = file.get_value("options", "version", 0)
|
|
# load name
|
|
name = file.get_value("options", "name", "SG")
|
|
# load difficulty
|
|
difficulty = file.get_value("options", "difficulty", Game.Difficulty.SPICY)
|
|
# load playtime
|
|
play_time = file.get_value("options", "play_time", 0.0)
|
|
palette = file.get_value("options", "palette", "default")
|
|
# TODO: load bought palettes
|
|
# TODO: load selected palette
|
|
# load level save data
|
|
for level_save in levels.values():
|
|
level_save.load_from_file(file)
|
|
|
|
func save_to_file() -> void:
|
|
var file = ConfigFile.new()
|
|
# use current format version
|
|
file.set_value("options", "version", FORMAT_VERSION)
|
|
# save name
|
|
file.set_value("options", "name", name)
|
|
# save difficulty
|
|
file.set_value("options", "difficulty", difficulty)
|
|
# save playtime
|
|
file.set_value("options", "play_time", play_time)
|
|
file.set_value("options", "palette", palette)
|
|
# TODO: save bought palettes
|
|
# TODO: save selected palette
|
|
# save level data
|
|
for level in levels.values():
|
|
level.save_to_file(file)
|
|
file.save(file_path)
|
|
|
|
|
|
## currently used save file
|
|
var current_file: SaveFile = null
|
|
|
|
func _ready() -> void:
|
|
if OS.is_debug_build():
|
|
current_file = SaveFile.new("user://debug_save.pr", true)
|
|
else:
|
|
current_file = load_file("user://file%d.pr" % Options.last_file)
|
|
if current_file:
|
|
Game.difficulty = current_file.difficulty
|
|
|
|
## shortcut for loading a save file from specific path
|
|
func load_file(path: String) -> SaveFile:
|
|
if File.new().file_exists(path):
|
|
var file = SaveFile.new(path)
|
|
file.load_from_file()
|
|
return file
|
|
else:
|
|
return null
|