diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs index eca3ae0763..b2de9763ee 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs @@ -17,7 +17,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; -using osu.Game.Online.Multiplayer.MatchRulesets.TeamVs; using osu.Game.Rulesets; using osu.Game.Screens.Play.HUD; using osu.Game.Users; @@ -38,7 +37,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants private RulesetStore rulesets { get; set; } private SpriteIcon crown; - private Box teamDisplay; private OsuSpriteText userRankText; private ModDisplay userModsDisplay; @@ -59,106 +57,108 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants var backgroundColour = Color4Extensions.FromHex("#33413C"); - InternalChildren = new Drawable[] + InternalChild = new GridContainer { - crown = new SpriteIcon + RelativeSizeAxes = Axes.Both, + ColumnDimensions = new[] { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Icon = FontAwesome.Solid.Crown, - Size = new Vector2(14), - Colour = Color4Extensions.FromHex("#F7E65D"), - Alpha = 0 + new Dimension(GridSizeMode.Absolute, 14), + new Dimension(GridSizeMode.AutoSize), + new Dimension() }, - teamDisplay = new Box + Content = new[] { - Colour = Color4.Black, - RelativeSizeAxes = Axes.Y, - Width = 15, - Alpha = 0, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = 24 }, - Child = new Container + new Drawable[] { - RelativeSizeAxes = Axes.Both, - Masking = true, - CornerRadius = 5, - Children = new Drawable[] + crown = new SpriteIcon { - new Box + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Icon = FontAwesome.Solid.Crown, + Size = new Vector2(14), + Colour = Color4Extensions.FromHex("#F7E65D"), + Alpha = 0 + }, + new TeamDisplay(user), + new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 5, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = backgroundColour - }, - new UserCoverBackground - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - RelativeSizeAxes = Axes.Both, - Width = 0.75f, - User = user, - Colour = ColourInfo.GradientHorizontal(Color4.White.Opacity(0), Color4.White.Opacity(0.25f)) - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.Both, - Spacing = new Vector2(10), - Direction = FillDirection.Horizontal, - Children = new Drawable[] + new Box { - new UpdateableAvatar + RelativeSizeAxes = Axes.Both, + Colour = backgroundColour + }, + new UserCoverBackground + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Both, + Width = 0.75f, + User = user, + Colour = ColourInfo.GradientHorizontal(Color4.White.Opacity(0), Color4.White.Opacity(0.25f)) + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Spacing = new Vector2(10), + Direction = FillDirection.Horizontal, + Children = new Drawable[] { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Both, - FillMode = FillMode.Fit, - User = user - }, - new UpdateableFlag - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Size = new Vector2(30, 20), - Country = user?.Country - }, - new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 18), - Text = user?.Username - }, - userRankText = new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 14), + new UpdateableAvatar + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit, + User = user + }, + new UpdateableFlag + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Size = new Vector2(30, 20), + Country = user?.Country + }, + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 18), + Text = user?.Username + }, + userRankText = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 14), + } } - } - }, - new Container - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Right = 70 }, - Child = userModsDisplay = new ModDisplay + }, + new Container { - Scale = new Vector2(0.5f), - ExpansionMode = ExpansionMode.AlwaysContracted, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Right = 70 }, + Child = userModsDisplay = new ModDisplay + { + Scale = new Vector2(0.5f), + ExpansionMode = ExpansionMode.AlwaysContracted, + } + }, + userStateDisplay = new StateDisplay + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Margin = new MarginPadding { Right = 10 }, } - }, - userStateDisplay = new StateDisplay - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Margin = new MarginPadding { Right = 10 }, } } - } + }, } }; } @@ -184,36 +184,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants else crown.FadeOut(fade_time); - if (User.MatchRulesetState is TeamVsMatchUserState teamState) - { - teamDisplay.Show(); - teamDisplay.FadeColour(getColourForTeam(teamState.TeamID), 100, Easing.OutQuint); - } - else - { - teamDisplay.Hide(); - } - // If the mods are updated at the end of the frame, the flow container will skip a reflow cycle: https://github.com/ppy/osu-framework/issues/4187 // This looks particularly jarring here, so re-schedule the update to that start of our frame as a fix. Schedule(() => userModsDisplay.Current.Value = User.Mods.Select(m => m.ToMod(ruleset)).ToList()); } - [Resolved] - private OsuColour colours { get; set; } - - private ColourInfo getColourForTeam(int id) - { - switch (id) - { - default: - return colours.Red; - - case 1: - return colours.Blue; - } - } - public MenuItem[] ContextMenuItems { get diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/TeamDisplay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/TeamDisplay.cs new file mode 100644 index 0000000000..fd4ce404f1 --- /dev/null +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/TeamDisplay.cs @@ -0,0 +1,130 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Online.Multiplayer; +using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus; +using osu.Game.Users; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants +{ + internal class TeamDisplay : MultiplayerRoomComposite + { + private readonly User user; + private Drawable box; + + [Resolved] + private OsuColour colours { get; set; } + + [Resolved] + private MultiplayerClient client { get; set; } + + public TeamDisplay(User user) + { + this.user = user; + + RelativeSizeAxes = Axes.Y; + Width = 15; + + Margin = new MarginPadding { Horizontal = 3 }; + } + + [BackgroundDependencyLoader] + private void load() + { + box = new Container + { + RelativeSizeAxes = Axes.Both, + CornerRadius = 5, + Masking = true, + Alpha = 0, + Scale = new Vector2(0, 1), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Child = new Box + { + Colour = Color4.White, + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }; + + if (user.Id == client.LocalUser?.UserID) + { + InternalChild = new OsuClickableContainer + { + RelativeSizeAxes = Axes.Both, + TooltipText = "Change team", + Action = changeTeam, + Child = box + }; + } + else + { + InternalChild = box; + } + } + + private void changeTeam() + { + client.SendMatchRequest(new ChangeTeamRequest + { + TeamID = ((client.LocalUser?.MatchState as TeamVersusUserState)?.TeamID + 1) % 2 ?? 0, + }); + } + + private int? displayedTeam; + + protected override void OnRoomUpdated() + { + base.OnRoomUpdated(); + + // we don't have a way of knowing when an individual user's state has updated, so just handle on RoomUpdated for now. + + var userRoomState = Room?.Users.FirstOrDefault(u => u.UserID == user.Id)?.MatchState; + + const double duration = 400; + + int? newTeam = (userRoomState as TeamVersusUserState)?.TeamID; + + if (newTeam == displayedTeam) + return; + + displayedTeam = newTeam; + + if (displayedTeam != null) + { + box.FadeIn(duration); + box.FadeColour(getColourForTeam(displayedTeam.Value), duration, Easing.OutQuint); + box.ScaleTo(new Vector2(box.Scale.X < 0 ? 1 : -1, 1), duration, Easing.OutQuint); + } + else + { + box.ScaleTo(new Vector2(0, 1), duration, Easing.OutQuint); + box.FadeOut(duration); + } + } + + private ColourInfo getColourForTeam(int id) + { + switch (id) + { + default: + return colours.Red; + + case 1: + return colours.Blue; + } + } + } +}