mirror of
https://github.com/ppy/osu.git
synced 2026-05-23 01:00:28 +08:00
Fix calibrating offset with auto-adjust enabled does not account for UR
Covered by test `TestAutomaticAdjustmentWithUnstableRate`.
This commit is contained in:
@@ -64,11 +64,11 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
[Resolved]
|
||||
private OsuConfigManager config { get; set; } = null!;
|
||||
|
||||
private double lastPlayMedian;
|
||||
private double lastPlayUnstableRate;
|
||||
private double lastPlayBeatmapOffset;
|
||||
private HitEventTimingDistributionGraph? lastPlayGraph;
|
||||
|
||||
private double suggestedOffset;
|
||||
|
||||
private SettingsButton? calibrateFromLastPlayButton;
|
||||
|
||||
private IDisposable? beatmapOffsetSubscription;
|
||||
@@ -237,10 +237,14 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
}
|
||||
|
||||
lastValidScore = score.NewValue!;
|
||||
lastPlayMedian = median;
|
||||
lastPlayUnstableRate = hitEvents.CalculateUnstableRate()!.Result;
|
||||
lastPlayBeatmapOffset = Current.Value;
|
||||
|
||||
double unstableRate = hitEvents.CalculateUnstableRate()!.Result;
|
||||
|
||||
bool autoAdjustBeatmapOffset = config.Get<bool>(OsuSetting.AutomaticallyAdjustBeatmapOffset);
|
||||
|
||||
suggestedOffset = computeSuggestedOffset(median, unstableRate, lastPlayBeatmapOffset, proportionalToUnstableRate: autoAdjustBeatmapOffset);
|
||||
|
||||
LinkFlowContainer offsetText;
|
||||
|
||||
referenceScoreContainer.AddRange(new Drawable[]
|
||||
@@ -257,7 +261,7 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
Action = () =>
|
||||
{
|
||||
if (!Current.Disabled)
|
||||
applySuggestedOffset(proportionalToUnstableRate: false);
|
||||
applySuggestedOffset();
|
||||
},
|
||||
},
|
||||
offsetText = new LinkFlowContainer
|
||||
@@ -267,9 +271,9 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
}
|
||||
});
|
||||
|
||||
if (config.Get<bool>(OsuSetting.AutomaticallyAdjustBeatmapOffset))
|
||||
if (autoAdjustBeatmapOffset && !Current.Disabled)
|
||||
{
|
||||
bool offsetChanged = applySuggestedOffset(proportionalToUnstableRate: true);
|
||||
bool offsetChanged = applySuggestedOffset();
|
||||
|
||||
calibrateFromLastPlayButton.Hide();
|
||||
|
||||
@@ -285,19 +289,11 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
offsetText.AddText(" based off this play.", t => t.Font = OsuFont.Style.Caption2);
|
||||
}
|
||||
|
||||
private bool applySuggestedOffset(bool proportionalToUnstableRate)
|
||||
private bool applySuggestedOffset()
|
||||
{
|
||||
const double ur_adjustment_cutoff = 90;
|
||||
const double exponential_factor = -0.0116;
|
||||
double lastOffset = Current.Value;
|
||||
|
||||
double offsetAdjustment = lastPlayMedian;
|
||||
|
||||
if (proportionalToUnstableRate && lastPlayUnstableRate >= ur_adjustment_cutoff)
|
||||
// A demonstrative graph of this algorithm is embedded in https://github.com/ppy/osu/discussions/30521.
|
||||
// This ultimately prevents scores with high unstable rate from suggesting potentially invalid offsets.
|
||||
offsetAdjustment *= Math.Exp(exponential_factor * (lastPlayUnstableRate - ur_adjustment_cutoff));
|
||||
|
||||
Current.Value = lastPlayBeatmapOffset - offsetAdjustment;
|
||||
Current.Value = suggestedOffset;
|
||||
lastAppliedScore.Value = lastValidScore;
|
||||
|
||||
return Math.Abs(Current.Value - lastPlayBeatmapOffset) > Current.Precision;
|
||||
@@ -319,7 +315,7 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
bool allow = allowOffsetAdjust;
|
||||
|
||||
if (calibrateFromLastPlayButton != null)
|
||||
calibrateFromLastPlayButton.Enabled.Value = allow && !Precision.AlmostEquals(lastPlayMedian, adjustmentSinceLastPlay, Current.Precision / 2);
|
||||
calibrateFromLastPlayButton.Enabled.Value = allow && !Precision.AlmostEquals(suggestedOffset, Current.Value, Current.Precision / 2);
|
||||
|
||||
Current.Disabled = !allow;
|
||||
}
|
||||
@@ -353,6 +349,21 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
{
|
||||
}
|
||||
|
||||
private static double computeSuggestedOffset(double median, double unstableRate, double currentOffset, bool proportionalToUnstableRate)
|
||||
{
|
||||
const double ur_adjustment_cutoff = 90;
|
||||
const double exponential_factor = -0.0116;
|
||||
|
||||
double offsetAdjustment = median;
|
||||
|
||||
if (proportionalToUnstableRate && unstableRate >= ur_adjustment_cutoff)
|
||||
// A demonstrative graph of this algorithm is embedded in https://github.com/ppy/osu/discussions/30521.
|
||||
// This ultimately prevents scores with high unstable rate from suggesting potentially invalid offsets.
|
||||
offsetAdjustment *= Math.Exp(exponential_factor * (unstableRate - ur_adjustment_cutoff));
|
||||
|
||||
return currentOffset - offsetAdjustment;
|
||||
}
|
||||
|
||||
public static LocalisableString GetOffsetExplanatoryText(double offset)
|
||||
{
|
||||
string formatOffset = offset.ToStandardFormattedString(1);
|
||||
|
||||
Reference in New Issue
Block a user