diff --git a/autoloads/game.gd b/autoloads/game.gd index 0ae099a..9784b39 100644 --- a/autoloads/game.gd +++ b/autoloads/game.gd @@ -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): diff --git a/autoloads/save.gd b/autoloads/save.gd index 9945c69..18e62bc 100644 --- a/autoloads/save.gd +++ b/autoloads/save.gd @@ -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 diff --git a/maps/level_select.gd b/maps/level_select.gd index 1c18907..4237305 100644 --- a/maps/level_select.gd +++ b/maps/level_select.gd @@ -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] diff --git a/maps/level_select.tscn b/maps/level_select.tscn index 8ab2645..fb4407a 100644 --- a/maps/level_select.tscn +++ b/maps/level_select.tscn @@ -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 diff --git a/menus/file_select.tscn b/menus/file_select.tscn index cb3e1f3..0fd797f 100644 --- a/menus/file_select.tscn +++ b/menus/file_select.tscn @@ -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 diff --git a/menus/file_select_panel.gd b/menus/file_select_panel.gd index 452255d..5ca4352 100644 --- a/menus/file_select_panel.gd +++ b/menus/file_select_panel.gd @@ -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 diff --git a/menus/file_select_panel.tscn b/menus/file_select_panel.tscn index d10cb4b..cdcdf7b 100644 --- a/menus/file_select_panel.tscn +++ b/menus/file_select_panel.tscn @@ -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 diff --git a/project.godot b/project.godot index 3719b4c..59a41ca 100644 --- a/project.godot +++ b/project.godot @@ -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"