From fcf7e0034d0993e29c4b180cc9f24dfe60b4f022 Mon Sep 17 00:00:00 2001 From: TextAdventurer12 Date: Thu, 28 Nov 2024 01:18:02 +1300 Subject: [PATCH 1/5] create clean branch with length changes --- .../Difficulty/OsuDifficultyAttributes.cs | 8 +++++++ .../Difficulty/OsuDifficultyCalculator.cs | 23 +++++++++++++++---- .../Difficulty/OsuPerformanceCalculator.cs | 14 +++-------- .../Difficulty/Skills/OsuStrainSkill.cs | 16 +++++++++++++ 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs index a3c0209a08..718e502178 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs @@ -52,6 +52,14 @@ namespace osu.Game.Rulesets.Osu.Difficulty [JsonProperty("speed_difficult_strain_count")] public double SpeedDifficultStrainCount { get; set; } + // DEV ATTRIBUTE - DO NOT STORE + [JsonProperty("aim_relevant_object_count")] + public double AimRelevantObjectCount { get; set; } + + // DEV ATTRIBUTE - DO NOTE STORE + [JsonProperty("speed_relevant_object_count")] + public double SpeedRelevantObjectCount { get; set; } + /// /// The perceived approach rate inclusive of rate-adjusting mods (DT/HT/etc). /// diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 575e03051c..a9df2bb4aa 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -46,11 +46,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty if (mods.Any(h => h is OsuModFlashlight)) flashlightRating = Math.Sqrt(skills[3].DifficultyValue()) * difficulty_multiplier; - double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1; - double aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).CountTopWeightedStrains(); double speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).CountTopWeightedStrains(); - if (mods.Any(m => m is OsuModTouchDevice)) { aimRating = Math.Pow(aimRating, 0.8); @@ -64,6 +61,22 @@ namespace osu.Game.Rulesets.Osu.Difficulty flashlightRating *= 0.7; } + + double aimRelevantObjectCount = ((OsuStrainSkill)skills[0]).CountRelevantObjects(); + double aimNoSlidersRelevantObjectCount = ((OsuStrainSkill)skills[1]).CountRelevantObjects(); + double speedRelevantObjectCount = ((OsuStrainSkill)skills[2]).CountRelevantObjects(); + + double aimLengthBonus = (aimRelevantObjectCount < 25 ? 0.8 + aimRelevantObjectCount / 150.0 : 0.9 + aimRelevantObjectCount / 375.0); + aimRating *= Math.Cbrt(aimLengthBonus); + double aimNoSlidersLengthBonus = (aimNoSlidersRelevantObjectCount < 25 ? 0.8 + aimNoSlidersRelevantObjectCount / 150.0 : 0.9 + aimNoSlidersRelevantObjectCount / 375.0); + aimRatingNoSliders *= Math.Cbrt(aimNoSlidersLengthBonus); + + double speedLengthBonus = 0.9 + 0.5 * Math.Min(1.0, speedRelevantObjectCount / 500.0) + + (speedRelevantObjectCount > 500 ? Math.Log10(speedRelevantObjectCount / 500.0) * 0.3 : 0.0); + speedRating *= Math.Cbrt(speedLengthBonus); + + double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1; + double baseAimPerformance = OsuStrainSkill.DifficultyToPerformance(aimRating); double baseSpeedPerformance = OsuStrainSkill.DifficultyToPerformance(speedRating); double baseFlashlightPerformance = 0.0; @@ -79,7 +92,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty ); double starRating = basePerformance > 0.00001 - ? Math.Cbrt(OsuPerformanceCalculator.PERFORMANCE_BASE_MULTIPLIER) * 0.027 * (Math.Cbrt(100000 / Math.Pow(2, 1 / 1.1) * basePerformance) + 4) + ? Math.Cbrt(OsuPerformanceCalculator.PERFORMANCE_BASE_MULTIPLIER) * 0.026 * (Math.Cbrt(100000 / Math.Pow(2, 1 / 1.1) * basePerformance) + 4) : 0; double preempt = IBeatmapDifficultyInfo.DifficultyRange(beatmap.Difficulty.ApproachRate, 1800, 1200, 450) / clockRate; @@ -105,6 +118,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty SliderFactor = sliderFactor, AimDifficultStrainCount = aimDifficultyStrainCount, SpeedDifficultStrainCount = speedDifficultyStrainCount, + AimRelevantObjectCount = aimRelevantObjectCount, + SpeedRelevantObjectCount = speedRelevantObjectCount, ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5, OverallDifficulty = (80 - hitWindowGreat) / 6, DrainRate = drainRate, diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs index 31b00dba2b..bed658559f 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty { public class OsuPerformanceCalculator : PerformanceCalculator { - public const double PERFORMANCE_BASE_MULTIPLIER = 1.15; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things. + public const double PERFORMANCE_BASE_MULTIPLIER = 1.152; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things. private bool usingClassicSliderAccuracy; @@ -137,10 +137,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty { double aimValue = OsuStrainSkill.DifficultyToPerformance(attributes.AimDifficulty); - 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); @@ -153,7 +149,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty if (score.Mods.Any(h => h is OsuModRelax)) approachRateFactor = 0.0; - aimValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR. + aimValue *= 1.0 + approachRateFactor; 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); @@ -201,10 +197,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty double speedValue = OsuStrainSkill.DifficultyToPerformance(attributes.SpeedDifficulty); - 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); @@ -212,7 +204,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty if (attributes.ApproachRate > 10.33) approachRateFactor = 0.3 * (attributes.ApproachRate - 10.33); - speedValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR. + speedValue *= 1.0 + approachRateFactor; if (score.Mods.Any(m => m is OsuModBlinds)) { diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs index 6823512cef..d4a85b9856 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs @@ -57,6 +57,22 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills return difficulty; } + /// + /// Returns the number of relevant objects weighted against the top strain. + /// + public double CountRelevantObjects() + { + double consistentTopStrain = DifficultyValue() / 10; // What would the top strain be if all strain values were identical + if (consistentTopStrain == 0) + return 0.0; + + //Being consistently difficult for 1000 notes should be worth more than being consistently difficult for 100. + double totalStrains = ObjectStrains.Count; + double lengthFactor = 0.74 * Math.Pow(0.9987, totalStrains); + //// Use a weighted sum of all strains. Constants are arbitrary and give nice values + return ObjectStrains.Sum(s => (1.1 - lengthFactor)/ (1 + Math.Exp(-10 * (s / consistentTopStrain - 0.88 - lengthFactor / 4.0)))); + } + public static double DifficultyToPerformance(double difficulty) => Math.Pow(5.0 * Math.Max(1.0, difficulty / 0.0675) - 4.0, 3.0) / 100000.0; } } From 9bfcb6474186a21637764c89c5f16a0d71fe57d5 Mon Sep 17 00:00:00 2001 From: kwotaq Date: Thu, 28 Nov 2024 00:15:40 +0200 Subject: [PATCH 2/5] add a log to aim length so it doesn't explode on really really long consistent maps --- osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index a9df2bb4aa..a2f8f21548 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -66,7 +66,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty double aimNoSlidersRelevantObjectCount = ((OsuStrainSkill)skills[1]).CountRelevantObjects(); double speedRelevantObjectCount = ((OsuStrainSkill)skills[2]).CountRelevantObjects(); - double aimLengthBonus = (aimRelevantObjectCount < 25 ? 0.8 + aimRelevantObjectCount / 150.0 : 0.9 + aimRelevantObjectCount / 375.0); + double aimLengthBonus = (aimRelevantObjectCount < 25 ? 0.8 + aimRelevantObjectCount / 150.0 : 0.9 + Math.Min(1.5, aimRelevantObjectCount / 375.0) + + (aimRelevantObjectCount > 562.5 ? Math.Log10(aimRelevantObjectCount / 562.5) : 0)); aimRating *= Math.Cbrt(aimLengthBonus); double aimNoSlidersLengthBonus = (aimNoSlidersRelevantObjectCount < 25 ? 0.8 + aimNoSlidersRelevantObjectCount / 150.0 : 0.9 + aimNoSlidersRelevantObjectCount / 375.0); aimRatingNoSliders *= Math.Cbrt(aimNoSlidersLengthBonus); From ea53e984bd919d378ffa1e711b75be941baad2d0 Mon Sep 17 00:00:00 2001 From: kwotaq Date: Thu, 28 Nov 2024 00:20:14 +0200 Subject: [PATCH 3/5] fix in line --- osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index a2f8f21548..9e24db3b51 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty double speedRelevantObjectCount = ((OsuStrainSkill)skills[2]).CountRelevantObjects(); double aimLengthBonus = (aimRelevantObjectCount < 25 ? 0.8 + aimRelevantObjectCount / 150.0 : 0.9 + Math.Min(1.5, aimRelevantObjectCount / 375.0) + - (aimRelevantObjectCount > 562.5 ? Math.Log10(aimRelevantObjectCount / 562.5) : 0)); + (aimRelevantObjectCount > 562.5 ? Math.Log10(aimRelevantObjectCount / 562.5) : 0)); aimRating *= Math.Cbrt(aimLengthBonus); double aimNoSlidersLengthBonus = (aimNoSlidersRelevantObjectCount < 25 ? 0.8 + aimNoSlidersRelevantObjectCount / 150.0 : 0.9 + aimNoSlidersRelevantObjectCount / 375.0); aimRatingNoSliders *= Math.Cbrt(aimNoSlidersLengthBonus); From d01d01a44b75d1ed4e9cddc6206d79d012386b10 Mon Sep 17 00:00:00 2001 From: TextAdventurer12 Date: Sat, 30 Nov 2024 11:36:04 +1300 Subject: [PATCH 4/5] fix sliderfactor on touch device --- osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 9e24db3b51..0a0b163c70 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -51,6 +51,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty if (mods.Any(m => m is OsuModTouchDevice)) { aimRating = Math.Pow(aimRating, 0.8); + aimRatingNoSliders = Math.Pow(aimRatingNoSliders, 0.8); flashlightRating = Math.Pow(flashlightRating, 0.8); } From 1539ce080546e5c335786c4ccf9b91aa3cb92f28 Mon Sep 17 00:00:00 2001 From: TextAdventurer12 Date: Sat, 30 Nov 2024 11:36:58 +1300 Subject: [PATCH 5/5] fix sliderfactor on relax --- osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 0a0b163c70..ce182d8560 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -48,6 +48,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty double aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).CountTopWeightedStrains(); double speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).CountTopWeightedStrains(); + if (mods.Any(m => m is OsuModTouchDevice)) { aimRating = Math.Pow(aimRating, 0.8); @@ -58,6 +59,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty if (mods.Any(h => h is OsuModRelax)) { aimRating *= 0.9; + aimRatingNoSliders *= 0.9; speedRating = 0.0; flashlightRating *= 0.7; }