1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-27 11:03:22 +08:00

Merge pull request #16985 from smoogipoo/multi-spectator-chat

Add chat display to multiplayer spectator
This commit is contained in:
Dean Herbert 2022-02-25 20:19:07 +09:00 committed by GitHub
commit 926abf7a0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 46 additions and 16 deletions

View File

@ -15,6 +15,7 @@ using osu.Game.Configuration;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus; using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
using osu.Game.Online.Rooms;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate; using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
@ -377,7 +378,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
Beatmap.Value = beatmapManager.GetWorkingBeatmap(importedBeatmap); Beatmap.Value = beatmapManager.GetWorkingBeatmap(importedBeatmap);
Ruleset.Value = importedBeatmap.Ruleset; Ruleset.Value = importedBeatmap.Ruleset;
LoadScreen(spectatorScreen = new TestMultiSpectatorScreen(playingUsers.ToArray(), gameplayStartTime)); LoadScreen(spectatorScreen = new TestMultiSpectatorScreen(SelectedRoom.Value, playingUsers.ToArray(), gameplayStartTime));
}); });
AddUntilStep("wait for screen load", () => spectatorScreen.LoadState == LoadState.Loaded && (!waitForPlayerLoad || spectatorScreen.AllPlayersLoaded)); AddUntilStep("wait for screen load", () => spectatorScreen.LoadState == LoadState.Loaded && (!waitForPlayerLoad || spectatorScreen.AllPlayersLoaded));
@ -465,8 +466,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
private readonly double? gameplayStartTime; private readonly double? gameplayStartTime;
public TestMultiSpectatorScreen(MultiplayerRoomUser[] users, double? gameplayStartTime = null) public TestMultiSpectatorScreen(Room room, MultiplayerRoomUser[] users, double? gameplayStartTime = null)
: base(users) : base(room, users)
{ {
this.gameplayStartTime = gameplayStartTime; this.gameplayStartTime = gameplayStartTime;
} }

View File

@ -838,7 +838,8 @@ namespace osu.Game
channelManager.HighPollRate.Value = channelManager.HighPollRate.Value =
chatOverlay.State.Value == Visibility.Visible chatOverlay.State.Value == Visibility.Visible
|| API.Activity.Value is UserActivity.InLobby || API.Activity.Value is UserActivity.InLobby
|| API.Activity.Value is UserActivity.InMultiplayerGame; || API.Activity.Value is UserActivity.InMultiplayerGame
|| API.Activity.Value is UserActivity.SpectatingMultiplayerGame;
} }
Add(difficultyRecommender); Add(difficultyRecommender);

View File

@ -1,6 +1,7 @@
// 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 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;
@ -15,10 +16,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
{ {
public class GameplayChatDisplay : MatchChatDisplay, IKeyBindingHandler<GlobalAction> public class GameplayChatDisplay : MatchChatDisplay, IKeyBindingHandler<GlobalAction>
{ {
[Resolved] [Resolved(CanBeNull = true)]
[CanBeNull]
private ILocalUserPlayInfo localUserInfo { get; set; } private ILocalUserPlayInfo localUserInfo { get; set; }
private IBindable<bool> localUserPlaying = new Bindable<bool>(); private readonly IBindable<bool> localUserPlaying = new Bindable<bool>();
public override bool PropagatePositionalInputSubTree => !localUserPlaying.Value; public override bool PropagatePositionalInputSubTree => !localUserPlaying.Value;
@ -46,7 +48,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
{ {
base.LoadComplete(); base.LoadComplete();
localUserPlaying = localUserInfo.IsPlaying.GetBoundCopy(); if (localUserInfo != null)
localUserPlaying.BindTo(localUserInfo.IsPlaying);
localUserPlaying.BindValueChanged(playing => localUserPlaying.BindValueChanged(playing =>
{ {
// for now let's never hold focus. this avoid misdirected gameplay keys entering chat. // for now let's never hold focus. this avoid misdirected gameplay keys entering chat.

View File

@ -449,7 +449,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
switch (client.LocalUser.State) switch (client.LocalUser.State)
{ {
case MultiplayerUserState.Spectating: case MultiplayerUserState.Spectating:
return new MultiSpectatorScreen(users.Take(PlayerGrid.MAX_PLAYERS).ToArray()); return new MultiSpectatorScreen(Room, users.Take(PlayerGrid.MAX_PLAYERS).ToArray());
default: default:
return new MultiplayerPlayerLoader(() => new MultiplayerPlayer(Room, SelectedItem.Value, users)); return new MultiplayerPlayerLoader(() => new MultiplayerPlayer(Room, SelectedItem.Value, users));

View File

@ -11,10 +11,13 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Online.Spectator; using osu.Game.Online.Spectator;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD;
using osu.Game.Screens.Spectate; using osu.Game.Screens.Spectate;
using osu.Game.Users;
using osuTK;
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
{ {
@ -34,6 +37,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
/// </summary> /// </summary>
public bool AllPlayersLoaded => instances.All(p => p?.PlayerLoaded == true); public bool AllPlayersLoaded => instances.All(p => p?.PlayerLoaded == true);
protected override UserActivity InitialActivity => new UserActivity.SpectatingMultiplayerGame(Beatmap.Value.BeatmapInfo, Ruleset.Value);
[Resolved] [Resolved]
private OsuColour colours { get; set; } private OsuColour colours { get; set; }
@ -48,15 +53,18 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
private PlayerArea currentAudioSource; private PlayerArea currentAudioSource;
private bool canStartMasterClock; private bool canStartMasterClock;
private readonly Room room;
private readonly MultiplayerRoomUser[] users; private readonly MultiplayerRoomUser[] users;
/// <summary> /// <summary>
/// Creates a new <see cref="MultiSpectatorScreen"/>. /// Creates a new <see cref="MultiSpectatorScreen"/>.
/// </summary> /// </summary>
/// <param name="room">The room.</param>
/// <param name="users">The players to spectate.</param> /// <param name="users">The players to spectate.</param>
public MultiSpectatorScreen(MultiplayerRoomUser[] users) public MultiSpectatorScreen(Room room, MultiplayerRoomUser[] users)
: base(users.Select(u => u.UserID).ToArray()) : base(users.Select(u => u.UserID).ToArray())
{ {
this.room = room;
this.users = users; this.users = users;
instances = new PlayerArea[Users.Count]; instances = new PlayerArea[Users.Count];
@ -65,7 +73,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
Container leaderboardContainer; FillFlowContainer leaderboardFlow;
Container scoreDisplayContainer; Container scoreDisplayContainer;
masterClockContainer = CreateMasterGameplayClockContainer(Beatmap.Value); masterClockContainer = CreateMasterGameplayClockContainer(Beatmap.Value);
@ -97,10 +105,13 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
{ {
new Drawable[] new Drawable[]
{ {
leaderboardContainer = new Container leaderboardFlow = new FillFlowContainer
{ {
RelativeSizeAxes = Axes.Y, Anchor = Anchor.CentreLeft,
AutoSizeAxes = Axes.X Origin = Anchor.CentreLeft,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Spacing = new Vector2(5)
}, },
grid = new PlayerGrid { RelativeSizeAxes = Axes.Both } grid = new PlayerGrid { RelativeSizeAxes = Axes.Both }
} }
@ -125,14 +136,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
LoadComponentAsync(leaderboard = new MultiSpectatorLeaderboard(scoreProcessor, users) LoadComponentAsync(leaderboard = new MultiSpectatorLeaderboard(scoreProcessor, users)
{ {
Expanded = { Value = true }, Expanded = { Value = true },
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
}, l => }, l =>
{ {
foreach (var instance in instances) foreach (var instance in instances)
leaderboard.AddClock(instance.UserId, instance.GameplayClock); leaderboard.AddClock(instance.UserId, instance.GameplayClock);
leaderboardContainer.Add(leaderboard); leaderboardFlow.Insert(0, leaderboard);
if (leaderboard.TeamScores.Count == 2) if (leaderboard.TeamScores.Count == 2)
{ {
@ -143,6 +152,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
}, scoreDisplayContainer.Add); }, scoreDisplayContainer.Add);
} }
}); });
LoadComponentAsync(new GameplayChatDisplay(room)
{
Expanded = { Value = true },
}, chat => leaderboardFlow.Insert(1, chat));
} }
protected override void LoadComplete() protected override void LoadComplete()

View File

@ -50,6 +50,16 @@ namespace osu.Game.Users
public override string Status => $@"{base.Status} with others"; public override string Status => $@"{base.Status} with others";
} }
public class SpectatingMultiplayerGame : InGame
{
public SpectatingMultiplayerGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset)
: base(beatmapInfo, ruleset)
{
}
public override string Status => $"Watching others {base.Status.ToLowerInvariant()}";
}
public class InPlaylistGame : InGame public class InPlaylistGame : InGame
{ {
public InPlaylistGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset) public InPlaylistGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset)