diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index bdc5a00583..aaef69f119 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -14,6 +14,7 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Mania.Beatmaps.Patterns; using osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy; +using osu.Game.Rulesets.Scoring.Legacy; using osu.Game.Utils; using osuTK; @@ -43,39 +44,41 @@ namespace osu.Game.Rulesets.Mania.Beatmaps : base(beatmap, ruleset) { IsForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(ruleset.RulesetInfo); + TargetColumns = GetColumnCount(LegacyBeatmapConversionDifficultyInfo.FromBeatmap(beatmap)); - double roundedCircleSize = Math.Round(beatmap.Difficulty.CircleSize); - double roundedOverallDifficulty = Math.Round(beatmap.Difficulty.OverallDifficulty); - - if (IsForCurrentRuleset) + if (IsForCurrentRuleset && TargetColumns > ManiaRuleset.MAX_STAGE_KEYS) { - TargetColumns = GetColumnCountForNonConvert(beatmap.BeatmapInfo); - - if (TargetColumns > ManiaRuleset.MAX_STAGE_KEYS) - { - TargetColumns /= 2; - Dual = true; - } - } - else - { - float percentSliderOrSpinner = (float)beatmap.HitObjects.Count(h => h is IHasDuration) / beatmap.HitObjects.Count; - if (percentSliderOrSpinner < 0.2) - TargetColumns = 7; - else if (percentSliderOrSpinner < 0.3 || roundedCircleSize >= 5) - TargetColumns = roundedOverallDifficulty > 5 ? 7 : 6; - else if (percentSliderOrSpinner > 0.6) - TargetColumns = roundedOverallDifficulty > 4 ? 5 : 4; - else - TargetColumns = Math.Max(4, Math.Min((int)roundedOverallDifficulty + 1, 7)); + TargetColumns /= 2; + Dual = true; } originalTargetColumns = TargetColumns; } - public static int GetColumnCountForNonConvert(BeatmapInfo beatmapInfo) + public static int GetColumnCount(LegacyBeatmapConversionDifficultyInfo difficulty) { - double roundedCircleSize = Math.Round(beatmapInfo.Difficulty.CircleSize); + if (new ManiaRuleset().RulesetInfo.Equals(difficulty.SourceRuleset)) + return GetColumnCountForNonConvert(difficulty); + + double roundedCircleSize = Math.Round(difficulty.CircleSize); + double roundedOverallDifficulty = Math.Round(difficulty.OverallDifficulty); + + int countSliderOrSpinner = difficulty.TotalObjectCount - difficulty.CircleCount; + float percentSpecialObjects = (float)countSliderOrSpinner / difficulty.TotalObjectCount; + + if (percentSpecialObjects < 0.2) + return 7; + if (percentSpecialObjects < 0.3 || roundedCircleSize >= 5) + return roundedOverallDifficulty > 5 ? 7 : 6; + if (percentSpecialObjects > 0.6) + return roundedOverallDifficulty > 4 ? 5 : 4; + + return Math.Max(4, Math.Min((int)roundedOverallDifficulty + 1, 7)); + } + + public static int GetColumnCountForNonConvert(IBeatmapDifficultyInfo difficulty) + { + double roundedCircleSize = Math.Round(difficulty.CircleSize); return (int)Math.Max(1, roundedCircleSize); } diff --git a/osu.Game.Rulesets.Mania/ManiaFilterCriteria.cs b/osu.Game.Rulesets.Mania/ManiaFilterCriteria.cs index c8832dfdfb..7f8a00bf88 100644 --- a/osu.Game.Rulesets.Mania/ManiaFilterCriteria.cs +++ b/osu.Game.Rulesets.Mania/ManiaFilterCriteria.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania public bool Matches(BeatmapInfo beatmapInfo) { - return !keys.HasFilter || (beatmapInfo.Ruleset.OnlineID == new ManiaRuleset().LegacyID && keys.IsInRange(ManiaBeatmapConverter.GetColumnCountForNonConvert(beatmapInfo))); + return !keys.HasFilter || (beatmapInfo.Ruleset.OnlineID == new ManiaRuleset().LegacyID && keys.IsInRange(ManiaBeatmapConverter.GetColumnCountForNonConvert(beatmapInfo.Difficulty))); } public bool TryParseCustomKeywordCriteria(string key, Operator op, string value) diff --git a/osu.Game/Rulesets/Scoring/Legacy/LegacyBeatmapConversionDifficultyInfo.cs b/osu.Game/Rulesets/Scoring/Legacy/LegacyBeatmapConversionDifficultyInfo.cs new file mode 100644 index 0000000000..97ccf787af --- /dev/null +++ b/osu.Game/Rulesets/Scoring/Legacy/LegacyBeatmapConversionDifficultyInfo.cs @@ -0,0 +1,67 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using osu.Game.Beatmaps; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Rulesets.Objects.Types; + +namespace osu.Game.Rulesets.Scoring.Legacy +{ + /// + /// A set of properties that are required to facilitate beatmap conversion between legacy rulesets. + /// + public class LegacyBeatmapConversionDifficultyInfo : IBeatmapDifficultyInfo + { + /// + /// The beatmap's ruleset. + /// + public IRulesetInfo SourceRuleset { get; set; } = new RulesetInfo(); + + /// + /// The beatmap circle size. + /// + public float CircleSize { get; set; } + + /// + /// The beatmap overall difficulty. + /// + public float OverallDifficulty { get; set; } + + /// + /// The count of hitcircles in the beatmap. + /// + /// + /// When converting from osu! ruleset beatmaps, this is equivalent to the sum of sliders and spinners in the beatmap. + /// + public int CircleCount { get; set; } + + /// + /// The total count of hitobjects in the beatmap. + /// + public int TotalObjectCount { get; set; } + + float IBeatmapDifficultyInfo.DrainRate => 0; + float IBeatmapDifficultyInfo.ApproachRate => 0; + double IBeatmapDifficultyInfo.SliderMultiplier => 0; + double IBeatmapDifficultyInfo.SliderTickRate => 0; + + public static LegacyBeatmapConversionDifficultyInfo FromAPIBeatmap(APIBeatmap apiBeatmap) => new LegacyBeatmapConversionDifficultyInfo + { + SourceRuleset = apiBeatmap.Ruleset, + CircleSize = apiBeatmap.CircleSize, + OverallDifficulty = apiBeatmap.OverallDifficulty, + CircleCount = apiBeatmap.CircleCount, + TotalObjectCount = apiBeatmap.SliderCount + apiBeatmap.SpinnerCount + apiBeatmap.CircleCount + }; + + public static LegacyBeatmapConversionDifficultyInfo FromBeatmap(IBeatmap beatmap) => new LegacyBeatmapConversionDifficultyInfo + { + SourceRuleset = beatmap.BeatmapInfo.Ruleset, + CircleSize = beatmap.Difficulty.CircleSize, + OverallDifficulty = beatmap.Difficulty.OverallDifficulty, + CircleCount = beatmap.HitObjects.Count(h => h is not IHasDuration), + TotalObjectCount = beatmap.HitObjects.Count + }; + } +}