diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs index 517f62b6f5..b4cbe03511 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs @@ -14,13 +14,13 @@ namespace osu.Game.Rulesets.Taiko.Tests { protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko"; - [TestCase(2.912326627861987d, 200, "diffcalc-test")] - [TestCase(2.912326627861987d, 200, "diffcalc-test-strong")] + [TestCase(3.3172381854905493d, 200, "diffcalc-test")] + [TestCase(3.3172381854905493d, 200, "diffcalc-test-strong")] public void Test(double expectedStarRating, int expectedMaxCombo, string name) => base.Test(expectedStarRating, expectedMaxCombo, name); - [TestCase(3.9339069955362014d, 200, "diffcalc-test")] - [TestCase(3.9339069955362014d, 200, "diffcalc-test-strong")] + [TestCase(4.4640702427013101d, 200, "diffcalc-test")] + [TestCase(4.4640702427013101d, 200, "diffcalc-test-strong")] public void TestClockRateAdjusted(double expectedStarRating, int expectedMaxCombo, string name) => Test(expectedStarRating, expectedMaxCombo, name, new TaikoModDoubleTime()); diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyAttributes.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyAttributes.cs index ef729e1f07..37e6996e5a 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyAttributes.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyAttributes.cs @@ -40,8 +40,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty [JsonProperty("mono_stamina_factor")] public double MonoStaminaFactor { get; set; } - [JsonProperty("reading_difficult_strains")] - public double ReadingTopStrains { get; set; } + [JsonProperty("rhythm_difficult_strains")] + public double RhythmTopStrains { get; set; } [JsonProperty("colour_difficult_strains")] public double ColourTopStrains { get; set; } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs index f8ff6f6065..3ad9d17526 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs @@ -24,10 +24,13 @@ namespace osu.Game.Rulesets.Taiko.Difficulty public class TaikoDifficultyCalculator : DifficultyCalculator { private const double difficulty_multiplier = 0.084375; - private const double rhythm_skill_multiplier = 1.24 * difficulty_multiplier; + private const double rhythm_skill_multiplier = 0.65 * difficulty_multiplier; private const double reading_skill_multiplier = 0.100 * difficulty_multiplier; private const double colour_skill_multiplier = 0.375 * difficulty_multiplier; - private const double stamina_skill_multiplier = 0.375 * difficulty_multiplier; + private const double stamina_skill_multiplier = 0.445 * difficulty_multiplier; + + private double strainLengthBonus; + private double patternMultiplier; public override int Version => 20241007; @@ -116,8 +119,16 @@ namespace osu.Game.Rulesets.Taiko.Difficulty double monoStaminaFactor = staminaRating == 0 ? 1 : Math.Pow(monoStaminaRating / staminaRating, 5); double colourDifficultStrains = colour.CountTopWeightedStrains(); - double readingDifficultStrains = reading.CountTopWeightedStrains(); - double staminaDifficultStrains = stamina.CountTopWeightedStrains(); + double rhythmDifficultStrains = rhythm.CountTopWeightedStrains(); + // Due to constraints of strain in cases where difficult strain values don't shift with range changes, we manually apply clockrate. + double staminaDifficultStrains = stamina.CountTopWeightedStrains() * clockRate; + + // As we don't have pattern integration in osu!taiko, we apply the other two skills relative to rhythm. + patternMultiplier = Math.Pow(staminaRating * colourRating, 0.10); + + strainLengthBonus = 1 + + Math.Min(Math.Max((staminaDifficultStrains - 1350) / 5000, 0), 0.15) + + Math.Min(Math.Max((staminaRating - 7.0) / 1.0, 0), 0.05); double combinedRating = combinedDifficultyValue(rhythm, reading, colour, stamina, isRelax); double starRating = rescale(combinedRating * 1.4); @@ -125,7 +136,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty // Converts are penalised outside the scope of difficulty calculation, as our assumptions surrounding standard play-styles becomes out-of-scope. if (beatmap.BeatmapInfo.Ruleset.OnlineID == 0) { - starRating *= 0.825; + starRating *= 0.7; // For maps with relax, multiple inputs are more likely to be abused. if (isRelax) @@ -144,7 +155,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty ColourDifficulty = colourRating, StaminaDifficulty = staminaRating, MonoStaminaFactor = monoStaminaFactor, - ReadingTopStrains = readingDifficultStrains, + RhythmTopStrains = rhythmDifficultStrains, ColourTopStrains = colourDifficultStrains, StaminaTopStrains = staminaDifficultStrains, GreatHitWindow = hitWindows.WindowFor(HitResult.Great) / clockRate, @@ -173,10 +184,10 @@ namespace osu.Game.Rulesets.Taiko.Difficulty for (int i = 0; i < colourPeaks.Count; i++) { - double rhythmPeak = rhythmPeaks[i] * rhythm_skill_multiplier; + double rhythmPeak = rhythmPeaks[i] * rhythm_skill_multiplier * patternMultiplier; double readingPeak = readingPeaks[i] * reading_skill_multiplier; double colourPeak = colourPeaks[i] * colour_skill_multiplier; - double staminaPeak = staminaPeaks[i] * stamina_skill_multiplier; + double staminaPeak = staminaPeaks[i] * stamina_skill_multiplier * strainLengthBonus; if (isRelax) { diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 4933c9dee6..c29ea3ba73 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -73,8 +73,10 @@ namespace osu.Game.Rulesets.Taiko.Difficulty private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes) { - double baseDifficulty = 5 * Math.Max(1.0, attributes.StarRating / 0.115) - 4.0; - double difficultyValue = Math.Min(Math.Pow(baseDifficulty, 3) / 69052.51, Math.Pow(baseDifficulty, 2.25) / 1150.0); + double baseDifficulty = 5 * Math.Max(1.0, attributes.StarRating / 0.110) - 4.0; + double difficultyValue = Math.Min(Math.Pow(baseDifficulty, 3) / 69052.51, Math.Pow(baseDifficulty, 2.25) / 1250.0); + + difficultyValue *= 1 + 0.10 * Math.Max(0, attributes.StarRating - 10); double lengthBonus = 1 + 0.1 * Math.Min(1.0, totalHits / 1500.0); difficultyValue *= lengthBonus; @@ -95,7 +97,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty // Scale accuracy more harshly on nearly-completely mono (single coloured) speed maps. double accScalingExponent = 2 + attributes.MonoStaminaFactor; - double accScalingShift = 400 - 100 * attributes.MonoStaminaFactor; + double accScalingShift = 500 - 100 * attributes.MonoStaminaFactor; return difficultyValue * Math.Pow(SpecialFunctions.Erf(accScalingShift / (Math.Sqrt(2) * estimatedUnstableRate.Value)), accScalingExponent); }