Update score conversion to consider legacy multiplier

This commit is contained in:
Dan Balasescu 2023-10-02 16:54:46 +09:00
parent da2a4681d9
commit b9ab4a2b7c
4 changed files with 20 additions and 13 deletions

View File

@ -127,8 +127,9 @@ public void TestDifficultyProcessingWhilePlaying()
});
}
[Test]
public void TestScoreUpgradeSuccess()
[TestCase(30000002)]
[TestCase(30000003)]
public void TestScoreUpgradeSuccess(int scoreVersion)
{
ScoreInfo scoreInfo = null!;
@ -138,7 +139,7 @@ public void TestScoreUpgradeSuccess()
{
r.Add(scoreInfo = new ScoreInfo(ruleset: r.All<RulesetInfo>().First(), beatmap: r.All<BeatmapInfo>().First())
{
TotalScoreVersion = 30000002,
TotalScoreVersion = scoreVersion,
LegacyTotalScore = 123456,
IsLegacyScore = true,
});

View File

@ -235,7 +235,9 @@ private void convertLegacyTotalScoreToStandardised()
Logger.Log("Querying for scores that need total score conversion...");
HashSet<Guid> scoreIds = realmAccess.Run(r => new HashSet<Guid>(r.All<ScoreInfo>()
.Where(s => !s.BackgroundReprocessingFailed && s.BeatmapInfo != null && s.TotalScoreVersion == 30000002)
.Where(s => !s.BackgroundReprocessingFailed && s.BeatmapInfo != null
&& (s.TotalScoreVersion == 30000002
|| s.TotalScoreVersion == 30000003))
.AsEnumerable().Select(s => s.ID)));
Logger.Log($"Found {scoreIds.Count} scores which require total score conversion.");

View File

@ -10,7 +10,6 @@
using osu.Game.Extensions;
using osu.Game.IO.Legacy;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
@ -225,28 +224,30 @@ public static long ConvertFromLegacyTotalScore(ScoreInfo score, BeatmapManager b
ILegacyScoreSimulator sv1Simulator = legacyRuleset.CreateLegacyScoreSimulator();
LegacyScoreAttributes attributes = sv1Simulator.Simulate(beatmap, playableBeatmap);
return ConvertFromLegacyTotalScore(score, attributes);
return ConvertFromLegacyTotalScore(score, LegacyBeatmapConversionDifficultyInfo.FromBeatmap(beatmap.Beatmap), attributes);
}
/// <summary>
/// Converts from <see cref="ScoreInfo.LegacyTotalScore"/> to the new standardised scoring of <see cref="ScoreProcessor"/>.
/// </summary>
/// <param name="score">The score to convert the total score of.</param>
/// <param name="attributes">Difficulty attributes providing the legacy scoring values
/// (<see cref="DifficultyAttributes.LegacyAccuracyScore"/>, <see cref="DifficultyAttributes.LegacyComboScore"/>, and <see cref="DifficultyAttributes.LegacyBonusScoreRatio"/>)
/// for the beatmap which the score was set on.</param>
/// <param name="difficulty">The beatmap difficulty.</param>
/// <param name="attributes">The legacy scoring attributes for the beatmap which the score was set on.</param>
/// <returns>The standardised total score.</returns>
public static long ConvertFromLegacyTotalScore(ScoreInfo score, LegacyScoreAttributes attributes)
public static long ConvertFromLegacyTotalScore(ScoreInfo score, LegacyBeatmapConversionDifficultyInfo difficulty, LegacyScoreAttributes attributes)
{
if (!score.IsLegacyScore)
return score.TotalScore;
Debug.Assert(score.LegacyTotalScore != null);
double modMultiplier = score.Mods.Select(m => m.ScoreMultiplier).Aggregate(1.0, (c, n) => c * n);
Ruleset ruleset = score.Ruleset.CreateInstance();
if (ruleset is not ILegacyRuleset legacyRuleset)
return score.TotalScore;
double legacyModMultiplier = legacyRuleset.CreateLegacyScoreSimulator().GetLegacyScoreMultiplier(score.Mods, difficulty);
int maximumLegacyAccuracyScore = attributes.AccuracyScore;
long maximumLegacyComboScore = (long)Math.Round(attributes.ComboScore * modMultiplier);
long maximumLegacyComboScore = (long)Math.Round(attributes.ComboScore * legacyModMultiplier);
double maximumLegacyBonusRatio = attributes.BonusScoreRatio;
// The part of total score that doesn't include bonus.
@ -258,6 +259,8 @@ public static long ConvertFromLegacyTotalScore(ScoreInfo score, LegacyScoreAttri
// The bonus proportion makes up the rest of the score that exceeds maximumLegacyBaseScore.
double bonusProportion = Math.Max(0, ((long)score.LegacyTotalScore - maximumLegacyBaseScore) * maximumLegacyBonusRatio);
double modMultiplier = score.Mods.Select(m => m.ScoreMultiplier).Aggregate(1.0, (c, n) => c * n);
switch (score.Ruleset.OnlineID)
{
case 0:

View File

@ -30,9 +30,10 @@ public class LegacyScoreEncoder
/// <item><description>30000001: Appends <see cref="LegacyReplaySoloScoreInfo"/> to the end of scores.</description></item>
/// <item><description>30000002: Score stored to replay calculated using the Score V2 algorithm. Legacy scores on this version are candidate to Score V1 -> V2 conversion.</description></item>
/// <item><description>30000003: First version after converting legacy total score to standardised.</description></item>
/// <item><description>30000004: Fixed mod multipliers during legacy score conversion. Reconvert all scores.</description></item>
/// </list>
/// </remarks>
public const int LATEST_VERSION = 30000003;
public const int LATEST_VERSION = 30000004;
/// <summary>
/// The first stable-compatible YYYYMMDD format version given to lazer usage of replays.