diff --git a/Content.Client/GameTicking/Managers/ClientGameTicker.cs b/Content.Client/GameTicking/Managers/ClientGameTicker.cs index 55df4d5f34..2cf8330d2a 100644 --- a/Content.Client/GameTicking/Managers/ClientGameTicker.cs +++ b/Content.Client/GameTicking/Managers/ClientGameTicker.cs @@ -18,6 +18,8 @@ namespace Content.Client.GameTicking.Managers public sealed class ClientGameTicker : SharedGameTicker { [Dependency] private readonly IStateManager _stateManager = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; + [ViewVariables] private bool _initialized; private Dictionary> _jobsAvailable = new(); private Dictionary _stationNames = new(); @@ -135,7 +137,7 @@ namespace Content.Client.GameTicking.Managers RestartSound = message.RestartSound; //This is not ideal at all, but I don't see an immediately better fit anywhere else. - var roundEnd = new RoundEndSummaryWindow(message.GamemodeTitle, message.RoundEndText, message.RoundDuration, message.RoundId, message.AllPlayersEndInfo); + var roundEnd = new RoundEndSummaryWindow(message.GamemodeTitle, message.RoundEndText, message.RoundDuration, message.RoundId, message.AllPlayersEndInfo, _entityManager); } private void RoundRestartCleanup(RoundRestartCleanupEvent ev) diff --git a/Content.Client/RoundEnd/RoundEndSummaryWindow.cs b/Content.Client/RoundEnd/RoundEndSummaryWindow.cs index 94ba34a23c..fd900fa4bd 100644 --- a/Content.Client/RoundEnd/RoundEndSummaryWindow.cs +++ b/Content.Client/RoundEnd/RoundEndSummaryWindow.cs @@ -1,6 +1,7 @@ using System.Linq; using Content.Client.Message; using Content.Shared.GameTicking; +using Robust.Client.GameObjects; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Shared.Utility; @@ -10,10 +11,13 @@ namespace Content.Client.RoundEnd { public sealed class RoundEndSummaryWindow : DefaultWindow { + private readonly IEntityManager _entityManager; public RoundEndSummaryWindow(string gm, string roundEnd, TimeSpan roundTimeSpan, int roundId, - RoundEndMessageEvent.RoundEndPlayerInfo[] info) + RoundEndMessageEvent.RoundEndPlayerInfo[] info, IEntityManager entityManager) { + _entityManager = entityManager; + MinSize = SetSize = (520, 580); Title = Loc.GetString("round-end-summary-window-title"); @@ -105,7 +109,27 @@ namespace Content.Client.RoundEnd //Create labels for each player info. foreach (var playerInfo in sortedPlayersInfo) { - var playerInfoText = new RichTextLabel(); + var hBox = new BoxContainer + { + Orientation = LayoutOrientation.Horizontal, + }; + + var playerInfoText = new RichTextLabel + { + VerticalAlignment = VAlignment.Center, + VerticalExpand = true, + }; + + if (_entityManager.TryGetComponent(playerInfo.PlayerEntityUid, out ISpriteComponent? sprite)) + { + hBox.AddChild(new SpriteView + { + Sprite = sprite, + OverrideDirection = Direction.South, + VerticalAlignment = VAlignment.Center, + VerticalExpand = true, + }); + } if (playerInfo.PlayerICName != null) { @@ -129,7 +153,8 @@ namespace Content.Client.RoundEnd ("playerRole", Loc.GetString(playerInfo.Role)))); } } - playerInfoContainer.AddChild(playerInfoText); + hBox.AddChild(playerInfoText); + playerInfoContainer.AddChild(hBox); } playerInfoContainerScrollbox.AddChild(playerInfoContainer); diff --git a/Content.Server/Administration/Commands/ThrowScoreboardCommand.cs b/Content.Server/Administration/Commands/ThrowScoreboardCommand.cs new file mode 100644 index 0000000000..ed4ec5a515 --- /dev/null +++ b/Content.Server/Administration/Commands/ThrowScoreboardCommand.cs @@ -0,0 +1,25 @@ +using Content.Server.GameTicking; +using Content.Shared.Administration; +using Robust.Shared.Console; + +namespace Content.Server.Administration.Commands; + +[AdminCommand(AdminFlags.VarEdit)] +public sealed class ThrowScoreboardCommand : IConsoleCommand +{ + public string Command => "throwscoreboard"; + + public string Description => Loc.GetString("throw-scoreboard-command-description"); + + public string Help => Loc.GetString("throw-scoreboard-command-help-text"); + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (args.Length > 0) + { + shell.WriteLine(Help); + return; + } + EntitySystem.Get().ShowRoundEndScoreboard(); + } +} diff --git a/Content.Server/GameTicking/GameTicker.RoundFlow.cs b/Content.Server/GameTicking/GameTicker.RoundFlow.cs index 073975222d..95a7dd6b9b 100644 --- a/Content.Server/GameTicking/GameTicker.RoundFlow.cs +++ b/Content.Server/GameTicking/GameTicker.RoundFlow.cs @@ -262,6 +262,11 @@ namespace Content.Server.GameTicking RunLevel = GameRunLevel.PostRound; + ShowRoundEndScoreboard(text); + } + + public void ShowRoundEndScoreboard(string text = "") + { //Tell every client the round has ended. var gamemodeTitle = Preset != null ? Loc.GetString(Preset.ModeTitle) : string.Empty; @@ -314,6 +319,7 @@ namespace Content.Server.GameTicking PlayerOOCName = contentPlayerData?.Name ?? "(IMPOSSIBLE: REGISTERED MIND WITH NO OWNER)", // Character name takes precedence over current entity name PlayerICName = playerIcName, + PlayerEntityUid = mind.OwnedEntity, Role = antag ? mind.AllRoles.First(role => role.Antagonist).Name : mind.AllRoles.FirstOrDefault()?.Name ?? Loc.GetString("game-ticker-unknown-role"), @@ -370,7 +376,7 @@ namespace Content.Server.GameTicking ReqWindowAttentionAll(); } } - + /// /// Cleanup that has to run to clear up anything from the previous round. /// Stuff like wiping the previous map clean. diff --git a/Content.Shared/GameTicking/SharedGameTicker.cs b/Content.Shared/GameTicking/SharedGameTicker.cs index 9b26cc8052..5a1aa9508f 100644 --- a/Content.Shared/GameTicking/SharedGameTicker.cs +++ b/Content.Shared/GameTicking/SharedGameTicker.cs @@ -1,5 +1,6 @@ using Robust.Shared.Network; using Robust.Shared.Serialization; +using Robust.Shared.Utility; namespace Content.Shared.GameTicking { @@ -127,6 +128,7 @@ namespace Content.Shared.GameTicking public string PlayerOOCName; public string? PlayerICName; public string Role; + public EntityUid? PlayerEntityUid; public bool Antag; public bool Observer; public bool Connected; diff --git a/Resources/Locale/en-US/administration/commands/throw-scoreboard-command.ftl b/Resources/Locale/en-US/administration/commands/throw-scoreboard-command.ftl new file mode 100644 index 0000000000..169c9088ab --- /dev/null +++ b/Resources/Locale/en-US/administration/commands/throw-scoreboard-command.ftl @@ -0,0 +1,2 @@ +throw-scoreboard-command-description = Show round-end scoreboard for all players, but not finish the round +throw-scoreboard-command-help-text = Usage: throwscoreboard