diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 105d3956ac..33dc23b7d8 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -54,14 +54,14 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills public double RelevantNoteCount() { - if (ObjectStrains.Count == 0) + if (ObjectDifficulties.Count == 0) return 0; - double maxStrain = ObjectStrains.Max(); + double maxStrain = ObjectDifficulties.Max(); if (maxStrain == 0) return 0; - return ObjectStrains.Sum(strain => 1.0 / (1.0 + Math.Exp(-(strain / maxStrain * 12.0 - 6.0)))); + return ObjectDifficulties.Sum(strain => 1.0 / (1.0 + Math.Exp(-(strain / maxStrain * 12.0 - 6.0)))); } public double CountTopWeightedSliders(double difficultyValue) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs index 4905dd3275..42a5dad315 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs @@ -186,10 +186,10 @@ namespace osu.Game.Rulesets.Taiko.Difficulty } List hitObjectStrainPeaks = combinePeaks( - rhythm.GetObjectStrains().ToList(), - reading.GetObjectStrains().ToList(), - colour.GetObjectStrains().ToList(), - stamina.GetObjectStrains().ToList() + rhythm.GetObjectDifficulties(), + reading.GetObjectDifficulties(), + colour.GetObjectDifficulties(), + stamina.GetObjectDifficulties() ); if (hitObjectStrainPeaks.Count == 0) @@ -211,7 +211,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty /// /// Combines lists of peak strains from multiple skills into a list of single peak strains for each section. /// - private List combinePeaks(List rhythmPeaks, List readingPeaks, List colourPeaks, List staminaPeaks) + private List combinePeaks(IReadOnlyList rhythmPeaks, IReadOnlyList readingPeaks, IReadOnlyList colourPeaks, IReadOnlyList staminaPeaks) { var combinedPeaks = new List(); diff --git a/osu.Game.Tests/NonVisual/TestSceneTimedDifficultyCalculation.cs b/osu.Game.Tests/NonVisual/TestSceneTimedDifficultyCalculation.cs index f860cd097a..daf0bec44c 100644 --- a/osu.Game.Tests/NonVisual/TestSceneTimedDifficultyCalculation.cs +++ b/osu.Game.Tests/NonVisual/TestSceneTimedDifficultyCalculation.cs @@ -200,8 +200,9 @@ namespace osu.Game.Tests.NonVisual { } - public override void Process(DifficultyHitObject current) + protected override double ProcessInternal(DifficultyHitObject current) { + return 0; } public override double DifficultyValue() => 1; diff --git a/osu.Game/Rulesets/Difficulty/Skills/Skill.cs b/osu.Game/Rulesets/Difficulty/Skills/Skill.cs index 8b8892113b..cf45104c94 100644 --- a/osu.Game/Rulesets/Difficulty/Skills/Skill.cs +++ b/osu.Game/Rulesets/Difficulty/Skills/Skill.cs @@ -20,6 +20,11 @@ namespace osu.Game.Rulesets.Difficulty.Skills /// protected IReadOnlyList Mods => mods; + /// + /// List of calculated per-object difficulties, populated by Process + /// + protected readonly List ObjectDifficulties = new List(); + private readonly Mod[] mods; protected Skill(Mod[] mods) @@ -31,11 +36,19 @@ namespace osu.Game.Rulesets.Difficulty.Skills /// Process a . /// /// The to process. - public abstract void Process(DifficultyHitObject current); + public void Process(DifficultyHitObject current) + { + double difficultyValue = ProcessInternal(current); + ObjectDifficulties.Add(difficultyValue); + } + + protected abstract double ProcessInternal(DifficultyHitObject current); /// /// Returns the calculated difficulty value representing all s that have been processed up to this point. /// public abstract double DifficultyValue(); + + public IReadOnlyList GetObjectDifficulties() => ObjectDifficulties; } } diff --git a/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs b/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs index 1fccf32242..f066be0ec7 100644 --- a/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs +++ b/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs @@ -29,7 +29,6 @@ namespace osu.Game.Rulesets.Difficulty.Skills private double currentSectionEnd; private readonly List strainPeaks = new List(); - protected readonly List ObjectStrains = new List(); // Store individual strains protected StrainSkill(Mod[] mods) : base(mods) @@ -44,7 +43,7 @@ namespace osu.Game.Rulesets.Difficulty.Skills /// /// Process a and update current strain values accordingly. /// - public sealed override void Process(DifficultyHitObject current) + protected sealed override double ProcessInternal(DifficultyHitObject current) { // The first object doesn't generate a strain, so we begin with an incremented section end if (current.Index == 0) @@ -60,8 +59,7 @@ namespace osu.Game.Rulesets.Difficulty.Skills double strain = StrainValueAt(current); currentSectionPeak = Math.Max(strain, currentSectionPeak); - // Store the strain value for the object - ObjectStrains.Add(strain); + return strain; } /// @@ -70,16 +68,16 @@ namespace osu.Game.Rulesets.Difficulty.Skills /// public virtual double CountTopWeightedStrains(double difficultyValue) { - if (ObjectStrains.Count == 0) + if (ObjectDifficulties.Count == 0) return 0.0; double consistentTopStrain = difficultyValue * (1 - DecayWeight); // What would the top strain be if all strain values were identical if (consistentTopStrain == 0) - return ObjectStrains.Count; + return ObjectDifficulties.Count; // Use a weighted sum of all strains. Constants are arbitrary and give nice values - return ObjectStrains.Sum(s => 1.1 / (1 + Math.Exp(-10 * (s / consistentTopStrain - 0.88)))); + return ObjectDifficulties.Sum(s => 1.1 / (1 + Math.Exp(-10 * (s / consistentTopStrain - 0.88)))); } /// @@ -116,8 +114,6 @@ namespace osu.Game.Rulesets.Difficulty.Skills /// public IEnumerable GetCurrentStrainPeaks() => strainPeaks.Append(currentSectionPeak); - public IEnumerable GetObjectStrains() => ObjectStrains; - /// /// Returns the calculated difficulty value representing all s that have been processed up to this point. ///