From a6e94dd4918e70e1e5040b5523ec0958e1fb0355 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Jul 2021 16:40:32 +0900 Subject: [PATCH] Add back extended limits support --- .../Mods/CatchModDifficultyAdjust.cs | 17 ++-- .../Mods/OsuModDifficultyAdjust.cs | 20 ++--- .../Mods/TaikoModDifficultyAdjust.cs | 9 +- .../TestSceneModDifficultyAdjustSettings.cs | 2 +- .../Mods/ApproachRateSettingsControl.cs | 8 -- .../Mods/DifficultyAdjustSettingsControl.cs | 21 +++-- osu.Game/Rulesets/Mods/DifficultyBindable.cs | 84 +++++++++++++++++++ osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 81 ++---------------- 8 files changed, 121 insertions(+), 121 deletions(-) create mode 100644 osu.Game/Rulesets/Mods/DifficultyBindable.cs diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index aaa426cd03..947edb5dd9 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -13,35 +13,28 @@ namespace osu.Game.Rulesets.Catch.Mods public class CatchModDifficultyAdjust : ModDifficultyAdjust, IApplicableToBeatmapProcessor { [SettingSource("Circle Size", "Override a beatmap's set CS.", FIRST_SETTING_ORDER - 1)] - public Bindable CircleSize { get; } = new Bindable + public DifficultyBindable CircleSize { get; } = new DifficultyBindable { - /* Precision = 0.1f, MinValue = 1, MaxValue = 10, - */ }; [SettingSource("Approach Rate", "Override a beatmap's set AR.", LAST_SETTING_ORDER + 1)] - public Bindable ApproachRate { get; } = new Bindable + public DifficultyBindable ApproachRate { get; } = new DifficultyBindable { - /* Precision = 0.1f, MinValue = 1, MaxValue = 10, - */ }; [SettingSource("Spicy Patterns", "Adjust the patterns as if Hard Rock is enabled.")] public BindableBool HardRockOffsets { get; } = new BindableBool(); - protected override void ApplyLimits(bool extended) + public CatchModDifficultyAdjust() { - base.ApplyLimits(extended); - - // TODO: reimplement - // CircleSize.MaxValue = extended ? 11 : 10; - // ApproachRate.MaxValue = extended ? 11 : 10; + CircleSize.ExtendedLimits.BindTo(ExtendedLimits); + ApproachRate.ExtendedLimits.BindTo(ExtendedLimits); } public override string SettingDescription diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index 82c4a6fd56..403ec2c33d 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; -using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; @@ -12,32 +11,27 @@ namespace osu.Game.Rulesets.Osu.Mods public class OsuModDifficultyAdjust : ModDifficultyAdjust { [SettingSource("Circle Size", "Override a beatmap's set CS.", FIRST_SETTING_ORDER - 1, SettingControlType = typeof(DifficultyAdjustSettingsControl))] - public Bindable CircleSize { get; } = new Bindable + public DifficultyBindable CircleSize { get; } = new DifficultyBindable { - /* Precision = 0.1f, MinValue = 0, MaxValue = 10, - */ + ExtendedMaxValue = 11, }; [SettingSource("Approach Rate", "Override a beatmap's set AR.", LAST_SETTING_ORDER + 1, SettingControlType = typeof(ApproachRateSettingsControl))] - public Bindable ApproachRate { get; } = new Bindable + public DifficultyBindable ApproachRate { get; } = new DifficultyBindable { - /* Precision = 0.1f, MinValue = 0, MaxValue = 10, - */ + ExtendedMaxValue = 11, }; - protected override void ApplyLimits(bool extended) + public OsuModDifficultyAdjust() { - base.ApplyLimits(extended); - - // TODO: reimplement - // CircleSize.MaxValue = extended ? 11 : 10; - // ApproachRate.MaxValue = extended ? 11 : 10; + CircleSize.ExtendedLimits.BindTo(ExtendedLimits); + ApproachRate.ExtendedLimits.BindTo(ExtendedLimits); } public override string SettingDescription diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs index 902ccdc14e..110a7eebc8 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; -using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; @@ -11,14 +10,12 @@ namespace osu.Game.Rulesets.Taiko.Mods { public class TaikoModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Scroll Speed", "Adjust a beatmap's set scroll speed", LAST_SETTING_ORDER + 1)] - public Bindable ScrollSpeed { get; } = new Bindable + [SettingSource("Scroll Speed", "Adjust a beatmap's set scroll speed", LAST_SETTING_ORDER + 1, SettingControlType = typeof(DifficultyAdjustSettingsControl))] + public DifficultyBindable ScrollSpeed { get; } = new DifficultyBindable { - /* Precision = 0.05f, MinValue = 0.25f, MaxValue = 4, - */ }; public override string SettingDescription @@ -39,7 +36,7 @@ namespace osu.Game.Rulesets.Taiko.Mods { base.ApplySettings(difficulty); - if (ScrollSpeed.Value != null) difficulty.SliderMultiplier = ScrollSpeed.Value.Value; + if (ScrollSpeed.Value != null) difficulty.SliderMultiplier *= ScrollSpeed.Value.Value; } } } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs index b1ad92273c..7d982a55cb 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs @@ -56,7 +56,7 @@ namespace osu.Game.Tests.Visual.UserInterface private void setBeatmapWithDifficultyParameters(float value) { - AddStep($"set beatmap with all {value}", () => Beatmap.Value = CreateWorkingBeatmap(new Beatmap() + AddStep($"set beatmap with all {value}", () => Beatmap.Value = CreateWorkingBeatmap(new Beatmap { BeatmapInfo = new BeatmapInfo { diff --git a/osu.Game/Rulesets/Mods/ApproachRateSettingsControl.cs b/osu.Game/Rulesets/Mods/ApproachRateSettingsControl.cs index 15a94cb271..18773afb30 100644 --- a/osu.Game/Rulesets/Mods/ApproachRateSettingsControl.cs +++ b/osu.Game/Rulesets/Mods/ApproachRateSettingsControl.cs @@ -7,14 +7,6 @@ namespace osu.Game.Rulesets.Mods { public class ApproachRateSettingsControl : DifficultyAdjustSettingsControl { - public ApproachRateSettingsControl() - { - CurrentNumber.Precision = 0.1f; - - CurrentNumber.MinValue = 0; - CurrentNumber.MaxValue = 10; - } - protected override float UpdateFromDifficulty(BeatmapDifficulty difficulty) => difficulty.ApproachRate; } } diff --git a/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs b/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs index 2b437370ea..1aede3425a 100644 --- a/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs +++ b/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs @@ -17,17 +17,26 @@ namespace osu.Game.Rulesets.Mods [Resolved] private IBindable beatmap { get; set; } - protected readonly BindableNumber CurrentNumber = new BindableNumber - { - // TODO: these need to be pulled out of the main bindable. - MinValue = 0, - MaxValue = 10, - }; + protected readonly BindableNumber CurrentNumber = new BindableNumber(); protected override Drawable CreateControl() => new ControlDrawable(CurrentNumber); private bool isInternalChange; + private DifficultyBindable difficultyBindable; + + public override Bindable Current + { + get => base.Current; + set + { + // intercept and extract the DifficultyBindable. + difficultyBindable = (DifficultyBindable)value; + CurrentNumber.BindTo(difficultyBindable.CurrentNumber); + base.Current = value; + } + } + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Rulesets/Mods/DifficultyBindable.cs b/osu.Game/Rulesets/Mods/DifficultyBindable.cs new file mode 100644 index 0000000000..d721154392 --- /dev/null +++ b/osu.Game/Rulesets/Mods/DifficultyBindable.cs @@ -0,0 +1,84 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Bindables; + +namespace osu.Game.Rulesets.Mods +{ + public class DifficultyBindable : Bindable + { + /// + /// Whether the extended limits should be applied to this bindable. + /// + public BindableBool ExtendedLimits { get; } = new BindableBool(); + + /// + /// An internal numeric bindable to hold and propagate min/max/precision. + /// The value of this bindable should not be set. + /// + public readonly BindableFloat CurrentNumber = new BindableFloat + { + MinValue = 0, + MaxValue = 10, + }; + + public float Precision + { + set => CurrentNumber.Precision = value; + } + + public float MinValue + { + set => CurrentNumber.MinValue = value; + } + + private float maxValue; + + public float MaxValue + { + set + { + if (value == maxValue) + return; + + maxValue = value; + updateMaxValue(); + } + } + + private float? extendedMaxValue; + + /// + /// The maximum value to be used when extended limits are applied. + /// + public float? ExtendedMaxValue + { + set + { + if (value == extendedMaxValue) + return; + + extendedMaxValue = value; + updateMaxValue(); + } + } + + public DifficultyBindable() + { + ExtendedLimits.BindValueChanged(_ => updateMaxValue()); + + BindValueChanged(val => + { + // Ensure that in the case serialisation runs in the wrong order (and limit extensions aren't applied yet) the deserialised value is still propagated. + if (val.NewValue != null) + CurrentNumber.MaxValue = MathF.Max(CurrentNumber.MaxValue, val.NewValue.Value); + }); + } + + private void updateMaxValue() + { + CurrentNumber.MaxValue = ExtendedLimits.Value && extendedMaxValue != null ? extendedMaxValue.Value : maxValue; + } + } +} diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index 4b68d9cc3f..d636f22dea 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -33,23 +33,21 @@ namespace osu.Game.Rulesets.Mods protected const int LAST_SETTING_ORDER = 2; [SettingSource("HP Drain", "Override a beatmap's set HP.", FIRST_SETTING_ORDER, SettingControlType = typeof(DifficultyAdjustSettingsControl))] - public Bindable DrainRate { get; } = new Bindable + public DifficultyBindable DrainRate { get; } = new DifficultyBindable { - /* Precision = 0.1f, MinValue = 0, MaxValue = 10, - */ + ExtendedMaxValue = 11, }; [SettingSource("Accuracy", "Override a beatmap's set OD.", LAST_SETTING_ORDER, SettingControlType = typeof(DifficultyAdjustSettingsControl))] - public Bindable OverallDifficulty { get; } = new Bindable + public DifficultyBindable OverallDifficulty { get; } = new DifficultyBindable { - /* Precision = 0.1f, MinValue = 0, MaxValue = 10, - */ + ExtendedMaxValue = 11, }; [SettingSource("Extended Limits", "Adjust difficulty beyond sane limits.")] @@ -57,18 +55,8 @@ namespace osu.Game.Rulesets.Mods protected ModDifficultyAdjust() { - ExtendedLimits.BindValueChanged(extend => ApplyLimits(extend.NewValue)); - } - - /// - /// Changes the difficulty adjustment limits. Occurs when the value of is changed. - /// - /// Whether limits should extend beyond sane ranges. - protected virtual void ApplyLimits(bool extended) - { - // TODO: reimplement - // DrainRate.MaxValue = extended ? 11 : 10; - // OverallDifficulty.MaxValue = extended ? 11 : 10; + OverallDifficulty.ExtendedLimits.BindTo(ExtendedLimits); + DrainRate.ExtendedLimits.BindTo(ExtendedLimits); } public override string SettingDescription @@ -101,62 +89,5 @@ namespace osu.Game.Rulesets.Mods if (DrainRate.Value != null) difficulty.DrainRate = DrainRate.Value.Value; if (OverallDifficulty.Value != null) difficulty.OverallDifficulty = OverallDifficulty.Value.Value; } - - /// - /// A that extends its min/max values to support any assigned value. - /// - protected class BindableDoubleWithLimitExtension : BindableDouble - { - public override double Value - { - get => base.Value; - set - { - if (value < MinValue) - MinValue = value; - if (value > MaxValue) - MaxValue = value; - base.Value = value; - } - } - } - - /// - /// A that extends its min/max values to support any assigned value. - /// - protected class BindableFloatWithLimitExtension : BindableFloat - { - public override float Value - { - get => base.Value; - set - { - if (value < MinValue) - MinValue = value; - if (value > MaxValue) - MaxValue = value; - base.Value = value; - } - } - } - - /// - /// A that extends its min/max values to support any assigned value. - /// - protected class BindableIntWithLimitExtension : BindableInt - { - public override int Value - { - get => base.Value; - set - { - if (value < MinValue) - MinValue = value; - if (value > MaxValue) - MaxValue = value; - base.Value = value; - } - } - } } }