mirror of
https://github.com/ppy/osu.git
synced 2025-01-28 14:12:55 +08:00
Fix PF/SD legacy mod conversion
Upon investigating an user report in #6091 that indicated that viewing replays using the Perfect mod would also display the Sudden Death mod icon despite Perfect being the more restrictive of the two, it turned out that the logic of importing legacy scores was missing that corner case. A similar case of Double Time/Nightcore mutual exclusion was handled, but PF/SD was missed. Add analogous handling of PF/SD legacy mods for all four rulesets, and additionally cover a tiny fraction of all cases with unit tests. The most problematic cases (NC+HD and PF+SD) are covered in all four basic rulesets.
This commit is contained in:
parent
089488b295
commit
a407e267a2
@ -0,0 +1,29 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps.Legacy;
|
||||
using osu.Game.Rulesets.Catch.Mods;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class CatchLegacyModConversionTest : LegacyModConversionTest
|
||||
{
|
||||
[TestCase(LegacyMods.Easy, new[] { typeof(CatchModEasy) })]
|
||||
[TestCase(LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(CatchModHardRock), typeof(CatchModDoubleTime) })]
|
||||
[TestCase(LegacyMods.DoubleTime, new[] { typeof(CatchModDoubleTime) })]
|
||||
[TestCase(LegacyMods.Nightcore, new[] { typeof(CatchModNightcore) })]
|
||||
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(CatchModNightcore) })]
|
||||
[TestCase(LegacyMods.Flashlight | LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(CatchModFlashlight), typeof(CatchModNightcore) })]
|
||||
[TestCase(LegacyMods.Perfect, new[] { typeof(CatchModPerfect) })]
|
||||
[TestCase(LegacyMods.SuddenDeath, new[] { typeof(CatchModSuddenDeath) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(CatchModPerfect) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath | LegacyMods.DoubleTime, new[] { typeof(CatchModDoubleTime), typeof(CatchModPerfect) })]
|
||||
public new void Test(LegacyMods legacyMods, Type[] expectedMods) => base.Test(legacyMods, expectedMods);
|
||||
|
||||
protected override Ruleset CreateRuleset() => new CatchRuleset();
|
||||
}
|
||||
}
|
@ -46,6 +46,11 @@ namespace osu.Game.Rulesets.Catch
|
||||
else if (mods.HasFlag(LegacyMods.DoubleTime))
|
||||
yield return new CatchModDoubleTime();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Perfect))
|
||||
yield return new CatchModPerfect();
|
||||
else if (mods.HasFlag(LegacyMods.SuddenDeath))
|
||||
yield return new CatchModSuddenDeath();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Autoplay))
|
||||
yield return new CatchModAutoplay();
|
||||
|
||||
@ -67,14 +72,8 @@ namespace osu.Game.Rulesets.Catch
|
||||
if (mods.HasFlag(LegacyMods.NoFail))
|
||||
yield return new CatchModNoFail();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Perfect))
|
||||
yield return new CatchModPerfect();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Relax))
|
||||
yield return new CatchModRelax();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.SuddenDeath))
|
||||
yield return new CatchModSuddenDeath();
|
||||
}
|
||||
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type)
|
||||
|
@ -0,0 +1,30 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps.Legacy;
|
||||
using osu.Game.Rulesets.Mania.Mods;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class ManiaLegacyModConversionTest : LegacyModConversionTest
|
||||
{
|
||||
[TestCase(LegacyMods.Easy, new[] { typeof(ManiaModEasy) })]
|
||||
[TestCase(LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(ManiaModHardRock), typeof(ManiaModDoubleTime) })]
|
||||
[TestCase(LegacyMods.DoubleTime, new[] { typeof(ManiaModDoubleTime) })]
|
||||
[TestCase(LegacyMods.Nightcore, new[] { typeof(ManiaModNightcore) })]
|
||||
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(ManiaModNightcore) })]
|
||||
[TestCase(LegacyMods.Flashlight | LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(ManiaModFlashlight), typeof(ManiaModNightcore) })]
|
||||
[TestCase(LegacyMods.Perfect, new[] { typeof(ManiaModPerfect) })]
|
||||
[TestCase(LegacyMods.SuddenDeath, new[] { typeof(ManiaModSuddenDeath) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(ManiaModPerfect) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath | LegacyMods.DoubleTime, new[] { typeof(ManiaModDoubleTime), typeof(ManiaModPerfect) })]
|
||||
[TestCase(LegacyMods.Random | LegacyMods.SuddenDeath, new[] { typeof(ManiaModRandom), typeof(ManiaModSuddenDeath) })]
|
||||
public new void Test(LegacyMods legacyMods, Type[] expectedMods) => base.Test(legacyMods, expectedMods);
|
||||
|
||||
protected override Ruleset CreateRuleset() => new ManiaRuleset();
|
||||
}
|
||||
}
|
@ -46,6 +46,11 @@ namespace osu.Game.Rulesets.Mania
|
||||
else if (mods.HasFlag(LegacyMods.DoubleTime))
|
||||
yield return new ManiaModDoubleTime();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Perfect))
|
||||
yield return new ManiaModPerfect();
|
||||
else if (mods.HasFlag(LegacyMods.SuddenDeath))
|
||||
yield return new ManiaModSuddenDeath();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Autoplay))
|
||||
yield return new ManiaModAutoplay();
|
||||
|
||||
@ -97,14 +102,8 @@ namespace osu.Game.Rulesets.Mania
|
||||
if (mods.HasFlag(LegacyMods.NoFail))
|
||||
yield return new ManiaModNoFail();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Perfect))
|
||||
yield return new ManiaModPerfect();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Random))
|
||||
yield return new ManiaModRandom();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.SuddenDeath))
|
||||
yield return new ManiaModSuddenDeath();
|
||||
}
|
||||
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type)
|
||||
|
30
osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs
Normal file
30
osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps.Legacy;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class OsuLegacyModConversionTest : LegacyModConversionTest
|
||||
{
|
||||
[TestCase(LegacyMods.Easy, new[] { typeof(OsuModEasy) })]
|
||||
[TestCase(LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(OsuModHardRock), typeof(OsuModDoubleTime) })]
|
||||
[TestCase(LegacyMods.DoubleTime, new[] { typeof(OsuModDoubleTime) })]
|
||||
[TestCase(LegacyMods.Nightcore, new[] { typeof(OsuModNightcore) })]
|
||||
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(OsuModNightcore) })]
|
||||
[TestCase(LegacyMods.Flashlight | LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(OsuModFlashlight), typeof(OsuModFlashlight) })]
|
||||
[TestCase(LegacyMods.Perfect, new[] { typeof(OsuModPerfect) })]
|
||||
[TestCase(LegacyMods.SuddenDeath, new[] { typeof(OsuModSuddenDeath) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(OsuModPerfect) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath | LegacyMods.DoubleTime, new[] { typeof(OsuModDoubleTime), typeof(OsuModPerfect) })]
|
||||
[TestCase(LegacyMods.SpunOut | LegacyMods.Easy, new[] { typeof(OsuModSpunOut), typeof(OsuModEasy) })]
|
||||
public new void Test(LegacyMods legacyMods, Type[] expectedMods) => base.Test(legacyMods, expectedMods);
|
||||
|
||||
protected override Ruleset CreateRuleset() => new OsuRuleset();
|
||||
}
|
||||
}
|
@ -52,6 +52,11 @@ namespace osu.Game.Rulesets.Osu
|
||||
else if (mods.HasFlag(LegacyMods.DoubleTime))
|
||||
yield return new OsuModDoubleTime();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Perfect))
|
||||
yield return new OsuModPerfect();
|
||||
else if (mods.HasFlag(LegacyMods.SuddenDeath))
|
||||
yield return new OsuModSuddenDeath();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Autopilot))
|
||||
yield return new OsuModAutopilot();
|
||||
|
||||
@ -76,18 +81,12 @@ namespace osu.Game.Rulesets.Osu
|
||||
if (mods.HasFlag(LegacyMods.NoFail))
|
||||
yield return new OsuModNoFail();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Perfect))
|
||||
yield return new OsuModPerfect();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Relax))
|
||||
yield return new OsuModRelax();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.SpunOut))
|
||||
yield return new OsuModSpunOut();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.SuddenDeath))
|
||||
yield return new OsuModSuddenDeath();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Target))
|
||||
yield return new OsuModTarget();
|
||||
|
||||
|
@ -0,0 +1,29 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps.Legacy;
|
||||
using osu.Game.Rulesets.Taiko.Mods;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TaikoLegacyModConversionTest : LegacyModConversionTest
|
||||
{
|
||||
[TestCase(LegacyMods.Easy, new[] { typeof(TaikoModEasy) })]
|
||||
[TestCase(LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(TaikoModHardRock), typeof(TaikoModDoubleTime) })]
|
||||
[TestCase(LegacyMods.DoubleTime, new[] { typeof(TaikoModDoubleTime) })]
|
||||
[TestCase(LegacyMods.Nightcore, new[] { typeof(TaikoModNightcore) })]
|
||||
[TestCase(LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(TaikoModNightcore) })]
|
||||
[TestCase(LegacyMods.Flashlight | LegacyMods.Nightcore | LegacyMods.DoubleTime, new[] { typeof(TaikoModFlashlight), typeof(TaikoModNightcore) })]
|
||||
[TestCase(LegacyMods.Perfect, new[] { typeof(TaikoModPerfect) })]
|
||||
[TestCase(LegacyMods.SuddenDeath, new[] { typeof(TaikoModSuddenDeath) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath, new[] { typeof(TaikoModPerfect) })]
|
||||
[TestCase(LegacyMods.Perfect | LegacyMods.SuddenDeath | LegacyMods.DoubleTime, new[] { typeof(TaikoModDoubleTime), typeof(TaikoModPerfect) })]
|
||||
public new void Test(LegacyMods legacyMods, Type[] expectedMods) => base.Test(legacyMods, expectedMods);
|
||||
|
||||
protected override Ruleset CreateRuleset() => new TaikoRuleset();
|
||||
}
|
||||
}
|
@ -45,6 +45,11 @@ namespace osu.Game.Rulesets.Taiko
|
||||
else if (mods.HasFlag(LegacyMods.DoubleTime))
|
||||
yield return new TaikoModDoubleTime();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Perfect))
|
||||
yield return new TaikoModPerfect();
|
||||
else if (mods.HasFlag(LegacyMods.SuddenDeath))
|
||||
yield return new TaikoModSuddenDeath();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Autoplay))
|
||||
yield return new TaikoModAutoplay();
|
||||
|
||||
@ -66,14 +71,8 @@ namespace osu.Game.Rulesets.Taiko
|
||||
if (mods.HasFlag(LegacyMods.NoFail))
|
||||
yield return new TaikoModNoFail();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Perfect))
|
||||
yield return new TaikoModPerfect();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.Relax))
|
||||
yield return new TaikoModRelax();
|
||||
|
||||
if (mods.HasFlag(LegacyMods.SuddenDeath))
|
||||
yield return new TaikoModSuddenDeath();
|
||||
}
|
||||
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type)
|
||||
|
35
osu.Game/Tests/Beatmaps/LegacyModConversionTest.cs
Normal file
35
osu.Game/Tests/Beatmaps/LegacyModConversionTest.cs
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps.Legacy;
|
||||
using osu.Game.Rulesets;
|
||||
|
||||
namespace osu.Game.Tests.Beatmaps
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for tests of converting <see cref="LegacyMods"/> enumeration flags to ruleset mod instances.
|
||||
/// </summary>
|
||||
public abstract class LegacyModConversionTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates the <see cref="Ruleset"/> whose legacy mod conversion is to be tested.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected abstract Ruleset CreateRuleset();
|
||||
|
||||
protected void Test(LegacyMods legacyMods, Type[] expectedMods)
|
||||
{
|
||||
var ruleset = CreateRuleset();
|
||||
var mods = ruleset.ConvertLegacyMods(legacyMods).ToList();
|
||||
Assert.AreEqual(expectedMods.Length, mods.Count);
|
||||
|
||||
foreach (var modType in expectedMods)
|
||||
{
|
||||
Assert.IsNotNull(mods.SingleOrDefault(mod => mod.GetType() == modType));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user