mirror of
https://github.com/ppy/osu.git
synced 2026-05-29 06:49:53 +08:00
Adjust logic to properly list selectable mods
This commit is contained in:
@@ -14,6 +14,7 @@ using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Mods;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Utils;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
||||
{
|
||||
@@ -80,7 +81,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
||||
|
||||
MultiplayerPlaylistItem currentItem = client.Room.CurrentPlaylistItem;
|
||||
Ruleset ruleset = rulesets.GetRuleset(client.LocalUser.RulesetId ?? currentItem.RulesetID)!.CreateInstance();
|
||||
Mod[] allowedMods = currentItem.AllowedMods.Select(m => m.ToMod(ruleset)).ToArray();
|
||||
Mod[] allowedMods = ModUtils.ListUserSelectableFreeMods(client.Room.Settings.MatchType, currentItem.RequiredMods, currentItem.AllowedMods, currentItem.Freestyle, ruleset);
|
||||
|
||||
// Update the mod panels to reflect the ones which are valid for selection.
|
||||
IsValidMod = m => allowedMods.Any(a => a.GetType() == m.GetType());
|
||||
|
||||
@@ -551,27 +551,18 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
||||
updateGameplayState();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lists the <see cref="Mod"/>s that are valid to be selected for the user mod style.
|
||||
/// </summary>
|
||||
private Mod[] listAllowedMods()
|
||||
{
|
||||
if (SelectedItem.Value == null)
|
||||
return [];
|
||||
|
||||
PlaylistItem item = SelectedItem.Value;
|
||||
RulesetInfo gameplayRuleset = UserRuleset.Value ?? rulesets.GetRuleset(item.RulesetID)!;
|
||||
Ruleset rulesetInstance = gameplayRuleset.CreateInstance();
|
||||
|
||||
return item.AllowedMods.Select(m => m.ToMod(rulesetInstance)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the user mod style against the selected item and ruleset style.
|
||||
/// </summary>
|
||||
private void validateUserMods()
|
||||
{
|
||||
Mod[] allowedMods = listAllowedMods();
|
||||
if (SelectedItem.Value == null)
|
||||
return;
|
||||
|
||||
PlaylistItem item = SelectedItem.Value;
|
||||
RulesetInfo gameplayRuleset = UserRuleset.Value ?? rulesets.GetRuleset(item.RulesetID)!;
|
||||
Mod[] allowedMods = ModUtils.ListUserSelectableFreeMods(MatchType.Playlists, item.RequiredMods, item.AllowedMods, item.Freestyle, gameplayRuleset.CreateInstance());
|
||||
|
||||
UserMods.Value = UserMods.Value.Where(m => allowedMods.Any(a => m.GetType() == a.GetType())).ToArray();
|
||||
}
|
||||
|
||||
@@ -588,7 +579,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
||||
IBeatmapInfo gameplayBeatmap = UserBeatmap.Value ?? item.Beatmap;
|
||||
RulesetInfo gameplayRuleset = UserRuleset.Value ?? rulesets.GetRuleset(item.RulesetID)!;
|
||||
Ruleset rulesetInstance = gameplayRuleset.CreateInstance();
|
||||
Mod[] allowedMods = listAllowedMods();
|
||||
Mod[] allowedMods = ModUtils.ListUserSelectableFreeMods(MatchType.Playlists, item.RequiredMods, item.AllowedMods, item.Freestyle, gameplayRuleset.CreateInstance());
|
||||
|
||||
// Update global gameplay state to correspond to the new selection.
|
||||
// Retrieve the corresponding local beatmap, since we can't directly use the playlist's beatmap info
|
||||
|
||||
@@ -320,5 +320,32 @@ namespace osu.Game.Utils
|
||||
return isRequired ? mod.ValidForMultiplayer : mod.ValidForMultiplayerAsFreeMod;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given an online listing of mods and the user's preferred ruleset, gathers the mods which are selectable as free mods by the current user.
|
||||
/// </summary>
|
||||
/// <param name="matchType">The type of match being played.</param>
|
||||
/// <param name="requiredMods">The required mods for the playlist item.</param>
|
||||
/// <param name="allowedMods">The allowed mods for the playlist item.</param>
|
||||
/// <param name="freestyle">Whether freestyle is enabled for the playlist item.</param>
|
||||
/// <param name="userRuleset">The user's preferred ruleset, which may differ from the playlist item's selection on freestyle playlist items.</param>
|
||||
public static Mod[] ListUserSelectableFreeMods(MatchType matchType, IEnumerable<APIMod> requiredMods, IEnumerable<APIMod> allowedMods, bool freestyle, Ruleset userRuleset)
|
||||
{
|
||||
if (freestyle)
|
||||
{
|
||||
Mod[] rulesetRequiredMods = requiredMods.Select(m => m.ToMod(userRuleset)).ToArray();
|
||||
|
||||
// In freestyle, the playlist item doesn't provide the allowed mods. Instead, all mods are unconditionally allowed by default.
|
||||
return userRuleset.AllMods.OfType<Mod>()
|
||||
// But the mods must still be compatible with the room...
|
||||
.Where(m => IsValidModForMatch(m, matchType, false, true))
|
||||
// ... And compatible with the required mods listing (this also handles de-duplication).
|
||||
.Where(m => CheckCompatibleSet(rulesetRequiredMods.Append(m)))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
// Without freestyle, only the mods specified by the playlist item are valid.
|
||||
return allowedMods.Select(m => m.ToMod(userRuleset)).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user