Skip to content

Commit

Permalink
Merge pull request #26082 from bdach/relax-legacy-score-conversion
Browse files Browse the repository at this point in the history
Fix standardised score conversion failing for scores set with 0.0x mod mutliplier
  • Loading branch information
smoogipoo committed Dec 23, 2023
2 parents fde0276 + 3a2ed36 commit 807ea8a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
30 changes: 23 additions & 7 deletions osu.Game/Database/StandardisedScoreMigrationTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -312,15 +312,21 @@ private static long convertFromLegacyTotalScore(ScoreInfo score, LegacyBeatmapCo

double legacyAccScore = maximumLegacyAccuracyScore * score.Accuracy;
// We can not separate the ComboScore from the BonusScore, so we keep the bonus in the ratio.
double comboProportion =
((double)score.LegacyTotalScore - legacyAccScore) / (maximumLegacyComboScore + maximumLegacyBonusScore);
// Note that `maximumLegacyComboScore + maximumLegacyBonusScore` can actually be 0
// when playing a beatmap with no bonus objects, with mods that have a 0.0x multiplier on stable (relax/autopilot).
// In such cases, just assume 0.
double comboProportion = maximumLegacyComboScore + maximumLegacyBonusScore > 0
? ((double)score.LegacyTotalScore - legacyAccScore) / (maximumLegacyComboScore + maximumLegacyBonusScore)
: 0;

// We assume the bonus proportion only makes up the rest of the score that exceeds maximumLegacyBaseScore.
long maximumLegacyBaseScore = maximumLegacyAccuracyScore + maximumLegacyComboScore;
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);

long convertedTotalScore;

switch (score.Ruleset.OnlineID)
{
case 0:
Expand Down Expand Up @@ -417,32 +423,42 @@ private static long convertFromLegacyTotalScore(ScoreInfo score, LegacyBeatmapCo

double newComboScoreProportion = estimatedComboPortionInStandardisedScore / maximumAchievableComboPortionInStandardisedScore;

return (long)Math.Round((
convertedTotalScore = (long)Math.Round((
500000 * newComboScoreProportion * score.Accuracy
+ 500000 * Math.Pow(score.Accuracy, 5)
+ bonusProportion) * modMultiplier);
break;

case 1:
return (long)Math.Round((
convertedTotalScore = (long)Math.Round((
250000 * comboProportion
+ 750000 * Math.Pow(score.Accuracy, 3.6)
+ bonusProportion) * modMultiplier);
break;

case 2:
return (long)Math.Round((
convertedTotalScore = (long)Math.Round((
600000 * comboProportion
+ 400000 * score.Accuracy
+ bonusProportion) * modMultiplier);
break;

case 3:
return (long)Math.Round((
convertedTotalScore = (long)Math.Round((
850000 * comboProportion
+ 150000 * Math.Pow(score.Accuracy, 2 + 2 * score.Accuracy)
+ bonusProportion) * modMultiplier);
break;

default:
return score.TotalScore;
convertedTotalScore = score.TotalScore;
break;
}

if (convertedTotalScore < 0)
throw new InvalidOperationException($"Total score conversion operation returned invalid total of {convertedTotalScore}");

return convertedTotalScore;
}

public static double ComputeAccuracy(ScoreInfo scoreInfo)
Expand Down
3 changes: 2 additions & 1 deletion osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ public class LegacyScoreEncoder
/// <item><description>30000006: Fix edge cases in conversion after combo exponent introduction that lead to NaNs. Reconvert all scores.</description></item>
/// <item><description>30000007: Adjust osu!mania combo and accuracy portions and judgement scoring values. Reconvert all scores.</description></item>
/// <item><description>30000008: Add accuracy conversion. Reconvert all scores.</description></item>
/// <item><description>30000009: Fix edge cases in conversion for scores which have 0.0x mod multiplier on stable. Reconvert all scores.</description></item>
/// </list>
/// </remarks>
public const int LATEST_VERSION = 30000008;
public const int LATEST_VERSION = 30000009;

/// <summary>
/// The first stable-compatible YYYYMMDD format version given to lazer usage of replays.
Expand Down

0 comments on commit 807ea8a

Please sign in to comment.