diff --git a/osu.Game/Overlays/BeatmapSet/LeaderboardModSelector.cs b/osu.Game/Overlays/BeatmapSet/LeaderboardModSelector.cs index 25aed4c980..97b89c6f74 100644 --- a/osu.Game/Overlays/BeatmapSet/LeaderboardModSelector.cs +++ b/osu.Game/Overlays/BeatmapSet/LeaderboardModSelector.cs @@ -63,7 +63,7 @@ namespace osu.Game.Overlays.BeatmapSet return; modsContainer.Add(new ModButton(new ModNoMod())); - modsContainer.AddRange(rulesetInstance.AllMods.Where(m => m.UserPlayable).Select(m => new ModButton(m))); + modsContainer.AddRange(rulesetInstance.AllMods.Where(m => m.IsPlayable(ModUsage.Solo)).Select(m => new ModButton(m))); modsContainer.ForEach(button => { diff --git a/osu.Game/Rulesets/Mods/IMod.cs b/osu.Game/Rulesets/Mods/IMod.cs index 5f4fecb649..bdfb273b13 100644 --- a/osu.Game/Rulesets/Mods/IMod.cs +++ b/osu.Game/Rulesets/Mods/IMod.cs @@ -33,24 +33,26 @@ namespace osu.Game.Rulesets.Mods /// IconUsage? Icon { get; } + /// + /// Whether this mod is playable for the given usage. + /// + /// + /// + /// Should be always false for cases where the user is not interacting with the game. + /// Should be false in for mods that make gameplay duration dependent on user input (e.g. ). + /// Should be false in for mods that affect the gameplay duration (e.g. and ). + /// + /// + /// The mod usage. + bool IsPlayable(ModUsage usage); + /// /// Whether this mod is playable by an end user. /// Should be false for cases where the user is not interacting with the game (so it can be excluded from multiplayer selection, for example). /// + [Obsolete("Override IsPlayable instead.")] // Can be removed 20220918 bool UserPlayable { get; } - /// - /// Whether this mod is playable in a multiplayer match. - /// Should be false for mods that make gameplay duration dependent on user input (e.g. ). - /// - bool PlayableInMultiplayer { get; } - - /// - /// Whether this mod is valid to be a "free mod" in a multiplayer match. - /// Should be false for mods that affect the gameplay duration (e.g. and ). - /// - bool ValidFreeModInMultiplayer { get; } - /// /// Create a fresh instance based on this mod. /// diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index a6562b4f4c..00aef1a598 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -91,16 +91,13 @@ namespace osu.Game.Rulesets.Mods [JsonIgnore] public virtual bool HasImplementation => this is IApplicableMod; + public virtual bool IsPlayable(ModUsage usage) => true; + [JsonIgnore] + [Obsolete("Override IsPlayable instead.")] // Can be removed 20220918 public virtual bool UserPlayable => true; - [JsonIgnore] - public virtual bool PlayableInMultiplayer => UserPlayable; - - [JsonIgnore] - public virtual bool ValidFreeModInMultiplayer => PlayableInMultiplayer; - - [Obsolete("Going forward, the concept of \"ranked\" doesn't exist. The only exceptions are automation mods, which should now override and set UserPlayable to false.")] // Can be removed 20211009 + [Obsolete("Going forward, the concept of \"ranked\" doesn't exist. The only exceptions are automation mods, which should now override IsPlayable to false.")] // Can be removed 20211009 public virtual bool Ranked => false; /// diff --git a/osu.Game/Rulesets/Mods/ModUsage.cs b/osu.Game/Rulesets/Mods/ModUsage.cs new file mode 100644 index 0000000000..82ff6bc418 --- /dev/null +++ b/osu.Game/Rulesets/Mods/ModUsage.cs @@ -0,0 +1,26 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Rulesets.Mods +{ + /// + /// The usage of this mod to determine its playability. + /// + public enum ModUsage + { + /// + /// In a solo gameplay session. + /// + Solo, + + /// + /// In a multiplayer match, as a required mod. + /// + MultiplayerRequired, + + /// + /// In a multiplayer match, as a "free" mod. + /// + MultiplayerFree, + } +}