diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs index 0054047573..8140ea6eaa 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs @@ -49,6 +49,8 @@ namespace osu.Game.Rulesets.Catch.Difficulty { CatchHitObject lastObject = null; + List objects = new List(); + // In 2B beatmaps, it is possible that a normal Fruit is placed in the middle of a JuiceStream. foreach (var hitObject in beatmap.HitObjects .SelectMany(obj => obj is JuiceStream stream ? stream.NestedHitObjects.AsEnumerable() : new[] { obj }) @@ -60,10 +62,12 @@ namespace osu.Game.Rulesets.Catch.Difficulty continue; if (lastObject != null) - yield return new CatchDifficultyHitObject(hitObject, lastObject, clockRate, halfCatcherWidth); + objects.Add(new CatchDifficultyHitObject(hitObject, lastObject, clockRate, halfCatcherWidth, objects, objects.Count)); lastObject = hitObject; } + + return objects; } protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) diff --git a/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs b/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs index b22ec93b43..3bcfce3a56 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Objects; @@ -24,8 +25,8 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Preprocessing /// public readonly double StrainTime; - public CatchDifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate, float halfCatcherWidth) - : base(hitObject, lastObject, clockRate) + public CatchDifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate, float halfCatcherWidth, List objects, int index) + : base(hitObject, lastObject, clockRate, objects, index) { // We will scale everything by this factor, so we can assume a uniform CircleSize among beatmaps. float scalingFactor = normalized_hitobject_radius / halfCatcherWidth; diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs index 88f51bf961..e90feaf4b4 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs @@ -70,8 +70,12 @@ namespace osu.Game.Rulesets.Mania.Difficulty LegacySortHelper.Sort(sortedObjects, Comparer.Create((a, b) => (int)Math.Round(a.StartTime) - (int)Math.Round(b.StartTime))); + List objects = new List(); + for (int i = 1; i < sortedObjects.Length; i++) - yield return new ManiaDifficultyHitObject(sortedObjects[i], sortedObjects[i - 1], clockRate); + objects.Add(new ManiaDifficultyHitObject(sortedObjects[i], sortedObjects[i - 1], clockRate, objects, objects.Count)); + + return objects; } // Sorting is done in CreateDifficultyHitObjects, since the full list of hitobjects is required. diff --git a/osu.Game.Rulesets.Mania/Difficulty/Preprocessing/ManiaDifficultyHitObject.cs b/osu.Game.Rulesets.Mania/Difficulty/Preprocessing/ManiaDifficultyHitObject.cs index 29ba934e9f..1c4204145b 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/Preprocessing/ManiaDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/Preprocessing/ManiaDifficultyHitObject.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Objects; @@ -11,8 +12,8 @@ namespace osu.Game.Rulesets.Mania.Difficulty.Preprocessing { public new ManiaHitObject BaseObject => (ManiaHitObject)base.BaseObject; - public ManiaDifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate) - : base(hitObject, lastObject, clockRate) + public ManiaDifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate, List objects, int index) + : base(hitObject, lastObject, clockRate, objects, index) { } } diff --git a/osu.Game.Rulesets.Mania/Difficulty/Skills/Strain.cs b/osu.Game.Rulesets.Mania/Difficulty/Skills/Strain.cs index 31550a8105..626f1bebbd 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/Skills/Strain.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/Skills/Strain.cs @@ -84,9 +84,9 @@ namespace osu.Game.Rulesets.Mania.Difficulty.Skills return individualStrain + overallStrain - CurrentStrain; } - protected override double CalculateInitialStrain(double offset) - => applyDecay(individualStrain, offset - Previous[0].StartTime, individual_decay_base) - + applyDecay(overallStrain, offset - Previous[0].StartTime, overall_decay_base); + protected override double CalculateInitialStrain(double offset, DifficultyHitObject current) + => applyDecay(individualStrain, offset - current.Previous(0).StartTime, individual_decay_base) + + applyDecay(overallStrain, offset - current.Previous(0).StartTime, overall_decay_base); private double applyDecay(double value, double deltaTime, double decayBase) => value * Math.Pow(decayBase, deltaTime / 1000); diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 4eb5c79808..0fa69c180a 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -87,16 +87,17 @@ namespace osu.Game.Rulesets.Osu.Difficulty protected override IEnumerable CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) { + List objects = new List(); + // The first jump is formed by the first two hitobjects of the map. // If the map has less than two OsuHitObjects, the enumerator will not return anything. for (int i = 1; i < beatmap.HitObjects.Count; i++) { var lastLast = i > 1 ? beatmap.HitObjects[i - 2] : null; - var last = beatmap.HitObjects[i - 1]; - var current = beatmap.HitObjects[i]; - - yield return new OsuDifficultyHitObject(current, lastLast, last, clockRate); + objects.Add(new OsuDifficultyHitObject(beatmap.HitObjects[i], beatmap.HitObjects[i - 1], lastLast, clockRate, objects, objects.Count)); } + + return objects; } protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs index cf4802d282..20921dd282 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Mods; @@ -74,8 +75,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing private readonly OsuHitObject lastLastObject; private readonly OsuHitObject lastObject; - public OsuDifficultyHitObject(HitObject hitObject, HitObject lastLastObject, HitObject lastObject, double clockRate) - : base(hitObject, lastObject, clockRate) + public OsuDifficultyHitObject(HitObject hitObject, HitObject lastObject, HitObject lastLastObject, double clockRate, List objects, int index) + : base(hitObject, lastObject, clockRate, objects, index) { this.lastLastObject = (OsuHitObject)lastLastObject; this.lastObject = (OsuHitObject)lastObject; diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index a6301aed6d..7e0b9b572b 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -22,8 +22,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills private readonly bool withSliders; - protected override int HistoryLength => 2; - private const double wide_angle_multiplier = 1.5; private const double acute_angle_multiplier = 2.0; private const double slider_multiplier = 1.5; @@ -36,12 +34,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills private double strainValueOf(DifficultyHitObject current) { - if (current.BaseObject is Spinner || Previous.Count <= 1 || Previous[0].BaseObject is Spinner) + if (current.BaseObject is Spinner || current.Index <= 1 || current.Previous(0).BaseObject is Spinner) return 0; var osuCurrObj = (OsuDifficultyHitObject)current; - var osuLastObj = (OsuDifficultyHitObject)Previous[0]; - var osuLastLastObj = (OsuDifficultyHitObject)Previous[1]; + var osuLastObj = (OsuDifficultyHitObject)current.Previous(0); + var osuLastLastObj = (OsuDifficultyHitObject)current.Previous(1); // Calculate the velocity to the current hitobject, which starts with a base distance / time assuming the last object is a hitcircle. double currVelocity = osuCurrObj.LazyJumpDistance / osuCurrObj.StrainTime; @@ -152,7 +150,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000); - protected override double CalculateInitialStrain(double time) => currentStrain * strainDecay(time - Previous[0].StartTime); + protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => currentStrain * strainDecay(time - current.Previous(0).StartTime); protected override double StrainValueAt(DifficultyHitObject current) { diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Flashlight.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Flashlight.cs index d93007fae5..cf0a7d3359 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Flashlight.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Flashlight.cs @@ -25,7 +25,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills private double skillMultiplier => 0.05; private double strainDecayBase => 0.15; protected override double DecayWeight => 1.0; - protected override int HistoryLength => 10; // Look back for 10 notes is added for the sake of flashlight calculations. private readonly bool hidden; @@ -51,9 +50,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills OsuDifficultyHitObject lastObj = osuCurrent; // This is iterating backwards in time from the current object. - for (int i = 0; i < Previous.Count; i++) + for (int i = 0; i < Math.Min(current.Index, 10); i++) { - var currentObj = (OsuDifficultyHitObject)Previous[i]; + var currentObj = (OsuDifficultyHitObject)current.Previous(i); var currentHitObject = (OsuHitObject)(currentObj.BaseObject); if (!(currentObj.BaseObject is Spinner)) @@ -89,7 +88,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000); - protected override double CalculateInitialStrain(double time) => currentStrain * strainDecay(time - Previous[0].StartTime); + protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => currentStrain * strainDecay(time - current.Previous(0).StartTime); protected override double StrainValueAt(DifficultyHitObject current) { diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 06d1ef7346..232c9526bc 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -29,8 +29,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills protected override int ReducedSectionCount => 5; protected override double DifficultyMultiplier => 1.04; - protected override int HistoryLength => 32; - private readonly double greatWindow; public Speed(Mod[] mods, double hitWindowGreat) @@ -55,20 +53,22 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills bool firstDeltaSwitch = false; + int historicalNoteCount = Math.Min(current.Index, 32); + int rhythmStart = 0; - while (rhythmStart < Previous.Count - 2 && current.StartTime - Previous[rhythmStart].StartTime < history_time_max) + while (rhythmStart < historicalNoteCount - 2 && current.StartTime - current.Previous(rhythmStart).StartTime < history_time_max) rhythmStart++; for (int i = rhythmStart; i > 0; i--) { - OsuDifficultyHitObject currObj = (OsuDifficultyHitObject)Previous[i - 1]; - OsuDifficultyHitObject prevObj = (OsuDifficultyHitObject)Previous[i]; - OsuDifficultyHitObject lastObj = (OsuDifficultyHitObject)Previous[i + 1]; + OsuDifficultyHitObject currObj = (OsuDifficultyHitObject)current.Previous(i - 1); + OsuDifficultyHitObject prevObj = (OsuDifficultyHitObject)current.Previous(i); + OsuDifficultyHitObject lastObj = (OsuDifficultyHitObject)current.Previous(i + 1); double currHistoricalDecay = (history_time_max - (current.StartTime - currObj.StartTime)) / history_time_max; // scales note 0 to 1 from history to now - currHistoricalDecay = Math.Min((double)(Previous.Count - i) / Previous.Count, currHistoricalDecay); // either we're limited by time or limited by object count. + currHistoricalDecay = Math.Min((double)(historicalNoteCount - i) / historicalNoteCount, currHistoricalDecay); // either we're limited by time or limited by object count. double currDelta = currObj.StrainTime; double prevDelta = prevObj.StrainTime; @@ -90,10 +90,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills } else { - if (Previous[i - 1].BaseObject is Slider) // bpm change is into slider, this is easy acc window + if (current.Previous(i - 1).BaseObject is Slider) // bpm change is into slider, this is easy acc window effectiveRatio *= 0.125; - if (Previous[i].BaseObject is Slider) // bpm change was from a slider, this is easier typically than circle -> circle + if (current.Previous(i).BaseObject is Slider) // bpm change was from a slider, this is easier typically than circle -> circle effectiveRatio *= 0.25; if (previousIslandSize == islandSize) // repeated island size (ex: triplet -> triplet) @@ -136,7 +136,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills // derive strainTime for calculation var osuCurrObj = (OsuDifficultyHitObject)current; - var osuPrevObj = Previous.Count > 0 ? (OsuDifficultyHitObject)Previous[0] : null; + var osuPrevObj = current.Index > 0 ? (OsuDifficultyHitObject)current.Previous(0) : null; double strainTime = osuCurrObj.StrainTime; double greatWindowFull = greatWindow * 2; @@ -164,7 +164,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000); - protected override double CalculateInitialStrain(double time) => (currentStrain * currentRhythm) * strainDecay(time - Previous[0].StartTime); + protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => (currentStrain * currentRhythm) * strainDecay(time - current.Previous(0).StartTime); protected override double StrainValueAt(DifficultyHitObject current) { diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObject.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObject.cs index ae33c184d0..d9049c45ea 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/TaikoDifficultyHitObject.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Linq; using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Objects; @@ -24,11 +25,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing /// public readonly HitType? HitType; - /// - /// The index of the object in the beatmap. - /// - public readonly int ObjectIndex; - /// /// Whether the object should carry a penalty due to being hittable using special techniques /// making it easier to do so. @@ -42,16 +38,15 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing /// The gameplay preceding . /// The gameplay preceding . /// The rate of the gameplay clock. Modified by speed-changing mods. - /// The index of the object in the beatmap. - public TaikoDifficultyHitObject(HitObject hitObject, HitObject lastObject, HitObject lastLastObject, double clockRate, int objectIndex) - : base(hitObject, lastObject, clockRate) + /// The list of s in the current beatmap. + /// /// The position of this in the list. + public TaikoDifficultyHitObject(HitObject hitObject, HitObject lastObject, HitObject lastLastObject, double clockRate, List objects, int index) + : base(hitObject, lastObject, clockRate, objects, index) { var currentHit = hitObject as Hit; Rhythm = getClosestRhythm(lastObject, lastLastObject, clockRate); HitType = currentHit?.Type; - - ObjectIndex = objectIndex; } /// diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs index 973e55f4b4..46b24af903 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs @@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills if (!samePattern(start, mostRecentPatternsToCompare)) continue; - int notesSince = hitObject.ObjectIndex - rhythmHistory[start].ObjectIndex; + int notesSince = hitObject.Index - rhythmHistory[start].Index; penalty *= repetitionPenalty(notesSince); break; } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs index 1aa31c6fe4..ce5b1d2236 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs @@ -46,13 +46,13 @@ namespace osu.Game.Rulesets.Taiko.Difficulty protected override IEnumerable CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) { - List taikoDifficultyHitObjects = new List(); + List taikoDifficultyHitObjects = new List(); for (int i = 2; i < beatmap.HitObjects.Count; i++) { taikoDifficultyHitObjects.Add( new TaikoDifficultyHitObject( - beatmap.HitObjects[i], beatmap.HitObjects[i - 1], beatmap.HitObjects[i - 2], clockRate, i + beatmap.HitObjects[i], beatmap.HitObjects[i - 1], beatmap.HitObjects[i - 2], clockRate, taikoDifficultyHitObjects, taikoDifficultyHitObjects.Count ) ); } diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index b5aec0d659..b030c0c560 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Difficulty foreach (var skill in skills) { cancellationToken.ThrowIfCancellationRequested(); - skill.ProcessInternal(hitObject); + skill.Process(hitObject); } } @@ -108,7 +108,7 @@ namespace osu.Game.Rulesets.Difficulty foreach (var skill in skills) { cancellationToken.ThrowIfCancellationRequested(); - skill.ProcessInternal(hitObject); + skill.Process(hitObject); } attribs.Add(new TimedDifficultyAttributes(hitObject.EndTime * clockRate, CreateDifficultyAttributes(progressiveBeatmap, playableMods, skills, clockRate))); diff --git a/osu.Game/Rulesets/Difficulty/Preprocessing/DifficultyHitObject.cs b/osu.Game/Rulesets/Difficulty/Preprocessing/DifficultyHitObject.cs index 5edfb2207b..5a2a40e241 100644 --- a/osu.Game/Rulesets/Difficulty/Preprocessing/DifficultyHitObject.cs +++ b/osu.Game/Rulesets/Difficulty/Preprocessing/DifficultyHitObject.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; +using System.Linq; using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Difficulty.Preprocessing @@ -10,6 +12,13 @@ namespace osu.Game.Rulesets.Difficulty.Preprocessing /// public class DifficultyHitObject { + private readonly IReadOnlyList difficultyHitObjects; + + /// + /// The index of this in the list of all s. + /// + public int Index; + /// /// The this wraps. /// @@ -41,13 +50,21 @@ namespace osu.Game.Rulesets.Difficulty.Preprocessing /// The which this wraps. /// The last which occurs before in the beatmap. /// The rate at which the gameplay clock is run at. - public DifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate) + /// The list of s in the current beatmap. + /// The index of this in list. + public DifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate, List objects, int index) { + difficultyHitObjects = objects; + Index = index; BaseObject = hitObject; LastObject = lastObject; DeltaTime = (hitObject.StartTime - lastObject.StartTime) / clockRate; StartTime = hitObject.StartTime / clockRate; EndTime = hitObject.GetEndTime() / clockRate; } + + public DifficultyHitObject Previous(int backwardsIndex) => difficultyHitObjects.ElementAtOrDefault(Index - (backwardsIndex + 1)); + + public DifficultyHitObject Next(int forwardsIndex) => difficultyHitObjects.ElementAtOrDefault(Index + (forwardsIndex + 1)); } } diff --git a/osu.Game/Rulesets/Difficulty/Skills/Skill.cs b/osu.Game/Rulesets/Difficulty/Skills/Skill.cs index b5c94ad806..770754f304 100644 --- a/osu.Game/Rulesets/Difficulty/Skills/Skill.cs +++ b/osu.Game/Rulesets/Difficulty/Skills/Skill.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using osu.Game.Rulesets.Difficulty.Preprocessing; -using osu.Game.Rulesets.Difficulty.Utils; using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Difficulty.Skills @@ -12,21 +11,10 @@ namespace osu.Game.Rulesets.Difficulty.Skills /// A bare minimal abstract skill for fully custom skill implementations. /// /// - /// This class should be considered a "processing" class and not persisted, as it keeps references to - /// gameplay objects after processing is run (see ). + /// This class should be considered a "processing" class and not persisted. /// public abstract class Skill { - /// - /// s that were processed previously. They can affect the strain values of the following objects. - /// - protected readonly ReverseQueue Previous; - - /// - /// Number of previous s to keep inside the queue. - /// - protected virtual int HistoryLength => 1; - /// /// Mods for use in skill calculations. /// @@ -37,24 +25,13 @@ namespace osu.Game.Rulesets.Difficulty.Skills protected Skill(Mod[] mods) { this.mods = mods; - Previous = new ReverseQueue(HistoryLength + 1); - } - - internal void ProcessInternal(DifficultyHitObject current) - { - while (Previous.Count > HistoryLength) - Previous.Dequeue(); - - Process(current); - - Previous.Enqueue(current); } /// /// Process a . /// /// The to process. - protected abstract void Process(DifficultyHitObject current); + public abstract void Process(DifficultyHitObject current); /// /// Returns the calculated difficulty value representing all s that have been processed up to this point. diff --git a/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs b/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs index d8babf2f32..3f3d57938b 100644 --- a/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs +++ b/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Difficulty.Skills { } - protected override double CalculateInitialStrain(double time) => CurrentStrain * strainDecay(time - Previous[0].StartTime); + protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => CurrentStrain * strainDecay(time - current.Previous(0).StartTime); protected override double StrainValueAt(DifficultyHitObject current) { diff --git a/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs b/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs index 97266562e4..0b327046b3 100644 --- a/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs +++ b/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs @@ -44,16 +44,16 @@ namespace osu.Game.Rulesets.Difficulty.Skills /// /// Process a and update current strain values accordingly. /// - protected sealed override void Process(DifficultyHitObject current) + public sealed override void Process(DifficultyHitObject current) { // The first object doesn't generate a strain, so we begin with an incremented section end - if (Previous.Count == 0) + if (current.Index == 0) currentSectionEnd = Math.Ceiling(current.StartTime / SectionLength) * SectionLength; while (current.StartTime > currentSectionEnd) { saveCurrentPeak(); - startNewSectionFrom(currentSectionEnd); + startNewSectionFrom(currentSectionEnd, current); currentSectionEnd += SectionLength; } @@ -72,19 +72,21 @@ namespace osu.Game.Rulesets.Difficulty.Skills /// Sets the initial strain level for a new section. /// /// The beginning of the new section in milliseconds. - private void startNewSectionFrom(double time) + /// The current hit object. + private void startNewSectionFrom(double time, DifficultyHitObject current) { // The maximum strain of the new section is not zero by default // This means we need to capture the strain level at the beginning of the new section, and use that as the initial peak level. - currentSectionPeak = CalculateInitialStrain(time); + currentSectionPeak = CalculateInitialStrain(time, current); } /// /// Retrieves the peak strain at a point in time. /// /// The time to retrieve the peak strain at. + /// The current hit object. /// The peak strain. - protected abstract double CalculateInitialStrain(double time); + protected abstract double CalculateInitialStrain(double time, DifficultyHitObject current); /// /// Returns a live enumerable of the peak strains for each section of the beatmap,