diff --git a/Scenes/Levels/AchievementMenu.tscn b/Scenes/Levels/AchievementMenu.tscn index fbb22190..b48dbcc1 100644 --- a/Scenes/Levels/AchievementMenu.tscn +++ b/Scenes/Levels/AchievementMenu.tscn @@ -94,17 +94,17 @@ func get_progress() -> int: for x in SpeedrunHandler.best_level_warpless_times: var level := 0 for i in x: - if i <= SpeedrunHandler.LEVEL_GOLD_WARPLESS_TIMES[campaign][world][level] * SpeedrunHandler.MEDAL_CONVERSIONS[medal_index] and i > 0: + if SpeedrunHandler.met_target_time(i, SpeedrunHandler.LEVEL_GOLD_WARPLESS_TIMES[campaign][world][level] * SpeedrunHandler.MEDAL_CONVERSIONS[medal_index]): medal_amount += 1 level += 1 world += 1 for x in SpeedrunHandler.best_level_any_times: - if SpeedrunHandler.best_level_any_times[x] <= SpeedrunHandler.LEVEL_GOLD_ANY_TIMES[campaign][x] * SpeedrunHandler.MEDAL_CONVERSIONS[medal_index] and SpeedrunHandler.best_level_any_times[x] > 0: + if SpeedrunHandler.met_target_time(SpeedrunHandler.best_level_any_times[x], SpeedrunHandler.LEVEL_GOLD_ANY_TIMES[campaign][x] * SpeedrunHandler.MEDAL_CONVERSIONS[medal_index]): medal_amount += 1 var save = JSON.parse_string(FileAccess.open(Global.config_path.path_join(\"saves/\" + campaign + \".sav\"), FileAccess.READ).get_as_text()) - if save.get(\"BestWarplessTime\", -1) <= SpeedrunHandler.GOLD_WARPLESS_TIMES[campaign] and save.get(\"BestWarplessTime\", -1) > 0: + if SpeedrunHandler.met_target_time(save.get(\"BestWarplessTime\", -1), SpeedrunHandler.GOLD_WARPLESS_TIMES[campaign] * SpeedrunHandler.MEDAL_CONVERSIONS[medal_index]): medal_amount += 1 - if save.get(\"BestAnyTime\", -1) <= SpeedrunHandler.GOLD_ANY_TIMES[campaign] and save.get(\"BestAnyTime\", -1) > 0: + if SpeedrunHandler.met_target_time(save.get(\"BestAnyTime\", -1), SpeedrunHandler.GOLD_ANY_TIMES[campaign] * SpeedrunHandler.MEDAL_CONVERSIONS[medal_index]): medal_amount += 1 return medal_amount " diff --git a/Scripts/Classes/BooRaceHandler.gd b/Scripts/Classes/BooRaceHandler.gd index 3419ba1f..b4f84e5f 100644 --- a/Scripts/Classes/BooRaceHandler.gd +++ b/Scripts/Classes/BooRaceHandler.gd @@ -71,7 +71,7 @@ func player_win_race() -> void: else: var idx := 0 for boo_time in boo.time_needed: - if SpeedrunHandler.timer < boo_time and idx < 4: + if SpeedrunHandler.met_target_time(SpeedrunHandler.timer, boo_time) and idx < 4: cleared_boo += 1 else: break diff --git a/Scripts/Classes/Singletons/SpeedrunHandler.gd b/Scripts/Classes/Singletons/SpeedrunHandler.gd index b8863a9a..4064b359 100644 --- a/Scripts/Classes/Singletons/SpeedrunHandler.gd +++ b/Scripts/Classes/Singletons/SpeedrunHandler.gd @@ -190,10 +190,18 @@ func record_frame(player: Player) -> void: current_recording += data + "," func format_time(time_time := 0.0) -> Dictionary: - var mils = abs(fmod(time_time, 1) * 100) - var secs = abs(fmod(time_time, 60)) - var mins = abs(time_time / 60) + var floor_time = floor(abs(time_time * 100)) + var mils = int(floor_time) % 100 + var secs = int(floor_time / 100) % 60 + var mins = floor_time / 6000 return {"mils": int(mils), "secs": int(secs), "mins": int(mins)} + +func met_target_time(record_time := -1.0, target_time := 0.0) -> bool: + if record_time < 0.0: + return false + # Ignore units of time smaller than a centisecond, as they're not displayed. + # Matching time exactly counts as beating it. + return int(record_time * 100) <= int(target_time * 100) func gen_time_string(timer_dict := {}) -> String: return str(int(timer_dict["mins"])).pad_zeros(2) + ":" + str(int(timer_dict["secs"])).pad_zeros(2) + ":" + str(int(timer_dict["mils"])).pad_zeros(2) @@ -339,11 +347,11 @@ func check_for_medal_achievement() -> void: for i in LEVEL_GOLD_ANY_TIMES[Global.current_campaign]: if best_level_any_times.has(i): - if best_level_any_times[i] > LEVEL_GOLD_ANY_TIMES[Global.current_campaign][i]: + if not met_target_time(best_level_any_times[i], LEVEL_GOLD_ANY_TIMES[Global.current_campaign][i]): has_gold_levels_any = false - if best_level_any_times[i] > LEVEL_GOLD_ANY_TIMES[Global.current_campaign][i] * MEDAL_CONVERSIONS[1]: + if not met_target_time(best_level_any_times[i], LEVEL_GOLD_ANY_TIMES[Global.current_campaign][i] * MEDAL_CONVERSIONS[1]): has_silver_levels_any = false - if best_level_any_times[i] > LEVEL_GOLD_ANY_TIMES[Global.current_campaign][i] * MEDAL_CONVERSIONS[0]: + if not met_target_time(best_level_any_times[i], LEVEL_GOLD_ANY_TIMES[Global.current_campaign][i] * MEDAL_CONVERSIONS[0]): has_bronze_levels_any = false else: has_gold_levels_any = false @@ -354,26 +362,24 @@ func check_for_medal_achievement() -> void: for i in best_level_warpless_times: var level := 0 for x in i: - if x < 0: + if not met_target_time(x, LEVEL_GOLD_WARPLESS_TIMES[Global.current_campaign][world][level]): has_gold_levels_warpless = false + if not met_target_time(x, LEVEL_GOLD_WARPLESS_TIMES[Global.current_campaign][world][level] * MEDAL_CONVERSIONS[1]): has_silver_levels_warpless = false - has_bronze_levels_warpless = false - if x > LEVEL_GOLD_WARPLESS_TIMES[Global.current_campaign][world][level]: - has_gold_levels_warpless = false - if x > LEVEL_GOLD_WARPLESS_TIMES[Global.current_campaign][world][level] * MEDAL_CONVERSIONS[1]: - has_silver_levels_warpless = false - if x > LEVEL_GOLD_WARPLESS_TIMES[Global.current_campaign][world][level] * MEDAL_CONVERSIONS[0]: + if not met_target_time(x, LEVEL_GOLD_WARPLESS_TIMES[Global.current_campaign][world][level] * MEDAL_CONVERSIONS[0]): has_bronze_levels_warpless = false level += 1 world += 1 - if marathon_best_any_time >= 0 and marathon_best_warpless_time >= 0: - if marathon_best_any_time <= GOLD_ANY_TIMES[Global.current_campaign] and marathon_best_warpless_time <= GOLD_WARPLESS_TIMES[Global.current_campaign]: - has_gold_full = true - if marathon_best_any_time <= GOLD_ANY_TIMES[Global.current_campaign] * MEDAL_CONVERSIONS[1] and marathon_best_warpless_time <= GOLD_WARPLESS_TIMES[Global.current_campaign] * MEDAL_CONVERSIONS[1]: - has_silver_full = true - if marathon_best_any_time <= GOLD_ANY_TIMES[Global.current_campaign] * MEDAL_CONVERSIONS[0] and marathon_best_warpless_time <= GOLD_WARPLESS_TIMES[Global.current_campaign] * MEDAL_CONVERSIONS[0]: - has_bronze_full = true + if (met_target_time(marathon_best_any_time, GOLD_ANY_TIMES[Global.current_campaign]) and + met_target_time(marathon_best_warpless_time, GOLD_WARPLESS_TIMES[Global.current_campaign])): + has_gold_full = true + if (met_target_time(marathon_best_any_time, GOLD_ANY_TIMES[Global.current_campaign] * MEDAL_CONVERSIONS[1]) and + met_target_time(marathon_best_warpless_time, GOLD_WARPLESS_TIMES[Global.current_campaign] * MEDAL_CONVERSIONS[1])): + has_silver_full = true + if (met_target_time(marathon_best_any_time, GOLD_ANY_TIMES[Global.current_campaign] * MEDAL_CONVERSIONS[0]) and + met_target_time(marathon_best_warpless_time, GOLD_WARPLESS_TIMES[Global.current_campaign] * MEDAL_CONVERSIONS[0])): + has_bronze_full = true if has_gold_levels_warpless and has_gold_levels_any and has_gold_full: match Global.current_campaign: diff --git a/Scripts/UI/LevelSelect.gd b/Scripts/UI/LevelSelect.gd index 1bb89617..ad265994 100644 --- a/Scripts/UI/LevelSelect.gd +++ b/Scripts/UI/LevelSelect.gd @@ -151,11 +151,11 @@ func update_pb() -> void: gold_any_time = SpeedrunHandler.LEVEL_GOLD_ANY_TIMES[Global.current_campaign][str(Global.world_num) + "-" + str(selected_level + 1)] for i in %FullRunMedals.get_children(): var target_time = gold_warpless_time * SpeedrunHandler.MEDAL_CONVERSIONS[i.get_index()] - i.get_node("Full").visible = best_warpless_time <= target_time and best_warpless_time > 0 + i.get_node("Full").visible = SpeedrunHandler.met_target_time(best_warpless_time, target_time) if gold_any_time != -1: for i in %WarpRunMedals.get_children(): var target_time = gold_any_time * SpeedrunHandler.MEDAL_CONVERSIONS[i.get_index()] - i.get_node("Full").visible = best_any_time <= target_time and best_any_time > 0 + i.get_node("Full").visible = SpeedrunHandler.met_target_time(best_any_time, target_time) else: for i in %WarpRunMedals.get_children(): i.get_node("Full").hide() diff --git a/Scripts/UI/MarathonResults.gd b/Scripts/UI/MarathonResults.gd index 20ee10ac..8ad73e3b 100644 --- a/Scripts/UI/MarathonResults.gd +++ b/Scripts/UI/MarathonResults.gd @@ -25,11 +25,11 @@ func setup_visuals() -> void: target_time = SpeedrunHandler.GOLD_WARPLESS_TIMES[Global.current_campaign] %Target.text = SpeedrunHandler.gen_time_string(SpeedrunHandler.format_time(target_time)) var medal_index := -1 - if SpeedrunHandler.timer <= target_time: + if SpeedrunHandler.met_target_time(SpeedrunHandler.timer, target_time): medal_index = 2 - elif SpeedrunHandler.timer <= target_time * SpeedrunHandler.MEDAL_CONVERSIONS[1]: + elif SpeedrunHandler.met_target_time(SpeedrunHandler.timer, target_time * SpeedrunHandler.MEDAL_CONVERSIONS[1]): medal_index = 1 - elif SpeedrunHandler.timer <= target_time * SpeedrunHandler.MEDAL_CONVERSIONS[0]: + elif SpeedrunHandler.met_target_time(SpeedrunHandler.timer, target_time * SpeedrunHandler.MEDAL_CONVERSIONS[0]): medal_index = 0 %Medal.get_node("Full").visible = medal_index >= 0 %Medal.get_node("Full").region_rect.position = Vector2(8 * medal_index, 0) diff --git a/Scripts/UI/MarathonSelect.gd b/Scripts/UI/MarathonSelect.gd index 5ee2e3fe..0f2d5502 100644 --- a/Scripts/UI/MarathonSelect.gd +++ b/Scripts/UI/MarathonSelect.gd @@ -49,6 +49,8 @@ func setup_visuals() -> void: %WarpedRunPB.text = SpeedrunHandler.gen_time_string(SpeedrunHandler.format_time(SpeedrunHandler.marathon_best_any_time)) for i in %FullMedals.get_children(): - i.get_node("Full").visible = SpeedrunHandler.marathon_best_warpless_time <= SpeedrunHandler.GOLD_WARPLESS_TIMES[Global.current_campaign] * SpeedrunHandler.MEDAL_CONVERSIONS[i.get_index()] and SpeedrunHandler.marathon_best_warpless_time > 0 + i.get_node("Full").visible = SpeedrunHandler.met_target_time( + SpeedrunHandler.marathon_best_warpless_time, SpeedrunHandler.GOLD_WARPLESS_TIMES[Global.current_campaign] * SpeedrunHandler.MEDAL_CONVERSIONS[i.get_index()]) for i in %WarpedMedals.get_children(): - i.get_node("Full").visible = SpeedrunHandler.marathon_best_any_time <= SpeedrunHandler.GOLD_ANY_TIMES[Global.current_campaign] * SpeedrunHandler.MEDAL_CONVERSIONS[i.get_index()] and SpeedrunHandler.marathon_best_any_time > 0 + i.get_node("Full").visible = SpeedrunHandler.met_target_time( + SpeedrunHandler.marathon_best_any_time, SpeedrunHandler.GOLD_ANY_TIMES[Global.current_campaign] * SpeedrunHandler.MEDAL_CONVERSIONS[i.get_index()])