diff --git a/resources/js/utils/score-helper.ts b/resources/js/utils/score-helper.ts index 750236a9308..b4ea926961f 100644 --- a/resources/js/utils/score-helper.ts +++ b/resources/js/utils/score-helper.ts @@ -106,64 +106,63 @@ export function rank(score: SoloScoreJson) { } export function rankCutoffs(score: SoloScoreJson): number[] { - // : minimum acc => (higher rank acc - current acc) // for SS, use minimum accuracy of 0.99 (any less and it's too small) // actual array is reversed as it's rendered from D to SS clockwise + let absoluteCutoffs: number[] = []; + const ruleset = rulesetName(score.ruleset_id); + if (shouldReturnLegacyValue(score)) { - return { - // SS: 0.99 => 0.01 - // S: 0.9801 => 0.0099 - // A: 0.9401 => 0.04 - // B: 0.9001 => 0.04 - // C: 0.8501 => 0.05 - // D: 0 => 0.8501 - fruits: [0.8501, 0.05, 0.04, 0.04, 0.0099, 0.01], - // SS: 0.99 => 0.01 - // S: 0.95 => 0.04 - // A: 0.9 => 0.05 - // B: 0.8 => 0.1 - // C: 0.7 => 0.1 - // D: 0 => 0.7 - mania: [0.7, 0.1, 0.1, 0.05, 0.04, 0.01], - // SS: 0.99 => 0.01 - // S: (0.9 * 300 + 0.1 * 100) / 300 = 0.933 => 0.057 - // A: (0.8 * 300 + 0.2 * 100) / 300 = 0.867 => 0.066 - // B: (0.7 * 300 + 0.3 * 100) / 300 = 0.8 => 0.067 - // C: 0.6 => 0.2 - // D: 0 => 0.6 - osu: [0.6, 0.2, 0.067, 0.066, 0.057, 0.01], - // SS: 0.99 => 0.01 - // S: (0.9 * 300 + 0.1 * 50) / 300 = 0.917 => 0.073 - // A: (0.8 * 300 + 0.2 * 50) / 300 = 0.833 => 0.084 - // B: (0.7 * 300 + 0.3 * 50) / 300 = 0.75 => 0.083 - // C: 0.6 => 0.15 - // D: 0 => 0.6 - taiko: [0.6, 0.15, 0.083, 0.084, 0.073, 0.01], - }[rulesetName(score.ruleset_id)]; + switch (ruleset) { + case 'fruits': + absoluteCutoffs = [0, 0.8501, 0.9001, 0.9401, 0.9801, 0.99, 1]; + break; + + case 'mania': + absoluteCutoffs = [0, 0.7, 0.8, 0.9, 0.95, 0.99, 1]; + break; + + case 'osu': + // S: (0.9 * 300 + 0.1 * 100) / 300 = 0.933 + // A: (0.8 * 300 + 0.2 * 100) / 300 = 0.867 + // B: (0.7 * 300 + 0.3 * 100) / 300 = 0.8 + absoluteCutoffs = [0, 0.6, 0.8, 0.867, 0.933, 0.99, 1]; + break; + + case 'taiko': + // S: (0.9 * 300 + 0.1 * 50) / 300 = 0.917 + // A: (0.8 * 300 + 0.2 * 50) / 300 = 0.833 + // B: (0.7 * 300 + 0.3 * 50) / 300 = 0.75 + absoluteCutoffs = [0, 0.6, 0.75, 0.833, 0.917, 0.99, 1]; + break; + } + } else { + switch (ruleset) { + case 'fruits': + // cross-reference: https://github.com/ppy/osu/blob/b658d9a681a04101900d5ce6c5b84d56320e08e7/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs#L108-L135 + absoluteCutoffs = [0, 0.85, 0.9, 0.94, 0.98, 0.99, 1]; + break; + + case 'mania': + case 'osu': + case 'taiko': + // cross-reference: https://github.com/ppy/osu/blob/b658d9a681a04101900d5ce6c5b84d56320e08e7/osu.Game/Rulesets/Scoring/ScoreProcessor.cs#L541-L572 + absoluteCutoffs = [0, 0.7, 0.8, 0.9, 0.95, 0.99, 1]; + break; + } + } + + return differenceBetweenConsecutiveElements(absoluteCutoffs); +} + +function differenceBetweenConsecutiveElements(arr: number[]): number[] { + const result = []; + + for (let i = 1; i < arr.length; ++i) { + result.push(arr[i] - arr[i - 1]); } - return { - // SS: 0.99 => 0.01 - // S: 0.98 => 0.01 - // A: 0.94 => 0.04 - // B: 0.9 => 0.04 - // C: 0.85 => 0.05 - // D: 0 => 0.85 - // cross-reference: https://github.com/ppy/osu/blob/b658d9a681a04101900d5ce6c5b84d56320e08e7/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs#L108-L135 - fruits: [0.85, 0.05, 0.04, 0.04, 0.01, 0.01], - // remaining rulesets use the same cutoffs - // SS: 0.99 => 0.01 - // S: 0.95 => 0.04 - // A: 0.9 => 0.05 - // B: 0.8 => 0.1 - // C: 0.7 => 0.1 - // D: 0 => 0.7 - // cross-reference: https://github.com/ppy/osu/blob/b658d9a681a04101900d5ce6c5b84d56320e08e7/osu.Game/Rulesets/Scoring/ScoreProcessor.cs#L541-L572 - mania: [0.7, 0.1, 0.1, 0.05, 0.04, 0.01], - osu: [0.7, 0.1, 0.1, 0.05, 0.04, 0.01], - taiko: [0.7, 0.1, 0.1, 0.05, 0.04, 0.01], - }[rulesetName(score.ruleset_id)]; + return result; } export function scoreDownloadUrl(score: SoloScoreJson) {