forked from team-sg/hero-mark-2
Save System Mk.III (and start of new difficulty system)
This commit is contained in:
parent
746b9813e2
commit
4958c420d8
8 changed files with 203 additions and 82 deletions
|
@ -1,5 +1,12 @@
|
|||
extends Node
|
||||
|
||||
enum Difficulty {
|
||||
SWEET, # slower enemies, infinite lives
|
||||
SALTY, # normal enemies, infinite lives
|
||||
SPICY, # normal enemies, 3 lives, DEFAULT
|
||||
PUNGENT, # faster enemies, 3 lives
|
||||
}
|
||||
|
||||
var resolution = Vector2(256,192)
|
||||
var current_sector = Vector2(0,0)
|
||||
#Onreadys
|
||||
|
@ -22,17 +29,39 @@ var current_level = 0 #Current level being played
|
|||
var current_file = 1 #Current save file
|
||||
var shards_collected = [false,false,false,false,false,false,false,false,false,false]
|
||||
var is_marathon_mode = false
|
||||
var is_easy_mode = false
|
||||
var easy_mode_speed_factor = 0.75
|
||||
var difficulty: int = Difficulty.SPICY setget _set_difficulty
|
||||
var enemy_speed_factor: float = 1.0 # multiplier of enemy speed
|
||||
var is_easy_mode = false # whether to do easy-specific behaviors
|
||||
var easy_mode_speed_factor = 0.75 # DEPRECATED: speed enemies go in easy mode
|
||||
var use_lives = false
|
||||
var can_pause = true
|
||||
var current_palette = "default"
|
||||
|
||||
func _ready():
|
||||
Save.load_file(current_file)
|
||||
Save.load_options()
|
||||
pause_mode = Node.PAUSE_MODE_PROCESS
|
||||
|
||||
|
||||
|
||||
# stuff to change when setting difficulty
|
||||
func _set_difficulty(value: int) -> void:
|
||||
difficulty = value
|
||||
match difficulty:
|
||||
Difficulty.SWEET:
|
||||
is_easy_mode = true
|
||||
enemy_speed_factor = 0.75
|
||||
use_lives = false
|
||||
Difficulty.SALTY:
|
||||
is_easy_mode = false
|
||||
enemy_speed_factor = 1.0
|
||||
use_lives = false
|
||||
Difficulty.SPICY:
|
||||
is_easy_mode = false
|
||||
enemy_speed_factor = 1.0
|
||||
use_lives = true
|
||||
Difficulty.PUNGENT:
|
||||
is_easy_mode = false
|
||||
enemy_speed_factor = 1.25
|
||||
use_lives = true
|
||||
|
||||
#Instances a node
|
||||
func instance_node(node:PackedScene,x:float,y:float,parent):
|
||||
var Instance = node.instance()
|
||||
|
@ -71,22 +100,32 @@ func clear_collectibles():
|
|||
|
||||
#Save
|
||||
func save():
|
||||
# get level's save data object
|
||||
var save_id = LevelData.levels[current_level].save_id
|
||||
var save_data = Save.get_level_data(save_id)
|
||||
var is_100 = shards >= 5 && keys >= 50
|
||||
# set score and time depending on completion
|
||||
if score > save_data["score_100" if is_100 else "score_any"]:
|
||||
Save.set_score(save_id, score, is_100)
|
||||
if time < save_data["time_100" if is_100 else "time_any"]:
|
||||
Save.set_time(save_id, time, is_100)
|
||||
var save_data: Save.LevelSaveData = Save.current_file.levels[save_id]
|
||||
|
||||
# save score and time depending on completion
|
||||
if shards >= 5 && keys >= 50:
|
||||
save_data.score_100 = max(save_data.score_100, score)
|
||||
save_data.time_100 = min(save_data.time_100, time)
|
||||
else:
|
||||
save_data.score_any = max(save_data.score_100, score)
|
||||
save_data.time_any = min(save_data.time_any, time)
|
||||
|
||||
# set shards
|
||||
for i in 8:
|
||||
if shards_collected[i]:
|
||||
Save.set_shard_collected(save_id, i, true)
|
||||
# set options
|
||||
Save.set_options()
|
||||
# save file
|
||||
Save.save_file(current_file)
|
||||
save_data.shards_collected[i] = true
|
||||
|
||||
# set keys
|
||||
save_data.keys_collected = max(save_data.keys_collected, keys)
|
||||
|
||||
# add to playtime
|
||||
Save.current_file.play_time += time
|
||||
|
||||
# save the file
|
||||
Save.current_file.save_to_file()
|
||||
|
||||
|
||||
#Convert seconds into M:SS:MS
|
||||
func timeify(input):
|
||||
|
|
|
@ -1,44 +1,127 @@
|
|||
extends Node
|
||||
|
||||
var file
|
||||
## contains the save data for a single level
|
||||
class LevelSaveData:
|
||||
var save_id: String
|
||||
|
||||
var score_any: int = 0
|
||||
var score_100: int = 0
|
||||
|
||||
var time_any: float = INF
|
||||
var time_100: float = INF
|
||||
|
||||
var keys_collected: int = 0
|
||||
var shards_collected: Array
|
||||
|
||||
func _init(id: String) -> void:
|
||||
save_id = id
|
||||
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 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])
|
||||
|
||||
## 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 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)
|
||||
|
||||
func load_file(file_number):
|
||||
var new_file = ConfigFile.new()
|
||||
new_file.load("user://file%d.pr" % file_number)
|
||||
file = new_file
|
||||
class SaveFile:
|
||||
# path of file to load/save from
|
||||
var file_path: String
|
||||
# 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
|
||||
|
||||
func _init(path: String) -> void:
|
||||
file_path = path
|
||||
levels = {}
|
||||
for level in LevelData.levels:
|
||||
levels[level.save_id] = LevelSaveData.new(level.save_id)
|
||||
|
||||
# return total number of shards
|
||||
func get_total_shards() -> int:
|
||||
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
|
||||
|
||||
func load_from_file() -> void:
|
||||
var file = ConfigFile.new()
|
||||
file.load(file_path)
|
||||
# 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)
|
||||
# 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()
|
||||
# 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)
|
||||
# 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)
|
||||
|
||||
func get_level_data(save_id):
|
||||
var shards = []
|
||||
shards.resize(8)
|
||||
for i in 8:
|
||||
shards[i] = file.get_value(save_id, "shard_%d" % i, false)
|
||||
return {
|
||||
# any% score and time
|
||||
score_any = file.get_value(save_id, "score_any", 0),
|
||||
time_any = file.get_value(save_id, "time_any", INF),
|
||||
# 100% score and time
|
||||
score_100 = file.get_value(save_id, "score_100", 0),
|
||||
time_100 = file.get_value(save_id, "time_100", INF),
|
||||
shards = shards
|
||||
}
|
||||
var current_file: SaveFile = null
|
||||
|
||||
func load_options():
|
||||
Game.use_lives = file.get_value("options","uselives",Game.use_lives)
|
||||
Game.is_easy_mode = file.get_value("game","easy",Game.is_easy_mode)
|
||||
func _ready() -> void:
|
||||
# TODO: make load last played file
|
||||
current_file = load_file("user://file1.pr")
|
||||
Game.difficulty = current_file.difficulty
|
||||
|
||||
func set_shard_collected(save_id, index, collected = true):
|
||||
file.set_value(save_id, "shard_%d" % index, collected)
|
||||
func _on_letter_chosen(glyph: String):
|
||||
if current_file != null:
|
||||
current_file.name += glyph
|
||||
|
||||
func set_score(save_id, score, is_100 = false):
|
||||
file.set_value(save_id, "score_100" if is_100 else "score_any", int(score))
|
||||
|
||||
func set_options():
|
||||
file.set_value("options","uselives",Game.use_lives)
|
||||
file.set_value("game","easy",Game.is_easy_mode)
|
||||
save_file(Game.current_file)
|
||||
|
||||
func set_time(save_id, time, is_100 = false):
|
||||
file.set_value(save_id, "time_100" if is_100 else "time_any", float(time))
|
||||
|
||||
func save_file(file_number):
|
||||
file.save("user://file%d.pr" % file_number)
|
||||
func load_file(path: String) -> SaveFile:
|
||||
var file = SaveFile.new(path)
|
||||
file.load_from_file()
|
||||
return file
|
||||
|
|
|
@ -32,6 +32,7 @@ export var target_time_any = 0
|
|||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
easy_mode_text.text = "difficulty: %s, X to change" % ["sweet", "salty", "spicy", "pungent"][Game.difficulty]
|
||||
Fade.fade_in(0.000000000000001)
|
||||
change_current_level(Game.current_level)
|
||||
Audio.ac_music.stop()
|
||||
|
@ -53,20 +54,8 @@ func _physics_process(delta):
|
|||
Game.change_map(level.scene)
|
||||
#Toggle lives mode
|
||||
if Input.is_action_just_pressed("ui_cancel"):
|
||||
Game.use_lives = !Game.use_lives
|
||||
Save.set_options()
|
||||
if Game.use_lives:
|
||||
lives_mode_text.text = "lives are on press z to change this"
|
||||
else:
|
||||
lives_mode_text.text = "lives are off press z to change this"
|
||||
#Toggle easy mode
|
||||
if Input.is_action_just_pressed("sword"):
|
||||
Game.is_easy_mode = !Game.is_easy_mode
|
||||
Save.set_options()
|
||||
if Game.is_easy_mode:
|
||||
easy_mode_text.text = "easy is on press c to change this"
|
||||
else:
|
||||
easy_mode_text.text = "easy is off press c to change this"
|
||||
Game.difficulty = (Game.difficulty + 1) % 4
|
||||
easy_mode_text.text = "difficulty: %s, X to change" % ["sweet", "salty", "spicy", "pungent"][Game.difficulty]
|
||||
|
||||
func change_current_shard(amount):
|
||||
if current_shard + amount != -1 && current_shard + amount != 8: #Check if in range
|
||||
|
@ -92,7 +81,7 @@ func change_current_level(amount):
|
|||
shard_arrow.position.x = 76
|
||||
#Load new data
|
||||
var save_id = LevelData.levels[current_level].save_id
|
||||
var save_data = Save.get_level_data(save_id)
|
||||
var save_data = Save.current_file.levels[save_id]
|
||||
# set any% scores
|
||||
high_score_any.text = "Any%%\n%05d\n%s" % [
|
||||
save_data.score_any,
|
||||
|
@ -105,4 +94,4 @@ func change_current_level(amount):
|
|||
]
|
||||
# set collected shards
|
||||
for i in 8:
|
||||
shards[i].visible = save_data.shards[i]
|
||||
shards[i].visible = save_data.shards_collected[i]
|
||||
|
|
|
@ -124,10 +124,11 @@ margin_top = 3.0
|
|||
margin_right = 256.0
|
||||
margin_bottom = 13.0
|
||||
theme = ExtResource( 1 )
|
||||
text = "easy is off press c to change this"
|
||||
text = "difficulty"
|
||||
align = 1
|
||||
|
||||
[node name="LivesModeText" type="Label" parent="."]
|
||||
visible = false
|
||||
material = ExtResource( 10 )
|
||||
margin_left = 2.0
|
||||
margin_top = 180.0
|
||||
|
|
|
@ -43,6 +43,12 @@ material = SubResource( 2 )
|
|||
margin_right = 256.0
|
||||
margin_bottom = 192.0
|
||||
|
||||
[node name="DeleteBackground" type="ColorRect" parent="."]
|
||||
visible = false
|
||||
material = SubResource( 3 )
|
||||
margin_right = 256.0
|
||||
margin_bottom = 192.0
|
||||
|
||||
[node name="Panel" parent="." instance=ExtResource( 1 )]
|
||||
margin_left = 12.0
|
||||
margin_top = 64.0
|
||||
|
@ -92,8 +98,3 @@ texture_normal = ExtResource( 9 )
|
|||
texture_focused = ExtResource( 9 )
|
||||
expand = true
|
||||
stretch_mode = 3
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="."]
|
||||
material = SubResource( 3 )
|
||||
margin_right = 256.0
|
||||
margin_bottom = 192.0
|
||||
|
|
|
@ -2,11 +2,15 @@ extends Panel
|
|||
|
||||
export var number = 1
|
||||
|
||||
var file: Save.SaveFile
|
||||
|
||||
func _ready():
|
||||
var file = File.new()
|
||||
if !file.file_exists("user://file" + str(number) + ".pr"):
|
||||
if File.new().file_exists("user://file%d.pr" % number):
|
||||
file = Save.load_file("user://file%d.pr" % number)
|
||||
$"%Name".text = file.name
|
||||
$"%ShardCounter".text = "%02d" % file.get_total_shards()
|
||||
$"%KeyCounter".text = "%03d" % file.get_total_keys()
|
||||
$"%TimeCounter".text = "%02d:%02d" % [file.play_time / 3600.0, fmod(file.play_time / 60.0, 60.0)]
|
||||
else:
|
||||
$FileExists.visible = false
|
||||
$FileDoesNotExist.visible = true
|
||||
else:
|
||||
#Fill out info
|
||||
pass
|
||||
|
|
|
@ -35,6 +35,7 @@ align = 1
|
|||
[node name="FileExists" type="Node2D" parent="."]
|
||||
|
||||
[node name="Name" type="Label" parent="FileExists"]
|
||||
unique_name_in_owner = true
|
||||
margin_left = 8.0
|
||||
margin_top = 4.0
|
||||
margin_right = 64.0
|
||||
|
@ -43,6 +44,7 @@ text = "SG"
|
|||
align = 1
|
||||
|
||||
[node name="TimeCounter" type="Label" parent="FileExists"]
|
||||
unique_name_in_owner = true
|
||||
margin_left = 3.0
|
||||
margin_top = 50.0
|
||||
margin_right = 69.0
|
||||
|
@ -60,6 +62,7 @@ texture = ExtResource( 8 )
|
|||
stretch_mode = 4
|
||||
|
||||
[node name="ShardCounter" type="Label" parent="FileExists"]
|
||||
unique_name_in_owner = true
|
||||
margin_left = 43.0
|
||||
margin_top = 20.0
|
||||
margin_right = 67.0
|
||||
|
@ -67,6 +70,7 @@ margin_bottom = 30.0
|
|||
text = "00"
|
||||
|
||||
[node name="KeyCounter" type="Label" parent="FileExists"]
|
||||
unique_name_in_owner = true
|
||||
margin_left = 43.0
|
||||
margin_top = 33.0
|
||||
margin_right = 64.0
|
||||
|
|
|
@ -71,10 +71,10 @@ config/icon="res://icon.png"
|
|||
[autoload]
|
||||
|
||||
Border="*res://autoloads/border.tscn"
|
||||
Save="*res://autoloads/save.gd"
|
||||
Game="*res://autoloads/game.gd"
|
||||
Audio="*res://autoloads/audio.tscn"
|
||||
LevelData="*res://autoloads/level_data.tscn"
|
||||
Save="*res://autoloads/save.gd"
|
||||
Debug="*res://autoloads/debug.tscn"
|
||||
Options="*res://autoloads/options.gd"
|
||||
TouchControls="*res://autoloads/touch_controls.tscn"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue