1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6namespace App\Libraries\Score;
7
8use App\Enums\Ruleset;
9
10class ScoringMode
11{
12 /**
13 * @see https://github.com/ppy/osu/blob/cd3b455341dd1fe420f62235dab5598a4a15c3e0/osu.Game/Rulesets/Scoring/ScoreProcessor.cs#L32 Client reference
14 */
15 private const int MAX_SCORE = 1000000;
16
17 /**
18 * Convert a "Standardised" score value to a "Classic" score value.
19 *
20 * @see https://github.com/ppy/osu/blob/cd3b455341dd1fe420f62235dab5598a4a15c3e0/osu.Game/Scoring/Legacy/ScoreInfoExtensions.cs#L48-L65 Client reference
21 */
22 public static function convertToClassic(Ruleset $ruleset, int $standardisedScore, int $objectCount): int
23 {
24 // Keep in mind when translating this code from client that PHP and C#
25 // have different behaviour for numeric type conversion and rounding
26 return match ($ruleset) {
27 Ruleset::osu => (int) round(
28 ($objectCount ** 2 * 32.57 + 100000) * $standardisedScore / self::MAX_SCORE,
29 mode: PHP_ROUND_HALF_EVEN,
30 ),
31 Ruleset::taiko => (int) round(
32 ($objectCount * 1109 + 100000) * $standardisedScore / self::MAX_SCORE,
33 mode: PHP_ROUND_HALF_EVEN,
34 ),
35 Ruleset::catch => (int) round(
36 ($standardisedScore / self::MAX_SCORE * $objectCount) ** 2 * 21.62 + $standardisedScore / 10,
37 mode: PHP_ROUND_HALF_EVEN,
38 ),
39 default => $standardisedScore,
40 };
41 }
42}