diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneScoring.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneScoring.cs index dfdde0a325ec..9f667358db22 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneScoring.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneScoring.cs @@ -2,6 +2,8 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Bindables; using osu.Game.Beatmaps; @@ -10,7 +12,9 @@ using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Scoring; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.Scoring.Legacy; using osu.Game.Tests.Visual.Gameplay; namespace osu.Game.Rulesets.Catch.Tests @@ -37,11 +41,14 @@ protected override IBeatmap CreateBeatmap(int maxCombo) return beatmap; } - protected override IScoringAlgorithm CreateScoreV1() => new ScoreV1 { ScoreMultiplier = { BindTarget = scoreMultiplier } }; + protected override IScoringAlgorithm CreateScoreV1(IReadOnlyList selectedMods) + => new ScoreV1(selectedMods) { ScoreMultiplier = { BindTarget = scoreMultiplier } }; - protected override IScoringAlgorithm CreateScoreV2(int maxCombo) => new ScoreV2(maxCombo); + protected override IScoringAlgorithm CreateScoreV2(int maxCombo, IReadOnlyList selectedMods) + => new ScoreV2(maxCombo, selectedMods); - protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode) => new CatchProcessorBasedScoringAlgorithm(beatmap, mode); + protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList selectedMods) + => new CatchProcessorBasedScoringAlgorithm(beatmap, mode, selectedMods); [Test] public void TestBasicScenarios() @@ -69,10 +76,21 @@ public void TestBasicScenarios() private class ScoreV1 : IScoringAlgorithm { - private int currentCombo; + private readonly double modMultiplier; public BindableDouble ScoreMultiplier { get; } = new BindableDouble(); + private int currentCombo; + + public ScoreV1(IReadOnlyList selectedMods) + { + var ruleset = new CatchRuleset(); + modMultiplier = ruleset.CreateLegacyScoreSimulator().GetLegacyScoreMultiplier(selectedMods, new LegacyBeatmapConversionDifficultyInfo + { + SourceRuleset = ruleset.RulesetInfo + }); + } + public void ApplyHit() => applyHitV1(base_great); public void ApplyNonPerfect() => throw new NotSupportedException("catch does not have \"non-perfect\" judgements."); @@ -91,7 +109,7 @@ private void applyHitV1(int baseScore) // combo multiplier // ReSharper disable once PossibleLossOfFraction - TotalScore += (int)(Math.Max(0, currentCombo - 1) * (baseScore / 25 * ScoreMultiplier.Value)); + TotalScore += (int)(Math.Max(0, currentCombo - 1) * (baseScore / 25 * (ScoreMultiplier.Value * modMultiplier))); currentCombo++; } @@ -104,13 +122,23 @@ private class ScoreV2 : IScoringAlgorithm private int currentCombo; private double comboPortion; + private readonly double modMultiplier; + private readonly double comboPortionMax; private const double combo_base = 4; private const int combo_cap = 200; - public ScoreV2(int maxCombo) + public ScoreV2(int maxCombo, IReadOnlyList selectedMods) { + var ruleset = new CatchRuleset(); + modMultiplier = ruleset.CreateLegacyScoreSimulator().GetLegacyScoreMultiplier( + selectedMods.Append(new ModScoreV2()).ToList(), + new LegacyBeatmapConversionDifficultyInfo + { + SourceRuleset = ruleset.RulesetInfo + }); + for (int i = 0; i < maxCombo; i++) ApplyHit(); @@ -135,13 +163,13 @@ public void ApplyMiss() } public long TotalScore - => (int)Math.Round(1000000 * comboPortion / comboPortionMax); // vast simplification, as we're not doing ticks here. + => (int)Math.Round((1000000 * comboPortion / comboPortionMax) * modMultiplier); // vast simplification, as we're not doing ticks here. } private class CatchProcessorBasedScoringAlgorithm : ProcessorBasedScoringAlgorithm { - public CatchProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode) - : base(beatmap, mode) + public CatchProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList selectedMods) + : base(beatmap, mode, selectedMods) { } diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneScoring.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneScoring.cs index ae3ea861ea97..19d90e055133 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneScoring.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneScoring.cs @@ -2,6 +2,8 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; @@ -9,7 +11,9 @@ using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Scoring; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.Scoring.Legacy; using osu.Game.Tests.Visual.Gameplay; namespace osu.Game.Rulesets.Mania.Tests @@ -25,9 +29,11 @@ protected override IBeatmap CreateBeatmap(int maxCombo) return beatmap; } - protected override IScoringAlgorithm CreateScoreV1() => new ScoreV1(MaxCombo.Value); - protected override IScoringAlgorithm CreateScoreV2(int maxCombo) => new ScoreV2(maxCombo); - protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode) => new ManiaProcessorBasedScoringAlgorithm(beatmap, mode); + protected override IScoringAlgorithm CreateScoreV1(IReadOnlyList selectedMods) => new ScoreV1(MaxCombo.Value, selectedMods); + protected override IScoringAlgorithm CreateScoreV2(int maxCombo, IReadOnlyList selectedMods) => new ScoreV2(maxCombo, selectedMods); + + protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList selectedMods) + => new ManiaProcessorBasedScoringAlgorithm(beatmap, mode, selectedMods); [Test] public void TestBasicScenarios() @@ -59,11 +65,17 @@ private class ScoreV1 : IScoringAlgorithm private int currentCombo; private double comboAddition = 100; private double totalScoreDouble; + private readonly double scoreMultiplier; - public ScoreV1(int maxCombo) + public ScoreV1(int maxCombo, IReadOnlyList selectedMods) { - scoreMultiplier = 500000d / maxCombo; + var ruleset = new ManiaRuleset(); + + scoreMultiplier = 500000d / maxCombo * ruleset.CreateLegacyScoreSimulator().GetLegacyScoreMultiplier(selectedMods, new LegacyBeatmapConversionDifficultyInfo + { + SourceRuleset = ruleset.RulesetInfo + }); } public void ApplyHit() => applyHitV1(320, add => add + 2, 32); @@ -103,13 +115,22 @@ private class ScoreV2 : IScoringAlgorithm private readonly double comboPortionMax; private readonly int maxCombo; + private readonly double modMultiplier; private const double combo_base = 4; - public ScoreV2(int maxCombo) + public ScoreV2(int maxCombo, IReadOnlyList selectedMods) { this.maxCombo = maxCombo; + var ruleset = new ManiaRuleset(); + modMultiplier = new ManiaRuleset().CreateLegacyScoreSimulator().GetLegacyScoreMultiplier( + selectedMods.Append(new ModScoreV2()).ToArray(), + new LegacyBeatmapConversionDifficultyInfo + { + SourceRuleset = ruleset.RulesetInfo + }); + for (int i = 0; i < this.maxCombo; i++) ApplyHit(); @@ -148,18 +169,18 @@ public long TotalScore float accuracy = (float)(currentBaseScore / maxBaseScore); return (int)Math.Round - ( + (( 200000 * comboPortion / comboPortionMax + 800000 * Math.Pow(accuracy, 2 + 2 * accuracy) * ((double)currentHits / maxCombo) - ); + ) * modMultiplier); } } } private class ManiaProcessorBasedScoringAlgorithm : ProcessorBasedScoringAlgorithm { - public ManiaProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode) - : base(beatmap, mode) + public ManiaProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList selectedMods) + : base(beatmap, mode, selectedMods) { } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneScoring.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneScoring.cs index bb09328ab7b3..627c8f416e35 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneScoring.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneScoring.cs @@ -2,15 +2,19 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.Scoring.Legacy; using osu.Game.Tests.Visual.Gameplay; namespace osu.Game.Rulesets.Osu.Tests @@ -32,9 +36,17 @@ protected override IBeatmap CreateBeatmap(int maxCombo) return beatmap; } - protected override IScoringAlgorithm CreateScoreV1() => new ScoreV1 { ScoreMultiplier = { BindTarget = scoreMultiplier } }; - protected override IScoringAlgorithm CreateScoreV2(int maxCombo) => new ScoreV2(maxCombo); - protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode) => new OsuProcessorBasedScoringAlgorithm(beatmap, mode); + protected override IScoringAlgorithm CreateScoreV1(IReadOnlyList selectedMods) + => new ScoreV1(selectedMods) + { + ScoreMultiplier = { BindTarget = scoreMultiplier } + }; + + protected override IScoringAlgorithm CreateScoreV2(int maxCombo, IReadOnlyList selectedMods) + => new ScoreV2(maxCombo, selectedMods); + + protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList mods) + => new OsuProcessorBasedScoringAlgorithm(beatmap, mode, mods); [Test] public void TestBasicScenarios() @@ -71,9 +83,19 @@ public void TestBasicScenarios() private class ScoreV1 : IScoringAlgorithm { + private readonly double modMultiplier; + public BindableDouble ScoreMultiplier { get; } = new BindableDouble(); + private int currentCombo; - public BindableDouble ScoreMultiplier { get; } = new BindableDouble(); + public ScoreV1(IReadOnlyList selectedMods) + { + var ruleset = new OsuRuleset(); + modMultiplier = ruleset.CreateLegacyScoreSimulator().GetLegacyScoreMultiplier(selectedMods, new LegacyBeatmapConversionDifficultyInfo + { + SourceRuleset = ruleset.RulesetInfo + }); + } public void ApplyHit() => applyHitV1(base_great); public void ApplyNonPerfect() => applyHitV1(base_ok); @@ -91,7 +113,7 @@ private void applyHitV1(int baseScore) // combo multiplier // ReSharper disable once PossibleLossOfFraction - TotalScore += (int)(Math.Max(0, currentCombo - 1) * (baseScore / 25 * ScoreMultiplier.Value)); + TotalScore += (int)(Math.Max(0, currentCombo - 1) * (baseScore / 25 * (ScoreMultiplier.Value * modMultiplier))); currentCombo++; } @@ -107,13 +129,23 @@ private class ScoreV2 : IScoringAlgorithm private double maxBaseScore; private int currentHits; + private readonly double modMultiplier; + private readonly double comboPortionMax; private readonly int maxCombo; - public ScoreV2(int maxCombo) + public ScoreV2(int maxCombo, IReadOnlyList selectedMods) { this.maxCombo = maxCombo; + var ruleset = new OsuRuleset(); + modMultiplier = ruleset.CreateLegacyScoreSimulator().GetLegacyScoreMultiplier( + selectedMods.Append(new ModScoreV2()).ToList(), + new LegacyBeatmapConversionDifficultyInfo + { + SourceRuleset = ruleset.RulesetInfo + }); + for (int i = 0; i < this.maxCombo; i++) ApplyHit(); @@ -152,18 +184,18 @@ public long TotalScore double accuracy = currentBaseScore / maxBaseScore; return (int)Math.Round - ( + (( 700000 * comboPortion / comboPortionMax + 300000 * Math.Pow(accuracy, 10) * ((double)currentHits / maxCombo) - ); + ) * modMultiplier); } } } private class OsuProcessorBasedScoringAlgorithm : ProcessorBasedScoringAlgorithm { - public OsuProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode) - : base(beatmap, mode) + public OsuProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList selectedMods) + : base(beatmap, mode, selectedMods) { } diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneScoring.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneScoring.cs index e0650708221c..cf8e3767da3c 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneScoring.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneScoring.cs @@ -2,11 +2,15 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.Scoring.Legacy; using osu.Game.Rulesets.Taiko.Beatmaps; using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Taiko.Objects; @@ -32,10 +36,17 @@ protected override IBeatmap CreateBeatmap(int maxCombo) return beatmap; } - protected override IScoringAlgorithm CreateScoreV1() => new ScoreV1 { ScoreMultiplier = { BindTarget = scoreMultiplier } }; - protected override IScoringAlgorithm CreateScoreV2(int maxCombo) => new ScoreV2(maxCombo); + protected override IScoringAlgorithm CreateScoreV1(IReadOnlyList selectedMods) + => new ScoreV1(selectedMods) + { + ScoreMultiplier = { BindTarget = scoreMultiplier } + }; + + protected override IScoringAlgorithm CreateScoreV2(int maxCombo, IReadOnlyList selectedMods) + => new ScoreV2(maxCombo, selectedMods); - protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode) => new TaikoProcessorBasedScoringAlgorithm(beatmap, mode); + protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList selectedMods) + => new TaikoProcessorBasedScoringAlgorithm(beatmap, mode, selectedMods); [Test] public void TestBasicScenarios() @@ -72,8 +83,19 @@ public void TestBasicScenarios() private class ScoreV1 : IScoringAlgorithm { + private readonly double modMultiplier; + private int currentCombo; + public ScoreV1(IReadOnlyList selectedMods) + { + var ruleset = new TaikoRuleset(); + modMultiplier = ruleset.CreateLegacyScoreSimulator().GetLegacyScoreMultiplier(selectedMods, new LegacyBeatmapConversionDifficultyInfo + { + SourceRuleset = ruleset.RulesetInfo + }); + } + public BindableDouble ScoreMultiplier { get; } = new BindableDouble(); public void ApplyHit() => applyHitV1(base_great); @@ -94,7 +116,7 @@ private void applyHitV1(int baseScore) // combo multiplier // ReSharper disable once PossibleLossOfFraction - TotalScore += (int)((baseScore / 35) * 2 * (ScoreMultiplier.Value + 1)) * (Math.Min(100, currentCombo) / 10); + TotalScore += (int)((baseScore / 35) * 2 * (ScoreMultiplier.Value + 1) * modMultiplier) * (Math.Min(100, currentCombo) / 10); currentCombo++; } @@ -110,15 +132,24 @@ private class ScoreV2 : IScoringAlgorithm private double maxBaseScore; private int currentHits; + private readonly double modMultiplier; private readonly double comboPortionMax; private readonly int maxCombo; private const double combo_base = 4; - public ScoreV2(int maxCombo) + public ScoreV2(int maxCombo, IReadOnlyList selectedMods) { this.maxCombo = maxCombo; + var ruleset = new TaikoRuleset(); + modMultiplier = ruleset.CreateLegacyScoreSimulator().GetLegacyScoreMultiplier( + selectedMods.Append(new ModScoreV2()).ToArray(), + new LegacyBeatmapConversionDifficultyInfo + { + SourceRuleset = ruleset.RulesetInfo + }); + for (int i = 0; i < this.maxCombo; i++) ApplyHit(); @@ -161,18 +192,18 @@ public long TotalScore double accuracy = currentBaseScore / maxBaseScore; return (int)Math.Round - ( + (( 250000 * comboPortion / comboPortionMax + 750000 * Math.Pow(accuracy, 3.6) * ((double)currentHits / maxCombo) - ); + ) * modMultiplier); } } } private class TaikoProcessorBasedScoringAlgorithm : ProcessorBasedScoringAlgorithm { - public TaikoProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode) - : base(beatmap, mode) + public TaikoProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList selectedMods) + : base(beatmap, mode, selectedMods) { } diff --git a/osu.Game/Tests/Visual/Gameplay/ScoringTestScene.cs b/osu.Game/Tests/Visual/Gameplay/ScoringTestScene.cs index de4688a6feac..e7053e42024b 100644 --- a/osu.Game/Tests/Visual/Gameplay/ScoringTestScene.cs +++ b/osu.Game/Tests/Visual/Gameplay/ScoringTestScene.cs @@ -18,8 +18,12 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Overlays; +using osu.Game.Overlays.Mods; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring.Legacy; using osuTK; @@ -32,9 +36,9 @@ public abstract partial class ScoringTestScene : OsuTestScene { protected abstract IBeatmap CreateBeatmap(int maxCombo); - protected abstract IScoringAlgorithm CreateScoreV1(); - protected abstract IScoringAlgorithm CreateScoreV2(int maxCombo); - protected abstract ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode); + protected abstract IScoringAlgorithm CreateScoreV1(IReadOnlyList selectedMods); + protected abstract IScoringAlgorithm CreateScoreV2(int maxCombo, IReadOnlyList selectedMods); + protected abstract ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList mods); protected Bindable MaxCombo => sliderMaxCombo.Current; protected BindableList NonPerfectLocations => graphs.NonPerfectLocations; @@ -53,6 +57,10 @@ public abstract partial class ScoringTestScene : OsuTestScene private readonly BindableBool scoreV1Visible = new BindableBool(true); private readonly BindableBool scoreV2Visible = new BindableBool(true); + private RoundedButton changeModsButton = null!; + private OsuSpriteText modsText = null!; + private TestModSelectOverlay modSelect = null!; + [Resolved] private OsuColour colours { get; set; } = null!; @@ -83,6 +91,7 @@ public void SetUpSteps() new Dimension(), new Dimension(GridSizeMode.AutoSize), new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), }, Content = new[] { @@ -104,6 +113,47 @@ public void SetUpSteps() }, }, new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = 20 }, + Children = new Drawable[] + { + new OsuSpriteText + { + Text = "Selected mods", + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + }, + new FillFlowContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10), + Children = new Drawable[] + { + changeModsButton = new RoundedButton + { + Text = "Change", + Width = 100, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + }, + modsText = new OsuSpriteText + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + }, + } + } + } + } + }, + new Drawable[] { new FillFlowContainer { @@ -139,6 +189,11 @@ public void SetUpSteps() }, }, } + }, + modSelect = new TestModSelectOverlay + { + RelativeSizeAxes = Axes.Both, + SelectedMods = { BindTarget = SelectedMods } } }; @@ -159,6 +214,9 @@ public void SetUpSteps() graphs.MaxCombo.BindTo(sliderMaxCombo.Current); + changeModsButton.Action = () => modSelect.Show(); + SelectedMods.BindValueChanged(mods => Rerun()); + Rerun(); }); } @@ -168,6 +226,10 @@ protected void Rerun() graphs.Clear(); legend.Clear(); + modsText.Text = SelectedMods.Value.Any() + ? string.Join(", ", SelectedMods.Value.Select(mod => mod.Acronym)) + : "(none)"; + runForProcessor("lazer-standardised", colours.Green1, ScoringMode.Standardised, standardisedVisible); runForProcessor("lazer-classic", colours.Blue1, ScoringMode.Classic, classicVisible); @@ -175,14 +237,14 @@ protected void Rerun() { Name = "ScoreV1 (classic)", Colour = colours.Purple1, - Algorithm = CreateScoreV1(), + Algorithm = CreateScoreV1(SelectedMods.Value), Visible = scoreV1Visible }); runForAlgorithm(new ScoringAlgorithmInfo { Name = "ScoreV2", Colour = colours.Red1, - Algorithm = CreateScoreV2(sliderMaxCombo.Current.Value), + Algorithm = CreateScoreV2(sliderMaxCombo.Current.Value, SelectedMods.Value), Visible = scoreV2Visible }); @@ -209,7 +271,7 @@ private void runForProcessor(string name, Color4 colour, ScoringMode scoringMode { int maxCombo = sliderMaxCombo.Current.Value; var beatmap = CreateBeatmap(maxCombo); - var algorithm = CreateScoreAlgorithm(beatmap, scoringMode); + var algorithm = CreateScoreAlgorithm(beatmap, scoringMode, SelectedMods.Value); runForAlgorithm(new ScoringAlgorithmInfo { @@ -282,11 +344,12 @@ protected abstract class ProcessorBasedScoringAlgorithm : IScoringAlgorithm private readonly ScoreProcessor scoreProcessor; private readonly ScoringMode mode; - protected ProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode) + protected ProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList selectedMods) { this.mode = mode; scoreProcessor = CreateScoreProcessor(); scoreProcessor.ApplyBeatmap(beatmap); + scoreProcessor.Mods.Value = selectedMods; } public void ApplyHit() => scoreProcessor.ApplyResult(CreatePerfectJudgementResult()); @@ -592,5 +655,16 @@ private void updateState() lineGraph.Alpha = Visible.Value ? 1 : 0; } } + + private partial class TestModSelectOverlay : UserModSelectOverlay + { + protected override bool ShowModEffects => true; + protected override bool ShowPresets => false; + + public TestModSelectOverlay() + : base(OverlayColourScheme.Aquamarine) + { + } + } } }