mirror of
https://github.com/SK-la/Ez2Lazer.git
synced 2026-03-13 11:20:28 +00:00
Adjust matchmaking naming, namespaces, xmldoc (#35123)
* Adjust matchmaking naming, namespaces, xmldoc * Change partial filenames to use `.` instead of `_` separator
This commit is contained in:
@@ -1,28 +0,0 @@
|
||||
// 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.Graphics;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
public partial class TestSceneBeatmapPanel : MultiplayerTestScene
|
||||
{
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddStep("add beatmap panel", () =>
|
||||
{
|
||||
Child = new BeatmapPanel(CreateAPIBeatmap())
|
||||
{
|
||||
Size = new Vector2(300, 70),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
public partial class TestSceneBeatmapSelectionOverlay : OsuTestScene
|
||||
{
|
||||
private BeatmapSelectionOverlay selectionOverlay = null!;
|
||||
|
||||
[SetUpSteps]
|
||||
public void SetupSteps()
|
||||
{
|
||||
AddStep("add drawable", () => Child = new Container
|
||||
{
|
||||
Width = 100,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(2),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0.1f,
|
||||
},
|
||||
selectionOverlay = new BeatmapSelectionOverlay
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSelectionOverlay()
|
||||
{
|
||||
AddStep("add maarvin", () => selectionOverlay.AddUser(new APIUser
|
||||
{
|
||||
Id = 6411631,
|
||||
Username = "Maarvin",
|
||||
}, isOwnUser: true));
|
||||
AddStep("add peppy", () => selectionOverlay.AddUser(new APIUser
|
||||
{
|
||||
Id = 2,
|
||||
Username = "peppy",
|
||||
}, false));
|
||||
AddStep("add smogipoo", () => selectionOverlay.AddUser(new APIUser
|
||||
{
|
||||
Id = 1040328,
|
||||
Username = "smoogipoo",
|
||||
}, false));
|
||||
AddStep("remove smogipoo", () => selectionOverlay.RemoveUser(1040328));
|
||||
AddStep("remove peppy", () => selectionOverlay.RemoveUser(2));
|
||||
AddStep("remove maarvin", () => selectionOverlay.RemoveUser(6411631));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Idle;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match.RoundWarmup;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
using osuTK;
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
return (user, 0);
|
||||
}).ToArray();
|
||||
|
||||
Child = new ScreenStack(new IdleScreen())
|
||||
Child = new ScreenStack(new SubScreenRoundWarmup())
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
||||
@@ -6,20 +6,20 @@ using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Queue;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
public partial class TestSceneMatchmakingCloud : OsuTestScene
|
||||
{
|
||||
private MatchmakingCloud cloud = null!;
|
||||
private CloudVisualisation cloud = null!;
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Child = cloud = new MatchmakingCloud
|
||||
Child = cloud = new CloudVisualisation
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Online.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Queue;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
@@ -14,7 +14,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddStep("add selector", () => Child = new MatchmakingPoolSelector
|
||||
AddStep("add selector", () => Child = new PoolSelector
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
||||
@@ -7,8 +7,8 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Intro;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Queue;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
using osu.Game.Users;
|
||||
|
||||
@@ -17,16 +17,16 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
public partial class TestSceneMatchmakingQueueScreen : MultiplayerTestScene
|
||||
{
|
||||
[Cached]
|
||||
private readonly MatchmakingController controller = new MatchmakingController();
|
||||
private readonly QueueController controller = new QueueController();
|
||||
|
||||
private MatchmakingQueueScreen? queueScreen => Stack.CurrentScreen as MatchmakingQueueScreen;
|
||||
private ScreenQueue? queueScreen => Stack.CurrentScreen as ScreenQueue;
|
||||
|
||||
[SetUpSteps]
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddStep("load screen", () => LoadScreen(new MatchmakingIntroScreen()));
|
||||
AddStep("load screen", () => LoadScreen(new IntroScreen()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -44,15 +44,15 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
}).ToArray();
|
||||
});
|
||||
|
||||
AddStep("change state to idle", () => queueScreen!.SetState(MatchmakingQueueScreen.MatchmakingScreenState.Idle));
|
||||
AddStep("change state to idle", () => queueScreen!.SetState(ScreenQueue.MatchmakingScreenState.Idle));
|
||||
|
||||
AddStep("change state to queueing", () => queueScreen!.SetState(MatchmakingQueueScreen.MatchmakingScreenState.Queueing));
|
||||
AddStep("change state to queueing", () => queueScreen!.SetState(ScreenQueue.MatchmakingScreenState.Queueing));
|
||||
|
||||
AddStep("change state to found match", () => queueScreen!.SetState(MatchmakingQueueScreen.MatchmakingScreenState.PendingAccept));
|
||||
AddStep("change state to found match", () => queueScreen!.SetState(ScreenQueue.MatchmakingScreenState.PendingAccept));
|
||||
|
||||
AddStep("change state to waiting for room", () => queueScreen!.SetState(MatchmakingQueueScreen.MatchmakingScreenState.AcceptedWaitingForRoom));
|
||||
AddStep("change state to waiting for room", () => queueScreen!.SetState(ScreenQueue.MatchmakingScreenState.AcceptedWaitingForRoom));
|
||||
|
||||
AddStep("change state to in room", () => queueScreen!.SetState(MatchmakingQueueScreen.MatchmakingScreenState.InRoom));
|
||||
AddStep("change state to in room", () => queueScreen!.SetState(ScreenQueue.MatchmakingScreenState.InRoom));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
@@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
private const int beatmap_count = 50;
|
||||
|
||||
private MultiplayerRoomUser[] users = null!;
|
||||
private MatchmakingScreen screen = null!;
|
||||
private ScreenMatchmaking screen = null!;
|
||||
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
@@ -80,7 +80,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
StarRating = i / 10.0
|
||||
}).ToArray();
|
||||
|
||||
LoadScreen(screen = new MatchmakingScreen(new MultiplayerRoom(0)
|
||||
LoadScreen(screen = new ScreenMatchmaking(new MultiplayerRoom(0)
|
||||
{
|
||||
Users = users,
|
||||
Playlist = beatmaps
|
||||
|
||||
@@ -11,7 +11,7 @@ using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
@@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
|
||||
AddStep("add carousel", () =>
|
||||
{
|
||||
Child = new MatchmakingScreenStack
|
||||
Child = new ScreenMatchmaking.ScreenStack
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Results;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match.Results;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
public partial class TestSceneRoomStatisticPanel : MultiplayerTestScene
|
||||
public partial class TestScenePanelRoomAward : MultiplayerTestScene
|
||||
{
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddStep("add statistic", () => Child = new RoomStatisticPanel("Statistic description", 1)
|
||||
AddStep("add statistic", () => Child = new PanelRoomAward("Statistic description", 1)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
@@ -10,7 +10,7 @@ using osu.Framework.Utils;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match.BeatmapSelect;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
@@ -79,9 +79,9 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
var selectedItems = new List<long>();
|
||||
|
||||
PickScreen screen = null!;
|
||||
SubScreenBeatmapSelect screen = null!;
|
||||
|
||||
AddStep("add screen", () => Child = new ScreenStack(screen = new PickScreen()));
|
||||
AddStep("add screen", () => Child = new ScreenStack(screen = new SubScreenBeatmapSelect()));
|
||||
|
||||
AddStep("select maps", () =>
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
using osu.Game.Users;
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
public partial class TestScenePlayerPanel : MultiplayerTestScene
|
||||
{
|
||||
private PlayerPanel panel = null!;
|
||||
private MatchmakingUserPanel panel = null!;
|
||||
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
@@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
AddStep("join room", () => JoinRoom(CreateDefaultRoom(MatchType.Matchmaking)));
|
||||
WaitForJoined();
|
||||
|
||||
AddStep("add panel", () => Child = panel = new PlayerPanel(new MultiplayerRoomUser(1)
|
||||
AddStep("add panel", () => Child = panel = new MatchmakingUserPanel(new MultiplayerRoomUser(1)
|
||||
{
|
||||
User = new APIUser
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Results;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match.Results;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
using osuTK;
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
|
||||
AddStep("add results screen", () =>
|
||||
{
|
||||
Child = new ScreenStack(new ResultsScreen())
|
||||
Child = new ScreenStack(new SubScreenResults())
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
||||
@@ -13,7 +13,7 @@ using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.RoundResults;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match.RoundResults;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
using osuTK;
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
|
||||
AddStep("load screen", () =>
|
||||
{
|
||||
Child = new ScreenStack(new RoundResultsScreen())
|
||||
Child = new ScreenStack(new SubScreenRoundResults())
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
||||
@@ -11,17 +11,17 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match.BeatmapSelect;
|
||||
using osu.Game.Tests.Visual.OnlinePlay;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
public partial class TestSceneBeatmapSelectionGrid : OnlinePlayTestScene
|
||||
public partial class TestSceneSelectionGrid : OnlinePlayTestScene
|
||||
{
|
||||
private MultiplayerPlaylistItem[] items = null!;
|
||||
|
||||
private BeatmapSelectionGrid grid = null!;
|
||||
private SelectionGrid grid = null!;
|
||||
|
||||
[Resolved]
|
||||
private BeatmapManager beatmapManager { get; set; } = null!;
|
||||
@@ -58,7 +58,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddStep("add grid", () => Child = grid = new BeatmapSelectionGrid
|
||||
AddStep("add grid", () => Child = grid = new SelectionGrid
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
@@ -154,7 +154,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
var (candidateItems, _) = pickRandomItems(count);
|
||||
|
||||
grid.TransferCandidatePanelsToRollContainer(candidateItems);
|
||||
grid.Delay(BeatmapSelectionGrid.ARRANGE_DELAY)
|
||||
grid.Delay(SelectionGrid.ARRANGE_DELAY)
|
||||
.Schedule(() => grid.ArrangeItemsForRollAnimation());
|
||||
});
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
|
||||
AddStep("display roll order", () =>
|
||||
{
|
||||
var panels = grid.ChildrenOfType<BeatmapSelectionPanel>().ToArray();
|
||||
var panels = grid.ChildrenOfType<SelectionPanel>().ToArray();
|
||||
|
||||
for (int i = 0; i < panels.Length; i++)
|
||||
{
|
||||
@@ -7,12 +7,12 @@ using osu.Framework.Graphics;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match.BeatmapSelect;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
public partial class TestSceneBeatmapSelectionPanel : MultiplayerTestScene
|
||||
public partial class TestSceneSelectionPanel : MultiplayerTestScene
|
||||
{
|
||||
[Cached]
|
||||
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
|
||||
@@ -20,9 +20,9 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
[Test]
|
||||
public void TestBeatmapPanel()
|
||||
{
|
||||
BeatmapSelectionPanel? panel = null;
|
||||
SelectionPanel? panel = null;
|
||||
|
||||
AddStep("add panel", () => Child = panel = new BeatmapSelectionPanel(new MultiplayerPlaylistItem())
|
||||
AddStep("add panel", () => Child = panel = new SelectionPanel(new MultiplayerPlaylistItem())
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
@@ -8,7 +8,7 @@ using osu.Framework.Graphics;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
|
||||
@@ -9,12 +9,12 @@ using osu.Game.Online.Matchmaking;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
public partial class TestSceneStageBubble : MultiplayerTestScene
|
||||
public partial class TestSceneStageSegment : MultiplayerTestScene
|
||||
{
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
@@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
AddStep("join room", () => JoinRoom(CreateDefaultRoom(MatchType.Matchmaking)));
|
||||
WaitForJoined();
|
||||
|
||||
AddStep("add bubble", () => Child = new StageBubble(null, MatchmakingStage.RoundWarmupTime, "Next Round")
|
||||
AddStep("add bubble", () => Child = new StageDisplay.StageSegment(null, MatchmakingStage.RoundWarmupTime, "Next Round")
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
@@ -7,12 +7,12 @@ using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
public partial class TestSceneStageText : MultiplayerTestScene
|
||||
public partial class TestSceneStatusText : MultiplayerTestScene
|
||||
{
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
@@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
AddStep("join room", () => JoinRoom(CreateDefaultRoom(MatchType.Matchmaking)));
|
||||
WaitForJoined();
|
||||
|
||||
AddStep("create display", () => Child = new StageText
|
||||
AddStep("create display", () => Child = new StageDisplay.StatusText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
@@ -11,15 +11,15 @@ using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
public partial class TestScenePlayerPanelList : MultiplayerTestScene
|
||||
public partial class TestSceneUserPanelOverlay : MultiplayerTestScene
|
||||
{
|
||||
private PlayerPanelList list = null!;
|
||||
private UserPanelOverlay list = null!;
|
||||
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
@@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Size = new Vector2(0.8f),
|
||||
Child = list = new PlayerPanelList()
|
||||
Child = list = new UserPanelOverlay()
|
||||
});
|
||||
}
|
||||
|
||||
@@ -55,15 +55,15 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
}
|
||||
});
|
||||
|
||||
AddStep("change to split mode", () => list.DisplayStyle = PlayerPanelList.PanelDisplayStyle.Split);
|
||||
AddStep("change to grid mode", () => list.DisplayStyle = PlayerPanelList.PanelDisplayStyle.Grid);
|
||||
AddStep("change to hidden mode", () => list.DisplayStyle = PlayerPanelList.PanelDisplayStyle.Hidden);
|
||||
AddStep("change to split mode", () => list.DisplayStyle = PanelDisplayStyle.Split);
|
||||
AddStep("change to grid mode", () => list.DisplayStyle = PanelDisplayStyle.Grid);
|
||||
AddStep("change to hidden mode", () => list.DisplayStyle = PanelDisplayStyle.Hidden);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddPanelsGrid()
|
||||
{
|
||||
AddStep("change to grid mode", () => list.DisplayStyle = PlayerPanelList.PanelDisplayStyle.Grid);
|
||||
AddStep("change to grid mode", () => list.DisplayStyle = PanelDisplayStyle.Grid);
|
||||
|
||||
int userId = 0;
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
[Test]
|
||||
public void AddPanelsSplit()
|
||||
{
|
||||
AddStep("change to split mode", () => list.DisplayStyle = PlayerPanelList.PanelDisplayStyle.Split);
|
||||
AddStep("change to split mode", () => list.DisplayStyle = PanelDisplayStyle.Split);
|
||||
|
||||
int userId = 0;
|
||||
|
||||
@@ -65,7 +65,7 @@ using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Footer;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osu.Game.Screens.OnlinePlay.DailyChallenge;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Queue;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||
using osu.Game.Screens.OnlinePlay.Playlists;
|
||||
using osu.Game.Screens.Play;
|
||||
@@ -80,6 +80,7 @@ using osu.Game.Utils;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using Sentry;
|
||||
using IntroScreen = osu.Game.Screens.Menu.IntroScreen;
|
||||
using MatchType = osu.Game.Online.Rooms.MatchType;
|
||||
|
||||
namespace osu.Game
|
||||
@@ -1271,7 +1272,7 @@ namespace osu.Game
|
||||
|
||||
loadComponentSingleFile(new BackgroundDataStoreProcessor(), Add);
|
||||
loadComponentSingleFile<BeatmapStore>(detachedBeatmapStore = new RealmDetachedBeatmapStore(), Add, true);
|
||||
loadComponentSingleFile(new MatchmakingController(), Add, true);
|
||||
loadComponentSingleFile(new QueueController(), Add, true);
|
||||
|
||||
Add(externalLinkOpener = new ExternalLinkOpener());
|
||||
Add(new MusicKeyBindingHandler());
|
||||
|
||||
@@ -37,7 +37,6 @@ using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.OnlinePlay.DailyChallenge;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||
using osu.Game.Screens.OnlinePlay.Playlists;
|
||||
using osu.Game.Screens.SelectV2;
|
||||
@@ -483,7 +482,7 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
private void loadSongSelect() => this.Push(new SoloSongSelect());
|
||||
|
||||
private void joinOrLeaveMatchmakingQueue() => this.Push(new MatchmakingIntroScreen());
|
||||
private void joinOrLeaveMatchmakingQueue() => this.Push(new OnlinePlay.Matchmaking.Intro.IntroScreen());
|
||||
|
||||
private partial class MobileDisclaimerDialog : PopupDialog
|
||||
{
|
||||
|
||||
@@ -14,10 +14,14 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Screens.OnlinePlay.Match;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Queue;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Intro
|
||||
{
|
||||
public partial class MatchmakingIntroScreen : OsuScreen
|
||||
/// <summary>
|
||||
/// A brief intro animation that introduces matchmaking to the user.
|
||||
/// </summary>
|
||||
public partial class IntroScreen : OsuScreen
|
||||
{
|
||||
public override bool DisallowExternalBeatmapRulesetChanges => false;
|
||||
|
||||
@@ -51,7 +55,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
|
||||
|
||||
protected override BackgroundScreen CreateBackground() => new MatchmakingIntroBackgroundScreen(colourProvider);
|
||||
|
||||
public MatchmakingIntroScreen()
|
||||
public IntroScreen()
|
||||
{
|
||||
ValidForResume = false;
|
||||
}
|
||||
@@ -191,7 +195,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
|
||||
Schedule(() =>
|
||||
{
|
||||
if (this.IsCurrentScreen())
|
||||
this.Push(new MatchmakingQueueScreen());
|
||||
this.Push(new ScreenQueue());
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,9 @@ using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match.BeatmapSelect
|
||||
{
|
||||
public partial class BeatmapSelectionGrid : CompositeDrawable
|
||||
public partial class SelectionGrid : CompositeDrawable
|
||||
{
|
||||
public const double ARRANGE_DELAY = 200;
|
||||
|
||||
@@ -37,10 +37,10 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; } = null!;
|
||||
|
||||
private readonly Dictionary<long, BeatmapSelectionPanel> panelLookup = new Dictionary<long, BeatmapSelectionPanel>();
|
||||
private readonly Dictionary<long, SelectionPanel> panelLookup = new Dictionary<long, SelectionPanel>();
|
||||
|
||||
private readonly PanelGridContainer panelGridContainer;
|
||||
private readonly Container<BeatmapSelectionPanel> rollContainer;
|
||||
private readonly Container<SelectionPanel> rollContainer;
|
||||
private readonly OsuScrollContainer scroll;
|
||||
|
||||
private bool allowSelection = true;
|
||||
@@ -51,7 +51,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
private Sample? swooshSample;
|
||||
private double? lastSamplePlayback;
|
||||
|
||||
public BeatmapSelectionGrid()
|
||||
public SelectionGrid()
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
@@ -67,7 +67,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
Spacing = new Vector2(panel_spacing)
|
||||
},
|
||||
},
|
||||
rollContainer = new Container<BeatmapSelectionPanel>
|
||||
rollContainer = new Container<SelectionPanel>
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
@@ -108,7 +108,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
|
||||
public void AddItem(MultiplayerPlaylistItem item)
|
||||
{
|
||||
var panel = panelLookup[item.ID] = new BeatmapSelectionPanel(item)
|
||||
var panel = panelLookup[item.ID] = new SelectionPanel(item)
|
||||
{
|
||||
Size = new Vector2(300, 70),
|
||||
AllowSelection = allowSelection,
|
||||
@@ -176,7 +176,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
|
||||
var rng = new Random();
|
||||
|
||||
var remainingPanels = new List<BeatmapSelectionPanel>();
|
||||
var remainingPanels = new List<SelectionPanel>();
|
||||
|
||||
foreach (var panel in panelGridContainer.Children.ToArray())
|
||||
{
|
||||
@@ -216,7 +216,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
{
|
||||
var panel = rollContainer.Children[i];
|
||||
|
||||
var position = positions[i] * (BeatmapPanel.SIZE + new Vector2(panel_spacing));
|
||||
var position = positions[i] * (SelectionPanel.SIZE + new Vector2(panel_spacing));
|
||||
|
||||
panel.MoveTo(position, duration + stagger * i, new SplitEasingFunction(Easing.InCubic, Easing.OutExpo, 0.3f));
|
||||
|
||||
@@ -285,7 +285,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
while ((numSteps - 1) % rollContainer.Children.Count != finalItemIndex)
|
||||
numSteps++;
|
||||
|
||||
BeatmapSelectionPanel? lastPanel = null;
|
||||
SelectionPanel? lastPanel = null;
|
||||
|
||||
for (int i = 0; i < numSteps; i++)
|
||||
{
|
||||
@@ -346,7 +346,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
PresentRolledBeatmap(finalItem);
|
||||
}
|
||||
|
||||
private partial class PanelGridContainer : FillFlowContainer<BeatmapSelectionPanel>
|
||||
private partial class PanelGridContainer : FillFlowContainer<SelectionPanel>
|
||||
{
|
||||
public bool LayoutDisabled;
|
||||
|
||||
@@ -0,0 +1,502 @@
|
||||
// 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 System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Overlays;
|
||||
using osuTK;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match.BeatmapSelect
|
||||
{
|
||||
public partial class SelectionPanel : Container
|
||||
{
|
||||
public static readonly Vector2 SIZE = new Vector2(300, 70);
|
||||
|
||||
private const float corner_radius = 6;
|
||||
private const float border_width = 3;
|
||||
|
||||
public readonly MultiplayerPlaylistItem Item;
|
||||
|
||||
private readonly Container scaleContainer;
|
||||
private readonly BeatmapPanel beatmapPanel;
|
||||
private readonly AvatarOverlay selectionOverlay;
|
||||
private readonly Container border;
|
||||
private readonly Box flash;
|
||||
|
||||
public bool AllowSelection;
|
||||
|
||||
public Action<MultiplayerPlaylistItem>? Action;
|
||||
|
||||
[Resolved]
|
||||
private BeatmapLookupCache beatmapLookupCache { get; set; } = null!;
|
||||
|
||||
public override bool PropagatePositionalInputSubTree => AllowSelection;
|
||||
|
||||
public SelectionPanel(MultiplayerPlaylistItem item)
|
||||
{
|
||||
Item = item;
|
||||
Size = SIZE;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
scaleContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding(-border_width),
|
||||
Child = border = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
CornerRadius = corner_radius + border_width,
|
||||
Alpha = 0,
|
||||
Child = new Box { RelativeSizeAxes = Axes.Both },
|
||||
}
|
||||
},
|
||||
beatmapPanel = new BeatmapPanel
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
OverlayLayer =
|
||||
{
|
||||
Children = new[]
|
||||
{
|
||||
flash = new Box
|
||||
{
|
||||
Blending = BlendingParameters.Additive,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
selectionOverlay = new AvatarOverlay
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Horizontal = 10 },
|
||||
Origin = Anchor.CentreLeft,
|
||||
},
|
||||
}
|
||||
},
|
||||
new HoverClickSounds(),
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
beatmapLookupCache.GetBeatmapAsync(Item.BeatmapID).ContinueWith(b => Schedule(() =>
|
||||
{
|
||||
var beatmap = b.GetResultSafely()!;
|
||||
|
||||
beatmap.StarRating = Item.StarRating;
|
||||
|
||||
beatmapPanel.Beatmap = beatmap;
|
||||
}));
|
||||
}
|
||||
|
||||
public bool AddUser(APIUser user, bool isOwnUser = false) => selectionOverlay.AddUser(user, isOwnUser);
|
||||
|
||||
public bool RemoveUser(int userId) => selectionOverlay.RemoveUser(userId);
|
||||
|
||||
public bool RemoveUser(APIUser user) => RemoveUser(user.Id);
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
flash.FadeTo(0.2f, 50)
|
||||
.Then()
|
||||
.FadeTo(0.1f, 300);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(HoverLostEvent e)
|
||||
{
|
||||
base.OnHoverLost(e);
|
||||
|
||||
flash.FadeOut(200);
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(MouseDownEvent e)
|
||||
{
|
||||
if (e.Button == MouseButton.Left)
|
||||
{
|
||||
scaleContainer.ScaleTo(0.95f, 400, Easing.OutExpo);
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseUpEvent e)
|
||||
{
|
||||
base.OnMouseUp(e);
|
||||
|
||||
if (e.Button == MouseButton.Left)
|
||||
{
|
||||
scaleContainer.ScaleTo(1f, 500, Easing.OutElasticHalf);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnClick(ClickEvent e)
|
||||
{
|
||||
Action?.Invoke(Item);
|
||||
|
||||
flash.FadeTo(0.5f, 50)
|
||||
.Then()
|
||||
.FadeTo(0.1f, 400);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ShowBorder() => border.Show();
|
||||
|
||||
public void HideBorder() => border.Hide();
|
||||
|
||||
public void FadeInAndEnterFromBelow(double duration = 500, double delay = 0, float distance = 200)
|
||||
{
|
||||
scaleContainer
|
||||
.FadeOut()
|
||||
.MoveToY(distance)
|
||||
.Delay(delay)
|
||||
.FadeIn(duration / 2)
|
||||
.MoveToY(0, duration, Easing.OutExpo);
|
||||
}
|
||||
|
||||
public void PopOutAndExpire(double duration = 400, double delay = 0, Easing easing = Easing.InCubic)
|
||||
{
|
||||
AllowSelection = false;
|
||||
|
||||
scaleContainer.Delay(delay)
|
||||
.ScaleTo(0, duration, easing)
|
||||
.FadeOut(duration);
|
||||
|
||||
this.Delay(delay + duration).FadeOut().Expire();
|
||||
}
|
||||
|
||||
// TODO: combine following two classes with above implementation for simplicity?
|
||||
private partial class BeatmapPanel : CompositeDrawable
|
||||
{
|
||||
public readonly Container OverlayLayer = new Container { RelativeSizeAxes = Axes.Both };
|
||||
|
||||
public APIBeatmap? Beatmap
|
||||
{
|
||||
get => beatmap;
|
||||
set
|
||||
{
|
||||
if (beatmap?.OnlineID == value?.OnlineID)
|
||||
return;
|
||||
|
||||
beatmap = value;
|
||||
|
||||
if (IsLoaded)
|
||||
updateContent();
|
||||
}
|
||||
}
|
||||
|
||||
private APIBeatmap? beatmap;
|
||||
|
||||
private Container content = null!;
|
||||
private UpdateableOnlineBeatmapSetCover cover = null!;
|
||||
|
||||
public BeatmapPanel(APIBeatmap? beatmap = null)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
{
|
||||
Masking = true;
|
||||
CornerRadius = 6;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
cover = new UpdateableOnlineBeatmapSetCover(BeatmapSetCoverType.Card, timeBeforeLoad: 0, timeBeforeUnload: 10000)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientHorizontal(
|
||||
colourProvider.Background4.Opacity(0.7f),
|
||||
colourProvider.Background4.Opacity(0.4f)
|
||||
)
|
||||
},
|
||||
content = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
OverlayLayer,
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
updateContent();
|
||||
FinishTransforms(true);
|
||||
}
|
||||
|
||||
private void updateContent()
|
||||
{
|
||||
foreach (var child in content.Children)
|
||||
child.FadeOut(300).Expire();
|
||||
|
||||
cover.OnlineInfo = beatmap?.BeatmapSet;
|
||||
|
||||
if (beatmap != null)
|
||||
{
|
||||
var panelContent = new BeatmapPanelContent(beatmap)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
};
|
||||
|
||||
content.Add(panelContent);
|
||||
|
||||
panelContent.FadeInFromZero(300);
|
||||
}
|
||||
}
|
||||
|
||||
private partial class BeatmapPanelContent : CompositeDrawable
|
||||
{
|
||||
private readonly APIBeatmap beatmap;
|
||||
|
||||
public BeatmapPanelContent(APIBeatmap beatmap)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Padding = new MarginPadding { Horizontal = 12 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TruncatingSpriteText
|
||||
{
|
||||
Text = new RomanisableString(beatmap.Metadata.TitleUnicode, beatmap.Metadata.TitleUnicode),
|
||||
Font = OsuFont.Default.With(size: 19, weight: FontWeight.SemiBold),
|
||||
RelativeSizeAxes = Axes.X,
|
||||
},
|
||||
new TextFlowContainer(s =>
|
||||
{
|
||||
s.Font = OsuFont.GetFont(size: 16, weight: FontWeight.SemiBold);
|
||||
}).With(d =>
|
||||
{
|
||||
d.RelativeSizeAxes = Axes.X;
|
||||
d.AutoSizeAxes = Axes.Y;
|
||||
d.AddText("by ");
|
||||
d.AddText(new RomanisableString(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist));
|
||||
}),
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Margin = new MarginPadding { Top = 6 },
|
||||
Spacing = new Vector2(4),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new StarRatingDisplay(new StarDifficulty(beatmap.StarRating, 0), StarRatingDisplaySize.Small)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
},
|
||||
new TruncatingSpriteText
|
||||
{
|
||||
Text = beatmap.DifficultyName,
|
||||
Font = OsuFont.Default.With(size: 16, weight: FontWeight.SemiBold),
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private partial class AvatarOverlay : CompositeDrawable
|
||||
{
|
||||
private readonly Dictionary<int, SelectionAvatar> avatars = new Dictionary<int, SelectionAvatar>();
|
||||
|
||||
private readonly Container<SelectionAvatar> avatarContainer;
|
||||
|
||||
private Sample? userAddedSample;
|
||||
private double? lastSamplePlayback;
|
||||
|
||||
public new Axes AutoSizeAxes
|
||||
{
|
||||
get => base.AutoSizeAxes;
|
||||
set => base.AutoSizeAxes = value;
|
||||
}
|
||||
|
||||
public new MarginPadding Padding
|
||||
{
|
||||
get => base.Padding;
|
||||
set => base.Padding = value;
|
||||
}
|
||||
|
||||
public AvatarOverlay()
|
||||
{
|
||||
InternalChild = avatarContainer = new Container<SelectionAvatar>();
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
avatarContainer.AutoSizeAxes = AutoSizeAxes;
|
||||
avatarContainer.RelativeSizeAxes = RelativeSizeAxes;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio)
|
||||
{
|
||||
userAddedSample = audio.Samples.Get(@"Multiplayer/player-ready");
|
||||
}
|
||||
|
||||
public bool AddUser(APIUser user, bool isOwnUser)
|
||||
{
|
||||
if (avatars.ContainsKey(user.Id))
|
||||
return false;
|
||||
|
||||
var avatar = new SelectionAvatar(user, isOwnUser)
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
};
|
||||
|
||||
avatarContainer.Add(avatars[user.Id] = avatar);
|
||||
|
||||
if (lastSamplePlayback == null || Time.Current - lastSamplePlayback > OsuGameBase.SAMPLE_DEBOUNCE_TIME)
|
||||
{
|
||||
userAddedSample?.Play();
|
||||
lastSamplePlayback = Time.Current;
|
||||
}
|
||||
|
||||
updateLayout();
|
||||
|
||||
avatar.FinishTransforms();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool RemoveUser(int id)
|
||||
{
|
||||
if (!avatars.Remove(id, out var avatar))
|
||||
return false;
|
||||
|
||||
avatar.PopOutAndExpire();
|
||||
avatarContainer.ChangeChildDepth(avatar, float.MaxValue);
|
||||
|
||||
updateLayout();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateLayout()
|
||||
{
|
||||
const double stagger = 30;
|
||||
const float spacing = 4;
|
||||
|
||||
double delay = 0;
|
||||
float x = 0;
|
||||
|
||||
for (int i = avatarContainer.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var avatar = avatarContainer[i];
|
||||
|
||||
if (avatar.Expired)
|
||||
continue;
|
||||
|
||||
avatar.Delay(delay).MoveToX(x, 500, Easing.OutElasticQuarter);
|
||||
|
||||
x -= avatar.LayoutSize.X + spacing;
|
||||
|
||||
delay += stagger;
|
||||
}
|
||||
}
|
||||
|
||||
public partial class SelectionAvatar : CompositeDrawable
|
||||
{
|
||||
public bool Expired { get; private set; }
|
||||
|
||||
private readonly Container content;
|
||||
|
||||
public SelectionAvatar(APIUser user, bool isOwnUser)
|
||||
{
|
||||
Size = new Vector2(30);
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
content = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Child = new MatchmakingAvatar(user, isOwnUser)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
content.ScaleTo(0)
|
||||
.ScaleTo(1, 500, Easing.OutElasticHalf)
|
||||
.FadeIn(200);
|
||||
}
|
||||
|
||||
public void PopOutAndExpire()
|
||||
{
|
||||
content.ScaleTo(0, 400, Easing.OutExpo);
|
||||
|
||||
this.FadeOut(100).Expire();
|
||||
Expired = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,19 +9,19 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Rooms;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match.BeatmapSelect
|
||||
{
|
||||
public partial class PickScreen : MatchmakingSubScreen
|
||||
public partial class SubScreenBeatmapSelect : MatchmakingSubScreen
|
||||
{
|
||||
public override PlayerPanelList.PanelDisplayStyle PlayersDisplayStyle => PlayerPanelList.PanelDisplayStyle.Split;
|
||||
public override PanelDisplayStyle PlayersDisplayStyle => PanelDisplayStyle.Split;
|
||||
public override Drawable PlayersDisplayArea { get; }
|
||||
|
||||
private readonly BeatmapSelectionGrid selectionGrid;
|
||||
private readonly SelectionGrid selectionGrid;
|
||||
|
||||
[Resolved]
|
||||
private MultiplayerClient client { get; set; } = null!;
|
||||
|
||||
public PickScreen()
|
||||
public SubScreenBeatmapSelect()
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
@@ -29,7 +29,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Horizontal = 200 },
|
||||
Child = selectionGrid = new BeatmapSelectionGrid
|
||||
Child = selectionGrid = new SelectionGrid
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
@@ -8,11 +8,11 @@ using osu.Game.Online.Rooms;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match.Gameplay
|
||||
{
|
||||
public partial class MatchmakingPlayer : MultiplayerPlayer
|
||||
public partial class ScreenGameplay : MultiplayerPlayer
|
||||
{
|
||||
public MatchmakingPlayer(Room room, PlaylistItem playlistItem, MultiplayerRoomUser[] users)
|
||||
public ScreenGameplay(Room room, PlaylistItem playlistItem, MultiplayerRoomUser[] users)
|
||||
: base(room, playlistItem, users)
|
||||
{
|
||||
}
|
||||
@@ -11,8 +11,12 @@ using osu.Game.Users.Drawables;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match
|
||||
{
|
||||
/// <summary>
|
||||
/// A circular player avatar used in matchmaking displays.
|
||||
/// Is part of a <see cref="MatchmakingUserPanel"/> but can also be used in isolation for a more ambient/decorative user display.
|
||||
/// </summary>
|
||||
public partial class MatchmakingAvatar : CompositeDrawable
|
||||
{
|
||||
public static readonly Vector2 SIZE = new Vector2(30);
|
||||
@@ -4,11 +4,11 @@
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Screens;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match
|
||||
{
|
||||
public abstract partial class MatchmakingSubScreen : Screen
|
||||
{
|
||||
public abstract PlayerPanelList.PanelDisplayStyle PlayersDisplayStyle { get; }
|
||||
public abstract PanelDisplayStyle PlayersDisplayStyle { get; }
|
||||
public abstract Drawable? PlayersDisplayArea { get; }
|
||||
|
||||
protected MatchmakingSubScreen()
|
||||
@@ -14,9 +14,13 @@ using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match
|
||||
{
|
||||
public partial class PlayerPanel : UserPanel
|
||||
/// <summary>
|
||||
/// A panel used throughout matchmaking to represent a user, including local information like their
|
||||
/// rank and high level statistics in the matchmaking system.
|
||||
/// </summary>
|
||||
public partial class MatchmakingUserPanel : UserPanel
|
||||
{
|
||||
public static readonly Vector2 SIZE_HORIZONTAL = new Vector2(250, 100);
|
||||
public static readonly Vector2 SIZE_VERTICAL = new Vector2(150, 200);
|
||||
@@ -51,7 +55,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
|
||||
private bool horizontal;
|
||||
|
||||
public PlayerPanel(MultiplayerRoomUser user)
|
||||
public MatchmakingUserPanel(MultiplayerRoomUser user)
|
||||
: base(user.User!)
|
||||
{
|
||||
RoomUser = user;
|
||||
@@ -11,16 +11,16 @@ using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Results
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match.Results
|
||||
{
|
||||
public partial class RoomStatisticPanel : CompositeDrawable
|
||||
public partial class PanelRoomAward : CompositeDrawable
|
||||
{
|
||||
private readonly Color4 backgroundColour = Color4.SaddleBrown;
|
||||
|
||||
private readonly string text;
|
||||
private readonly int userId;
|
||||
|
||||
public RoomStatisticPanel(string text, int userId)
|
||||
public PanelRoomAward(string text, int userId)
|
||||
{
|
||||
this.text = text;
|
||||
this.userId = userId;
|
||||
@@ -8,15 +8,15 @@ using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Results
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match.Results
|
||||
{
|
||||
public partial class UserStatisticPanel : CompositeDrawable
|
||||
public partial class PanelUserStatistic : CompositeDrawable
|
||||
{
|
||||
private readonly Color4 backgroundColour = Color4.SaddleBrown;
|
||||
|
||||
private readonly string text;
|
||||
|
||||
public UserStatisticPanel(string text)
|
||||
public PanelUserStatistic(string text)
|
||||
{
|
||||
this.text = text;
|
||||
|
||||
@@ -14,23 +14,26 @@ using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Utils;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Results
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match.Results
|
||||
{
|
||||
public partial class ResultsScreen : MatchmakingSubScreen
|
||||
/// <summary>
|
||||
/// Final room results, during <see cref="MatchmakingStage.Ended"/>
|
||||
/// </summary>
|
||||
public partial class SubScreenResults : MatchmakingSubScreen
|
||||
{
|
||||
private const float grid_spacing = 5;
|
||||
|
||||
public override PlayerPanelList.PanelDisplayStyle PlayersDisplayStyle => PlayerPanelList.PanelDisplayStyle.Grid;
|
||||
public override PanelDisplayStyle PlayersDisplayStyle => PanelDisplayStyle.Grid;
|
||||
public override Drawable PlayersDisplayArea { get; }
|
||||
|
||||
[Resolved]
|
||||
private MultiplayerClient client { get; set; } = null!;
|
||||
|
||||
private readonly OsuSpriteText placementText;
|
||||
private readonly FillFlowContainer<UserStatisticPanel> userStatistics;
|
||||
private readonly FillFlowContainer<RoomStatisticPanel> roomStatistics;
|
||||
private readonly FillFlowContainer<PanelUserStatistic> userStatistics;
|
||||
private readonly FillFlowContainer<PanelRoomAward> roomStatistics;
|
||||
|
||||
public ResultsScreen()
|
||||
public SubScreenResults()
|
||||
{
|
||||
InternalChild = new GridContainer
|
||||
{
|
||||
@@ -103,7 +106,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Results
|
||||
Text = "Breakdown",
|
||||
Font = OsuFont.Default.With(size: 12)
|
||||
},
|
||||
userStatistics = new FillFlowContainer<UserStatisticPanel>
|
||||
userStatistics = new FillFlowContainer<PanelUserStatistic>
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
@@ -139,7 +142,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Results
|
||||
Text = "Statistics",
|
||||
Font = OsuFont.Default.With(size: 12)
|
||||
},
|
||||
roomStatistics = new FillFlowContainer<RoomStatisticPanel>
|
||||
roomStatistics = new FillFlowContainer<PanelRoomAward>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
@@ -196,7 +199,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Results
|
||||
|
||||
void addStatistic(string text)
|
||||
{
|
||||
userStatistics.Add(new UserStatisticPanel(text)
|
||||
userStatistics.Add(new PanelUserStatistic(text)
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre
|
||||
@@ -321,7 +324,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Results
|
||||
|
||||
void addStatistic(int userId, string text)
|
||||
{
|
||||
roomStatistics.Add(new RoomStatisticPanel(text, userId)
|
||||
roomStatistics.Add(new PanelRoomAward(text, userId)
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre
|
||||
@@ -18,18 +18,22 @@ using osu.Game.Models;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.RoundResults
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match.RoundResults
|
||||
{
|
||||
public partial class RoundResultsScreen : MatchmakingSubScreen
|
||||
/// <summary>
|
||||
/// Per-round results, during <see cref="MatchmakingStage.ResultsDisplaying"/>
|
||||
/// </summary>
|
||||
public partial class SubScreenRoundResults : MatchmakingSubScreen
|
||||
{
|
||||
private const int panel_spacing = 5;
|
||||
|
||||
public override PlayerPanelList.PanelDisplayStyle PlayersDisplayStyle => PlayerPanelList.PanelDisplayStyle.Hidden;
|
||||
public override PanelDisplayStyle PlayersDisplayStyle => PanelDisplayStyle.Hidden;
|
||||
public override Drawable? PlayersDisplayArea => null;
|
||||
|
||||
[Resolved]
|
||||
@@ -153,6 +157,32 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.RoundResults
|
||||
}
|
||||
});
|
||||
|
||||
private partial class RoundResultsScorePanel : CompositeDrawable
|
||||
{
|
||||
public RoundResultsScorePanel(ScoreInfo score)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
InternalChild = new InstantSizingScorePanel(score);
|
||||
}
|
||||
|
||||
public override bool PropagateNonPositionalInputSubTree => false;
|
||||
public override bool PropagatePositionalInputSubTree => false;
|
||||
|
||||
private partial class InstantSizingScorePanel : ScorePanel
|
||||
{
|
||||
public InstantSizingScorePanel(ScoreInfo score, bool isNewLocalScore = false)
|
||||
: base(score, isNewLocalScore)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
FinishTransforms(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private partial class AutoScrollContainer : UserTrackingScrollContainer
|
||||
{
|
||||
private const float initial_offset = -0.5f;
|
||||
@@ -3,12 +3,16 @@
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Idle
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match.RoundWarmup
|
||||
{
|
||||
public partial class IdleScreen : MatchmakingSubScreen
|
||||
/// <summary>
|
||||
/// Shown during <see cref="MatchmakingStage.RoundWarmupTime"/>
|
||||
/// </summary>
|
||||
public partial class SubScreenRoundWarmup : MatchmakingSubScreen
|
||||
{
|
||||
public override PlayerPanelList.PanelDisplayStyle PlayersDisplayStyle => PlayerPanelList.PanelDisplayStyle.Grid;
|
||||
public override PanelDisplayStyle PlayersDisplayStyle => PanelDisplayStyle.Grid;
|
||||
public override Drawable PlayersDisplayArea => this;
|
||||
|
||||
public override void OnEntering(ScreenTransitionEvent e)
|
||||
@@ -0,0 +1,133 @@
|
||||
// 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 System.Diagnostics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match.BeatmapSelect;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match.Results;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match.RoundResults;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match.RoundWarmup;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match
|
||||
{
|
||||
public partial class ScreenMatchmaking
|
||||
{
|
||||
public partial class ScreenStack : CompositeDrawable
|
||||
{
|
||||
[Resolved]
|
||||
private MultiplayerClient client { get; set; } = null!;
|
||||
|
||||
private Framework.Screens.ScreenStack screenStack = null!;
|
||||
private UserPanelOverlay playersList = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding(10)
|
||||
{
|
||||
Bottom = StageDisplay.HEIGHT,
|
||||
},
|
||||
Children = new Drawable[]
|
||||
{
|
||||
screenStack = new Framework.Screens.ScreenStack(),
|
||||
}
|
||||
},
|
||||
playersList = new UserPanelOverlay
|
||||
{
|
||||
DisplayArea = this
|
||||
},
|
||||
new StageDisplay
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.X
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
screenStack.ScreenPushed += onScreenPushed;
|
||||
screenStack.ScreenExited += onScreenExited;
|
||||
|
||||
screenStack.Push(new SubScreenRoundWarmup());
|
||||
|
||||
client.MatchRoomStateChanged += onMatchRoomStateChanged;
|
||||
onMatchRoomStateChanged(client.Room!.MatchState);
|
||||
}
|
||||
|
||||
private void onScreenPushed(IScreen lastScreen, IScreen newScreen)
|
||||
{
|
||||
if (newScreen is not MatchmakingSubScreen matchmakingSubScreen)
|
||||
return;
|
||||
|
||||
playersList.DisplayStyle = matchmakingSubScreen.PlayersDisplayStyle;
|
||||
playersList.DisplayArea = matchmakingSubScreen.PlayersDisplayArea;
|
||||
}
|
||||
|
||||
private void onScreenExited(IScreen lastScreen, IScreen newScreen)
|
||||
{
|
||||
if (newScreen is not MatchmakingSubScreen matchmakingSubScreen)
|
||||
return;
|
||||
|
||||
playersList.DisplayStyle = matchmakingSubScreen.PlayersDisplayStyle;
|
||||
playersList.DisplayArea = matchmakingSubScreen.PlayersDisplayArea;
|
||||
}
|
||||
|
||||
private void onMatchRoomStateChanged(MatchRoomState? state) => Scheduler.Add(() =>
|
||||
{
|
||||
if (state is not MatchmakingRoomState matchmakingState)
|
||||
return;
|
||||
|
||||
switch (matchmakingState.Stage)
|
||||
{
|
||||
case MatchmakingStage.WaitingForClientsJoin:
|
||||
case MatchmakingStage.RoundWarmupTime:
|
||||
while (screenStack.CurrentScreen is not SubScreenRoundWarmup)
|
||||
screenStack.Exit();
|
||||
break;
|
||||
|
||||
case MatchmakingStage.UserBeatmapSelect:
|
||||
screenStack.Push(new SubScreenBeatmapSelect());
|
||||
break;
|
||||
|
||||
case MatchmakingStage.ServerBeatmapFinalised:
|
||||
Debug.Assert(screenStack.CurrentScreen is SubScreenBeatmapSelect);
|
||||
((SubScreenBeatmapSelect)screenStack.CurrentScreen).RollFinalBeatmap(matchmakingState.CandidateItems, matchmakingState.CandidateItem);
|
||||
break;
|
||||
|
||||
case MatchmakingStage.ResultsDisplaying:
|
||||
screenStack.Push(new SubScreenRoundResults());
|
||||
break;
|
||||
|
||||
case MatchmakingStage.Ended:
|
||||
screenStack.Push(new SubScreenResults());
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (client.IsNotNull())
|
||||
client.MatchRoomStateChanged -= onMatchRoomStateChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,13 +25,16 @@ using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Dialog;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.OnlinePlay.Match.Components;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match.Gameplay;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match
|
||||
{
|
||||
public partial class MatchmakingScreen : OsuScreen
|
||||
/// <summary>
|
||||
/// The main matchmaking screen which houses a custom <see cref="ScreenStack"/> through the life cycle of a single session.
|
||||
/// </summary>
|
||||
public partial class ScreenMatchmaking : OsuScreen
|
||||
{
|
||||
/// <summary>
|
||||
/// Padding between rows of the content.
|
||||
@@ -76,7 +79,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
|
||||
private MatchChatDisplay chat = null!;
|
||||
|
||||
public MatchmakingScreen(MultiplayerRoom room)
|
||||
public ScreenMatchmaking(MultiplayerRoom room)
|
||||
{
|
||||
this.room = room;
|
||||
|
||||
@@ -128,7 +131,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colourProvider.Background6,
|
||||
},
|
||||
new MatchmakingScreenStack(),
|
||||
new ScreenStack(),
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -248,7 +251,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
|
||||
sampleStart?.Play();
|
||||
|
||||
this.Push(new MultiplayerPlayerLoader(() => new MatchmakingPlayer(new Room(room), new PlaylistItem(client.Room!.CurrentPlaylistItem), room.Users.ToArray())));
|
||||
this.Push(new MultiplayerPlayerLoader(() => new ScreenGameplay(new Room(room), new PlaylistItem(client.Room!.CurrentPlaylistItem), room.Users.ToArray())));
|
||||
});
|
||||
|
||||
private void checkForAutomaticDownload()
|
||||
@@ -0,0 +1,234 @@
|
||||
// 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 System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Matchmaking;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Overlays;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match
|
||||
{
|
||||
public partial class StageDisplay
|
||||
{
|
||||
internal partial class StageSegment : CompositeDrawable
|
||||
{
|
||||
[Resolved]
|
||||
private MultiplayerClient client { get; set; } = null!;
|
||||
|
||||
public readonly int? Round;
|
||||
|
||||
private readonly MatchmakingStage stage;
|
||||
|
||||
private readonly LocalisableString displayText;
|
||||
private Drawable progressBar = null!;
|
||||
|
||||
private DateTimeOffset countdownStartTime;
|
||||
private DateTimeOffset countdownEndTime;
|
||||
private SpriteIcon arrow = null!;
|
||||
|
||||
private Sample? countdownTickSample;
|
||||
private double? lastSamplePlayback;
|
||||
|
||||
public bool Active { get; private set; }
|
||||
|
||||
public float Progress => progressBar.Width;
|
||||
|
||||
public StageSegment(int? round, MatchmakingStage stage, LocalisableString displayText)
|
||||
{
|
||||
Round = round;
|
||||
this.stage = stage;
|
||||
this.displayText = displayText;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio, OverlayColourProvider colourProvider)
|
||||
{
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
arrow = new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Alpha = 0.5f,
|
||||
Size = new Vector2(16),
|
||||
Icon = FontAwesome.Solid.ArrowRight,
|
||||
Margin = new MarginPadding { Horizontal = 10 }
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Masking = true,
|
||||
CornerRadius = 5,
|
||||
CornerExponent = 10,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour =
|
||||
ColourInfo.GradientVertical(
|
||||
colourProvider.Dark2,
|
||||
colourProvider.Dark1
|
||||
),
|
||||
},
|
||||
progressBar = new Box
|
||||
{
|
||||
Blending = BlendingParameters.Additive,
|
||||
EdgeSmoothness = new Vector2(1),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0,
|
||||
Colour = colourProvider.Dark3,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Text = displayText,
|
||||
Padding = new MarginPadding(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Alpha = 0.5f;
|
||||
countdownTickSample = audio.Samples.Get(@"Multiplayer/countdown-tick");
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
client.MatchRoomStateChanged += onMatchRoomStateChanged;
|
||||
client.CountdownStarted += onCountdownStarted;
|
||||
client.CountdownStopped += onCountdownStopped;
|
||||
|
||||
if (client.Room != null)
|
||||
{
|
||||
onMatchRoomStateChanged(client.Room.MatchState);
|
||||
foreach (var countdown in client.Room.ActiveCountdowns)
|
||||
onCountdownStarted(countdown);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (!Active)
|
||||
return;
|
||||
|
||||
TimeSpan total = countdownEndTime - countdownStartTime;
|
||||
TimeSpan elapsed = DateTimeOffset.Now - countdownStartTime;
|
||||
|
||||
if (total.TotalMilliseconds <= 0)
|
||||
{
|
||||
progressBar.Width = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
progressBar.Width = (float)Math.Clamp(elapsed.TotalMilliseconds / total.TotalMilliseconds, 0, 1);
|
||||
|
||||
int secondsRemaining = Math.Max(0, (int)Math.Ceiling((total.TotalMilliseconds - elapsed.TotalMilliseconds) / 1000));
|
||||
|
||||
if (total.TotalMilliseconds - elapsed.TotalMilliseconds <= 3000
|
||||
&& lastSamplePlayback != secondsRemaining)
|
||||
{
|
||||
countdownTickSample?.Play();
|
||||
lastSamplePlayback = secondsRemaining;
|
||||
}
|
||||
}
|
||||
|
||||
private void onMatchRoomStateChanged(MatchRoomState? state) => Scheduler.Add(() =>
|
||||
{
|
||||
bool wasActive = Active;
|
||||
|
||||
Active = false;
|
||||
|
||||
if (state is not MatchmakingRoomState roomState)
|
||||
return;
|
||||
|
||||
if (Round != null && roomState.CurrentRound != Round)
|
||||
return;
|
||||
|
||||
Active = stage == roomState.Stage;
|
||||
|
||||
if (wasActive)
|
||||
progressBar.Width = 1;
|
||||
|
||||
bool isPreparing =
|
||||
(stage == MatchmakingStage.RoundWarmupTime && roomState.Stage == MatchmakingStage.WaitingForClientsJoin) ||
|
||||
(stage == MatchmakingStage.GameplayWarmupTime && roomState.Stage == MatchmakingStage.WaitingForClientsBeatmapDownload) ||
|
||||
(stage == MatchmakingStage.ResultsDisplaying && roomState.Stage == MatchmakingStage.Gameplay);
|
||||
|
||||
if (isPreparing)
|
||||
{
|
||||
arrow.FadeTo(1, 500)
|
||||
.Then()
|
||||
.FadeTo(0.5f, 500)
|
||||
.Loop();
|
||||
}
|
||||
});
|
||||
|
||||
private void onCountdownStarted(MultiplayerCountdown countdown) => Scheduler.Add(() =>
|
||||
{
|
||||
if (!Active)
|
||||
return;
|
||||
|
||||
if (countdown is not MatchmakingStageCountdown)
|
||||
return;
|
||||
|
||||
countdownStartTime = DateTimeOffset.Now;
|
||||
countdownEndTime = countdownStartTime + countdown.TimeRemaining;
|
||||
arrow.FadeIn(500, Easing.OutQuint);
|
||||
|
||||
this.FadeIn(200);
|
||||
});
|
||||
|
||||
private void onCountdownStopped(MultiplayerCountdown countdown) => Scheduler.Add(() =>
|
||||
{
|
||||
if (!Active)
|
||||
return;
|
||||
|
||||
if (countdown is not MatchmakingStageCountdown)
|
||||
return;
|
||||
|
||||
countdownEndTime = DateTimeOffset.Now;
|
||||
});
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (client.IsNotNull())
|
||||
{
|
||||
client.MatchRoomStateChanged -= onMatchRoomStateChanged;
|
||||
client.CountdownStarted -= onCountdownStarted;
|
||||
client.CountdownStopped -= onCountdownStopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
// 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.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match
|
||||
{
|
||||
public partial class StageDisplay
|
||||
{
|
||||
public partial class StatusText : CompositeDrawable
|
||||
{
|
||||
[Resolved]
|
||||
private MultiplayerClient client { get; set; } = null!;
|
||||
|
||||
private OsuSpriteText text = null!;
|
||||
|
||||
private Sample? textChangedSample;
|
||||
private double? lastSamplePlayback;
|
||||
|
||||
public StatusText()
|
||||
{
|
||||
AutoSizeAxes = Axes.X;
|
||||
Height = 16;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio)
|
||||
{
|
||||
InternalChild = text = new OsuSpriteText
|
||||
{
|
||||
Alpha = 0,
|
||||
Height = 16,
|
||||
Font = OsuFont.Style.Caption1,
|
||||
AlwaysPresent = true,
|
||||
};
|
||||
|
||||
textChangedSample = audio.Samples.Get(@"Multiplayer/Matchmaking/stage-message");
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
client.MatchRoomStateChanged += onMatchRoomStateChanged;
|
||||
onMatchRoomStateChanged(client.Room!.MatchState);
|
||||
}
|
||||
|
||||
private void onMatchRoomStateChanged(MatchRoomState? state) => Scheduler.Add(() =>
|
||||
{
|
||||
if (state is not MatchmakingRoomState matchmakingState)
|
||||
return;
|
||||
|
||||
text.Text = getTextForStatus(matchmakingState.Stage);
|
||||
|
||||
if (text.Text == string.Empty || (lastSamplePlayback != null && Time.Current - lastSamplePlayback < OsuGameBase.SAMPLE_DEBOUNCE_TIME))
|
||||
return;
|
||||
|
||||
textChangedSample?.Play();
|
||||
lastSamplePlayback = Time.Current;
|
||||
|
||||
LocalisableString textForStatus = getTextForStatus(matchmakingState.Stage);
|
||||
|
||||
if (string.IsNullOrEmpty(textForStatus.ToString()))
|
||||
{
|
||||
text.FadeOut();
|
||||
return;
|
||||
}
|
||||
|
||||
text.RotateTo(2f)
|
||||
.RotateTo(0, 500, Easing.OutQuint);
|
||||
|
||||
text.FadeInFromZero(500, Easing.OutQuint);
|
||||
|
||||
using (text.BeginDelayedSequence(500))
|
||||
{
|
||||
text
|
||||
.FadeTo(0.6f, 400, Easing.In)
|
||||
.Then()
|
||||
.FadeTo(1, 400, Easing.Out)
|
||||
.Loop();
|
||||
}
|
||||
|
||||
text.ScaleTo(0.3f)
|
||||
.ScaleTo(1, 500, Easing.OutQuint);
|
||||
|
||||
text.Text = textForStatus;
|
||||
});
|
||||
|
||||
private LocalisableString getTextForStatus(MatchmakingStage status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case MatchmakingStage.WaitingForClientsJoin:
|
||||
return "Players are joining the match...";
|
||||
|
||||
case MatchmakingStage.WaitingForClientsBeatmapDownload:
|
||||
return "Players are downloading the beatmap...";
|
||||
|
||||
case MatchmakingStage.Gameplay:
|
||||
return "Game is in progress...";
|
||||
|
||||
case MatchmakingStage.Ended:
|
||||
return "Thanks for playing! The match will close shortly.";
|
||||
|
||||
default:
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (client.IsNotNull())
|
||||
client.MatchRoomStateChanged -= onMatchRoomStateChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,11 @@ using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Overlays;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match
|
||||
{
|
||||
/// <summary>
|
||||
/// A "global" footer staple element in matchmaking which shows the current progression of the room, from start to finish.
|
||||
/// </summary>
|
||||
public partial class StageDisplay : CompositeDrawable
|
||||
{
|
||||
public const float HEIGHT = 96;
|
||||
@@ -68,7 +71,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
Direction = FillDirection.Horizontal,
|
||||
},
|
||||
},
|
||||
new StageText
|
||||
new StatusText
|
||||
{
|
||||
Y = 32,
|
||||
Anchor = Anchor.Centre,
|
||||
@@ -93,23 +96,23 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
},
|
||||
};
|
||||
|
||||
flow.Add(new StageBubble(null, MatchmakingStage.WaitingForClientsJoin, "Waiting for other users"));
|
||||
flow.Add(new StageSegment(null, MatchmakingStage.WaitingForClientsJoin, "Waiting for other users"));
|
||||
|
||||
for (int i = 1; i <= round_count; i++)
|
||||
{
|
||||
flow.Add(new StageBubble(i, MatchmakingStage.RoundWarmupTime, "Next Round"));
|
||||
flow.Add(new StageBubble(i, MatchmakingStage.UserBeatmapSelect, "Beatmap Selection"));
|
||||
flow.Add(new StageBubble(i, MatchmakingStage.GameplayWarmupTime, "Get Ready"));
|
||||
flow.Add(new StageBubble(i, MatchmakingStage.ResultsDisplaying, "Results"));
|
||||
flow.Add(new StageSegment(i, MatchmakingStage.RoundWarmupTime, "Next Round"));
|
||||
flow.Add(new StageSegment(i, MatchmakingStage.UserBeatmapSelect, "Beatmap Selection"));
|
||||
flow.Add(new StageSegment(i, MatchmakingStage.GameplayWarmupTime, "Get Ready"));
|
||||
flow.Add(new StageSegment(i, MatchmakingStage.ResultsDisplaying, "Results"));
|
||||
}
|
||||
|
||||
flow.Add(new StageBubble(null, MatchmakingStage.Ended, "Match End"));
|
||||
flow.Add(new StageSegment(null, MatchmakingStage.Ended, "Match End"));
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
var bubble = flow.OfType<StageBubble>().FirstOrDefault(b => b.Active);
|
||||
var bubble = flow.OfType<StageSegment>().FirstOrDefault(b => b.Active);
|
||||
|
||||
if (bubble != null)
|
||||
{
|
||||
@@ -12,14 +12,18 @@ using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Match
|
||||
{
|
||||
public partial class PlayerPanelList : CompositeDrawable
|
||||
/// <summary>
|
||||
/// A component which maintains the layout of the players in a matchmaking room.
|
||||
/// Can be controlled to display the panels in a certain location and in multiple styles.
|
||||
/// </summary>
|
||||
public partial class UserPanelOverlay : CompositeDrawable
|
||||
{
|
||||
[Resolved]
|
||||
private MultiplayerClient client { get; set; } = null!;
|
||||
|
||||
private Container<PlayerPanel> panels = null!;
|
||||
private Container<MatchmakingUserPanel> panels = null!;
|
||||
private PlayerPanelCellContainer gridLayout = null!;
|
||||
private PlayerPanelCellContainer splitLayoutLeft = null!;
|
||||
private PlayerPanelCellContainer splitLayoutRight = null!;
|
||||
@@ -56,7 +60,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(20, 5),
|
||||
},
|
||||
panels = new Container<PlayerPanel>
|
||||
panels = new Container<MatchmakingUserPanel>
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}
|
||||
@@ -106,7 +110,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
|
||||
private void onUserJoined(MultiplayerRoomUser user) => Scheduler.Add(() =>
|
||||
{
|
||||
panels.Add(new PlayerPanel(user)
|
||||
panels.Add(new MatchmakingUserPanel(user)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
@@ -211,7 +215,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
[Resolved]
|
||||
private MultiplayerClient client { get; set; } = null!;
|
||||
|
||||
public void AcquirePanels(PlayerPanel[] panels)
|
||||
public void AcquirePanels(MatchmakingUserPanel[] panels)
|
||||
{
|
||||
while (Count < panels.Length)
|
||||
{
|
||||
@@ -255,10 +259,10 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
|
||||
private partial class PlayerPanelCell : Drawable
|
||||
{
|
||||
private PlayerPanel? panel;
|
||||
private MatchmakingUserPanel? panel;
|
||||
private bool isAnimating;
|
||||
|
||||
public void AcquirePanel(PlayerPanel panel)
|
||||
public void AcquirePanel(MatchmakingUserPanel panel)
|
||||
{
|
||||
this.panel = panel;
|
||||
isAnimating = true;
|
||||
@@ -276,7 +280,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
if (panel == null)
|
||||
return;
|
||||
|
||||
Size = panel.Horizontal ? PlayerPanel.SIZE_HORIZONTAL : PlayerPanel.SIZE_VERTICAL;
|
||||
Size = panel.Horizontal ? MatchmakingUserPanel.SIZE_HORIZONTAL : MatchmakingUserPanel.SIZE_VERTICAL;
|
||||
Size *= panel.Scale;
|
||||
|
||||
var targetPos = getFinalPosition();
|
||||
@@ -298,12 +302,12 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
=> panel.Parent!.ToLocalSpace(ScreenSpaceDrawQuad.Centre) - panel.AnchorPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum PanelDisplayStyle
|
||||
{
|
||||
Grid,
|
||||
Split,
|
||||
Hidden
|
||||
}
|
||||
public enum PanelDisplayStyle
|
||||
{
|
||||
Grid,
|
||||
Split,
|
||||
Hidden
|
||||
}
|
||||
}
|
||||
@@ -11,12 +11,17 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
{
|
||||
public partial class MatchmakingCloud : CompositeDrawable
|
||||
/// <summary>
|
||||
/// A visualisation at the top level of matchmaking which shows the overall system status.
|
||||
/// This is intended to be something which users can watch while idle, for fun or otherwise.
|
||||
/// </summary>
|
||||
public partial class CloudVisualisation : CompositeDrawable
|
||||
{
|
||||
private APIUser[] users = [];
|
||||
private Container usersContainer = null!;
|
||||
@@ -16,9 +16,9 @@ using osu.Game.Rulesets;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
{
|
||||
public partial class MatchmakingPoolSelector : CompositeDrawable
|
||||
public partial class PoolSelector : CompositeDrawable
|
||||
{
|
||||
private const float icon_size = 48;
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
|
||||
private FillFlowContainer<SelectorButton> poolFlow = null!;
|
||||
|
||||
public MatchmakingPoolSelector()
|
||||
public PoolSelector()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
}
|
||||
@@ -10,13 +10,21 @@ using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Intro;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
{
|
||||
public partial class MatchmakingController : Component
|
||||
/// <summary>
|
||||
/// A component which acts as a bridge between the online component (ie <see cref="MultiplayerClient"/>)
|
||||
/// and the visual representations and flow of queueing for matchmaking.
|
||||
///
|
||||
/// Includes support for deferring to background.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is initialised and cached in the <see cref="ScreenQueue"/> but can be used throughout the system via DI.</remarks>
|
||||
public partial class QueueController : Component
|
||||
{
|
||||
public readonly Bindable<MatchmakingQueueScreen.MatchmakingScreenState> CurrentState = new Bindable<MatchmakingQueueScreen.MatchmakingScreenState>();
|
||||
public readonly Bindable<ScreenQueue.MatchmakingScreenState> CurrentState = new Bindable<ScreenQueue.MatchmakingScreenState>();
|
||||
|
||||
[Resolved]
|
||||
private MultiplayerClient client { get; set; } = null!;
|
||||
@@ -63,12 +71,12 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
private void onRoomUpdated() => Scheduler.Add(() =>
|
||||
{
|
||||
if (client.Room == null)
|
||||
CurrentState.Value = MatchmakingQueueScreen.MatchmakingScreenState.Idle;
|
||||
CurrentState.Value = ScreenQueue.MatchmakingScreenState.Idle;
|
||||
});
|
||||
|
||||
private void onMatchmakingQueueJoined() => Scheduler.Add(() =>
|
||||
{
|
||||
CurrentState.Value = MatchmakingQueueScreen.MatchmakingScreenState.Queueing;
|
||||
CurrentState.Value = ScreenQueue.MatchmakingScreenState.Queueing;
|
||||
|
||||
if (isBackgrounded)
|
||||
{
|
||||
@@ -79,15 +87,15 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
|
||||
private void onMatchmakingQueueLeft() => Scheduler.Add(() =>
|
||||
{
|
||||
if (CurrentState.Value != MatchmakingQueueScreen.MatchmakingScreenState.InRoom)
|
||||
CurrentState.Value = MatchmakingQueueScreen.MatchmakingScreenState.Idle;
|
||||
if (CurrentState.Value != ScreenQueue.MatchmakingScreenState.InRoom)
|
||||
CurrentState.Value = ScreenQueue.MatchmakingScreenState.Idle;
|
||||
|
||||
closeNotifications();
|
||||
});
|
||||
|
||||
private void onMatchmakingRoomInvited() => Scheduler.Add(() =>
|
||||
{
|
||||
CurrentState.Value = MatchmakingQueueScreen.MatchmakingScreenState.PendingAccept;
|
||||
CurrentState.Value = ScreenQueue.MatchmakingScreenState.PendingAccept;
|
||||
|
||||
if (backgroundNotification != null)
|
||||
{
|
||||
@@ -101,7 +109,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
client.JoinRoom(new Room { RoomID = roomId }, password)
|
||||
.FireAndForget(() => Scheduler.Add(() =>
|
||||
{
|
||||
CurrentState.Value = MatchmakingQueueScreen.MatchmakingScreenState.InRoom;
|
||||
CurrentState.Value = ScreenQueue.MatchmakingScreenState.InRoom;
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -118,7 +126,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
CompletionClickAction = () =>
|
||||
{
|
||||
client.MatchmakingAcceptInvitation().FireAndForget();
|
||||
performer?.PerformFromScreen(s => s.Push(new MatchmakingIntroScreen()));
|
||||
performer?.PerformFromScreen(s => s.Push(new IntroScreen()));
|
||||
|
||||
closeNotifications();
|
||||
return true;
|
||||
@@ -27,18 +27,22 @@ using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Dialog;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Match;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
|
||||
{
|
||||
public partial class MatchmakingQueueScreen : OsuScreen
|
||||
/// <summary>
|
||||
/// The initial screen that users arrive at when preparing for a quick play session.
|
||||
/// </summary>
|
||||
public partial class ScreenQueue : OsuScreen
|
||||
{
|
||||
public override bool ShowFooter => true;
|
||||
|
||||
private Container mainContent = null!;
|
||||
|
||||
private MatchmakingScreenState state;
|
||||
private MatchmakingCloud cloud = null!;
|
||||
private CloudVisualisation cloud = null!;
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; } = null!;
|
||||
@@ -56,7 +60,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
|
||||
private IDialogOverlay dialogOverlay { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private MatchmakingController controller { get; set; } = null!;
|
||||
private QueueController controller { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private UserLookupCache userLookupCache { get; set; } = null!;
|
||||
@@ -79,7 +83,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
cloud = new MatchmakingCloud
|
||||
cloud = new CloudVisualisation
|
||||
{
|
||||
Y = -100,
|
||||
Anchor = Anchor.Centre,
|
||||
@@ -252,7 +256,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
|
||||
Spacing = new Vector2(10),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new MatchmakingPoolSelector
|
||||
new PoolSelector
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
@@ -411,7 +415,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
|
||||
};
|
||||
|
||||
using (BeginDelayedSequence(2000))
|
||||
Schedule(() => this.Push(new MatchmakingScreen(client.Room!)));
|
||||
Schedule(() => this.Push(new ScreenMatchmaking(client.Room!)));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1,130 +0,0 @@
|
||||
// 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 System.Diagnostics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Idle;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Results;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Screens.RoundResults;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens
|
||||
{
|
||||
public partial class MatchmakingScreenStack : CompositeDrawable
|
||||
{
|
||||
[Resolved]
|
||||
private MultiplayerClient client { get; set; } = null!;
|
||||
|
||||
private ScreenStack screenStack = null!;
|
||||
private PlayerPanelList playersList = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding(10)
|
||||
{
|
||||
Bottom = StageDisplay.HEIGHT,
|
||||
},
|
||||
Children = new Drawable[]
|
||||
{
|
||||
screenStack = new ScreenStack(),
|
||||
}
|
||||
},
|
||||
playersList = new PlayerPanelList
|
||||
{
|
||||
DisplayArea = this
|
||||
},
|
||||
new StageDisplay
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.X
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
screenStack.ScreenPushed += onScreenPushed;
|
||||
screenStack.ScreenExited += onScreenExited;
|
||||
|
||||
screenStack.Push(new IdleScreen());
|
||||
|
||||
client.MatchRoomStateChanged += onMatchRoomStateChanged;
|
||||
onMatchRoomStateChanged(client.Room!.MatchState);
|
||||
}
|
||||
|
||||
private void onScreenPushed(IScreen lastScreen, IScreen newScreen)
|
||||
{
|
||||
if (newScreen is not MatchmakingSubScreen matchmakingSubScreen)
|
||||
return;
|
||||
|
||||
playersList.DisplayStyle = matchmakingSubScreen.PlayersDisplayStyle;
|
||||
playersList.DisplayArea = matchmakingSubScreen.PlayersDisplayArea;
|
||||
}
|
||||
|
||||
private void onScreenExited(IScreen lastScreen, IScreen newScreen)
|
||||
{
|
||||
if (newScreen is not MatchmakingSubScreen matchmakingSubScreen)
|
||||
return;
|
||||
|
||||
playersList.DisplayStyle = matchmakingSubScreen.PlayersDisplayStyle;
|
||||
playersList.DisplayArea = matchmakingSubScreen.PlayersDisplayArea;
|
||||
}
|
||||
|
||||
private void onMatchRoomStateChanged(MatchRoomState? state) => Scheduler.Add(() =>
|
||||
{
|
||||
if (state is not MatchmakingRoomState matchmakingState)
|
||||
return;
|
||||
|
||||
switch (matchmakingState.Stage)
|
||||
{
|
||||
case MatchmakingStage.WaitingForClientsJoin:
|
||||
case MatchmakingStage.RoundWarmupTime:
|
||||
while (screenStack.CurrentScreen is not IdleScreen)
|
||||
screenStack.Exit();
|
||||
break;
|
||||
|
||||
case MatchmakingStage.UserBeatmapSelect:
|
||||
screenStack.Push(new PickScreen());
|
||||
break;
|
||||
|
||||
case MatchmakingStage.ServerBeatmapFinalised:
|
||||
Debug.Assert(screenStack.CurrentScreen is PickScreen);
|
||||
((PickScreen)screenStack.CurrentScreen).RollFinalBeatmap(matchmakingState.CandidateItems, matchmakingState.CandidateItem);
|
||||
break;
|
||||
|
||||
case MatchmakingStage.ResultsDisplaying:
|
||||
screenStack.Push(new RoundResultsScreen());
|
||||
break;
|
||||
|
||||
case MatchmakingStage.Ended:
|
||||
screenStack.Push(new ResultsScreen());
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (client.IsNotNull())
|
||||
client.MatchRoomStateChanged -= onMatchRoomStateChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
// 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.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
{
|
||||
public partial class BeatmapPanel : CompositeDrawable
|
||||
{
|
||||
public static readonly Vector2 SIZE = new Vector2(300, 70);
|
||||
|
||||
public readonly Container OverlayLayer = new Container { RelativeSizeAxes = Axes.Both };
|
||||
|
||||
public APIBeatmap? Beatmap
|
||||
{
|
||||
get => beatmap;
|
||||
set
|
||||
{
|
||||
if (beatmap?.OnlineID == value?.OnlineID)
|
||||
return;
|
||||
|
||||
beatmap = value;
|
||||
|
||||
if (IsLoaded)
|
||||
updateContent();
|
||||
}
|
||||
}
|
||||
|
||||
private APIBeatmap? beatmap;
|
||||
|
||||
private Container content = null!;
|
||||
private UpdateableOnlineBeatmapSetCover cover = null!;
|
||||
|
||||
public BeatmapPanel(APIBeatmap? beatmap = null)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
{
|
||||
Masking = true;
|
||||
CornerRadius = 6;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
cover = new UpdateableOnlineBeatmapSetCover(BeatmapSetCoverType.Card, timeBeforeLoad: 0, timeBeforeUnload: 10000)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientHorizontal(
|
||||
colourProvider.Background4.Opacity(0.7f),
|
||||
colourProvider.Background4.Opacity(0.4f)
|
||||
)
|
||||
},
|
||||
content = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
OverlayLayer,
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
updateContent();
|
||||
FinishTransforms(true);
|
||||
}
|
||||
|
||||
private void updateContent()
|
||||
{
|
||||
foreach (var child in content.Children)
|
||||
child.FadeOut(300).Expire();
|
||||
|
||||
cover.OnlineInfo = beatmap?.BeatmapSet;
|
||||
|
||||
if (beatmap != null)
|
||||
{
|
||||
var panelContent = new BeatmapPanelContent(beatmap)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
};
|
||||
|
||||
content.Add(panelContent);
|
||||
|
||||
panelContent.FadeInFromZero(300);
|
||||
}
|
||||
}
|
||||
|
||||
private partial class BeatmapPanelContent : CompositeDrawable
|
||||
{
|
||||
private readonly APIBeatmap beatmap;
|
||||
|
||||
public BeatmapPanelContent(APIBeatmap beatmap)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Padding = new MarginPadding { Horizontal = 12 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TruncatingSpriteText
|
||||
{
|
||||
Text = new RomanisableString(beatmap.Metadata.TitleUnicode, beatmap.Metadata.TitleUnicode),
|
||||
Font = OsuFont.Default.With(size: 19, weight: FontWeight.SemiBold),
|
||||
RelativeSizeAxes = Axes.X,
|
||||
},
|
||||
new TextFlowContainer(s =>
|
||||
{
|
||||
s.Font = OsuFont.GetFont(size: 16, weight: FontWeight.SemiBold);
|
||||
}).With(d =>
|
||||
{
|
||||
d.RelativeSizeAxes = Axes.X;
|
||||
d.AutoSizeAxes = Axes.Y;
|
||||
d.AddText("by ");
|
||||
d.AddText(new RomanisableString(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist));
|
||||
}),
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Margin = new MarginPadding { Top = 6 },
|
||||
Spacing = new Vector2(4),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new StarRatingDisplay(new StarDifficulty(beatmap.StarRating, 0), StarRatingDisplaySize.Small)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
},
|
||||
new TruncatingSpriteText
|
||||
{
|
||||
Text = beatmap.DifficultyName,
|
||||
Font = OsuFont.Default.With(size: 16, weight: FontWeight.SemiBold),
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
// 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 System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
{
|
||||
public partial class BeatmapSelectionOverlay : CompositeDrawable
|
||||
{
|
||||
private readonly Dictionary<int, SelectionAvatar> avatars = new Dictionary<int, SelectionAvatar>();
|
||||
|
||||
private readonly Container<SelectionAvatar> avatarContainer;
|
||||
|
||||
private Sample? userAddedSample;
|
||||
private double? lastSamplePlayback;
|
||||
|
||||
public new Axes AutoSizeAxes
|
||||
{
|
||||
get => base.AutoSizeAxes;
|
||||
set => base.AutoSizeAxes = value;
|
||||
}
|
||||
|
||||
public new MarginPadding Padding
|
||||
{
|
||||
get => base.Padding;
|
||||
set => base.Padding = value;
|
||||
}
|
||||
|
||||
public BeatmapSelectionOverlay()
|
||||
{
|
||||
InternalChild = avatarContainer = new Container<SelectionAvatar>();
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
avatarContainer.AutoSizeAxes = AutoSizeAxes;
|
||||
avatarContainer.RelativeSizeAxes = RelativeSizeAxes;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio)
|
||||
{
|
||||
userAddedSample = audio.Samples.Get(@"Multiplayer/player-ready");
|
||||
}
|
||||
|
||||
public bool AddUser(APIUser user, bool isOwnUser)
|
||||
{
|
||||
if (avatars.ContainsKey(user.Id))
|
||||
return false;
|
||||
|
||||
var avatar = new SelectionAvatar(user, isOwnUser)
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
};
|
||||
|
||||
avatarContainer.Add(avatars[user.Id] = avatar);
|
||||
|
||||
if (lastSamplePlayback == null || Time.Current - lastSamplePlayback > OsuGameBase.SAMPLE_DEBOUNCE_TIME)
|
||||
{
|
||||
userAddedSample?.Play();
|
||||
lastSamplePlayback = Time.Current;
|
||||
}
|
||||
|
||||
updateLayout();
|
||||
|
||||
avatar.FinishTransforms();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool RemoveUser(int id)
|
||||
{
|
||||
if (!avatars.Remove(id, out var avatar))
|
||||
return false;
|
||||
|
||||
avatar.PopOutAndExpire();
|
||||
avatarContainer.ChangeChildDepth(avatar, float.MaxValue);
|
||||
|
||||
updateLayout();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateLayout()
|
||||
{
|
||||
const double stagger = 30;
|
||||
const float spacing = 4;
|
||||
|
||||
double delay = 0;
|
||||
float x = 0;
|
||||
|
||||
for (int i = avatarContainer.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var avatar = avatarContainer[i];
|
||||
|
||||
if (avatar.Expired)
|
||||
continue;
|
||||
|
||||
avatar.Delay(delay).MoveToX(x, 500, Easing.OutElasticQuarter);
|
||||
|
||||
x -= avatar.LayoutSize.X + spacing;
|
||||
|
||||
delay += stagger;
|
||||
}
|
||||
}
|
||||
|
||||
public partial class SelectionAvatar : CompositeDrawable
|
||||
{
|
||||
public bool Expired { get; private set; }
|
||||
|
||||
private readonly Container content;
|
||||
|
||||
public SelectionAvatar(APIUser user, bool isOwnUser)
|
||||
{
|
||||
Size = new Vector2(30);
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
content = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Child = new MatchmakingAvatar(user, isOwnUser)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
content.ScaleTo(0)
|
||||
.ScaleTo(1, 500, Easing.OutElasticHalf)
|
||||
.FadeIn(200);
|
||||
}
|
||||
|
||||
public void PopOutAndExpire()
|
||||
{
|
||||
content.ScaleTo(0, 400, Easing.OutExpo);
|
||||
|
||||
this.FadeOut(100).Expire();
|
||||
Expired = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
// 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 System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.Pick
|
||||
{
|
||||
public partial class BeatmapSelectionPanel : Container
|
||||
{
|
||||
private const float corner_radius = 6;
|
||||
private const float border_width = 3;
|
||||
|
||||
public readonly MultiplayerPlaylistItem Item;
|
||||
|
||||
private readonly Container scaleContainer;
|
||||
private readonly BeatmapPanel beatmapPanel;
|
||||
private readonly BeatmapSelectionOverlay selectionOverlay;
|
||||
private readonly Container border;
|
||||
private readonly Box flash;
|
||||
|
||||
public bool AllowSelection;
|
||||
|
||||
public Action<MultiplayerPlaylistItem>? Action;
|
||||
|
||||
[Resolved]
|
||||
private BeatmapLookupCache beatmapLookupCache { get; set; } = null!;
|
||||
|
||||
public override bool PropagatePositionalInputSubTree => AllowSelection;
|
||||
|
||||
public BeatmapSelectionPanel(MultiplayerPlaylistItem item)
|
||||
{
|
||||
Item = item;
|
||||
Size = BeatmapPanel.SIZE;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
scaleContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding(-border_width),
|
||||
Child = border = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
CornerRadius = corner_radius + border_width,
|
||||
Alpha = 0,
|
||||
Child = new Box { RelativeSizeAxes = Axes.Both },
|
||||
}
|
||||
},
|
||||
beatmapPanel = new BeatmapPanel
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
OverlayLayer =
|
||||
{
|
||||
Children = new[]
|
||||
{
|
||||
flash = new Box
|
||||
{
|
||||
Blending = BlendingParameters.Additive,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
selectionOverlay = new BeatmapSelectionOverlay
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Horizontal = 10 },
|
||||
Origin = Anchor.CentreLeft,
|
||||
},
|
||||
}
|
||||
},
|
||||
new HoverClickSounds(),
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
beatmapLookupCache.GetBeatmapAsync(Item.BeatmapID).ContinueWith(b => Schedule(() =>
|
||||
{
|
||||
var beatmap = b.GetResultSafely()!;
|
||||
|
||||
beatmap.StarRating = Item.StarRating;
|
||||
|
||||
beatmapPanel.Beatmap = beatmap;
|
||||
}));
|
||||
}
|
||||
|
||||
public bool AddUser(APIUser user, bool isOwnUser = false) => selectionOverlay.AddUser(user, isOwnUser);
|
||||
|
||||
public bool RemoveUser(int userId) => selectionOverlay.RemoveUser(userId);
|
||||
|
||||
public bool RemoveUser(APIUser user) => RemoveUser(user.Id);
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
flash.FadeTo(0.2f, 50)
|
||||
.Then()
|
||||
.FadeTo(0.1f, 300);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(HoverLostEvent e)
|
||||
{
|
||||
base.OnHoverLost(e);
|
||||
|
||||
flash.FadeOut(200);
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(MouseDownEvent e)
|
||||
{
|
||||
if (e.Button == MouseButton.Left)
|
||||
{
|
||||
scaleContainer.ScaleTo(0.95f, 400, Easing.OutExpo);
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseUpEvent e)
|
||||
{
|
||||
base.OnMouseUp(e);
|
||||
|
||||
if (e.Button == MouseButton.Left)
|
||||
{
|
||||
scaleContainer.ScaleTo(1f, 500, Easing.OutElasticHalf);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnClick(ClickEvent e)
|
||||
{
|
||||
Action?.Invoke(Item);
|
||||
|
||||
flash.FadeTo(0.5f, 50)
|
||||
.Then()
|
||||
.FadeTo(0.1f, 400);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ShowBorder() => border.Show();
|
||||
|
||||
public void HideBorder() => border.Hide();
|
||||
|
||||
public void FadeInAndEnterFromBelow(double duration = 500, double delay = 0, float distance = 200)
|
||||
{
|
||||
scaleContainer
|
||||
.FadeOut()
|
||||
.MoveToY(distance)
|
||||
.Delay(delay)
|
||||
.FadeIn(duration / 2)
|
||||
.MoveToY(0, duration, Easing.OutExpo);
|
||||
}
|
||||
|
||||
public void PopOutAndExpire(double duration = 400, double delay = 0, Easing easing = Easing.InCubic)
|
||||
{
|
||||
AllowSelection = false;
|
||||
|
||||
scaleContainer.Delay(delay)
|
||||
.ScaleTo(0, duration, easing)
|
||||
.FadeOut(duration);
|
||||
|
||||
this.Delay(delay + duration).FadeOut().Expire();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// 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.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking.Screens.RoundResults
|
||||
{
|
||||
internal partial class RoundResultsScorePanel : CompositeDrawable
|
||||
{
|
||||
public RoundResultsScorePanel(ScoreInfo score)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
InternalChild = new InstantSizingScorePanel(score);
|
||||
}
|
||||
|
||||
public override bool PropagateNonPositionalInputSubTree => false;
|
||||
public override bool PropagatePositionalInputSubTree => false;
|
||||
|
||||
private partial class InstantSizingScorePanel : ScorePanel
|
||||
{
|
||||
public InstantSizingScorePanel(ScoreInfo score, bool isNewLocalScore = false)
|
||||
: base(score, isNewLocalScore)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
FinishTransforms(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
// 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 System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Matchmaking;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
using osu.Game.Overlays;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
{
|
||||
internal partial class StageBubble : CompositeDrawable
|
||||
{
|
||||
[Resolved]
|
||||
private MultiplayerClient client { get; set; } = null!;
|
||||
|
||||
public readonly int? Round;
|
||||
|
||||
private readonly MatchmakingStage stage;
|
||||
|
||||
private readonly LocalisableString displayText;
|
||||
private Drawable progressBar = null!;
|
||||
|
||||
private DateTimeOffset countdownStartTime;
|
||||
private DateTimeOffset countdownEndTime;
|
||||
private SpriteIcon arrow = null!;
|
||||
|
||||
private Sample? countdownTickSample;
|
||||
private double? lastSamplePlayback;
|
||||
|
||||
public bool Active { get; private set; }
|
||||
|
||||
public float Progress => progressBar.Width;
|
||||
|
||||
public StageBubble(int? round, MatchmakingStage stage, LocalisableString displayText)
|
||||
{
|
||||
Round = round;
|
||||
this.stage = stage;
|
||||
this.displayText = displayText;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio, OverlayColourProvider colourProvider)
|
||||
{
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
arrow = new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Alpha = 0.5f,
|
||||
Size = new Vector2(16),
|
||||
Icon = FontAwesome.Solid.ArrowRight,
|
||||
Margin = new MarginPadding { Horizontal = 10 }
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Masking = true,
|
||||
CornerRadius = 5,
|
||||
CornerExponent = 10,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour =
|
||||
ColourInfo.GradientVertical(
|
||||
colourProvider.Dark2,
|
||||
colourProvider.Dark1
|
||||
),
|
||||
},
|
||||
progressBar = new Box
|
||||
{
|
||||
Blending = BlendingParameters.Additive,
|
||||
EdgeSmoothness = new Vector2(1),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0,
|
||||
Colour = colourProvider.Dark3,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Text = displayText,
|
||||
Padding = new MarginPadding(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Alpha = 0.5f;
|
||||
countdownTickSample = audio.Samples.Get(@"Multiplayer/countdown-tick");
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
client.MatchRoomStateChanged += onMatchRoomStateChanged;
|
||||
client.CountdownStarted += onCountdownStarted;
|
||||
client.CountdownStopped += onCountdownStopped;
|
||||
|
||||
if (client.Room != null)
|
||||
{
|
||||
onMatchRoomStateChanged(client.Room.MatchState);
|
||||
foreach (var countdown in client.Room.ActiveCountdowns)
|
||||
onCountdownStarted(countdown);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (!Active)
|
||||
return;
|
||||
|
||||
TimeSpan total = countdownEndTime - countdownStartTime;
|
||||
TimeSpan elapsed = DateTimeOffset.Now - countdownStartTime;
|
||||
|
||||
if (total.TotalMilliseconds <= 0)
|
||||
{
|
||||
progressBar.Width = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
progressBar.Width = (float)Math.Clamp(elapsed.TotalMilliseconds / total.TotalMilliseconds, 0, 1);
|
||||
|
||||
int secondsRemaining = Math.Max(0, (int)Math.Ceiling((total.TotalMilliseconds - elapsed.TotalMilliseconds) / 1000));
|
||||
|
||||
if (total.TotalMilliseconds - elapsed.TotalMilliseconds <= 3000
|
||||
&& lastSamplePlayback != secondsRemaining)
|
||||
{
|
||||
countdownTickSample?.Play();
|
||||
lastSamplePlayback = secondsRemaining;
|
||||
}
|
||||
}
|
||||
|
||||
private void onMatchRoomStateChanged(MatchRoomState? state) => Scheduler.Add(() =>
|
||||
{
|
||||
bool wasActive = Active;
|
||||
|
||||
Active = false;
|
||||
|
||||
if (state is not MatchmakingRoomState roomState)
|
||||
return;
|
||||
|
||||
if (Round != null && roomState.CurrentRound != Round)
|
||||
return;
|
||||
|
||||
Active = stage == roomState.Stage;
|
||||
|
||||
if (wasActive)
|
||||
progressBar.Width = 1;
|
||||
|
||||
bool isPreparing =
|
||||
(stage == MatchmakingStage.RoundWarmupTime && roomState.Stage == MatchmakingStage.WaitingForClientsJoin) ||
|
||||
(stage == MatchmakingStage.GameplayWarmupTime && roomState.Stage == MatchmakingStage.WaitingForClientsBeatmapDownload) ||
|
||||
(stage == MatchmakingStage.ResultsDisplaying && roomState.Stage == MatchmakingStage.Gameplay);
|
||||
|
||||
if (isPreparing)
|
||||
{
|
||||
arrow.FadeTo(1, 500)
|
||||
.Then()
|
||||
.FadeTo(0.5f, 500)
|
||||
.Loop();
|
||||
}
|
||||
});
|
||||
|
||||
private void onCountdownStarted(MultiplayerCountdown countdown) => Scheduler.Add(() =>
|
||||
{
|
||||
if (!Active)
|
||||
return;
|
||||
|
||||
if (countdown is not MatchmakingStageCountdown)
|
||||
return;
|
||||
|
||||
countdownStartTime = DateTimeOffset.Now;
|
||||
countdownEndTime = countdownStartTime + countdown.TimeRemaining;
|
||||
arrow.FadeIn(500, Easing.OutQuint);
|
||||
|
||||
this.FadeIn(200);
|
||||
});
|
||||
|
||||
private void onCountdownStopped(MultiplayerCountdown countdown) => Scheduler.Add(() =>
|
||||
{
|
||||
if (!Active)
|
||||
return;
|
||||
|
||||
if (countdown is not MatchmakingStageCountdown)
|
||||
return;
|
||||
|
||||
countdownEndTime = DateTimeOffset.Now;
|
||||
});
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (client.IsNotNull())
|
||||
{
|
||||
client.MatchRoomStateChanged -= onMatchRoomStateChanged;
|
||||
client.CountdownStarted -= onCountdownStarted;
|
||||
client.CountdownStopped -= onCountdownStopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
// 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.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.Matchmaking;
|
||||
|
||||
namespace osu.Game.Screens.OnlinePlay.Matchmaking
|
||||
{
|
||||
public partial class StageText : CompositeDrawable
|
||||
{
|
||||
[Resolved]
|
||||
private MultiplayerClient client { get; set; } = null!;
|
||||
|
||||
private OsuSpriteText text = null!;
|
||||
|
||||
private Sample? textChangedSample;
|
||||
private double? lastSamplePlayback;
|
||||
|
||||
public StageText()
|
||||
{
|
||||
AutoSizeAxes = Axes.X;
|
||||
Height = 16;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio)
|
||||
{
|
||||
InternalChild = text = new OsuSpriteText
|
||||
{
|
||||
Alpha = 0,
|
||||
Height = 16,
|
||||
Font = OsuFont.Style.Caption1,
|
||||
AlwaysPresent = true,
|
||||
};
|
||||
|
||||
textChangedSample = audio.Samples.Get(@"Multiplayer/Matchmaking/stage-message");
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
client.MatchRoomStateChanged += onMatchRoomStateChanged;
|
||||
onMatchRoomStateChanged(client.Room!.MatchState);
|
||||
}
|
||||
|
||||
private void onMatchRoomStateChanged(MatchRoomState? state) => Scheduler.Add(() =>
|
||||
{
|
||||
if (state is not MatchmakingRoomState matchmakingState)
|
||||
return;
|
||||
|
||||
text.Text = getTextForStatus(matchmakingState.Stage);
|
||||
|
||||
if (text.Text == string.Empty || (lastSamplePlayback != null && Time.Current - lastSamplePlayback < OsuGameBase.SAMPLE_DEBOUNCE_TIME))
|
||||
return;
|
||||
|
||||
textChangedSample?.Play();
|
||||
lastSamplePlayback = Time.Current;
|
||||
|
||||
LocalisableString textForStatus = getTextForStatus(matchmakingState.Stage);
|
||||
|
||||
if (string.IsNullOrEmpty(textForStatus.ToString()))
|
||||
{
|
||||
text.FadeOut();
|
||||
return;
|
||||
}
|
||||
|
||||
text.RotateTo(2f)
|
||||
.RotateTo(0, 500, Easing.OutQuint);
|
||||
|
||||
text.FadeInFromZero(500, Easing.OutQuint);
|
||||
|
||||
using (text.BeginDelayedSequence(500))
|
||||
{
|
||||
text
|
||||
.FadeTo(0.6f, 400, Easing.In)
|
||||
.Then()
|
||||
.FadeTo(1, 400, Easing.Out)
|
||||
.Loop();
|
||||
}
|
||||
|
||||
text.ScaleTo(0.3f)
|
||||
.ScaleTo(1, 500, Easing.OutQuint);
|
||||
|
||||
text.Text = textForStatus;
|
||||
});
|
||||
|
||||
private LocalisableString getTextForStatus(MatchmakingStage status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case MatchmakingStage.WaitingForClientsJoin:
|
||||
return "Players are joining the match...";
|
||||
|
||||
case MatchmakingStage.WaitingForClientsBeatmapDownload:
|
||||
return "Players are downloading the beatmap...";
|
||||
|
||||
case MatchmakingStage.Gameplay:
|
||||
return "Game is in progress...";
|
||||
|
||||
case MatchmakingStage.Ended:
|
||||
return "Thanks for playing! The match will close shortly.";
|
||||
|
||||
default:
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (client.IsNotNull())
|
||||
client.MatchRoomStateChanged -= onMatchRoomStateChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user