diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index dc163ed77e..eb8cf137fa 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -176,15 +176,20 @@ namespace osu.Game.Rulesets.Catch public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetCatch }; - protected override IEnumerable GetValidHitResults() + public override IEnumerable GetValidHitResults() { return new[] { HitResult.Great, + HitResult.Miss, HitResult.LargeTickHit, + HitResult.LargeTickMiss, HitResult.SmallTickHit, + HitResult.SmallTickMiss, HitResult.LargeBonus, + HitResult.IgnoreHit, + HitResult.IgnoreMiss, }; } diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index cc64ee0d69..3fad9d1047 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -383,7 +383,7 @@ namespace osu.Game.Rulesets.Mania return (PlayfieldType)Enum.GetValues(typeof(PlayfieldType)).Cast().OrderDescending().First(v => variant >= v); } - protected override IEnumerable GetValidHitResults() + public override IEnumerable GetValidHitResults() { return new[] { @@ -392,9 +392,11 @@ namespace osu.Game.Rulesets.Mania HitResult.Good, HitResult.Ok, HitResult.Meh, + HitResult.Miss, - // HitResult.SmallBonus is used for awarding perfect bonus score but is not included here as - // it would be a bit redundant to show this to the user. + HitResult.IgnoreHit, + HitResult.ComboBreak, + HitResult.IgnoreMiss, }; } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index b2f924ca3b..f0c4e74410 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -277,19 +277,24 @@ namespace osu.Game.Rulesets.Osu public override IRulesetConfigManager CreateConfig(SettingsStore? settings) => new OsuRulesetConfigManager(settings, RulesetInfo); - protected override IEnumerable GetValidHitResults() + public override IEnumerable GetValidHitResults() { return new[] { HitResult.Great, HitResult.Ok, HitResult.Meh, + HitResult.Miss, HitResult.LargeTickHit, + HitResult.LargeTickMiss, HitResult.SmallTickHit, + HitResult.SmallTickMiss, HitResult.SliderTailHit, HitResult.SmallBonus, HitResult.LargeBonus, + HitResult.IgnoreHit, + HitResult.IgnoreMiss, }; } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index b25672f719..686d40ff37 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -222,15 +222,18 @@ namespace osu.Game.Rulesets.Taiko public override RulesetSettingsSubsection CreateSettings() => new TaikoSettingsSubsection(this); - protected override IEnumerable GetValidHitResults() + public override IEnumerable GetValidHitResults() { return new[] { HitResult.Great, HitResult.Ok, + HitResult.Miss, HitResult.SmallBonus, HitResult.LargeBonus, + HitResult.IgnoreHit, + HitResult.IgnoreMiss, }; } diff --git a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs index f45422e0c4..9b87ce4bb4 100644 --- a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs +++ b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs @@ -526,7 +526,7 @@ namespace osu.Game.Tests.Rulesets.Scoring // ReSharper disable once MemberHidesStaticFromOuterClass private class TestRuleset : Ruleset { - protected override IEnumerable GetValidHitResults() => new[] { HitResult.Great }; + public override IEnumerable GetValidHitResults() => new[] { HitResult.Great }; public override IEnumerable GetModsFor(ModType type) => throw new NotImplementedException(); diff --git a/osu.Game/Database/StandardisedScoreMigrationTools.cs b/osu.Game/Database/StandardisedScoreMigrationTools.cs index 15e3da3c19..204198a410 100644 --- a/osu.Game/Database/StandardisedScoreMigrationTools.cs +++ b/osu.Game/Database/StandardisedScoreMigrationTools.cs @@ -51,7 +51,7 @@ namespace osu.Game.Database var beatmap = new Beatmap(); - HitResult maxRulesetJudgement = ruleset.GetHitResults().First().result; + HitResult maxRulesetJudgement = ruleset.GetHitResultsForDisplay().First().result; // This is a list of all results, ordered from best to worst. // We are constructing a "best possible" score from the statistics provided because it's the best we can do. diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 0c8943ba7d..1e62b23780 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -106,7 +106,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores var ruleset = scores.First().Ruleset.CreateInstance(); - foreach (var resultGroup in ruleset.GetHitResults().GroupBy(r => r.displayName)) + foreach (var resultGroup in ruleset.GetHitResultsForDisplay().GroupBy(r => r.displayName)) { if (!resultGroup.Any(r => allScoreStatistics.Contains(r.result))) continue; diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 0dbe6e8845..905c4011dc 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -13,6 +13,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; using osu.Framework.IO.Stores; using osu.Framework.Localisation; +using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Legacy; using osu.Game.Configuration; @@ -334,13 +335,17 @@ namespace osu.Game.Rulesets public virtual StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap) => Array.Empty(); /// - /// Get all valid s for this ruleset. - /// Generally used for results display purposes, where it can't be determined if zero-count means the user has not achieved any or the type is not used by this ruleset. + /// Get all s for this ruleset which are important enough to displayed to the end user. + /// Used for results display purposes, where it can't be determined if zero-count means the user has not achieved any or the type is not used by this ruleset. /// + /// + /// is implicitly included. Special types like are not returned by this method. + /// Values are returned as ordered by . + /// /// - /// All valid s along with a display-friendly name. + /// All relevant s along with a display-friendly name. /// - public IEnumerable<(HitResult result, LocalisableString displayName)> GetHitResults() + public IEnumerable<(HitResult result, LocalisableString displayName)> GetHitResultsForDisplay() { var validResults = GetValidHitResults(); @@ -353,6 +358,7 @@ namespace osu.Game.Rulesets case HitResult.None: case HitResult.IgnoreHit: case HitResult.IgnoreMiss: + case HitResult.ComboBreak: // display is handled as a completion count with corresponding "hit" type. case HitResult.LargeTickMiss: case HitResult.SmallTickMiss: @@ -366,12 +372,10 @@ namespace osu.Game.Rulesets /// /// Get all valid s for this ruleset. - /// Generally used for results display purposes, where it can't be determined if zero-count means the user has not achieved any or the type is not used by this ruleset. + /// Used for strict validation purposes. The ruleset should return ALL applicable types here + /// (except and obsolete types). /// - /// - /// is implicitly included. Special types like are ignored even when specified. - /// - protected virtual IEnumerable GetValidHitResults() => EnumExtensions.GetValuesInOrder(); + public virtual IEnumerable GetValidHitResults() => EnumExtensions.GetValuesInOrder(); /// /// Get a display friendly name for the specified result type. diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index 393df65cc8..05070d96ec 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -211,7 +211,7 @@ namespace osu.Game.Scoring.Legacy var scoreProcessor = rulesetInstance.CreateScoreProcessor(); // Populate the maximum statistics. - HitResult maxBasicResult = rulesetInstance.GetHitResults() + HitResult maxBasicResult = rulesetInstance.GetHitResultsForDisplay() .Select(h => h.result) .Where(h => h.IsBasic()).MaxBy(scoreProcessor.GetBaseScoreForResult); diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index 9e10b93168..5c524e9d36 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -361,7 +361,7 @@ namespace osu.Game.Scoring public IEnumerable GetStatisticsForDisplay() { - foreach (var r in Ruleset.CreateInstance().GetHitResults()) + foreach (var r in Ruleset.CreateInstance().GetHitResultsForDisplay()) { int value = Statistics.GetValueOrDefault(r.result); diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCountController.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCountController.cs index c00cb3487b..a979ed03fd 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCountController.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCountController.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { // Due to weirdness in judgements, some results have the same name and should be aggregated for display purposes. // There's only one case of this right now ("slider end"). - foreach (var group in ruleset.Value.CreateInstance().GetHitResults().GroupBy(r => r.displayName)) + foreach (var group in ruleset.Value.CreateInstance().GetHitResultsForDisplay().GroupBy(r => r.displayName)) { var judgementCount = new JudgementCount {