From 22e839d62b646f6f42b129df83336694547bef8e Mon Sep 17 00:00:00 2001 From: StanR Date: Mon, 20 Jan 2025 14:39:35 +0500 Subject: [PATCH] Replace indexed skill access with `skills.OfType<...>().Single()` (#30034) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Replace indexed skill access with `skills.First(s is ...)` * Fix comment * Further refactoring to remove casts --------- Co-authored-by: Dan Balasescu Co-authored-by: Bartłomiej Dach --- .../Difficulty/CatchDifficultyCalculator.cs | 3 ++- .../Difficulty/ManiaDifficultyCalculator.cs | 2 +- .../Difficulty/OsuDifficultyCalculator.cs | 24 ++++++++++--------- .../Difficulty/Skills/Aim.cs | 10 ++++---- .../Difficulty/Skills/Stamina.cs | 8 +++---- .../Difficulty/TaikoDifficultyCalculator.cs | 10 ++++---- 6 files changed, 30 insertions(+), 27 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs index 7d21409ee8..99df2731ff 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Beatmaps; using osu.Game.Rulesets.Catch.Difficulty.Preprocessing; @@ -40,7 +41,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty CatchDifficultyAttributes attributes = new CatchDifficultyAttributes { - StarRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier, + StarRating = Math.Sqrt(skills.OfType().Single().DifficultyValue()) * difficulty_multiplier, Mods = mods, ApproachRate = preempt > 1200.0 ? -(preempt - 1800.0) / 120.0 : -(preempt - 1200.0) / 150.0 + 5.0, MaxCombo = beatmap.GetMaxCombo(), diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs index ff9aa4aa7b..1efa7cb42f 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty ManiaDifficultyAttributes attributes = new ManiaDifficultyAttributes { - StarRating = skills[0].DifficultyValue() * difficulty_multiplier, + StarRating = skills.OfType().Single().DifficultyValue() * difficulty_multiplier, Mods = mods, // In osu-stable mania, rate-adjustment mods don't affect the hit window. // This is done the way it is to introduce fractional differences in order to match osu-stable for the time being. diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 5a61ea586a..1505c51592 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -36,20 +36,22 @@ namespace osu.Game.Rulesets.Osu.Difficulty if (beatmap.HitObjects.Count == 0) return new OsuDifficultyAttributes { Mods = mods }; - double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier; - double aimRatingNoSliders = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier; - double speedRating = Math.Sqrt(skills[2].DifficultyValue()) * difficulty_multiplier; - double speedNotes = ((Speed)skills[2]).RelevantNoteCount(); - double difficultSliders = ((Aim)skills[0]).GetDifficultSliders(); - double flashlightRating = 0.0; - - if (mods.Any(h => h is OsuModFlashlight)) - flashlightRating = Math.Sqrt(skills[3].DifficultyValue()) * difficulty_multiplier; + var aim = skills.OfType().Single(a => a.IncludeSliders); + double aimRating = Math.Sqrt(aim.DifficultyValue()) * difficulty_multiplier; + double aimDifficultyStrainCount = aim.CountTopWeightedStrains(); + double difficultSliders = aim.GetDifficultSliders(); + var aimWithoutSliders = skills.OfType().Single(a => !a.IncludeSliders); + double aimRatingNoSliders = Math.Sqrt(aimWithoutSliders.DifficultyValue()) * difficulty_multiplier; double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1; - double aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).CountTopWeightedStrains(); - double speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).CountTopWeightedStrains(); + var speed = skills.OfType().Single(); + double speedRating = Math.Sqrt(speed.DifficultyValue()) * difficulty_multiplier; + double speedNotes = speed.RelevantNoteCount(); + double speedDifficultyStrainCount = speed.CountTopWeightedStrains(); + + var flashlight = skills.OfType().SingleOrDefault(); + double flashlightRating = flashlight == null ? 0.0 : Math.Sqrt(flashlight.DifficultyValue()) * difficulty_multiplier; if (mods.Any(m => m is OsuModTouchDevice)) { diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index f04b679b73..89adda302c 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -16,14 +16,14 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// public class Aim : OsuStrainSkill { - public Aim(Mod[] mods, bool withSliders) + public readonly bool IncludeSliders; + + public Aim(Mod[] mods, bool includeSliders) : base(mods) { - this.withSliders = withSliders; + IncludeSliders = includeSliders; } - private readonly bool withSliders; - private double currentStrain; private double skillMultiplier => 25.6; @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills protected override double StrainValueAt(DifficultyHitObject current) { currentStrain *= strainDecay(current.DeltaTime); - currentStrain += AimEvaluator.EvaluateDifficultyOf(current, withSliders) * skillMultiplier; + currentStrain += AimEvaluator.EvaluateDifficultyOf(current, IncludeSliders) * skillMultiplier; if (current.BaseObject is Slider) { diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs index aea491aca3..12e1396dd7 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills private double skillMultiplier => 1.1; private double strainDecayBase => 0.4; - private readonly bool singleColourStamina; + public readonly bool SingleColourStamina; private readonly bool isConvert; private double currentStrain; @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills public Stamina(Mod[] mods, bool singleColourStamina, bool isConvert) : base(mods) { - this.singleColourStamina = singleColourStamina; + SingleColourStamina = singleColourStamina; this.isConvert = isConvert; } @@ -50,12 +50,12 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills double monolengthBonus = isConvert ? 1 : 1 + Math.Min(Math.Max((index - 5) / 50.0, 0), 0.30); - if (singleColourStamina) + if (SingleColourStamina) return DifficultyCalculationUtils.Logistic(-(index - 10) / 2.0, currentStrain); return currentStrain * monolengthBonus; } - protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => singleColourStamina ? 0 : currentStrain * strainDecay(time - current.Previous(0).StartTime); + protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => SingleColourStamina ? 0 : currentStrain * strainDecay(time - current.Previous(0).StartTime); } } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs index b1dcf2d7a0..bcd26a06bc 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs @@ -109,11 +109,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty bool isRelax = mods.Any(h => h is TaikoModRelax); - Rhythm rhythm = (Rhythm)skills.First(x => x is Rhythm); - Reading reading = (Reading)skills.First(x => x is Reading); - Colour colour = (Colour)skills.First(x => x is Colour); - Stamina stamina = (Stamina)skills.First(x => x is Stamina); - Stamina singleColourStamina = (Stamina)skills.Last(x => x is Stamina); + var rhythm = skills.OfType().Single(); + var reading = skills.OfType().Single(); + var colour = skills.OfType().Single(); + var stamina = skills.OfType().Single(s => !s.SingleColourStamina); + var singleColourStamina = skills.OfType().Single(s => s.SingleColourStamina); double rhythmRating = rhythm.DifficultyValue() * rhythm_skill_multiplier; double readingRating = reading.DifficultyValue() * reading_skill_multiplier;