diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 5a22b6fad1..828f17d87c 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; @@ -464,15 +465,13 @@ namespace osu.Game.Rulesets.Mania yield return new RulesetBeatmapAttribute(SongSelectStrings.Accuracy, @"OD", originalDifficulty.OverallDifficulty, adjustedDifficulty.OverallDifficulty, 10) { Description = "Affects timing requirements for notes.", - AdditionalMetrics = - [ - new RulesetBeatmapAttribute.AdditionalMetric("PERFECT hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Perfect):0.##}ms"), colours.ForHitResult(HitResult.Perfect)), - new RulesetBeatmapAttribute.AdditionalMetric("GREAT hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Great):0.##}ms"), colours.ForHitResult(HitResult.Great)), - new RulesetBeatmapAttribute.AdditionalMetric("GOOD hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Good):0.##}ms"), colours.ForHitResult(HitResult.Good)), - new RulesetBeatmapAttribute.AdditionalMetric("OK hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Ok):0.##}ms"), colours.ForHitResult(HitResult.Ok)), - new RulesetBeatmapAttribute.AdditionalMetric("MEH hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Meh):0.##}ms"), colours.ForHitResult(HitResult.Meh)), - new RulesetBeatmapAttribute.AdditionalMetric("MISS hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Miss):0.##}ms"), colours.ForHitResult(HitResult.Miss)), - ] + AdditionalMetrics = hitWindows.GetAllAvailableWindows() + .Reverse() + .Select(window => new RulesetBeatmapAttribute.AdditionalMetric( + $"{window.result.GetDescription().ToUpperInvariant()} hit window", + LocalisableString.Interpolate($@"±{hitWindows.WindowFor(window.result):0.##}ms"), + colours.ForHitResult(window.result) + )).ToArray() }; yield return new RulesetBeatmapAttribute(SongSelectStrings.HPDrain, @"HP", originalDifficulty.DrainRate, adjustedDifficulty.DrainRate, 10) diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 967f09328e..d1db74b691 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using osu.Framework.Extensions; using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -426,15 +427,16 @@ namespace osu.Game.Rulesets.Osu yield return new RulesetBeatmapAttribute(SongSelectStrings.Accuracy, @"OD", originalDifficulty.OverallDifficulty, effectiveDifficulty.OverallDifficulty, 10) { Description = "Affects timing requirements for hit circles and spin speed requirements for spinners.", - AdditionalMetrics = - [ - new RulesetBeatmapAttribute.AdditionalMetric("GREAT hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Great) / rate:0.##}ms"), colours.ForHitResult(HitResult.Great)), - new RulesetBeatmapAttribute.AdditionalMetric("OK hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Ok) / rate:0.##}ms"), colours.ForHitResult(HitResult.Ok)), - new RulesetBeatmapAttribute.AdditionalMetric("MEH hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Meh) / rate:0.##}ms"), colours.ForHitResult(HitResult.Meh)), - new RulesetBeatmapAttribute.AdditionalMetric("MISS hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Miss) / rate:0.##}ms"), colours.ForHitResult(HitResult.Miss)), - new RulesetBeatmapAttribute.AdditionalMetric("RPM required to clear spinners", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRange(modAdjustedDifficulty.OverallDifficulty, Spinner.CLEAR_RPM_RANGE):N0} RPM")), - new RulesetBeatmapAttribute.AdditionalMetric("RPM required to get full spinner bonus", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRange(modAdjustedDifficulty.OverallDifficulty, Spinner.COMPLETE_RPM_RANGE):N0} RPM")), - ] + AdditionalMetrics = hitWindows.GetAllAvailableWindows() + .Reverse() + .Select(window => new RulesetBeatmapAttribute.AdditionalMetric( + $"{window.result.GetDescription().ToUpperInvariant()} hit window", + LocalisableString.Interpolate($@"±{hitWindows.WindowFor(window.result):0.##}ms"), + colours.ForHitResult(window.result) + )).Concat([ + new RulesetBeatmapAttribute.AdditionalMetric("RPM required to clear spinners", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRange(modAdjustedDifficulty.OverallDifficulty, Spinner.CLEAR_RPM_RANGE):N0} RPM")), + new RulesetBeatmapAttribute.AdditionalMetric("RPM required to get full spinner bonus", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRange(modAdjustedDifficulty.OverallDifficulty, Spinner.COMPLETE_RPM_RANGE):N0} RPM")), + ]).ToArray() }; // HP drain is thankfully simple enough. diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index e72fe7206c..d771bfa5c5 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; @@ -302,13 +303,15 @@ namespace osu.Game.Rulesets.Taiko yield return new RulesetBeatmapAttribute(SongSelectStrings.Accuracy, @"OD", originalDifficulty.OverallDifficulty, effectiveDifficulty.OverallDifficulty, 10) { Description = "Affects timing requirements for hits and mash rate requirements for swells.", - AdditionalMetrics = - [ - new RulesetBeatmapAttribute.AdditionalMetric("GREAT hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Great) / rate:0.##}ms"), colours.ForHitResult(HitResult.Great)), - new RulesetBeatmapAttribute.AdditionalMetric("OK hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Ok) / rate:0.##}ms"), colours.ForHitResult(HitResult.Ok)), - new RulesetBeatmapAttribute.AdditionalMetric("MISS hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Miss) / rate:0.##}ms"), colours.ForHitResult(HitResult.Miss)), - new RulesetBeatmapAttribute.AdditionalMetric("Hits per second required to clear swells", LocalisableString.Interpolate($@"{TaikoBeatmapConverter.RequiredSwellHitsPerSecond(modAdjustedDifficulty.OverallDifficulty):0.##}")), - ] + AdditionalMetrics = hitWindows.GetAllAvailableWindows() + .Reverse() + .Select(window => new RulesetBeatmapAttribute.AdditionalMetric( + $"{window.result.GetDescription().ToUpperInvariant()} hit window", + LocalisableString.Interpolate($@"±{hitWindows.WindowFor(window.result):0.##}ms"), + colours.ForHitResult(window.result) + )) + .Append(new RulesetBeatmapAttribute.AdditionalMetric("Hits per second required to clear swells", LocalisableString.Interpolate($@"{TaikoBeatmapConverter.RequiredSwellHitsPerSecond(modAdjustedDifficulty.OverallDifficulty):0.##}"))) + .ToArray() }; yield return new RulesetBeatmapAttribute(SongSelectStrings.HPDrain, @"HP", originalDifficulty.DrainRate, effectiveDifficulty.DrainRate, 10)