mirror of
https://github.com/ppy/osu.git
synced 2025-01-15 06:42:56 +08:00
Merge branch 'master' into playlists-freemod-support
This commit is contained in:
commit
4504023a23
@ -36,18 +36,23 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
[Key(5)]
|
[Key(5)]
|
||||||
public IEnumerable<APIMod> AllowedMods { get; set; } = Enumerable.Empty<APIMod>();
|
public IEnumerable<APIMod> AllowedMods { get; set; } = Enumerable.Empty<APIMod>();
|
||||||
|
|
||||||
|
[Key(6)]
|
||||||
|
public long PlaylistItemId { get; set; }
|
||||||
|
|
||||||
public bool Equals(MultiplayerRoomSettings other)
|
public bool Equals(MultiplayerRoomSettings other)
|
||||||
=> BeatmapID == other.BeatmapID
|
=> BeatmapID == other.BeatmapID
|
||||||
&& BeatmapChecksum == other.BeatmapChecksum
|
&& BeatmapChecksum == other.BeatmapChecksum
|
||||||
&& RequiredMods.SequenceEqual(other.RequiredMods)
|
&& RequiredMods.SequenceEqual(other.RequiredMods)
|
||||||
&& AllowedMods.SequenceEqual(other.AllowedMods)
|
&& AllowedMods.SequenceEqual(other.AllowedMods)
|
||||||
&& RulesetID == other.RulesetID
|
&& RulesetID == other.RulesetID
|
||||||
&& Name.Equals(other.Name, StringComparison.Ordinal);
|
&& Name.Equals(other.Name, StringComparison.Ordinal)
|
||||||
|
&& PlaylistItemId == other.PlaylistItemId;
|
||||||
|
|
||||||
public override string ToString() => $"Name:{Name}"
|
public override string ToString() => $"Name:{Name}"
|
||||||
+ $" Beatmap:{BeatmapID} ({BeatmapChecksum})"
|
+ $" Beatmap:{BeatmapID} ({BeatmapChecksum})"
|
||||||
+ $" RequiredMods:{string.Join(',', RequiredMods)}"
|
+ $" RequiredMods:{string.Join(',', RequiredMods)}"
|
||||||
+ $" AllowedMods:{string.Join(',', AllowedMods)}"
|
+ $" AllowedMods:{string.Join(',', AllowedMods)}"
|
||||||
+ $" Ruleset:{RulesetID}";
|
+ $" Ruleset:{RulesetID}"
|
||||||
|
+ $" Item:{PlaylistItemId}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,8 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly BindableList<int> CurrentMatchPlayingUserIds = new BindableList<int>();
|
public readonly BindableList<int> CurrentMatchPlayingUserIds = new BindableList<int>();
|
||||||
|
|
||||||
|
public readonly Bindable<PlaylistItem?> CurrentMatchPlayingItem = new Bindable<PlaylistItem?>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="MultiplayerRoomUser"/> corresponding to the local player, if available.
|
/// The <see cref="MultiplayerRoomUser"/> corresponding to the local player, if available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -92,10 +94,11 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; } = null!;
|
private RulesetStore rulesets { get; set; } = null!;
|
||||||
|
|
||||||
private Room? apiRoom;
|
// Only exists for compatibility with old osu-server-spectator build.
|
||||||
|
// Todo: Can be removed on 2021/02/26.
|
||||||
|
private long defaultPlaylistItemId;
|
||||||
|
|
||||||
// Todo: This is temporary, until the multiplayer server returns the item id on match start or otherwise.
|
private Room? apiRoom;
|
||||||
private long playlistItemId;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
@ -142,7 +145,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
{
|
{
|
||||||
Room = joinedRoom;
|
Room = joinedRoom;
|
||||||
apiRoom = room;
|
apiRoom = room;
|
||||||
playlistItemId = room.Playlist.SingleOrDefault()?.ID ?? 0;
|
defaultPlaylistItemId = apiRoom.Playlist.FirstOrDefault()?.ID ?? 0;
|
||||||
}, cancellationSource.Token);
|
}, cancellationSource.Token);
|
||||||
|
|
||||||
// Update room settings.
|
// Update room settings.
|
||||||
@ -218,7 +221,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
BeatmapChecksum = item.GetOr(existingPlaylistItem).Beatmap.Value.MD5Hash,
|
BeatmapChecksum = item.GetOr(existingPlaylistItem).Beatmap.Value.MD5Hash,
|
||||||
RulesetID = item.GetOr(existingPlaylistItem).RulesetID,
|
RulesetID = item.GetOr(existingPlaylistItem).RulesetID,
|
||||||
RequiredMods = item.HasValue ? item.Value.AsNonNull().RequiredMods.Select(m => new APIMod(m)).ToList() : Room.Settings.RequiredMods,
|
RequiredMods = item.HasValue ? item.Value.AsNonNull().RequiredMods.Select(m => new APIMod(m)).ToList() : Room.Settings.RequiredMods,
|
||||||
AllowedMods = item.HasValue ? item.Value.AsNonNull().AllowedMods.Select(m => new APIMod(m)).ToList() : Room.Settings.AllowedMods
|
AllowedMods = item.HasValue ? item.Value.AsNonNull().AllowedMods.Select(m => new APIMod(m)).ToList() : Room.Settings.AllowedMods,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,14 +509,13 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
Room.Settings = settings;
|
Room.Settings = settings;
|
||||||
apiRoom.Name.Value = Room.Settings.Name;
|
apiRoom.Name.Value = Room.Settings.Name;
|
||||||
|
|
||||||
// The playlist update is delayed until an online beatmap lookup (below) succeeds.
|
// The current item update is delayed until an online beatmap lookup (below) succeeds.
|
||||||
// In-order for the client to not display an outdated beatmap, the playlist is forcefully cleared here.
|
// In-order for the client to not display an outdated beatmap, the current item is forcefully cleared here.
|
||||||
apiRoom.Playlist.Clear();
|
CurrentMatchPlayingItem.Value = null;
|
||||||
|
|
||||||
RoomUpdated?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
|
|
||||||
var req = new GetBeatmapSetRequest(settings.BeatmapID, BeatmapSetLookupType.BeatmapId);
|
var req = new GetBeatmapSetRequest(settings.BeatmapID, BeatmapSetLookupType.BeatmapId);
|
||||||
|
|
||||||
req.Success += res =>
|
req.Success += res =>
|
||||||
{
|
{
|
||||||
if (cancellationToken.IsCancellationRequested)
|
if (cancellationToken.IsCancellationRequested)
|
||||||
@ -540,20 +542,32 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
var mods = settings.RequiredMods.Select(m => m.ToMod(ruleset));
|
var mods = settings.RequiredMods.Select(m => m.ToMod(ruleset));
|
||||||
var allowedMods = settings.AllowedMods.Select(m => m.ToMod(ruleset));
|
var allowedMods = settings.AllowedMods.Select(m => m.ToMod(ruleset));
|
||||||
|
|
||||||
PlaylistItem playlistItem = new PlaylistItem
|
// Try to retrieve the existing playlist item from the API room.
|
||||||
|
var playlistItem = apiRoom.Playlist.FirstOrDefault(i => i.ID == settings.PlaylistItemId);
|
||||||
|
|
||||||
|
if (playlistItem != null)
|
||||||
|
updateItem(playlistItem);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
ID = playlistItemId,
|
// An existing playlist item does not exist, so append a new one.
|
||||||
Beatmap = { Value = beatmap },
|
updateItem(playlistItem = new PlaylistItem());
|
||||||
Ruleset = { Value = ruleset.RulesetInfo },
|
|
||||||
};
|
|
||||||
|
|
||||||
playlistItem.RequiredMods.AddRange(mods);
|
|
||||||
playlistItem.AllowedMods.AddRange(allowedMods);
|
|
||||||
|
|
||||||
apiRoom.Playlist.Clear(); // Clearing should be unnecessary, but here for sanity.
|
|
||||||
apiRoom.Playlist.Add(playlistItem);
|
apiRoom.Playlist.Add(playlistItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CurrentMatchPlayingItem.Value = playlistItem;
|
||||||
|
|
||||||
|
void updateItem(PlaylistItem item)
|
||||||
|
{
|
||||||
|
item.ID = settings.PlaylistItemId == 0 ? defaultPlaylistItemId : settings.PlaylistItemId;
|
||||||
|
item.Beatmap.Value = beatmap;
|
||||||
|
item.Ruleset.Value = ruleset.RulesetInfo;
|
||||||
|
item.RequiredMods.Clear();
|
||||||
|
item.RequiredMods.AddRange(mods);
|
||||||
|
item.AllowedMods.Clear();
|
||||||
|
item.AllowedMods.AddRange(allowedMods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For the provided user ID, update whether the user is included in <see cref="CurrentMatchPlayingUserIds"/>.
|
/// For the provided user ID, update whether the user is included in <see cref="CurrentMatchPlayingUserIds"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -23,6 +23,12 @@ namespace osu.Game.Online.Rooms
|
|||||||
[JsonProperty("ruleset_id")]
|
[JsonProperty("ruleset_id")]
|
||||||
public int RulesetID { get; set; }
|
public int RulesetID { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this <see cref="PlaylistItem"/> is still a valid selection for the <see cref="Room"/>.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("expired")]
|
||||||
|
public bool Expired { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public readonly Bindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
|
public readonly Bindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
|
||||||
|
|
||||||
|
@ -153,6 +153,12 @@ namespace osu.Game.Online.Rooms
|
|||||||
if (EndDate.Value != null && DateTimeOffset.Now >= EndDate.Value)
|
if (EndDate.Value != null && DateTimeOffset.Now >= EndDate.Value)
|
||||||
Status.Value = new RoomStatusEnded();
|
Status.Value = new RoomStatusEnded();
|
||||||
|
|
||||||
|
// Todo: This is not the best way/place to do this, but the intention is to display all playlist items when the room has ended,
|
||||||
|
// and display only the non-expired playlist items while the room is still active. In order to achieve this, all expired items are removed from the source Room.
|
||||||
|
// More refactoring is required before this can be done locally instead - DrawableRoomPlaylist is currently directly bound to the playlist to display items in the room.
|
||||||
|
if (!(Status.Value is RoomStatusEnded))
|
||||||
|
other.Playlist.RemoveAll(i => i.Expired);
|
||||||
|
|
||||||
if (!Playlist.SequenceEqual(other.Playlist))
|
if (!Playlist.SequenceEqual(other.Playlist))
|
||||||
{
|
{
|
||||||
Playlist.Clear();
|
Playlist.Clear();
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
@ -25,6 +24,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
|||||||
[Cached(typeof(IPreviewTrackOwner))]
|
[Cached(typeof(IPreviewTrackOwner))]
|
||||||
public abstract class RoomSubScreen : OnlinePlaySubScreen, IPreviewTrackOwner
|
public abstract class RoomSubScreen : OnlinePlaySubScreen, IPreviewTrackOwner
|
||||||
{
|
{
|
||||||
|
[Cached(typeof(IBindable<PlaylistItem>))]
|
||||||
protected readonly Bindable<PlaylistItem> SelectedItem = new Bindable<PlaylistItem>();
|
protected readonly Bindable<PlaylistItem> SelectedItem = new Bindable<PlaylistItem>();
|
||||||
|
|
||||||
public override bool DisallowExternalBeatmapRulesetChanges => true;
|
public override bool DisallowExternalBeatmapRulesetChanges => true;
|
||||||
@ -39,9 +39,6 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
|||||||
|
|
||||||
private Sample sampleStart;
|
private Sample sampleStart;
|
||||||
|
|
||||||
[Resolved(typeof(Room), nameof(Room.Playlist))]
|
|
||||||
protected BindableList<PlaylistItem> Playlist { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Any mods applied by/to the local user.
|
/// Any mods applied by/to the local user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -103,8 +100,6 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
|||||||
|
|
||||||
SelectedItem.BindValueChanged(_ => Scheduler.AddOnce(selectedItemChanged));
|
SelectedItem.BindValueChanged(_ => Scheduler.AddOnce(selectedItemChanged));
|
||||||
|
|
||||||
Playlist.BindCollectionChanged(onPlaylistChanged, true);
|
|
||||||
|
|
||||||
managerUpdated = beatmapManager.ItemUpdated.GetBoundCopy();
|
managerUpdated = beatmapManager.ItemUpdated.GetBoundCopy();
|
||||||
managerUpdated.BindValueChanged(beatmapUpdated);
|
managerUpdated.BindValueChanged(beatmapUpdated);
|
||||||
|
|
||||||
@ -122,9 +117,6 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
|||||||
return base.OnBackButton();
|
return base.OnBackButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onPlaylistChanged(object sender, NotifyCollectionChangedEventArgs e) =>
|
|
||||||
SelectedItem.Value = Playlist.FirstOrDefault();
|
|
||||||
|
|
||||||
protected void ShowUserModSelect() => userModsSelectOverlay.Show();
|
protected void ShowUserModSelect() => userModsSelectOverlay.Show();
|
||||||
|
|
||||||
public override void OnEntering(IScreen last)
|
public override void OnEntering(IScreen last)
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -13,7 +11,7 @@ using osu.Game.Screens.OnlinePlay.Match.Components;
|
|||||||
|
|
||||||
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
||||||
{
|
{
|
||||||
public class BeatmapSelectionControl : OnlinePlayComposite
|
public class BeatmapSelectionControl : RoomSubScreenComposite
|
||||||
{
|
{
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private MultiplayerMatchSubScreen matchSubScreen { get; set; }
|
private MultiplayerMatchSubScreen matchSubScreen { get; set; }
|
||||||
@ -60,7 +58,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
Playlist.BindCollectionChanged(onPlaylistChanged, true);
|
SelectedItem.BindValueChanged(_ => updateBeatmap(), true);
|
||||||
Host.BindValueChanged(host =>
|
Host.BindValueChanged(host =>
|
||||||
{
|
{
|
||||||
if (RoomID.Value == null || host.NewValue?.Equals(api.LocalUser.Value) == true)
|
if (RoomID.Value == null || host.NewValue?.Equals(api.LocalUser.Value) == true)
|
||||||
@ -70,12 +68,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
|||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onPlaylistChanged(object sender, NotifyCollectionChangedEventArgs e)
|
private void updateBeatmap()
|
||||||
{
|
{
|
||||||
if (Playlist.Any())
|
if (SelectedItem.Value == null)
|
||||||
beatmapPanelContainer.Child = new DrawableRoomPlaylistItem(Playlist.Single(), false, false);
|
|
||||||
else
|
|
||||||
beatmapPanelContainer.Clear();
|
beatmapPanelContainer.Clear();
|
||||||
|
else
|
||||||
|
beatmapPanelContainer.Child = new DrawableRoomPlaylistItem(SelectedItem.Value, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
|
|
||||||
private MultiplayerMatchSettingsOverlay settingsOverlay;
|
private MultiplayerMatchSettingsOverlay settingsOverlay;
|
||||||
|
|
||||||
private IBindable<bool> isConnected;
|
private readonly IBindable<bool> isConnected = new Bindable<bool>();
|
||||||
|
|
||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
private IDisposable readyClickOperation;
|
private IDisposable readyClickOperation;
|
||||||
@ -252,13 +252,15 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
|
SelectedItem.BindTo(client.CurrentMatchPlayingItem);
|
||||||
|
|
||||||
BeatmapAvailability.BindValueChanged(updateBeatmapAvailability, true);
|
BeatmapAvailability.BindValueChanged(updateBeatmapAvailability, true);
|
||||||
UserMods.BindValueChanged(onUserModsChanged);
|
UserMods.BindValueChanged(onUserModsChanged);
|
||||||
|
|
||||||
client.LoadRequested += onLoadRequested;
|
client.LoadRequested += onLoadRequested;
|
||||||
client.RoomUpdated += onRoomUpdated;
|
client.RoomUpdated += onRoomUpdated;
|
||||||
|
|
||||||
isConnected = client.IsConnected.GetBoundCopy();
|
isConnected.BindTo(client.IsConnected);
|
||||||
isConnected.BindValueChanged(connected =>
|
isConnected.BindValueChanged(connected =>
|
||||||
{
|
{
|
||||||
if (!connected.NewValue)
|
if (!connected.NewValue)
|
||||||
|
@ -2,14 +2,19 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
|
using osu.Game.Screens.OnlinePlay.Match;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Screens.OnlinePlay
|
namespace osu.Game.Screens.OnlinePlay
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="CompositeDrawable"/> that exposes bindables for <see cref="Room"/> properties.
|
||||||
|
/// </summary>
|
||||||
public class OnlinePlayComposite : CompositeDrawable
|
public class OnlinePlayComposite : CompositeDrawable
|
||||||
{
|
{
|
||||||
[Resolved(typeof(Room))]
|
[Resolved(typeof(Room))]
|
||||||
@ -53,5 +58,23 @@ namespace osu.Game.Screens.OnlinePlay
|
|||||||
|
|
||||||
[Resolved(typeof(Room))]
|
[Resolved(typeof(Room))]
|
||||||
protected Bindable<TimeSpan?> Duration { get; private set; }
|
protected Bindable<TimeSpan?> Duration { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The currently selected item in the <see cref="RoomSubScreen"/>, or the first item from <see cref="Playlist"/>
|
||||||
|
/// if this <see cref="OnlinePlayComposite"/> is not within a <see cref="RoomSubScreen"/>.
|
||||||
|
/// </summary>
|
||||||
|
protected readonly Bindable<PlaylistItem> SelectedItem = new Bindable<PlaylistItem>();
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
Playlist.BindCollectionChanged((_, __) => UpdateSelectedItem(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void UpdateSelectedItem()
|
||||||
|
{
|
||||||
|
SelectedItem.Value = Playlist.FirstOrDefault();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -33,6 +34,10 @@ namespace osu.Game.Screens.OnlinePlay
|
|||||||
|
|
||||||
protected readonly Bindable<IReadOnlyList<Mod>> FreeMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
|
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 FreeModSelectOverlay freeModSelectOverlay;
|
private readonly FreeModSelectOverlay freeModSelectOverlay;
|
||||||
|
|
||||||
private WorkingBeatmap initialBeatmap;
|
private WorkingBeatmap initialBeatmap;
|
||||||
@ -67,8 +72,8 @@ 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.
|
// 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.
|
// Similarly, freeMods is currently empty but should only contain the allowed mods.
|
||||||
Mods.Value = Playlist.FirstOrDefault()?.RequiredMods.Select(m => m.CreateCopy()).ToArray() ?? Array.Empty<Mod>();
|
Mods.Value = selectedItem?.Value?.RequiredMods.Select(m => m.CreateCopy()).ToArray() ?? Array.Empty<Mod>();
|
||||||
FreeMods.Value = Playlist.FirstOrDefault()?.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);
|
Ruleset.BindValueChanged(onRulesetChanged);
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,9 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
|||||||
[Resolved(typeof(Room), nameof(Room.RoomID))]
|
[Resolved(typeof(Room), nameof(Room.RoomID))]
|
||||||
private Bindable<long?> roomId { get; set; }
|
private Bindable<long?> roomId { get; set; }
|
||||||
|
|
||||||
|
[Resolved(typeof(Room), nameof(Room.Playlist))]
|
||||||
|
private BindableList<PlaylistItem> playlist { get; set; }
|
||||||
|
|
||||||
private MatchSettingsOverlay settingsOverlay;
|
private MatchSettingsOverlay settingsOverlay;
|
||||||
private MatchLeaderboard leaderboard;
|
private MatchLeaderboard leaderboard;
|
||||||
|
|
||||||
@ -119,7 +122,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
|||||||
new DrawableRoomPlaylistWithResults
|
new DrawableRoomPlaylistWithResults
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Items = { BindTarget = Playlist },
|
Items = { BindTarget = playlist },
|
||||||
SelectedItem = { BindTarget = SelectedItem },
|
SelectedItem = { BindTarget = SelectedItem },
|
||||||
RequestShowResults = item =>
|
RequestShowResults = item =>
|
||||||
{
|
{
|
||||||
@ -266,7 +269,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
|||||||
|
|
||||||
// Set the first playlist item.
|
// Set the first playlist item.
|
||||||
// This is scheduled since updating the room and playlist may happen in an arbitrary order (via Room.CopyFrom()).
|
// This is scheduled since updating the room and playlist may happen in an arbitrary order (via Room.CopyFrom()).
|
||||||
Schedule(() => SelectedItem.Value = Playlist.FirstOrDefault());
|
Schedule(() => SelectedItem.Value = playlist.FirstOrDefault());
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
38
osu.Game/Screens/OnlinePlay/RoomSubScreenComposite.cs
Normal file
38
osu.Game/Screens/OnlinePlay/RoomSubScreenComposite.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Online.Rooms;
|
||||||
|
using osu.Game.Screens.OnlinePlay.Match;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.OnlinePlay
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An <see cref="OnlinePlayComposite"/> with additional logic tracking the currently-selected <see cref="PlaylistItem"/> inside a <see cref="RoomSubScreen"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class RoomSubScreenComposite : OnlinePlayComposite
|
||||||
|
{
|
||||||
|
[Resolved]
|
||||||
|
private IBindable<PlaylistItem> subScreenSelectedItem { get; set; }
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
subScreenSelectedItem.BindValueChanged(_ => UpdateSelectedItem(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void UpdateSelectedItem()
|
||||||
|
{
|
||||||
|
if (RoomID.Value == null)
|
||||||
|
{
|
||||||
|
// If the room hasn't been created yet, fall-back to the base logic.
|
||||||
|
base.UpdateSelectedItem();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectedItem.Value = subScreenSelectedItem.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user