diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs index af05084cfe31..70b9f7b066ac 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -55,26 +55,16 @@ protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo s }; } - private double hard_hit_multiplier = 1.0; - private double easy_hit_multiplier = 0.5; private double computeDifficultyValue(ManiaDifficultyAttributes attributes) { - double difficultyValue = 8.0 * Math.Pow(Math.Max(attributes.StarRating - 0.15, 0.05), 2.2); // Star rating to pp curve + double difficultyValue = 8.0 * Math.Pow(Math.Max(attributes.StarRating - 0.15, 0.05), 2.2) // Star rating to pp curve + * Math.Max(0, 5 * scoreAccuracy - 4) // From 80% accuracy, 1/20th of total pp is awarded per additional 1% accuracy + * (1 + 0.1 * Math.Min(1, totalHits / 1500)); // Length bonus, capped at 1500 notes - HardHitMuliplier = hard_hit_multiplier; - EasyHitMuliplier = easy_hit_multiplier; - - CalculateBaseLengthBonus(difficultyValue, attributes.StrainFactor, totalHits); - - double lengthBonus = EasyLengthBonus + HardLengthBonus; - lengthBonus /= 2; - - difficultyValue += lengthBonus; - - return difficultyValue * Math.Max(0, 5 * scoreAccuracy - 4); + return difficultyValue; } - private int totalHits => countPerfect + countOk + countGreat + countGood + countMeh + countMiss; + private double totalHits => countPerfect + countOk + countGreat + countGood + countMeh + countMiss; /// /// Accuracy used to weight judgements independently from the score's actual accuracy. @@ -84,10 +74,7 @@ private double calculateCustomAccuracy() if (totalHits == 0) return 0; - double summedHits = countPerfect * 320 + countGreat * 300 + countGood * 200 + countOk * 100 + countMeh * 50; - summedHits /= totalHits * 320; - - return summedHits; + return (countPerfect * 320 + countGreat * 300 + countGood * 200 + countOk * 100 + countMeh * 50) / (totalHits * 320); } } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs index 27713cd58b53..6ca8d3b3927e 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -140,9 +140,6 @@ protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo s }; } - private const double hard_hit_multiplier = 1.9; //multiplier to balance spikes weigth - private const double easy_hit_multiplier = 1.1; //multiplier to balance filler weigth - private double computeAimValue(ScoreInfo score, OsuDifficultyAttributes attributes) { if (score.Mods.Any(h => h is OsuModAutopilot)) @@ -173,33 +170,23 @@ private double computeAimValue(ScoreInfo score, OsuDifficultyAttributes attribut double aimValue = OsuStrainSkill.DifficultyToPerformance(aimDifficulty); - double approachRateFactor = 0.0; //AR bonus for higher and lower AR + double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) + + (totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0); + aimValue *= lengthBonus; + + if (effectiveMissCount > 0) + aimValue *= calculateMissPenalty(effectiveMissCount, attributes.AimDifficultStrainCount); + double approachRateFactor = 0.0; if (attributes.ApproachRate > 10.33) approachRateFactor = 0.3 * (attributes.ApproachRate - 10.33); else if (attributes.ApproachRate < 8.0) approachRateFactor = 0.05 * (8.0 - attributes.ApproachRate); - HardHitMuliplier = hard_hit_multiplier; - EasyHitMuliplier = easy_hit_multiplier; - - CalculateBaseLengthBonus(aimValue, attributes.AimDifficultyFactor, totalHits); - - double lengthBonus; - - if (!score.Mods.Any(h => h is OsuModRelax)) - { - lengthBonus = EasyLengthBonus + HardLengthBonus * (1.0 + approachRateFactor); - } - else - { - lengthBonus = EasyLengthBonus + HardLengthBonus; - } - - aimValue += lengthBonus; + if (score.Mods.Any(h => h is OsuModRelax)) + approachRateFactor = 0.0; - if (effectiveMissCount > 0) - aimValue *= calculateMissPenalty(effectiveMissCount, attributes.AimDifficultStrainCount); + aimValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR. if (score.Mods.Any(m => m is OsuModBlinds)) aimValue *= 1.3 + (totalHits * (0.0016 / (1 + 2 * effectiveMissCount)) * Math.Pow(accuracy, 16)) * (1 - 0.003 * attributes.DrainRate * attributes.DrainRate); @@ -223,22 +210,21 @@ private double computeSpeedValue(ScoreInfo score, OsuDifficultyAttributes attrib double speedValue = OsuStrainSkill.DifficultyToPerformance(attributes.SpeedDifficulty); - double approachRateFactor = 0.0; //AR bonus for higher and lower AR + double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) + + (totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0); + speedValue *= lengthBonus; + + if (effectiveMissCount > 0) + speedValue *= calculateMissPenalty(effectiveMissCount, attributes.SpeedDifficultStrainCount); + double approachRateFactor = 0.0; if (attributes.ApproachRate > 10.33) approachRateFactor = 0.3 * (attributes.ApproachRate - 10.33); - HardHitMuliplier = hard_hit_multiplier; - EasyHitMuliplier = easy_hit_multiplier; - - CalculateBaseLengthBonus(speedValue, attributes.SpeedDifficultyFactor, totalHits); - - double lengthBonus = EasyLengthBonus + HardLengthBonus * (1.0 + approachRateFactor); - - speedValue += lengthBonus; + if (score.Mods.Any(h => h is OsuModAutopilot)) + approachRateFactor = 0.0; - if (effectiveMissCount > 0) - speedValue *= calculateMissPenalty(effectiveMissCount, attributes.SpeedDifficultStrainCount); + speedValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR. if (score.Mods.Any(m => m is OsuModBlinds)) {