1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-16 05:52:55 +08:00

Merge pull request #11793 from peppy/playlists-freemod-support

Add "free mod" user mod selection support to the playlists system
This commit is contained in:
Dean Herbert 2021-02-19 16:56:21 +09:00 committed by GitHub
commit 781379826b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 121 additions and 59 deletions

View File

@ -8,11 +8,14 @@ using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Screens;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Online.Rooms;
using osu.Game.Overlays;
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Play;
@ -26,6 +29,14 @@ namespace osu.Game.Screens.OnlinePlay.Match
public override bool DisallowExternalBeatmapRulesetChanges => true;
private readonly ModSelectOverlay userModsSelectOverlay;
/// <summary>
/// A container that provides controls for selection of user mods.
/// This will be shown/hidden automatically when applicable.
/// </summary>
protected Drawable UserModsSection;
private Sample sampleStart;
/// <summary>
@ -51,9 +62,26 @@ namespace osu.Game.Screens.OnlinePlay.Match
protected RoomSubScreen()
{
AddInternal(BeatmapAvailablilityTracker = new OnlinePlayBeatmapAvailablilityTracker
AddRangeInternal(new Drawable[]
{
SelectedItem = { BindTarget = SelectedItem }
BeatmapAvailablilityTracker = new OnlinePlayBeatmapAvailablilityTracker
{
SelectedItem = { BindTarget = SelectedItem }
},
new Container
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Depth = float.MinValue,
RelativeSizeAxes = Axes.Both,
Height = 0.5f,
Padding = new MarginPadding { Horizontal = HORIZONTAL_OVERFLOW_PADDING },
Child = userModsSelectOverlay = new UserModSelectOverlay
{
SelectedMods = { BindTarget = UserMods },
IsValidMod = _ => false
}
},
});
}
@ -78,6 +106,19 @@ namespace osu.Game.Screens.OnlinePlay.Match
UserMods.BindValueChanged(_ => Scheduler.AddOnce(UpdateMods));
}
public override bool OnBackButton()
{
if (userModsSelectOverlay.State.Value == Visibility.Visible)
{
userModsSelectOverlay.Hide();
return true;
}
return base.OnBackButton();
}
protected void ShowUserModSelect() => userModsSelectOverlay.Show();
public override void OnEntering(IScreen last)
{
base.OnEntering(last);
@ -117,17 +158,31 @@ namespace osu.Game.Screens.OnlinePlay.Match
{
updateWorkingBeatmap();
if (SelectedItem.Value == null)
var selected = SelectedItem.Value;
if (selected == null)
return;
// Remove any user mods that are no longer allowed.
UserMods.Value = UserMods.Value
.Where(m => SelectedItem.Value.AllowedMods.Any(a => m.GetType() == a.GetType()))
.Where(m => selected.AllowedMods.Any(a => m.GetType() == a.GetType()))
.ToList();
UpdateMods();
Ruleset.Value = SelectedItem.Value.Ruleset.Value;
Ruleset.Value = selected.Ruleset.Value;
if (!selected.AllowedMods.Any())
{
UserModsSection?.Hide();
userModsSelectOverlay.Hide();
userModsSelectOverlay.IsValidMod = _ => false;
}
else
{
UserModsSection?.Show();
userModsSelectOverlay.IsValidMod = m => selected.AllowedMods.Any(a => a.GetType() == m.GetType());
}
}
private void beatmapUpdated(ValueChangedEvent<WeakReference<BeatmapSetInfo>> weakSet) => Schedule(updateWorkingBeatmap);
@ -182,5 +237,9 @@ namespace osu.Game.Screens.OnlinePlay.Match
if (track != null)
track.Looping = false;
}
private class UserModSelectOverlay : LocalPlayerModSelectOverlay
{
}
}
}

View File

@ -15,7 +15,6 @@ using osu.Framework.Threading;
using osu.Game.Configuration;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.OnlinePlay.Components;
using osu.Game.Screens.OnlinePlay.Match;
@ -42,9 +41,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
[Resolved]
private OngoingOperationTracker ongoingOperationTracker { get; set; }
private ModSelectOverlay userModsSelectOverlay;
private MultiplayerMatchSettingsOverlay settingsOverlay;
private Drawable userModsSection;
private readonly IBindable<bool> isConnected = new Bindable<bool>();
@ -154,7 +151,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
new BeatmapSelectionControl { RelativeSizeAxes = Axes.X }
}
},
userModsSection = new FillFlowContainer
UserModsSection = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
@ -175,7 +172,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
Origin = Anchor.CentreLeft,
Width = 90,
Text = "Select",
Action = () => userModsSelectOverlay.Show()
Action = ShowUserModSelect,
},
new ModDisplay
{
@ -230,19 +227,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
new Dimension(GridSizeMode.AutoSize),
}
},
new Container
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
RelativeSizeAxes = Axes.Both,
Height = 0.5f,
Padding = new MarginPadding { Horizontal = HORIZONTAL_OVERFLOW_PADDING },
Child = userModsSelectOverlay = new UserModSelectOverlay
{
SelectedMods = { BindTarget = UserMods },
IsValidMod = _ => false
}
},
settingsOverlay = new MultiplayerMatchSettingsOverlay
{
RelativeSizeAxes = Axes.Both,
@ -269,7 +253,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
base.LoadComplete();
SelectedItem.BindTo(client.CurrentMatchPlayingItem);
SelectedItem.BindValueChanged(onSelectedItemChanged, true);
BeatmapAvailability.BindValueChanged(updateBeatmapAvailability, true);
UserMods.BindValueChanged(onUserModsChanged);
@ -285,24 +268,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
}, true);
}
private void onSelectedItemChanged(ValueChangedEvent<PlaylistItem> item)
{
if (client?.LocalUser == null)
return;
if (item.NewValue?.AllowedMods.Any() != true)
{
userModsSection.Hide();
userModsSelectOverlay.Hide();
userModsSelectOverlay.IsValidMod = _ => false;
}
else
{
userModsSection.Show();
userModsSelectOverlay.IsValidMod = m => item.NewValue.AllowedMods.Any(a => a.GetType() == m.GetType());
}
}
protected override void UpdateMods()
{
if (SelectedItem.Value == null || client.LocalUser == null)
@ -322,12 +287,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
return true;
}
if (userModsSelectOverlay.State.Value == Visibility.Visible)
{
userModsSelectOverlay.Hide();
return true;
}
return base.OnBackButton();
}
@ -435,9 +394,5 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
modSettingChangeTracker?.Dispose();
}
private class UserModSelectOverlay : LocalPlayerModSelectOverlay
{
}
}
}

View File

@ -32,11 +32,12 @@ namespace osu.Game.Screens.OnlinePlay
[Resolved(typeof(Room), nameof(Room.Playlist))]
protected BindableList<PlaylistItem> Playlist { get; private set; }
protected readonly Bindable<IReadOnlyList<Mod>> FreeMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
[CanBeNull]
[Resolved(CanBeNull = true)]
private IBindable<PlaylistItem> selectedItem { get; set; }
private readonly Bindable<IReadOnlyList<Mod>> freeMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
private readonly FreeModSelectOverlay freeModSelectOverlay;
private WorkingBeatmap initialBeatmap;
@ -50,7 +51,7 @@ namespace osu.Game.Screens.OnlinePlay
freeModSelectOverlay = new FreeModSelectOverlay
{
SelectedMods = { BindTarget = freeMods },
SelectedMods = { BindTarget = FreeMods },
IsValidMod = IsValidFreeMod,
};
}
@ -72,14 +73,14 @@ namespace osu.Game.Screens.OnlinePlay
// At this point, Mods contains both the required and allowed mods. For selection purposes, it should only contain the required mods.
// Similarly, freeMods is currently empty but should only contain the allowed mods.
Mods.Value = selectedItem?.Value?.RequiredMods.Select(m => m.CreateCopy()).ToArray() ?? Array.Empty<Mod>();
freeMods.Value = selectedItem?.Value?.AllowedMods.Select(m => m.CreateCopy()).ToArray() ?? Array.Empty<Mod>();
FreeMods.Value = selectedItem?.Value?.AllowedMods.Select(m => m.CreateCopy()).ToArray() ?? Array.Empty<Mod>();
Ruleset.BindValueChanged(onRulesetChanged);
}
private void onRulesetChanged(ValueChangedEvent<RulesetInfo> ruleset)
{
freeMods.Value = Array.Empty<Mod>();
FreeMods.Value = Array.Empty<Mod>();
}
protected sealed override bool OnStart()
@ -95,7 +96,7 @@ namespace osu.Game.Screens.OnlinePlay
item.RequiredMods.AddRange(Mods.Value.Select(m => m.CreateCopy()));
item.AllowedMods.Clear();
item.AllowedMods.AddRange(freeMods.Value.Select(m => m.CreateCopy()));
item.AllowedMods.AddRange(FreeMods.Value.Select(m => m.CreateCopy()));
SelectItem(item);
return true;
@ -138,7 +139,7 @@ namespace osu.Game.Screens.OnlinePlay
protected override IEnumerable<(FooterButton, OverlayContainer)> CreateFooterButtons()
{
var buttons = base.CreateFooterButtons().ToList();
buttons.Insert(buttons.FindIndex(b => b.Item1 is FooterButtonMods) + 1, (new FooterButtonFreeMods { Current = freeMods }, freeModSelectOverlay));
buttons.Insert(buttons.FindIndex(b => b.Item1 is FooterButtonMods) + 1, (new FooterButtonFreeMods { Current = FreeMods }, freeModSelectOverlay));
return buttons;
}

View File

@ -13,7 +13,9 @@ using osu.Game.Online.Rooms;
using osu.Game.Screens.OnlinePlay.Components;
using osu.Game.Screens.OnlinePlay.Match;
using osu.Game.Screens.OnlinePlay.Match.Components;
using osu.Game.Screens.Play.HUD;
using osu.Game.Users;
using osuTK;
using Footer = osu.Game.Screens.OnlinePlay.Match.Components.Footer;
namespace osu.Game.Screens.OnlinePlay.Playlists
@ -143,13 +145,55 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
RelativeSizeAxes = Axes.Both,
Content = new[]
{
new Drawable[] { new OverlinedHeader("Leaderboard"), },
new[]
{
UserModsSection = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Margin = new MarginPadding { Bottom = 10 },
Children = new Drawable[]
{
new OverlinedHeader("Extra mods"),
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(10, 0),
Children = new Drawable[]
{
new PurpleTriangleButton
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Width = 90,
Text = "Select",
Action = ShowUserModSelect,
},
new ModDisplay
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
DisplayUnrankedText = false,
Current = UserMods,
Scale = new Vector2(0.8f),
},
}
}
}
},
},
new Drawable[]
{
new OverlinedHeader("Leaderboard")
},
new Drawable[] { leaderboard = new MatchLeaderboard { RelativeSizeAxes = Axes.Both }, },
new Drawable[] { new OverlinedHeader("Chat"), },
new Drawable[] { new MatchChatDisplay { RelativeSizeAxes = Axes.Both } }
},
RowDimensions = new[]
{
new Dimension(GridSizeMode.AutoSize),
new Dimension(GridSizeMode.AutoSize),
new Dimension(),
new Dimension(GridSizeMode.AutoSize),

View File

@ -56,6 +56,9 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
item.RequiredMods.Clear();
item.RequiredMods.AddRange(Mods.Value.Select(m => m.CreateCopy()));
item.AllowedMods.Clear();
item.AllowedMods.AddRange(FreeMods.Value.Select(m => m.CreateCopy()));
}
}
}