From 8b8b54b58ffc2f82c22e775cffc855964c1d77e3 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sat, 5 Mar 2022 21:48:57 +0800 Subject: [PATCH] Scale rate adjustments based on hit timing consistency and tweak some related numbers --- osu.Game/Rulesets/Mods/ModAdaptiveSpeed.cs | 29 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModAdaptiveSpeed.cs b/osu.Game/Rulesets/Mods/ModAdaptiveSpeed.cs index e7ca1d3150..1115b95e6f 100644 --- a/osu.Game/Rulesets/Mods/ModAdaptiveSpeed.cs +++ b/osu.Game/Rulesets/Mods/ModAdaptiveSpeed.cs @@ -70,8 +70,8 @@ namespace osu.Game.Rulesets.Mods // The two constants below denote the maximum allowable change in rate caused by a single hit // This prevents sudden jolts caused by a badly-timed hit. - private const double min_allowable_rate_change = 0.8d; - private const double max_allowable_rate_change = 1.25d; + private const double min_allowable_rate_change = 0.9d; + private const double max_allowable_rate_change = 1.11d; // Apply a fixed rate change when missing, allowing the player to catch up when the rate is too fast. private const double rate_change_on_miss = 0.95d; @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Mods /// The number of most recent track rates (approximated from how early/late each object was hit relative to the previous object) /// which should be averaged to calculate . /// - private const int recent_rate_count = 6; + private const int recent_rate_count = 8; /// /// Stores the most recent approximated track rates @@ -172,7 +172,7 @@ namespace osu.Game.Rulesets.Mods recentRates.Add(Math.Clamp(getRelativeRateChange(result) * SpeedChange.Value, min_allowable_rate, max_allowable_rate)); - targetRate = recentRates.Average(); + updateTargetRate(); }; drawable.OnRevertResult += (o, result) => { @@ -184,7 +184,7 @@ namespace osu.Game.Rulesets.Mods recentRates.RemoveAt(recentRates.Count - 1); - targetRate = recentRates.Average(); + updateTargetRate(); }; } @@ -246,5 +246,24 @@ namespace osu.Game.Rulesets.Mods max_allowable_rate_change ); } + + /// + /// Update based on the values in . + /// + private void updateTargetRate() + { + // Compare values in recentRates to see how consistent the player's speed is + // If the player hits half of the notes too fast and the other half too slow: Abs(consistency) = 0 + // If the player hits all their notes too fast or too slow: Abs(consistency) = recent_rate_count - 1 + int consistency = 0; + + for (int i = 1; i < recentRates.Count; i++) + { + consistency += Math.Sign(recentRates[i] - recentRates[i - 1]); + } + + // Scale the rate adjustment based on consistency + targetRate = Interpolation.Lerp(targetRate, recentRates.Average(), Math.Abs(consistency) / (recent_rate_count - 1d)); + } } }