mirror of
https://github.com/ppy/osu.git
synced 2025-01-31 18:33:20 +08:00
Merge pull request #29198 from bdach/fix-difficulty-bindable
Fix incorrect `DifficultyBindable` logic
This commit is contained in:
commit
c80f338893
@ -8,6 +8,8 @@ using osu.Game.Online.API;
|
|||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Mods
|
namespace osu.Game.Tests.Mods
|
||||||
@ -105,9 +107,6 @@ namespace osu.Game.Tests.Mods
|
|||||||
testMod.ResetSettingsToDefaults();
|
testMod.ResetSettingsToDefaults();
|
||||||
|
|
||||||
Assert.That(testMod.DrainRate.Value, Is.Null);
|
Assert.That(testMod.DrainRate.Value, Is.Null);
|
||||||
|
|
||||||
// ReSharper disable once HeuristicUnreachableCode
|
|
||||||
// see https://youtrack.jetbrains.com/issue/RIDER-70159.
|
|
||||||
Assert.That(testMod.OverallDifficulty.Value, Is.Null);
|
Assert.That(testMod.OverallDifficulty.Value, Is.Null);
|
||||||
|
|
||||||
var applied = applyDifficulty(new BeatmapDifficulty
|
var applied = applyDifficulty(new BeatmapDifficulty
|
||||||
@ -119,6 +118,48 @@ namespace osu.Game.Tests.Mods
|
|||||||
Assert.That(applied.OverallDifficulty, Is.EqualTo(10));
|
Assert.That(applied.OverallDifficulty, Is.EqualTo(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDeserializeIncorrectRange()
|
||||||
|
{
|
||||||
|
var apiMod = new APIMod
|
||||||
|
{
|
||||||
|
Acronym = @"DA",
|
||||||
|
Settings = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
[@"circle_size"] = -727,
|
||||||
|
[@"approach_rate"] = -727,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var ruleset = new OsuRuleset();
|
||||||
|
|
||||||
|
var mod = (OsuModDifficultyAdjust)apiMod.ToMod(ruleset);
|
||||||
|
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
|
Assert.That(mod.CircleSize.Value, Is.GreaterThanOrEqualTo(0).And.LessThanOrEqualTo(11));
|
||||||
|
Assert.That(mod.ApproachRate.Value, Is.GreaterThanOrEqualTo(-10).And.LessThanOrEqualTo(11));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDeserializeNegativeApproachRate()
|
||||||
|
{
|
||||||
|
var apiMod = new APIMod
|
||||||
|
{
|
||||||
|
Acronym = @"DA",
|
||||||
|
Settings = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
[@"approach_rate"] = -9,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var ruleset = new OsuRuleset();
|
||||||
|
|
||||||
|
var mod = (OsuModDifficultyAdjust)apiMod.ToMod(ruleset);
|
||||||
|
|
||||||
|
Assert.That(mod.ApproachRate.Value, Is.GreaterThanOrEqualTo(-10).And.LessThanOrEqualTo(11));
|
||||||
|
Assert.That(mod.ApproachRate.Value, Is.EqualTo(-9));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Applies a <see cref="BeatmapDifficulty"/> to the mod and returns a new <see cref="BeatmapDifficulty"/>
|
/// Applies a <see cref="BeatmapDifficulty"/> to the mod and returns a new <see cref="BeatmapDifficulty"/>
|
||||||
/// representing the result if the mod were applied to a fresh <see cref="BeatmapDifficulty"/> instance.
|
/// representing the result if the mod were applied to a fresh <see cref="BeatmapDifficulty"/> instance.
|
||||||
|
@ -70,7 +70,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestOutOfRangeValueStillApplied()
|
public void TestValueAboveRangeStillApplied()
|
||||||
{
|
{
|
||||||
AddStep("set override cs to 11", () => modDifficultyAdjust.CircleSize.Value = 11);
|
AddStep("set override cs to 11", () => modDifficultyAdjust.CircleSize.Value = 11);
|
||||||
|
|
||||||
@ -91,6 +91,28 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
checkBindableAtValue("Circle Size", 11);
|
checkBindableAtValue("Circle Size", 11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestValueBelowRangeStillApplied()
|
||||||
|
{
|
||||||
|
AddStep("set override cs to -5", () => modDifficultyAdjust.ApproachRate.Value = -5);
|
||||||
|
|
||||||
|
checkSliderAtValue("Approach Rate", -5);
|
||||||
|
checkBindableAtValue("Approach Rate", -5);
|
||||||
|
|
||||||
|
// this is a no-op, just showing that it won't reset the value during deserialisation.
|
||||||
|
setExtendedLimits(false);
|
||||||
|
|
||||||
|
checkSliderAtValue("Approach Rate", -5);
|
||||||
|
checkBindableAtValue("Approach Rate", -5);
|
||||||
|
|
||||||
|
// setting extended limits will reset the serialisation exception.
|
||||||
|
// this should be fine as the goal is to allow, at most, the value of extended limits.
|
||||||
|
setExtendedLimits(true);
|
||||||
|
|
||||||
|
checkSliderAtValue("Approach Rate", -5);
|
||||||
|
checkBindableAtValue("Approach Rate", -5);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestExtendedLimits()
|
public void TestExtendedLimits()
|
||||||
{
|
{
|
||||||
@ -109,6 +131,11 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
checkSliderAtValue("Circle Size", 11);
|
checkSliderAtValue("Circle Size", 11);
|
||||||
checkBindableAtValue("Circle Size", 11);
|
checkBindableAtValue("Circle Size", 11);
|
||||||
|
|
||||||
|
setSliderValue("Approach Rate", -5);
|
||||||
|
|
||||||
|
checkSliderAtValue("Approach Rate", -5);
|
||||||
|
checkBindableAtValue("Approach Rate", -5);
|
||||||
|
|
||||||
setExtendedLimits(false);
|
setExtendedLimits(false);
|
||||||
|
|
||||||
checkSliderAtValue("Circle Size", 10);
|
checkSliderAtValue("Circle Size", 10);
|
||||||
|
@ -38,6 +38,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
|
|
||||||
public float MinValue
|
public float MinValue
|
||||||
{
|
{
|
||||||
|
get => minValue;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == minValue)
|
if (value == minValue)
|
||||||
@ -52,6 +53,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
|
|
||||||
public float MaxValue
|
public float MaxValue
|
||||||
{
|
{
|
||||||
|
get => maxValue;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == maxValue)
|
if (value == maxValue)
|
||||||
@ -69,6 +71,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public float? ExtendedMinValue
|
public float? ExtendedMinValue
|
||||||
{
|
{
|
||||||
|
get => extendedMinValue;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == extendedMinValue)
|
if (value == extendedMinValue)
|
||||||
@ -86,6 +89,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public float? ExtendedMaxValue
|
public float? ExtendedMaxValue
|
||||||
{
|
{
|
||||||
|
get => extendedMaxValue;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == extendedMaxValue)
|
if (value == extendedMaxValue)
|
||||||
@ -114,9 +118,14 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
{
|
{
|
||||||
// Ensure that in the case serialisation runs in the wrong order (and limit extensions aren't applied yet) the deserialised value is still propagated.
|
// 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 (value != null)
|
if (value != null)
|
||||||
CurrentNumber.MaxValue = MathF.Max(CurrentNumber.MaxValue, value.Value);
|
{
|
||||||
|
CurrentNumber.MinValue = Math.Clamp(MathF.Min(CurrentNumber.MinValue, value.Value), ExtendedMinValue ?? MinValue, MinValue);
|
||||||
|
CurrentNumber.MaxValue = Math.Clamp(MathF.Max(CurrentNumber.MaxValue, value.Value), MaxValue, ExtendedMaxValue ?? MaxValue);
|
||||||
|
|
||||||
base.Value = value;
|
base.Value = Math.Clamp(value.Value, CurrentNumber.MinValue, CurrentNumber.MaxValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
base.Value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +147,8 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
// the following max value copies are only safe as long as these values are effectively constants.
|
// the following max value copies are only safe as long as these values are effectively constants.
|
||||||
otherDifficultyBindable.MaxValue = maxValue;
|
otherDifficultyBindable.MaxValue = maxValue;
|
||||||
otherDifficultyBindable.ExtendedMaxValue = extendedMaxValue;
|
otherDifficultyBindable.ExtendedMaxValue = extendedMaxValue;
|
||||||
|
otherDifficultyBindable.MinValue = minValue;
|
||||||
|
otherDifficultyBindable.ExtendedMinValue = extendedMinValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void BindTo(Bindable<float?> them)
|
public override void BindTo(Bindable<float?> them)
|
||||||
|
Loading…
Reference in New Issue
Block a user