Skip to content

Commit 52b06e8

Browse files
committed
allow beatmap conversion between non-std rulesets
Supersedes ppy#23875, fix ppy#9263 Gives the ruleset full control which maps to show both with and without converts enabled - e.g. a competitive/harder version ruleset such as for mania could make mania maps show without enabling converts, as well as control which ones to support only if conversions are enabled in the settings. There is a CanConvert function in BeatmapConverter which I considered using as well, however it looks like this beatmap converter isn't directly accessible in the carousel and adding it may be quite severe on performance impact. This way, maps may also show if they fail in conversion, but playing them will show a notification that the maps aren't playable. For the future an async task that just goes through maps to try and see if they are convertible for different modes and caches that might be useful. (e.g. generally mania->taiko converts might be good to have, but a quality control function inside CanConvert could make the conversion fail if it's unplayable) This enables the following additional conversions since in my small testing using the default bundled osu maps they worked quite well: ctb -> mania (gives surprisingly fun beginner 7k maps) ctb -> taiko If wanted I can also move this into a new interface, however I think the FilterCriteria interface fits quite well actually
1 parent 5a53eed commit 52b06e8

File tree

8 files changed

+132
-9
lines changed

8 files changed

+132
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
2+
// See the LICENCE file in the repository root for full licence text.
3+
4+
using System.Collections.Generic;
5+
using osu.Framework.Bindables;
6+
using osu.Game.Beatmaps;
7+
using osu.Game.Rulesets.Filter;
8+
using osu.Game.Rulesets.Mods;
9+
using osu.Game.Screens.Select;
10+
using osu.Game.Screens.Select.Filter;
11+
12+
namespace osu.Game.Rulesets.Catch
13+
{
14+
public class CatchFilterCriteria : IRulesetFilterCriteria
15+
{
16+
public bool Matches(BeatmapInfo beatmapInfo, FilterCriteria criteria)
17+
{
18+
return beatmapInfo.Ruleset.ShortName == "fruits"
19+
|| (criteria.AllowConvertedBeatmaps && (
20+
beatmapInfo.Ruleset.ShortName == "osu"));
21+
}
22+
23+
public bool TryParseCustomKeywordCriteria(string key, Operator op, string value)
24+
{
25+
return false;
26+
}
27+
28+
public bool FilterMayChangeFromMods(ValueChangedEvent<IReadOnlyList<Mod>> mods)
29+
{
30+
return false;
31+
}
32+
}
33+
}

osu.Game.Rulesets.Catch/CatchRuleset.cs

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
using osu.Game.Rulesets.Catch.UI;
2525
using osu.Game.Rulesets.Difficulty;
2626
using osu.Game.Rulesets.Edit;
27+
using osu.Game.Rulesets.Filter;
2728
using osu.Game.Rulesets.Mods;
2829
using osu.Game.Rulesets.Replays.Types;
2930
using osu.Game.Rulesets.Scoring;
@@ -49,6 +50,8 @@ public class CatchRuleset : Ruleset, ILegacyRuleset
4950

5051
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap);
5152

53+
public override IRulesetFilterCriteria CreateRulesetFilterCriteria() => new CatchFilterCriteria();
54+
5255
public const string SHORT_NAME = "fruits";
5356

5457
public override string RulesetAPIVersionSupported => CURRENT_RULESET_API_VERSION;

osu.Game.Rulesets.Mania/ManiaFilterCriteria.cs

+16-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,22 @@ public class ManiaFilterCriteria : IRulesetFilterCriteria
2121

2222
public bool Matches(BeatmapInfo beatmapInfo, FilterCriteria criteria)
2323
{
24-
return !keys.HasFilter || keys.IsInRange(ManiaBeatmapConverter.GetColumnCount(LegacyBeatmapConversionDifficultyInfo.FromBeatmapInfo(beatmapInfo), criteria.Mods));
24+
// taiko maps currently don't yet convert very well to mania
25+
if (!criteria.AllowConvertedBeatmaps || beatmapInfo.Ruleset.ShortName == "taiko")
26+
return false;
27+
return (beatmapInfo.Ruleset.ShortName == "mania"
28+
|| (criteria.AllowConvertedBeatmaps && (
29+
beatmapInfo.Ruleset.ShortName == "osu" ||
30+
beatmapInfo.Ruleset.ShortName == "fruits"))
31+
) && (!keys.HasFilter
32+
|| keys.IsInRange(
33+
ManiaBeatmapConverter.GetColumnCount(
34+
LegacyBeatmapConversionDifficultyInfo.FromBeatmapInfo(
35+
beatmapInfo
36+
), criteria.Mods
37+
)
38+
)
39+
);
2540
}
2641

2742
public bool TryParseCustomKeywordCriteria(string key, Operator op, string value)
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
2+
// See the LICENCE file in the repository root for full licence text.
3+
4+
using System.Collections.Generic;
5+
using osu.Framework.Bindables;
6+
using osu.Game.Beatmaps;
7+
using osu.Game.Rulesets.Filter;
8+
using osu.Game.Rulesets.Mods;
9+
using osu.Game.Screens.Select;
10+
using osu.Game.Screens.Select.Filter;
11+
12+
namespace osu.Game.Rulesets.Osu
13+
{
14+
public class OsuFilterCriteria : IRulesetFilterCriteria
15+
{
16+
public bool Matches(BeatmapInfo beatmapInfo, FilterCriteria criteria)
17+
{
18+
// for std osu, don't allow any conversions from other modes
19+
// (maybe we could allow CtB in the future since the converted maps
20+
// are surpsingly playable)
21+
return beatmapInfo.Ruleset.ShortName == "osu";
22+
}
23+
24+
public bool TryParseCustomKeywordCriteria(string key, Operator op, string value)
25+
{
26+
return false;
27+
}
28+
29+
public bool FilterMayChangeFromMods(ValueChangedEvent<IReadOnlyList<Mod>> mods)
30+
{
31+
return false;
32+
}
33+
}
34+
}

osu.Game.Rulesets.Osu/OsuRuleset.cs

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using osu.Game.Rulesets.Configuration;
1818
using osu.Game.Rulesets.Difficulty;
1919
using osu.Game.Rulesets.Edit;
20+
using osu.Game.Rulesets.Filter;
2021
using osu.Game.Rulesets.Mods;
2122
using osu.Game.Rulesets.Osu.Beatmaps;
2223
using osu.Game.Rulesets.Osu.Configuration;
@@ -56,6 +57,8 @@ public class OsuRuleset : Ruleset, ILegacyRuleset
5657

5758
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap);
5859

60+
public override IRulesetFilterCriteria CreateRulesetFilterCriteria() => new OsuFilterCriteria();
61+
5962
public const string SHORT_NAME = "osu";
6063

6164
public override string RulesetAPIVersionSupported => CURRENT_RULESET_API_VERSION;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
2+
// See the LICENCE file in the repository root for full licence text.
3+
4+
using System.Collections.Generic;
5+
using osu.Framework.Bindables;
6+
using osu.Game.Beatmaps;
7+
using osu.Game.Rulesets.Filter;
8+
using osu.Game.Rulesets.Mods;
9+
using osu.Game.Screens.Select;
10+
using osu.Game.Screens.Select.Filter;
11+
12+
namespace osu.Game.Rulesets.Taiko
13+
{
14+
public class TaikoFilterCriteria : IRulesetFilterCriteria
15+
{
16+
public bool Matches(BeatmapInfo beatmapInfo, FilterCriteria criteria)
17+
{
18+
// Taiko is very well convertible, surprisingly even with CtB.
19+
// However, Mania conversion currently still needs some work since
20+
// the converted maps often have way too many spinners.
21+
return beatmapInfo.Ruleset.ShortName == "taiko"
22+
|| (criteria.AllowConvertedBeatmaps && (
23+
beatmapInfo.Ruleset.ShortName == "osu" ||
24+
beatmapInfo.Ruleset.ShortName == "fruits"));
25+
}
26+
27+
public bool TryParseCustomKeywordCriteria(string key, Operator op, string value)
28+
{
29+
return false;
30+
}
31+
32+
public bool FilterMayChangeFromMods(ValueChangedEvent<IReadOnlyList<Mod>> mods)
33+
{
34+
return false;
35+
}
36+
}
37+
}

osu.Game.Rulesets.Taiko/TaikoRuleset.cs

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
using osu.Game.Rulesets.Taiko.Configuration;
3838
using osu.Game.Rulesets.Taiko.Edit.Setup;
3939
using osu.Game.Screens.Edit.Setup;
40+
using osu.Game.Rulesets.Filter;
4041

4142
namespace osu.Game.Rulesets.Taiko
4243
{
@@ -64,6 +65,8 @@ public class TaikoRuleset : Ruleset, ILegacyRuleset
6465
return null;
6566
}
6667

68+
public override IRulesetFilterCriteria CreateRulesetFilterCriteria() => new TaikoFilterCriteria();
69+
6770
public const string SHORT_NAME = "taiko";
6871

6972
public override string RulesetAPIVersionSupported => CURRENT_RULESET_API_VERSION;

osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs

+3-8
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,13 @@ public override void Filter(FilterCriteria criteria)
3131

3232
private bool checkMatch(FilterCriteria criteria)
3333
{
34-
bool match =
35-
criteria.Ruleset == null ||
36-
BeatmapInfo.Ruleset.ShortName == criteria.Ruleset.ShortName ||
37-
(BeatmapInfo.Ruleset.OnlineID == 0 && criteria.Ruleset.OnlineID != 0 && criteria.AllowConvertedBeatmaps);
38-
3934
if (BeatmapInfo.BeatmapSet?.Equals(criteria.SelectedBeatmapSet) == true)
4035
{
41-
// only check ruleset equality or convertability for selected beatmap
42-
return match;
36+
// only check convertability for selected beatmap
37+
return true;
4338
}
4439

45-
if (!match) return false;
40+
bool match = true;
4641

4742
if (criteria.SearchTerms.Length > 0)
4843
{

0 commit comments

Comments
 (0)