mirror of
https://github.com/ppy/osu.git
synced 2026-05-22 22:20:53 +08:00
Fix rate change hotkeys sometimes losing track of adjust pitch setting
Fixes https://osu.ppy.sh/community/forums/topics/1983327. The cause of the bug is a bit convoluted, and stems from the fact that the mod select overlay controls all of the game-global mod instances if present. `ModSpeedHotkeyHandler` would store the last spotted instance of a rate adjust mod - which in this case is a problem, because on deselection of a mod, the mod select overlay resets its settings to defaults: https://github.com/ppy/osu/blob/a258059d4338b999b8e065e48b952d14a6d14fb8/osu.Game/Overlays/Mods/ModSelectOverlay.cs#L424-L425 A way to defend against this is a clone, but this reveals another issue, in that the existing code was *relying* on the reference to the mod remaining the same in any other case, to read the latest valid settings of the mod. This basically only mattered in the edge case wherein Double Time would swap places with Half Time and vice versa (think [0.95,1.05] range). Therefore, track mod settings too explicitly to ensure that the stored clone is as up-to-date as possible.
This commit is contained in:
@@ -27,6 +27,7 @@ namespace osu.Game.Screens.Select
|
||||
private OnScreenDisplay? onScreenDisplay { get; set; }
|
||||
|
||||
private ModRateAdjust? lastActiveRateAdjustMod;
|
||||
private ModSettingChangeTracker? settingChangeTracker;
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
@@ -34,10 +35,19 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
selectedMods.BindValueChanged(val =>
|
||||
{
|
||||
lastActiveRateAdjustMod = val.NewValue.OfType<ModRateAdjust>().SingleOrDefault() ?? lastActiveRateAdjustMod;
|
||||
storeLastActiveRateAdjustMod();
|
||||
|
||||
settingChangeTracker?.Dispose();
|
||||
settingChangeTracker = new ModSettingChangeTracker(val.NewValue);
|
||||
settingChangeTracker.SettingChanged += _ => storeLastActiveRateAdjustMod();
|
||||
}, true);
|
||||
}
|
||||
|
||||
private void storeLastActiveRateAdjustMod()
|
||||
{
|
||||
lastActiveRateAdjustMod = (ModRateAdjust?)selectedMods.Value.OfType<ModRateAdjust>().SingleOrDefault()?.DeepClone() ?? lastActiveRateAdjustMod;
|
||||
}
|
||||
|
||||
public bool ChangeSpeed(double delta, IEnumerable<Mod> availableMods)
|
||||
{
|
||||
double targetSpeed = (selectedMods.Value.OfType<ModRateAdjust>().SingleOrDefault()?.SpeedChange.Value ?? 1) + delta;
|
||||
|
||||
Reference in New Issue
Block a user