From e1b8a1589bae578864766632fe7d6da7b77b9354 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 11:15:14 +0900 Subject: [PATCH 1/3] Fix TimeRate not being considered for performance calculation --- .../Scoring/OsuPerformanceCalculator.cs | 24 +++++++++++++++---- osu.Game/Beatmaps/DifficultyCalculator.cs | 2 +- .../Rulesets/Scoring/PerformanceCalculator.cs | 15 ++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index a12bdf7f20..aa94572cb4 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -18,7 +18,17 @@ namespace osu.Game.Rulesets.Osu.Scoring private readonly int beatmapMaxCombo; private Mod[] mods; + + /// + /// Approach rate adjusted by mods. + /// private double realApproachRate; + + /// + /// Overall difficulty adjusted by mods. + /// + private double realOverallDifficulty; + private double accuracy; private int scoreMaxCombo; private int count300; @@ -58,9 +68,13 @@ namespace osu.Game.Rulesets.Osu.Scoring ar = Math.Min(10, ar * 1.4); if (mods.Any(m => m is OsuModEasy)) ar = Math.Max(0, ar / 2); - double preEmpt = BeatmapDifficulty.DifficultyRange(ar, 1800, 1200, 450); - realApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5; + double preEmpt = BeatmapDifficulty.DifficultyRange(ar, 1800, 1200, 450) / TimeRate; + double hitWindow300 = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate; + + realApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5; + realOverallDifficulty = (80 - 0.5 - hitWindow300) / 6; + // Custom multipliers for NoFail and SpunOut. double multiplier = 1.12f; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things @@ -133,7 +147,7 @@ namespace osu.Game.Rulesets.Osu.Scoring // Scale the aim value with accuracy _slightly_ aimValue *= 0.5f + accuracy / 2.0f; // It is important to also consider accuracy difficulty when doing that - aimValue *= 0.98f + Math.Pow(Beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty, 2) / 2500; + aimValue *= 0.98f + Math.Pow(realOverallDifficulty, 2) / 2500; return aimValue; } @@ -159,7 +173,7 @@ namespace osu.Game.Rulesets.Osu.Scoring // Scale the speed value with accuracy _slightly_ speedValue *= 0.5f + accuracy / 2.0f; // It is important to also consider accuracy difficulty when doing that - speedValue *= 0.98f + Math.Pow(Beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty, 2) / 2500; + speedValue *= 0.98f + Math.Pow(realOverallDifficulty, 2) / 2500; return speedValue; } @@ -181,7 +195,7 @@ namespace osu.Game.Rulesets.Osu.Scoring // Lots of arbitrary values from testing. // Considering to use derivation from perfect accuracy in a probabilistic manner - assume normal distribution - double accuracyValue = Math.Pow(1.52163f, Beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty) * Math.Pow(betterAccuracyPercentage, 24) * 2.83f; + double accuracyValue = Math.Pow(1.52163f, realOverallDifficulty) * Math.Pow(betterAccuracyPercentage, 24) * 2.83f; // Bonus for many hitcircles - it's harder to keep good accuracy up for longer accuracyValue *= Math.Min(1.15f, Math.Pow(amountHitObjectsWithAccuracy / 1000.0f, 0.3f)); diff --git a/osu.Game/Beatmaps/DifficultyCalculator.cs b/osu.Game/Beatmaps/DifficultyCalculator.cs index 37155c09cd..5cac9ed923 100644 --- a/osu.Game/Beatmaps/DifficultyCalculator.cs +++ b/osu.Game/Beatmaps/DifficultyCalculator.cs @@ -14,7 +14,7 @@ namespace osu.Game.Beatmaps protected readonly IBeatmap Beatmap; protected readonly Mod[] Mods; - protected double TimeRate = 1; + protected double TimeRate { get; private set; } = 1; protected DifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) { diff --git a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs b/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs index 5b8f5f0d0f..b23e06e15c 100644 --- a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs +++ b/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs @@ -2,7 +2,11 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.Linq; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Timing; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Scoring { @@ -14,6 +18,8 @@ namespace osu.Game.Rulesets.Scoring protected readonly IBeatmap Beatmap; protected readonly Score Score; + protected double TimeRate { get; private set; } = 1; + protected PerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) { Score = score; @@ -22,6 +28,15 @@ namespace osu.Game.Rulesets.Scoring var diffCalc = ruleset.CreateDifficultyCalculator(beatmap, score.Mods); diffCalc.Calculate(attributes); + + ApplyMods(score.Mods); + } + + protected virtual void ApplyMods(Mod[] mods) + { + var clock = new StopwatchClock(); + mods.OfType().ForEach(m => m.ApplyToClock(clock)); + TimeRate = clock.Rate; } public abstract double Calculate(Dictionary categoryDifficulty = null); From ce6b4cc2d30d60480793d1c94838f0f0e6500680 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 11:15:37 +0900 Subject: [PATCH 2/3] Add more attributes to OsuPerformanceCalculator's output --- osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index aa94572cb4..e927cc946e 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -99,6 +99,9 @@ namespace osu.Game.Rulesets.Osu.Scoring categoryRatings.Add("Aim", aimValue); categoryRatings.Add("Speed", speedValue); categoryRatings.Add("Accuracy", accuracyValue); + categoryRatings.Add("OD", realOverallDifficulty); + categoryRatings.Add("AR", realApproachRate); + categoryRatings.Add("Max Combo", beatmapMaxCombo); } return totalValue; From a81921118dac58379808e0c55a0b281c02ffdf5b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 11:52:22 +0900 Subject: [PATCH 3/3] Strip whitespaces --- .../Scoring/OsuPerformanceCalculator.cs | 12 ++++++------ osu.Game/Rulesets/Scoring/PerformanceCalculator.cs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index e927cc946e..4942a55004 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -18,17 +18,17 @@ namespace osu.Game.Rulesets.Osu.Scoring private readonly int beatmapMaxCombo; private Mod[] mods; - + /// /// Approach rate adjusted by mods. /// private double realApproachRate; - + /// /// Overall difficulty adjusted by mods. /// private double realOverallDifficulty; - + private double accuracy; private int scoreMaxCombo; private int count300; @@ -70,11 +70,11 @@ namespace osu.Game.Rulesets.Osu.Scoring ar = Math.Max(0, ar / 2); double preEmpt = BeatmapDifficulty.DifficultyRange(ar, 1800, 1200, 450) / TimeRate; - double hitWindow300 = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate; - + double hitWindow300 = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate; + realApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5; realOverallDifficulty = (80 - 0.5 - hitWindow300) / 6; - + // Custom multipliers for NoFail and SpunOut. double multiplier = 1.12f; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things diff --git a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs b/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs index b23e06e15c..f2c495fa5d 100644 --- a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs +++ b/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Scoring ApplyMods(score.Mods); } - + protected virtual void ApplyMods(Mod[] mods) { var clock = new StopwatchClock();