mirror of
https://github.com/ppy/osu.git
synced 2025-01-27 00:23:01 +08:00
Merge pull request #24933 from bdach/scoring-test-mods
Include mod multipliers in scoring test scenes
This commit is contained in:
commit
644dd68180
@ -2,6 +2,8 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -10,7 +12,9 @@ using osu.Game.Rulesets.Catch.Judgements;
|
|||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.Scoring;
|
using osu.Game.Rulesets.Catch.Scoring;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Rulesets.Scoring.Legacy;
|
||||||
using osu.Game.Tests.Visual.Gameplay;
|
using osu.Game.Tests.Visual.Gameplay;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Tests
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
@ -37,11 +41,14 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
return beatmap;
|
return beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IScoringAlgorithm CreateScoreV1() => new ScoreV1 { ScoreMultiplier = { BindTarget = scoreMultiplier } };
|
protected override IScoringAlgorithm CreateScoreV1(IReadOnlyList<Mod> selectedMods)
|
||||||
|
=> new ScoreV1(selectedMods) { ScoreMultiplier = { BindTarget = scoreMultiplier } };
|
||||||
|
|
||||||
protected override IScoringAlgorithm CreateScoreV2(int maxCombo) => new ScoreV2(maxCombo);
|
protected override IScoringAlgorithm CreateScoreV2(int maxCombo, IReadOnlyList<Mod> 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<Mod> selectedMods)
|
||||||
|
=> new CatchProcessorBasedScoringAlgorithm(beatmap, mode, selectedMods);
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestBasicScenarios()
|
public void TestBasicScenarios()
|
||||||
@ -69,10 +76,21 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
|
|
||||||
private class ScoreV1 : IScoringAlgorithm
|
private class ScoreV1 : IScoringAlgorithm
|
||||||
{
|
{
|
||||||
private int currentCombo;
|
private readonly double modMultiplier;
|
||||||
|
|
||||||
public BindableDouble ScoreMultiplier { get; } = new BindableDouble();
|
public BindableDouble ScoreMultiplier { get; } = new BindableDouble();
|
||||||
|
|
||||||
|
private int currentCombo;
|
||||||
|
|
||||||
|
public ScoreV1(IReadOnlyList<Mod> selectedMods)
|
||||||
|
{
|
||||||
|
var ruleset = new CatchRuleset();
|
||||||
|
modMultiplier = ruleset.CreateLegacyScoreSimulator().GetLegacyScoreMultiplier(selectedMods, new LegacyBeatmapConversionDifficultyInfo
|
||||||
|
{
|
||||||
|
SourceRuleset = ruleset.RulesetInfo
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void ApplyHit() => applyHitV1(base_great);
|
public void ApplyHit() => applyHitV1(base_great);
|
||||||
|
|
||||||
public void ApplyNonPerfect() => throw new NotSupportedException("catch does not have \"non-perfect\" judgements.");
|
public void ApplyNonPerfect() => throw new NotSupportedException("catch does not have \"non-perfect\" judgements.");
|
||||||
@ -91,7 +109,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
|
|
||||||
// combo multiplier
|
// combo multiplier
|
||||||
// ReSharper disable once PossibleLossOfFraction
|
// 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++;
|
currentCombo++;
|
||||||
}
|
}
|
||||||
@ -104,13 +122,23 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
private int currentCombo;
|
private int currentCombo;
|
||||||
private double comboPortion;
|
private double comboPortion;
|
||||||
|
|
||||||
|
private readonly double modMultiplier;
|
||||||
|
|
||||||
private readonly double comboPortionMax;
|
private readonly double comboPortionMax;
|
||||||
|
|
||||||
private const double combo_base = 4;
|
private const double combo_base = 4;
|
||||||
private const int combo_cap = 200;
|
private const int combo_cap = 200;
|
||||||
|
|
||||||
public ScoreV2(int maxCombo)
|
public ScoreV2(int maxCombo, IReadOnlyList<Mod> 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++)
|
for (int i = 0; i < maxCombo; i++)
|
||||||
ApplyHit();
|
ApplyHit();
|
||||||
|
|
||||||
@ -135,13 +163,13 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
public long TotalScore
|
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
|
private class CatchProcessorBasedScoringAlgorithm : ProcessorBasedScoringAlgorithm
|
||||||
{
|
{
|
||||||
public CatchProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode)
|
public CatchProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList<Mod> selectedMods)
|
||||||
: base(beatmap, mode)
|
: base(beatmap, mode, selectedMods)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
@ -9,7 +11,9 @@ using osu.Game.Rulesets.Mania.Beatmaps;
|
|||||||
using osu.Game.Rulesets.Mania.Judgements;
|
using osu.Game.Rulesets.Mania.Judgements;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Mania.Scoring;
|
using osu.Game.Rulesets.Mania.Scoring;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Rulesets.Scoring.Legacy;
|
||||||
using osu.Game.Tests.Visual.Gameplay;
|
using osu.Game.Tests.Visual.Gameplay;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Tests
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
@ -25,9 +29,11 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
return beatmap;
|
return beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IScoringAlgorithm CreateScoreV1() => new ScoreV1(MaxCombo.Value);
|
protected override IScoringAlgorithm CreateScoreV1(IReadOnlyList<Mod> selectedMods) => new ScoreV1(MaxCombo.Value, selectedMods);
|
||||||
protected override IScoringAlgorithm CreateScoreV2(int maxCombo) => new ScoreV2(maxCombo);
|
protected override IScoringAlgorithm CreateScoreV2(int maxCombo, IReadOnlyList<Mod> selectedMods) => new ScoreV2(maxCombo, selectedMods);
|
||||||
protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode) => new ManiaProcessorBasedScoringAlgorithm(beatmap, mode);
|
|
||||||
|
protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList<Mod> selectedMods)
|
||||||
|
=> new ManiaProcessorBasedScoringAlgorithm(beatmap, mode, selectedMods);
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestBasicScenarios()
|
public void TestBasicScenarios()
|
||||||
@ -59,11 +65,17 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
private int currentCombo;
|
private int currentCombo;
|
||||||
private double comboAddition = 100;
|
private double comboAddition = 100;
|
||||||
private double totalScoreDouble;
|
private double totalScoreDouble;
|
||||||
|
|
||||||
private readonly double scoreMultiplier;
|
private readonly double scoreMultiplier;
|
||||||
|
|
||||||
public ScoreV1(int maxCombo)
|
public ScoreV1(int maxCombo, IReadOnlyList<Mod> 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);
|
public void ApplyHit() => applyHitV1(320, add => add + 2, 32);
|
||||||
@ -103,13 +115,22 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
|
|
||||||
private readonly double comboPortionMax;
|
private readonly double comboPortionMax;
|
||||||
private readonly int maxCombo;
|
private readonly int maxCombo;
|
||||||
|
private readonly double modMultiplier;
|
||||||
|
|
||||||
private const double combo_base = 4;
|
private const double combo_base = 4;
|
||||||
|
|
||||||
public ScoreV2(int maxCombo)
|
public ScoreV2(int maxCombo, IReadOnlyList<Mod> selectedMods)
|
||||||
{
|
{
|
||||||
this.maxCombo = maxCombo;
|
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++)
|
for (int i = 0; i < this.maxCombo; i++)
|
||||||
ApplyHit();
|
ApplyHit();
|
||||||
|
|
||||||
@ -148,18 +169,18 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
float accuracy = (float)(currentBaseScore / maxBaseScore);
|
float accuracy = (float)(currentBaseScore / maxBaseScore);
|
||||||
|
|
||||||
return (int)Math.Round
|
return (int)Math.Round
|
||||||
(
|
((
|
||||||
200000 * comboPortion / comboPortionMax +
|
200000 * comboPortion / comboPortionMax +
|
||||||
800000 * Math.Pow(accuracy, 2 + 2 * accuracy) * ((double)currentHits / maxCombo)
|
800000 * Math.Pow(accuracy, 2 + 2 * accuracy) * ((double)currentHits / maxCombo)
|
||||||
);
|
) * modMultiplier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ManiaProcessorBasedScoringAlgorithm : ProcessorBasedScoringAlgorithm
|
private class ManiaProcessorBasedScoringAlgorithm : ProcessorBasedScoringAlgorithm
|
||||||
{
|
{
|
||||||
public ManiaProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode)
|
public ManiaProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList<Mod> selectedMods)
|
||||||
: base(beatmap, mode)
|
: base(beatmap, mode, selectedMods)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,15 +2,19 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||||
using osu.Game.Rulesets.Osu.Judgements;
|
using osu.Game.Rulesets.Osu.Judgements;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Scoring;
|
using osu.Game.Rulesets.Osu.Scoring;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Rulesets.Scoring.Legacy;
|
||||||
using osu.Game.Tests.Visual.Gameplay;
|
using osu.Game.Tests.Visual.Gameplay;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Tests
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
@ -32,9 +36,17 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
return beatmap;
|
return beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IScoringAlgorithm CreateScoreV1() => new ScoreV1 { ScoreMultiplier = { BindTarget = scoreMultiplier } };
|
protected override IScoringAlgorithm CreateScoreV1(IReadOnlyList<Mod> selectedMods)
|
||||||
protected override IScoringAlgorithm CreateScoreV2(int maxCombo) => new ScoreV2(maxCombo);
|
=> new ScoreV1(selectedMods)
|
||||||
protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode) => new OsuProcessorBasedScoringAlgorithm(beatmap, mode);
|
{
|
||||||
|
ScoreMultiplier = { BindTarget = scoreMultiplier }
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override IScoringAlgorithm CreateScoreV2(int maxCombo, IReadOnlyList<Mod> selectedMods)
|
||||||
|
=> new ScoreV2(maxCombo, selectedMods);
|
||||||
|
|
||||||
|
protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList<Mod> mods)
|
||||||
|
=> new OsuProcessorBasedScoringAlgorithm(beatmap, mode, mods);
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestBasicScenarios()
|
public void TestBasicScenarios()
|
||||||
@ -71,9 +83,19 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
private class ScoreV1 : IScoringAlgorithm
|
private class ScoreV1 : IScoringAlgorithm
|
||||||
{
|
{
|
||||||
|
private readonly double modMultiplier;
|
||||||
|
public BindableDouble ScoreMultiplier { get; } = new BindableDouble();
|
||||||
|
|
||||||
private int currentCombo;
|
private int currentCombo;
|
||||||
|
|
||||||
public BindableDouble ScoreMultiplier { get; } = new BindableDouble();
|
public ScoreV1(IReadOnlyList<Mod> selectedMods)
|
||||||
|
{
|
||||||
|
var ruleset = new OsuRuleset();
|
||||||
|
modMultiplier = ruleset.CreateLegacyScoreSimulator().GetLegacyScoreMultiplier(selectedMods, new LegacyBeatmapConversionDifficultyInfo
|
||||||
|
{
|
||||||
|
SourceRuleset = ruleset.RulesetInfo
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void ApplyHit() => applyHitV1(base_great);
|
public void ApplyHit() => applyHitV1(base_great);
|
||||||
public void ApplyNonPerfect() => applyHitV1(base_ok);
|
public void ApplyNonPerfect() => applyHitV1(base_ok);
|
||||||
@ -91,7 +113,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
// combo multiplier
|
// combo multiplier
|
||||||
// ReSharper disable once PossibleLossOfFraction
|
// 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++;
|
currentCombo++;
|
||||||
}
|
}
|
||||||
@ -107,13 +129,23 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
private double maxBaseScore;
|
private double maxBaseScore;
|
||||||
private int currentHits;
|
private int currentHits;
|
||||||
|
|
||||||
|
private readonly double modMultiplier;
|
||||||
|
|
||||||
private readonly double comboPortionMax;
|
private readonly double comboPortionMax;
|
||||||
private readonly int maxCombo;
|
private readonly int maxCombo;
|
||||||
|
|
||||||
public ScoreV2(int maxCombo)
|
public ScoreV2(int maxCombo, IReadOnlyList<Mod> selectedMods)
|
||||||
{
|
{
|
||||||
this.maxCombo = maxCombo;
|
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++)
|
for (int i = 0; i < this.maxCombo; i++)
|
||||||
ApplyHit();
|
ApplyHit();
|
||||||
|
|
||||||
@ -152,18 +184,18 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
double accuracy = currentBaseScore / maxBaseScore;
|
double accuracy = currentBaseScore / maxBaseScore;
|
||||||
|
|
||||||
return (int)Math.Round
|
return (int)Math.Round
|
||||||
(
|
((
|
||||||
700000 * comboPortion / comboPortionMax +
|
700000 * comboPortion / comboPortionMax +
|
||||||
300000 * Math.Pow(accuracy, 10) * ((double)currentHits / maxCombo)
|
300000 * Math.Pow(accuracy, 10) * ((double)currentHits / maxCombo)
|
||||||
);
|
) * modMultiplier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class OsuProcessorBasedScoringAlgorithm : ProcessorBasedScoringAlgorithm
|
private class OsuProcessorBasedScoringAlgorithm : ProcessorBasedScoringAlgorithm
|
||||||
{
|
{
|
||||||
public OsuProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode)
|
public OsuProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList<Mod> selectedMods)
|
||||||
: base(beatmap, mode)
|
: base(beatmap, mode, selectedMods)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,15 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Rulesets.Scoring.Legacy;
|
||||||
using osu.Game.Rulesets.Taiko.Beatmaps;
|
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||||
using osu.Game.Rulesets.Taiko.Judgements;
|
using osu.Game.Rulesets.Taiko.Judgements;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
@ -32,10 +36,17 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
return beatmap;
|
return beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IScoringAlgorithm CreateScoreV1() => new ScoreV1 { ScoreMultiplier = { BindTarget = scoreMultiplier } };
|
protected override IScoringAlgorithm CreateScoreV1(IReadOnlyList<Mod> selectedMods)
|
||||||
protected override IScoringAlgorithm CreateScoreV2(int maxCombo) => new ScoreV2(maxCombo);
|
=> new ScoreV1(selectedMods)
|
||||||
|
{
|
||||||
|
ScoreMultiplier = { BindTarget = scoreMultiplier }
|
||||||
|
};
|
||||||
|
|
||||||
protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode) => new TaikoProcessorBasedScoringAlgorithm(beatmap, mode);
|
protected override IScoringAlgorithm CreateScoreV2(int maxCombo, IReadOnlyList<Mod> selectedMods)
|
||||||
|
=> new ScoreV2(maxCombo, selectedMods);
|
||||||
|
|
||||||
|
protected override ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList<Mod> selectedMods)
|
||||||
|
=> new TaikoProcessorBasedScoringAlgorithm(beatmap, mode, selectedMods);
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestBasicScenarios()
|
public void TestBasicScenarios()
|
||||||
@ -72,8 +83,19 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
|
|
||||||
private class ScoreV1 : IScoringAlgorithm
|
private class ScoreV1 : IScoringAlgorithm
|
||||||
{
|
{
|
||||||
|
private readonly double modMultiplier;
|
||||||
|
|
||||||
private int currentCombo;
|
private int currentCombo;
|
||||||
|
|
||||||
|
public ScoreV1(IReadOnlyList<Mod> selectedMods)
|
||||||
|
{
|
||||||
|
var ruleset = new TaikoRuleset();
|
||||||
|
modMultiplier = ruleset.CreateLegacyScoreSimulator().GetLegacyScoreMultiplier(selectedMods, new LegacyBeatmapConversionDifficultyInfo
|
||||||
|
{
|
||||||
|
SourceRuleset = ruleset.RulesetInfo
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public BindableDouble ScoreMultiplier { get; } = new BindableDouble();
|
public BindableDouble ScoreMultiplier { get; } = new BindableDouble();
|
||||||
|
|
||||||
public void ApplyHit() => applyHitV1(base_great);
|
public void ApplyHit() => applyHitV1(base_great);
|
||||||
@ -94,7 +116,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
|
|
||||||
// combo multiplier
|
// combo multiplier
|
||||||
// ReSharper disable once PossibleLossOfFraction
|
// 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++;
|
currentCombo++;
|
||||||
}
|
}
|
||||||
@ -110,15 +132,24 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
private double maxBaseScore;
|
private double maxBaseScore;
|
||||||
private int currentHits;
|
private int currentHits;
|
||||||
|
|
||||||
|
private readonly double modMultiplier;
|
||||||
private readonly double comboPortionMax;
|
private readonly double comboPortionMax;
|
||||||
private readonly int maxCombo;
|
private readonly int maxCombo;
|
||||||
|
|
||||||
private const double combo_base = 4;
|
private const double combo_base = 4;
|
||||||
|
|
||||||
public ScoreV2(int maxCombo)
|
public ScoreV2(int maxCombo, IReadOnlyList<Mod> selectedMods)
|
||||||
{
|
{
|
||||||
this.maxCombo = maxCombo;
|
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++)
|
for (int i = 0; i < this.maxCombo; i++)
|
||||||
ApplyHit();
|
ApplyHit();
|
||||||
|
|
||||||
@ -161,18 +192,18 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
double accuracy = currentBaseScore / maxBaseScore;
|
double accuracy = currentBaseScore / maxBaseScore;
|
||||||
|
|
||||||
return (int)Math.Round
|
return (int)Math.Round
|
||||||
(
|
((
|
||||||
250000 * comboPortion / comboPortionMax +
|
250000 * comboPortion / comboPortionMax +
|
||||||
750000 * Math.Pow(accuracy, 3.6) * ((double)currentHits / maxCombo)
|
750000 * Math.Pow(accuracy, 3.6) * ((double)currentHits / maxCombo)
|
||||||
);
|
) * modMultiplier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TaikoProcessorBasedScoringAlgorithm : ProcessorBasedScoringAlgorithm
|
private class TaikoProcessorBasedScoringAlgorithm : ProcessorBasedScoringAlgorithm
|
||||||
{
|
{
|
||||||
public TaikoProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode)
|
public TaikoProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList<Mod> selectedMods)
|
||||||
: base(beatmap, mode)
|
: base(beatmap, mode, selectedMods)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,8 +18,12 @@ using osu.Game.Graphics;
|
|||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
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.Overlays.Settings;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Scoring.Legacy;
|
using osu.Game.Scoring.Legacy;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -32,9 +36,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
protected abstract IBeatmap CreateBeatmap(int maxCombo);
|
protected abstract IBeatmap CreateBeatmap(int maxCombo);
|
||||||
|
|
||||||
protected abstract IScoringAlgorithm CreateScoreV1();
|
protected abstract IScoringAlgorithm CreateScoreV1(IReadOnlyList<Mod> selectedMods);
|
||||||
protected abstract IScoringAlgorithm CreateScoreV2(int maxCombo);
|
protected abstract IScoringAlgorithm CreateScoreV2(int maxCombo, IReadOnlyList<Mod> selectedMods);
|
||||||
protected abstract ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode);
|
protected abstract ProcessorBasedScoringAlgorithm CreateScoreAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList<Mod> mods);
|
||||||
|
|
||||||
protected Bindable<int> MaxCombo => sliderMaxCombo.Current;
|
protected Bindable<int> MaxCombo => sliderMaxCombo.Current;
|
||||||
protected BindableList<double> NonPerfectLocations => graphs.NonPerfectLocations;
|
protected BindableList<double> NonPerfectLocations => graphs.NonPerfectLocations;
|
||||||
@ -53,6 +57,10 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
private readonly BindableBool scoreV1Visible = new BindableBool(true);
|
private readonly BindableBool scoreV1Visible = new BindableBool(true);
|
||||||
private readonly BindableBool scoreV2Visible = new BindableBool(true);
|
private readonly BindableBool scoreV2Visible = new BindableBool(true);
|
||||||
|
|
||||||
|
private RoundedButton changeModsButton = null!;
|
||||||
|
private OsuSpriteText modsText = null!;
|
||||||
|
private TestModSelectOverlay modSelect = null!;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuColour colours { get; set; } = null!;
|
private OsuColour colours { get; set; } = null!;
|
||||||
|
|
||||||
@ -83,6 +91,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
new Dimension(),
|
new Dimension(),
|
||||||
new Dimension(GridSizeMode.AutoSize),
|
new Dimension(GridSizeMode.AutoSize),
|
||||||
new Dimension(GridSizeMode.AutoSize),
|
new Dimension(GridSizeMode.AutoSize),
|
||||||
|
new Dimension(GridSizeMode.AutoSize),
|
||||||
},
|
},
|
||||||
Content = new[]
|
Content = new[]
|
||||||
{
|
{
|
||||||
@ -104,6 +113,47 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
new Drawable[]
|
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
|
new FillFlowContainer
|
||||||
{
|
{
|
||||||
@ -139,6 +189,11 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
modSelect = new TestModSelectOverlay
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
SelectedMods = { BindTarget = SelectedMods }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -159,6 +214,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
graphs.MaxCombo.BindTo(sliderMaxCombo.Current);
|
graphs.MaxCombo.BindTo(sliderMaxCombo.Current);
|
||||||
|
|
||||||
|
changeModsButton.Action = () => modSelect.Show();
|
||||||
|
SelectedMods.BindValueChanged(mods => Rerun());
|
||||||
|
|
||||||
Rerun();
|
Rerun();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -168,6 +226,10 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
graphs.Clear();
|
graphs.Clear();
|
||||||
legend.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-standardised", colours.Green1, ScoringMode.Standardised, standardisedVisible);
|
||||||
runForProcessor("lazer-classic", colours.Blue1, ScoringMode.Classic, classicVisible);
|
runForProcessor("lazer-classic", colours.Blue1, ScoringMode.Classic, classicVisible);
|
||||||
|
|
||||||
@ -175,14 +237,14 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
Name = "ScoreV1 (classic)",
|
Name = "ScoreV1 (classic)",
|
||||||
Colour = colours.Purple1,
|
Colour = colours.Purple1,
|
||||||
Algorithm = CreateScoreV1(),
|
Algorithm = CreateScoreV1(SelectedMods.Value),
|
||||||
Visible = scoreV1Visible
|
Visible = scoreV1Visible
|
||||||
});
|
});
|
||||||
runForAlgorithm(new ScoringAlgorithmInfo
|
runForAlgorithm(new ScoringAlgorithmInfo
|
||||||
{
|
{
|
||||||
Name = "ScoreV2",
|
Name = "ScoreV2",
|
||||||
Colour = colours.Red1,
|
Colour = colours.Red1,
|
||||||
Algorithm = CreateScoreV2(sliderMaxCombo.Current.Value),
|
Algorithm = CreateScoreV2(sliderMaxCombo.Current.Value, SelectedMods.Value),
|
||||||
Visible = scoreV2Visible
|
Visible = scoreV2Visible
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -209,7 +271,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
int maxCombo = sliderMaxCombo.Current.Value;
|
int maxCombo = sliderMaxCombo.Current.Value;
|
||||||
var beatmap = CreateBeatmap(maxCombo);
|
var beatmap = CreateBeatmap(maxCombo);
|
||||||
var algorithm = CreateScoreAlgorithm(beatmap, scoringMode);
|
var algorithm = CreateScoreAlgorithm(beatmap, scoringMode, SelectedMods.Value);
|
||||||
|
|
||||||
runForAlgorithm(new ScoringAlgorithmInfo
|
runForAlgorithm(new ScoringAlgorithmInfo
|
||||||
{
|
{
|
||||||
@ -282,11 +344,12 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
private readonly ScoreProcessor scoreProcessor;
|
private readonly ScoreProcessor scoreProcessor;
|
||||||
private readonly ScoringMode mode;
|
private readonly ScoringMode mode;
|
||||||
|
|
||||||
protected ProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode)
|
protected ProcessorBasedScoringAlgorithm(IBeatmap beatmap, ScoringMode mode, IReadOnlyList<Mod> selectedMods)
|
||||||
{
|
{
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
scoreProcessor = CreateScoreProcessor();
|
scoreProcessor = CreateScoreProcessor();
|
||||||
scoreProcessor.ApplyBeatmap(beatmap);
|
scoreProcessor.ApplyBeatmap(beatmap);
|
||||||
|
scoreProcessor.Mods.Value = selectedMods;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyHit() => scoreProcessor.ApplyResult(CreatePerfectJudgementResult());
|
public void ApplyHit() => scoreProcessor.ApplyResult(CreatePerfectJudgementResult());
|
||||||
@ -592,5 +655,16 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
lineGraph.Alpha = Visible.Value ? 1 : 0;
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user