mirror of
https://github.com/ppy/osu.git
synced 2024-12-16 16:22:57 +08:00
66643a97b0
Although this isn't necessary for existing official rulesets and calculators, custom calculators can have use cases for accessing mods in difficulty calculation. For example, accounting for the effects of visual mods.
222 lines
8.8 KiB
C#
222 lines
8.8 KiB
C#
// 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.Collections.Generic;
|
|
using NUnit.Framework;
|
|
using osu.Game.Beatmaps;
|
|
using osu.Game.Rulesets.Difficulty;
|
|
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
|
using osu.Game.Rulesets.Difficulty.Skills;
|
|
using osu.Game.Rulesets.Mods;
|
|
|
|
namespace osu.Game.Tests.NonVisual
|
|
{
|
|
[TestFixture]
|
|
public class DifficultyAdjustmentModCombinationsTest
|
|
{
|
|
[Test]
|
|
public void TestNoMods()
|
|
{
|
|
var combinations = new TestLegacyDifficultyCalculator().CreateDifficultyAdjustmentModCombinations();
|
|
|
|
Assert.AreEqual(1, combinations.Length);
|
|
Assert.IsTrue(combinations[0] is ModNoMod);
|
|
}
|
|
|
|
[Test]
|
|
public void TestSingleMod()
|
|
{
|
|
var combinations = new TestLegacyDifficultyCalculator(new ModA()).CreateDifficultyAdjustmentModCombinations();
|
|
|
|
Assert.AreEqual(2, combinations.Length);
|
|
Assert.IsTrue(combinations[0] is ModNoMod);
|
|
Assert.IsTrue(combinations[1] is ModA);
|
|
}
|
|
|
|
[Test]
|
|
public void TestDoubleMod()
|
|
{
|
|
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new ModB()).CreateDifficultyAdjustmentModCombinations();
|
|
|
|
Assert.AreEqual(4, combinations.Length);
|
|
Assert.IsTrue(combinations[0] is ModNoMod);
|
|
Assert.IsTrue(combinations[1] is ModA);
|
|
Assert.IsTrue(combinations[2] is MultiMod);
|
|
Assert.IsTrue(combinations[3] is ModB);
|
|
|
|
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA);
|
|
Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModB);
|
|
}
|
|
|
|
[Test]
|
|
public void TestIncompatibleMods()
|
|
{
|
|
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new ModIncompatibleWithA()).CreateDifficultyAdjustmentModCombinations();
|
|
|
|
Assert.AreEqual(3, combinations.Length);
|
|
Assert.IsTrue(combinations[0] is ModNoMod);
|
|
Assert.IsTrue(combinations[1] is ModA);
|
|
Assert.IsTrue(combinations[2] is ModIncompatibleWithA);
|
|
}
|
|
|
|
[Test]
|
|
public void TestDoubleIncompatibleMods()
|
|
{
|
|
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new ModB(), new ModIncompatibleWithA(), new ModIncompatibleWithAAndB()).CreateDifficultyAdjustmentModCombinations();
|
|
|
|
Assert.AreEqual(8, combinations.Length);
|
|
Assert.IsTrue(combinations[0] is ModNoMod);
|
|
Assert.IsTrue(combinations[1] is ModA);
|
|
Assert.IsTrue(combinations[2] is MultiMod);
|
|
Assert.IsTrue(combinations[3] is ModB);
|
|
Assert.IsTrue(combinations[4] is MultiMod);
|
|
Assert.IsTrue(combinations[5] is ModIncompatibleWithA);
|
|
Assert.IsTrue(combinations[6] is MultiMod);
|
|
Assert.IsTrue(combinations[7] is ModIncompatibleWithAAndB);
|
|
|
|
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA);
|
|
Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModB);
|
|
Assert.IsTrue(((MultiMod)combinations[4]).Mods[0] is ModB);
|
|
Assert.IsTrue(((MultiMod)combinations[4]).Mods[1] is ModIncompatibleWithA);
|
|
Assert.IsTrue(((MultiMod)combinations[6]).Mods[0] is ModIncompatibleWithA);
|
|
Assert.IsTrue(((MultiMod)combinations[6]).Mods[1] is ModIncompatibleWithAAndB);
|
|
}
|
|
|
|
[Test]
|
|
public void TestIncompatibleThroughBaseType()
|
|
{
|
|
var combinations = new TestLegacyDifficultyCalculator(new ModAofA(), new ModIncompatibleWithAofA()).CreateDifficultyAdjustmentModCombinations();
|
|
|
|
Assert.AreEqual(3, combinations.Length);
|
|
Assert.IsTrue(combinations[0] is ModNoMod);
|
|
Assert.IsTrue(combinations[1] is ModAofA);
|
|
Assert.IsTrue(combinations[2] is ModIncompatibleWithAofA);
|
|
}
|
|
|
|
[Test]
|
|
public void TestMultiModFlattening()
|
|
{
|
|
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new MultiMod(new ModB(), new ModC())).CreateDifficultyAdjustmentModCombinations();
|
|
|
|
Assert.AreEqual(4, combinations.Length);
|
|
Assert.IsTrue(combinations[0] is ModNoMod);
|
|
Assert.IsTrue(combinations[1] is ModA);
|
|
Assert.IsTrue(combinations[2] is MultiMod);
|
|
Assert.IsTrue(combinations[3] is MultiMod);
|
|
|
|
Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA);
|
|
Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModB);
|
|
Assert.IsTrue(((MultiMod)combinations[2]).Mods[2] is ModC);
|
|
Assert.IsTrue(((MultiMod)combinations[3]).Mods[0] is ModB);
|
|
Assert.IsTrue(((MultiMod)combinations[3]).Mods[1] is ModC);
|
|
}
|
|
|
|
[Test]
|
|
public void TestIncompatibleThroughMultiMod()
|
|
{
|
|
var combinations = new TestLegacyDifficultyCalculator(new ModA(), new MultiMod(new ModB(), new ModIncompatibleWithA())).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 ModB);
|
|
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
|
|
{
|
|
public override string Name => nameof(ModA);
|
|
public override string Acronym => nameof(ModA);
|
|
public override double ScoreMultiplier => 1;
|
|
|
|
public override Type[] IncompatibleMods => new[] { typeof(ModIncompatibleWithA), typeof(ModIncompatibleWithAAndB) };
|
|
}
|
|
|
|
private class ModB : Mod
|
|
{
|
|
public override string Name => nameof(ModB);
|
|
public override string Acronym => nameof(ModB);
|
|
public override double ScoreMultiplier => 1;
|
|
|
|
public override Type[] IncompatibleMods => new[] { typeof(ModIncompatibleWithAAndB) };
|
|
}
|
|
|
|
private class ModC : Mod
|
|
{
|
|
public override string Name => nameof(ModC);
|
|
public override string Acronym => nameof(ModC);
|
|
public override double ScoreMultiplier => 1;
|
|
}
|
|
|
|
private class ModIncompatibleWithA : Mod
|
|
{
|
|
public override string Name => $"Incompatible With {nameof(ModA)}";
|
|
public override string Acronym => $"Incompatible With {nameof(ModA)}";
|
|
public override double ScoreMultiplier => 1;
|
|
|
|
public override Type[] IncompatibleMods => new[] { typeof(ModA) };
|
|
}
|
|
|
|
private class ModAofA : ModA
|
|
{
|
|
}
|
|
|
|
private class ModIncompatibleWithAofA : ModIncompatibleWithA
|
|
{
|
|
// Incompatible through base type
|
|
}
|
|
|
|
private class ModIncompatibleWithAAndB : Mod
|
|
{
|
|
public override string Name => $"Incompatible With {nameof(ModA)} and {nameof(ModB)}";
|
|
public override string Acronym => $"Incompatible With {nameof(ModA)} and {nameof(ModB)}";
|
|
public override double ScoreMultiplier => 1;
|
|
|
|
public override Type[] IncompatibleMods => new[] { typeof(ModA), typeof(ModB) };
|
|
}
|
|
|
|
private class TestLegacyDifficultyCalculator : DifficultyCalculator
|
|
{
|
|
public TestLegacyDifficultyCalculator(params Mod[] mods)
|
|
: base(null, null)
|
|
{
|
|
DifficultyAdjustmentMods = mods;
|
|
}
|
|
|
|
protected override Mod[] DifficultyAdjustmentMods { get; }
|
|
|
|
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
}
|
|
}
|