1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-27 02:42:58 +08:00

Fix same-type incompatibility through multimod

This commit is contained in:
smoogipoo 2020-10-14 19:53:37 +09:00
parent e9ebeedbe2
commit c4fdd35223
2 changed files with 24 additions and 8 deletions

View File

@ -126,6 +126,20 @@ namespace osu.Game.Tests.NonVisual
Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModIncompatibleWithA); Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModIncompatibleWithA);
} }
[Test]
public void TestIncompatibleWithSameInstanceViaMultiMod()
{
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new MultiMod(new ModA(), new ModB())).CreateDifficultyAdjustmentModCombinations();
Assert.AreEqual(3, combinations.Length);
Assert.IsTrue(combinations[0] is ModNoMod);
Assert.IsTrue(combinations[1] is ModA);
Assert.IsTrue(combinations[2] is MultiMod);
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA);
Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModB);
}
private class ModA : Mod private class ModA : Mod
{ {
public override string Name => nameof(ModA); public override string Name => nameof(ModA);

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using osu.Framework.Audio.Track; using osu.Framework.Audio.Track;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -11,6 +12,7 @@ using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills; using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using Sentry;
namespace osu.Game.Rulesets.Difficulty namespace osu.Game.Rulesets.Difficulty
{ {
@ -132,18 +134,18 @@ namespace osu.Game.Rulesets.Difficulty
// Apply the rest of the remaining mods recursively. // Apply the rest of the remaining mods recursively.
for (int i = 0; i < remainingMods.Length; i++) for (int i = 0; i < remainingMods.Length; i++)
{ {
var adjustmentMod = remainingMods.Span[i]; var (nextSet, nextCount) = flatten(remainingMods.Span[i]);
if (currentSet.Any(c => c.IncompatibleMods.Any(m => m.IsInstanceOfType(adjustmentMod)) // Check if any mods in the next set are incompatible with any of the current set.
|| adjustmentMod.IncompatibleMods.Any(m => m.IsInstanceOfType(c)))) if (currentSet.SelectMany(m => m.IncompatibleMods).Any(c => nextSet.Any(c.IsInstanceOfType)))
{
continue; continue;
}
// Append the new mod. // Check if any mods in the next set are the same type as the current set. Mods of the exact same type are not incompatible with themselves.
var (newSet, newSetCount) = flatten(adjustmentMod); if (currentSet.Any(c => nextSet.Any(n => c.GetType() == n.GetType())))
continue;
foreach (var combo in createDifficultyAdjustmentModCombinations(remainingMods.Slice(i + 1), currentSet.Concat(newSet), currentSetCount + newSetCount)) // If all's good, attach the next set to the current set and recurse further.
foreach (var combo in createDifficultyAdjustmentModCombinations(remainingMods.Slice(i + 1), currentSet.Concat(nextSet), currentSetCount + nextCount))
yield return combo; yield return combo;
} }
} }