From 02f9c5259c0d71471e5213069027d95bd9a51757 Mon Sep 17 00:00:00 2001 From: scuffedjays Date: Wed, 8 Apr 2020 06:07:54 -0500 Subject: [PATCH 1/9] Add foundation for Round End Summary Screen. Adjust GamePreset class, added title alongside description. --- .../GameTicking/ClientGameTicker.cs | 12 ++++ .../UserInterface/RoundEndSummaryWindow.cs | 56 +++++++++++++++++++ Content.Server/GameTicking/GamePreset.cs | 3 +- .../GamePresets/PresetDeathMatch.cs | 5 +- .../GameTicking/GamePresets/PresetSandbox.cs | 5 +- Content.Server/GameTicking/GameTicker.cs | 14 ++++- Content.Shared/SharedGameTicker.cs | 33 ++++++++++- 7 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 Content.Client/UserInterface/RoundEndSummaryWindow.cs diff --git a/Content.Client/GameTicking/ClientGameTicker.cs b/Content.Client/GameTicking/ClientGameTicker.cs index 77ca609371..ad8bc976c8 100644 --- a/Content.Client/GameTicking/ClientGameTicker.cs +++ b/Content.Client/GameTicking/ClientGameTicker.cs @@ -1,6 +1,7 @@ using System; using Content.Client.Interfaces; using Content.Client.State; +using Content.Client.UserInterface; using Content.Shared; using Robust.Client.Interfaces.State; using Robust.Shared.Interfaces.Network; @@ -35,10 +36,13 @@ namespace Content.Client.GameTicking _netManager.RegisterNetMessage(nameof(MsgTickerJoinGame), JoinGame); _netManager.RegisterNetMessage(nameof(MsgTickerLobbyStatus), LobbyStatus); _netManager.RegisterNetMessage(nameof(MsgTickerLobbyInfo), LobbyInfo); + _netManager.RegisterNetMessage(nameof(MsgRoundEndMessage), RoundEnd); _initialized = true; } + + private void JoinLobby(MsgTickerJoinLobby message) { _stateManager.RequestStateChange(); @@ -64,5 +68,13 @@ namespace Content.Client.GameTicking { _stateManager.RequestStateChange(); } + + private void RoundEnd(MsgRoundEndMessage message) + { + + //This is not ideal at all, but I don't see an immediately better fit anywhere else. + var roundEnd = new RoundEndSummaryWindow(message.GamemodeTitle, message.DurationInHours); + + } } } diff --git a/Content.Client/UserInterface/RoundEndSummaryWindow.cs b/Content.Client/UserInterface/RoundEndSummaryWindow.cs new file mode 100644 index 0000000000..b3abe84b69 --- /dev/null +++ b/Content.Client/UserInterface/RoundEndSummaryWindow.cs @@ -0,0 +1,56 @@ +using Robust.Client.Graphics; +using Robust.Client.Interfaces.Input; +using Robust.Client.Interfaces.ResourceManagement; +using Robust.Client.ResourceManagement; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.CustomControls; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Maths; +using Content.Client.Utility; + +namespace Content.Client.UserInterface +{ + public sealed class RoundEndSummaryWindow : SS14Window + { + private readonly int _headerFontSize = 14; + private VBoxContainer VBox { get; } + + protected override Vector2? CustomSize => (520, 580); + +#pragma warning disable 649 + [Dependency] private readonly IResourceCache _resourceCache; + [Dependency] private readonly ILocalizationManager _loc; + [Dependency] private readonly IInputManager _inputManager; +#pragma warning restore 649 + + public RoundEndSummaryWindow(string gm, uint duration) + { + Title = "Round End Summary"; + + //Get section header font + _loc = IoCManager.Resolve(); + var cache = IoCManager.Resolve(); + var inputManager = IoCManager.Resolve(); + Font headerFont = new VectorFont(cache.GetResource("/Nano/NotoSans/NotoSans-Regular.ttf"), _headerFontSize); + + var scrollContainer = new ScrollContainer(); + scrollContainer.AddChild(VBox = new VBoxContainer()); + Contents.AddChild(scrollContainer); + + //Gamemode Name + var gamemodeLabel = new RichTextLabel(); + gamemodeLabel.SetMarkup(_loc.GetString("Round of: [color=white]{0}[/color] has ended.", gm)); + VBox.AddChild(gamemodeLabel); + + //Duration + var roundDurationInfo = new RichTextLabel(); + roundDurationInfo.SetMarkup(_loc.GetString("The round lasted for [color=yellow]{0}[/color] hours.", duration)); + VBox.AddChild(roundDurationInfo); + + OpenCentered(); + MoveToFront(); + + } + } +} diff --git a/Content.Server/GameTicking/GamePreset.cs b/Content.Server/GameTicking/GamePreset.cs index cf7981b725..b880b162a0 100644 --- a/Content.Server/GameTicking/GamePreset.cs +++ b/Content.Server/GameTicking/GamePreset.cs @@ -1,4 +1,4 @@ -namespace Content.Server.GameTicking +namespace Content.Server.GameTicking { /// /// A round-start setup preset, such as which antagonists to spawn. @@ -6,6 +6,7 @@ namespace Content.Server.GameTicking public abstract class GamePreset { public abstract void Start(); + public virtual string ModeTitle => "Sandbox"; public virtual string Description => "Secret!"; } } diff --git a/Content.Server/GameTicking/GamePresets/PresetDeathMatch.cs b/Content.Server/GameTicking/GamePresets/PresetDeathMatch.cs index 11c716442d..5b866dc8fa 100644 --- a/Content.Server/GameTicking/GamePresets/PresetDeathMatch.cs +++ b/Content.Server/GameTicking/GamePresets/PresetDeathMatch.cs @@ -1,4 +1,4 @@ -using Content.Server.GameTicking.GameRules; +using Content.Server.GameTicking.GameRules; using Content.Server.Interfaces.GameTicking; using Robust.Shared.IoC; @@ -15,6 +15,7 @@ namespace Content.Server.GameTicking.GamePresets _gameTicker.AddGameRule(); } - public override string Description => "Deathmatch, go and kill everybody else to win!"; + public override string ModeTitle => "Deathmatch"; + public override string Description => "Kill anything that moves!"; } } diff --git a/Content.Server/GameTicking/GamePresets/PresetSandbox.cs b/Content.Server/GameTicking/GamePresets/PresetSandbox.cs index f80b41ebd0..05f15c6972 100644 --- a/Content.Server/GameTicking/GamePresets/PresetSandbox.cs +++ b/Content.Server/GameTicking/GamePresets/PresetSandbox.cs @@ -1,4 +1,4 @@ -using Content.Server.Sandbox; +using Content.Server.Sandbox; using Robust.Shared.IoC; namespace Content.Server.GameTicking.GamePresets @@ -14,6 +14,7 @@ namespace Content.Server.GameTicking.GamePresets _sandboxManager.IsSandboxEnabled = true; } - public override string Description => "Sandbox, go and build something!"; + public override string ModeTitle => "Sandbox"; + public override string Description => "No stress, build something!"; } } diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index e8c654b2c3..3df9f50c4a 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -100,6 +100,7 @@ namespace Content.Server.GameTicking _netManager.RegisterNetMessage(nameof(MsgTickerJoinGame)); _netManager.RegisterNetMessage(nameof(MsgTickerLobbyStatus)); _netManager.RegisterNetMessage(nameof(MsgTickerLobbyInfo)); + _netManager.RegisterNetMessage(nameof(MsgRoundEndMessage)); SetStartPreset(_configurationManager.GetCVar("game.defaultpreset")); @@ -200,6 +201,13 @@ namespace Content.Server.GameTicking Logger.InfoS("ticker", "Ending round!"); RunLevel = GameRunLevel.PostRound; + + //Tell every client the round has ended. + var roundEndMessage = _netManager.CreateNetMessage(); + roundEndMessage.GamemodeTitle = MakeGamePreset().ModeTitle; + //TODO:Grab actual timespan of round. + roundEndMessage.DurationInHours = 1337; + _netManager.ServerSendToAll(roundEndMessage); } public void Respawn(IPlayerSession targetPlayer) @@ -559,10 +567,12 @@ namespace Content.Server.GameTicking private string GetInfoText() { - var gameMode = MakeGamePreset().Description; + var gmTitle = MakeGamePreset().ModeTitle; + var desc = MakeGamePreset().Description; return _localization.GetString(@"Hi and welcome to [color=white]Space Station 14![/color] -The current game mode is [color=white]{0}[/color]", gameMode); +The current game mode is: [color=white]{0}[/color]. +[color=yellow]{1}[/color]", gmTitle, desc ); } private void UpdateInfoText() diff --git a/Content.Shared/SharedGameTicker.cs b/Content.Shared/SharedGameTicker.cs index 126a44e0e9..616e53ef1c 100644 --- a/Content.Shared/SharedGameTicker.cs +++ b/Content.Shared/SharedGameTicker.cs @@ -1,4 +1,4 @@ -using System; +using System; using Lidgren.Network; using Robust.Shared.Interfaces.Network; using Robust.Shared.Network; @@ -114,5 +114,36 @@ namespace Content.Shared buffer.Write(TextBlob); } } + + protected class MsgRoundEndMessage : NetMessage + { + + #region REQUIRED + + public const MsgGroups GROUP = MsgGroups.Command; + public const string NAME = nameof(MsgRoundEndMessage); + public MsgRoundEndMessage(INetChannel channel) : base(NAME, GROUP) { } + + #endregion + + public string GamemodeTitle; + //TODO: Change to a more detailed measurement of time. + public uint DurationInHours; + + public override void ReadFromBuffer(NetIncomingMessage buffer) + { + GamemodeTitle = buffer.ReadString(); + DurationInHours = buffer.ReadUInt32(); + } + + public override void WriteToBuffer(NetOutgoingMessage buffer) + { + buffer.Write(GamemodeTitle); + buffer.Write(DurationInHours); + + } + + } } } + From febe9aa46ca951815139f5b5084587da0b66da88 Mon Sep 17 00:00:00 2001 From: scuffedjays Date: Wed, 8 Apr 2020 19:09:02 -0500 Subject: [PATCH 2/9] Removed unused. Use Loc instead. --- .../UserInterface/RoundEndSummaryWindow.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Content.Client/UserInterface/RoundEndSummaryWindow.cs b/Content.Client/UserInterface/RoundEndSummaryWindow.cs index b3abe84b69..4c12d01b90 100644 --- a/Content.Client/UserInterface/RoundEndSummaryWindow.cs +++ b/Content.Client/UserInterface/RoundEndSummaryWindow.cs @@ -18,18 +18,10 @@ namespace Content.Client.UserInterface protected override Vector2? CustomSize => (520, 580); -#pragma warning disable 649 - [Dependency] private readonly IResourceCache _resourceCache; - [Dependency] private readonly ILocalizationManager _loc; - [Dependency] private readonly IInputManager _inputManager; -#pragma warning restore 649 - public RoundEndSummaryWindow(string gm, uint duration) { - Title = "Round End Summary"; + Title = Loc.GetString("Round End Summary"); - //Get section header font - _loc = IoCManager.Resolve(); var cache = IoCManager.Resolve(); var inputManager = IoCManager.Resolve(); Font headerFont = new VectorFont(cache.GetResource("/Nano/NotoSans/NotoSans-Regular.ttf"), _headerFontSize); @@ -40,12 +32,12 @@ namespace Content.Client.UserInterface //Gamemode Name var gamemodeLabel = new RichTextLabel(); - gamemodeLabel.SetMarkup(_loc.GetString("Round of: [color=white]{0}[/color] has ended.", gm)); + gamemodeLabel.SetMarkup(Loc.GetString("Round of: [color=white]{0}[/color] has ended.", gm)); VBox.AddChild(gamemodeLabel); //Duration var roundDurationInfo = new RichTextLabel(); - roundDurationInfo.SetMarkup(_loc.GetString("The round lasted for [color=yellow]{0}[/color] hours.", duration)); + roundDurationInfo.SetMarkup(Loc.GetString("The round lasted for [color=yellow]{0}[/color] hours.", duration)); VBox.AddChild(roundDurationInfo); OpenCentered(); From c47368231bc3af106aa3acabc14fd6544bb8b0fb Mon Sep 17 00:00:00 2001 From: scuffedjays Date: Wed, 8 Apr 2020 23:51:49 -0500 Subject: [PATCH 3/9] Add scrollable player list to round end menu with OOC Usernames. --- .../UserInterface/RoundEndSummaryWindow.cs | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/Content.Client/UserInterface/RoundEndSummaryWindow.cs b/Content.Client/UserInterface/RoundEndSummaryWindow.cs index 4c12d01b90..a12c9076ba 100644 --- a/Content.Client/UserInterface/RoundEndSummaryWindow.cs +++ b/Content.Client/UserInterface/RoundEndSummaryWindow.cs @@ -8,13 +8,22 @@ using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Maths; using Content.Client.Utility; +using Robust.Client.Player; +using System.Linq; +using static Robust.Client.UserInterface.Controls.ItemList; namespace Content.Client.UserInterface { public sealed class RoundEndSummaryWindow : SS14Window { + + #pragma warning disable 649 + [Dependency] private IPlayerManager _playerManager; +#pragma warning restore 649 + private readonly int _headerFontSize = 14; private VBoxContainer VBox { get; } + private ItemList _playerList; protected override Vector2? CustomSize => (520, 580); @@ -32,7 +41,7 @@ namespace Content.Client.UserInterface //Gamemode Name var gamemodeLabel = new RichTextLabel(); - gamemodeLabel.SetMarkup(Loc.GetString("Round of: [color=white]{0}[/color] has ended.", gm)); + gamemodeLabel.SetMarkup(Loc.GetString("Round of [color=white]{0}[/color] has ended.", gm)); VBox.AddChild(gamemodeLabel); //Duration @@ -40,9 +49,27 @@ namespace Content.Client.UserInterface roundDurationInfo.SetMarkup(Loc.GetString("The round lasted for [color=yellow]{0}[/color] hours.", duration)); VBox.AddChild(roundDurationInfo); + + //Populate list of players. + _playerManager = IoCManager.Resolve(); + _playerList = new ItemList() + { + SizeFlagsStretchRatio = 8, + SizeFlagsVertical = SizeFlags.FillExpand, + SelectMode = ItemList.ItemListSelectMode.Button + }; + + foreach (var session in _playerManager.Sessions.OrderBy(s => s.Name)) + { + var playerOOCName = session.SessionId.Username; + //No Mind data so no ICName/Job/Role, etc. + _playerList.AddItem(playerOOCName); + } + VBox.AddChild(_playerList); OpenCentered(); MoveToFront(); } } + } From 3ce50879b7510fa054cad4b42e4df627ec94b332 Mon Sep 17 00:00:00 2001 From: scuffedjays Date: Fri, 10 Apr 2020 01:37:14 -0500 Subject: [PATCH 4/9] New struct for basic round end info per player. --- .../GameTicking/ClientGameTicker.cs | 2 +- .../UserInterface/RoundEndSummaryWindow.cs | 15 +++++--- Content.Server/GameTicking/GameTicker.cs | 22 +++++++++++ Content.Shared/SharedGameTicker.cs | 38 +++++++++++++++++++ 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/Content.Client/GameTicking/ClientGameTicker.cs b/Content.Client/GameTicking/ClientGameTicker.cs index ad8bc976c8..621be8e936 100644 --- a/Content.Client/GameTicking/ClientGameTicker.cs +++ b/Content.Client/GameTicking/ClientGameTicker.cs @@ -73,7 +73,7 @@ namespace Content.Client.GameTicking { //This is not ideal at all, but I don't see an immediately better fit anywhere else. - var roundEnd = new RoundEndSummaryWindow(message.GamemodeTitle, message.DurationInHours); + var roundEnd = new RoundEndSummaryWindow(message.GamemodeTitle, message.DurationInHours, message.AllPlayersEndInfo); } } diff --git a/Content.Client/UserInterface/RoundEndSummaryWindow.cs b/Content.Client/UserInterface/RoundEndSummaryWindow.cs index a12c9076ba..b393edfddd 100644 --- a/Content.Client/UserInterface/RoundEndSummaryWindow.cs +++ b/Content.Client/UserInterface/RoundEndSummaryWindow.cs @@ -10,7 +10,9 @@ using Robust.Shared.Maths; using Content.Client.Utility; using Robust.Client.Player; using System.Linq; +using System.Collections.Generic; using static Robust.Client.UserInterface.Controls.ItemList; +using static Content.Shared.SharedGameTicker; namespace Content.Client.UserInterface { @@ -27,7 +29,7 @@ namespace Content.Client.UserInterface protected override Vector2? CustomSize => (520, 580); - public RoundEndSummaryWindow(string gm, uint duration) + public RoundEndSummaryWindow(string gm, uint duration, List info ) { Title = Loc.GetString("Round End Summary"); @@ -59,12 +61,15 @@ namespace Content.Client.UserInterface SelectMode = ItemList.ItemListSelectMode.Button }; - foreach (var session in _playerManager.Sessions.OrderBy(s => s.Name)) + foreach(var plyinfo in info) { - var playerOOCName = session.SessionId.Username; - //No Mind data so no ICName/Job/Role, etc. - _playerList.AddItem(playerOOCName); + var oocName = plyinfo.PlayerOOCName; + var icName = plyinfo.PlayerICName; + var role = plyinfo.Role; + var wasAntag = plyinfo.Antag; + _playerList.AddItem($"{oocName} was {icName} playing role of {role}."); } + VBox.AddChild(_playerList); OpenCentered(); MoveToFront(); diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index 3df9f50c4a..a7b2b9bf61 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -205,8 +205,30 @@ namespace Content.Server.GameTicking //Tell every client the round has ended. var roundEndMessage = _netManager.CreateNetMessage(); roundEndMessage.GamemodeTitle = MakeGamePreset().ModeTitle; + //TODO:Grab actual timespan of round. roundEndMessage.DurationInHours = 1337; + + //Generate a list of basic player info to display in the end round summary. + var listOfPlayerInfo = new List(); + foreach(var ply in _playerManager.GetAllPlayers().OrderBy(p => p.Name)) + { + if (ply == null) continue; + if(ply.AttachedEntity.TryGetComponent(out var mindComponent) + && mindComponent.HasMind) + { + var playerEndRoundInfo = new RoundEndPlayerInfo() + { + PlayerOOCName = ply.Name, + PlayerICName = mindComponent.Mind.CurrentEntity.Name, + Role = mindComponent.Mind.AllRoles.First().Name, + Antag = false + }; + listOfPlayerInfo.Add(playerEndRoundInfo); + } + } + + roundEndMessage.AllPlayersEndInfo = listOfPlayerInfo; _netManager.ServerSendToAll(roundEndMessage); } diff --git a/Content.Shared/SharedGameTicker.cs b/Content.Shared/SharedGameTicker.cs index 616e53ef1c..41a1651d12 100644 --- a/Content.Shared/SharedGameTicker.cs +++ b/Content.Shared/SharedGameTicker.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using Lidgren.Network; +using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Network; using Robust.Shared.Network; @@ -114,6 +116,14 @@ namespace Content.Shared buffer.Write(TextBlob); } } + public struct RoundEndPlayerInfo + { + public string PlayerOOCName; + public string PlayerICName; + public string Role; + public bool Antag; + + } protected class MsgRoundEndMessage : NetMessage { @@ -130,10 +140,30 @@ namespace Content.Shared //TODO: Change to a more detailed measurement of time. public uint DurationInHours; + public uint PlayerCount; + + public List AllPlayersEndInfo; + public override void ReadFromBuffer(NetIncomingMessage buffer) { GamemodeTitle = buffer.ReadString(); DurationInHours = buffer.ReadUInt32(); + + PlayerCount = buffer.ReadUInt32(); + AllPlayersEndInfo = new List(); + for(var i = 0; i < PlayerCount + 1; i++) + { + var readPlayerData = new RoundEndPlayerInfo + { + PlayerOOCName = buffer.ReadString(), + PlayerICName = buffer.ReadString(), + Role = buffer.ReadString(), + Antag = buffer.ReadBoolean() + }; + + AllPlayersEndInfo.Add(readPlayerData); + } + } public override void WriteToBuffer(NetOutgoingMessage buffer) @@ -141,6 +171,14 @@ namespace Content.Shared buffer.Write(GamemodeTitle); buffer.Write(DurationInHours); + buffer.Write(PlayerCount); + foreach(var playerEndInfo in AllPlayersEndInfo) + { + buffer.Write(playerEndInfo.PlayerOOCName); + buffer.Write(playerEndInfo.PlayerICName); + buffer.Write(playerEndInfo.Role); + buffer.Write(playerEndInfo.Antag); + } } } From 5d3018d76d856a4468f9e0621d457ea21edb1c7e Mon Sep 17 00:00:00 2001 From: scuffedjays Date: Sat, 11 Apr 2020 10:31:44 -0500 Subject: [PATCH 5/9] Change frm ItemList to list of labels with markup --- .../UserInterface/RoundEndSummaryWindow.cs | 51 ++++++++----------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/Content.Client/UserInterface/RoundEndSummaryWindow.cs b/Content.Client/UserInterface/RoundEndSummaryWindow.cs index b393edfddd..e68d6c8d38 100644 --- a/Content.Client/UserInterface/RoundEndSummaryWindow.cs +++ b/Content.Client/UserInterface/RoundEndSummaryWindow.cs @@ -18,59 +18,48 @@ namespace Content.Client.UserInterface { public sealed class RoundEndSummaryWindow : SS14Window { - - #pragma warning disable 649 - [Dependency] private IPlayerManager _playerManager; -#pragma warning restore 649 - - private readonly int _headerFontSize = 14; private VBoxContainer VBox { get; } - private ItemList _playerList; - protected override Vector2? CustomSize => (520, 580); public RoundEndSummaryWindow(string gm, uint duration, List info ) { Title = Loc.GetString("Round End Summary"); - - var cache = IoCManager.Resolve(); - var inputManager = IoCManager.Resolve(); - Font headerFont = new VectorFont(cache.GetResource("/Nano/NotoSans/NotoSans-Regular.ttf"), _headerFontSize); - - var scrollContainer = new ScrollContainer(); - scrollContainer.AddChild(VBox = new VBoxContainer()); - Contents.AddChild(scrollContainer); - + VBox = new VBoxContainer(); + Contents.AddChild(VBox); //Gamemode Name var gamemodeLabel = new RichTextLabel(); gamemodeLabel.SetMarkup(Loc.GetString("Round of [color=white]{0}[/color] has ended.", gm)); VBox.AddChild(gamemodeLabel); //Duration - var roundDurationInfo = new RichTextLabel(); - roundDurationInfo.SetMarkup(Loc.GetString("The round lasted for [color=yellow]{0}[/color] hours.", duration)); - VBox.AddChild(roundDurationInfo); + //var roundDurationInfo = new RichTextLabel(); + //roundDurationInfo.SetMarkup(Loc.GetString("The round lasted for [color=yellow]{0}[/color] hours.", duration)); + //VBox.AddChild(roundDurationInfo); - //Populate list of players. - _playerManager = IoCManager.Resolve(); - _playerList = new ItemList() - { - SizeFlagsStretchRatio = 8, - SizeFlagsVertical = SizeFlags.FillExpand, - SelectMode = ItemList.ItemListSelectMode.Button - }; + //Initialize what will be the list of players display. + var scrollContainer = new ScrollContainer(); + scrollContainer.SizeFlagsVertical = SizeFlags.FillExpand; + var innerScrollContainer = new VBoxContainer(); - foreach(var plyinfo in info) + //Create labels for each player info. + foreach (var plyinfo in info) { var oocName = plyinfo.PlayerOOCName; var icName = plyinfo.PlayerICName; var role = plyinfo.Role; var wasAntag = plyinfo.Antag; - _playerList.AddItem($"{oocName} was {icName} playing role of {role}."); + + var playerInfoText = new RichTextLabel(); + playerInfoText.SetMarkup(Loc.GetString($"[color=gray]{oocName}[/color] was [color=white]{icName}[/color] playing role of [color=orange]{role}[/color].")); + innerScrollContainer.AddChild(playerInfoText); } - VBox.AddChild(_playerList); + scrollContainer.AddChild(innerScrollContainer); + //Attach the entire ScrollContainer that holds all the playerinfo. + VBox.AddChild(scrollContainer); + + //Finally, display the window. OpenCentered(); MoveToFront(); From 18e10e289e4c2c59ae31f9833bf7ec11c737b4e9 Mon Sep 17 00:00:00 2001 From: scuffedjays Date: Sun, 12 Apr 2020 00:59:44 -0500 Subject: [PATCH 6/9] Added tabs to separate player info and general round info. Colored players IC name depending on antag status. --- .../UserInterface/RoundEndSummaryWindow.cs | 61 +++++++++++++------ 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/Content.Client/UserInterface/RoundEndSummaryWindow.cs b/Content.Client/UserInterface/RoundEndSummaryWindow.cs index e68d6c8d38..024182fab6 100644 --- a/Content.Client/UserInterface/RoundEndSummaryWindow.cs +++ b/Content.Client/UserInterface/RoundEndSummaryWindow.cs @@ -18,52 +18,79 @@ namespace Content.Client.UserInterface { public sealed class RoundEndSummaryWindow : SS14Window { - private VBoxContainer VBox { get; } + private VBoxContainer RoundEndSummaryTab { get; } + private VBoxContainer PlayerManifestoTab { get; } + private TabContainer RoundEndWindowTabs { get; } protected override Vector2? CustomSize => (520, 580); public RoundEndSummaryWindow(string gm, uint duration, List info ) { + Title = Loc.GetString("Round End Summary"); - VBox = new VBoxContainer(); - Contents.AddChild(VBox); + + //Round End Window is split into two tabs, one about the round stats + //and the other is a list of RoundEndPlayerInfo for each player. + //This tab would be a good place for things like: "x many people died.", + //"clown slipped the crew x times.", "x shots were fired this round.", etc. + //Also good for serious info. + RoundEndSummaryTab = new VBoxContainer() + { + Name = Loc.GetString("Round Information") + }; + + //Tab for listing unique info per player. + PlayerManifestoTab = new VBoxContainer() + { + Name = Loc.GetString("Player Manifesto") + }; + + RoundEndWindowTabs = new TabContainer(); + RoundEndWindowTabs.AddChild(RoundEndSummaryTab); + RoundEndWindowTabs.AddChild(PlayerManifestoTab); + + Contents.AddChild(RoundEndWindowTabs); + //Gamemode Name var gamemodeLabel = new RichTextLabel(); gamemodeLabel.SetMarkup(Loc.GetString("Round of [color=white]{0}[/color] has ended.", gm)); - VBox.AddChild(gamemodeLabel); - - //Duration - //var roundDurationInfo = new RichTextLabel(); - //roundDurationInfo.SetMarkup(Loc.GetString("The round lasted for [color=yellow]{0}[/color] hours.", duration)); - //VBox.AddChild(roundDurationInfo); + RoundEndSummaryTab.AddChild(gamemodeLabel); + //TODO: Implement showing the duration of the round. //Initialize what will be the list of players display. var scrollContainer = new ScrollContainer(); scrollContainer.SizeFlagsVertical = SizeFlags.FillExpand; var innerScrollContainer = new VBoxContainer(); + //Put antags on top of the list. + var manifestSortedList = info.OrderBy(p => !p.Antag); //Create labels for each player info. - foreach (var plyinfo in info) + foreach (var plyinfo in manifestSortedList) { - var oocName = plyinfo.PlayerOOCName; - var icName = plyinfo.PlayerICName; - var role = plyinfo.Role; - var wasAntag = plyinfo.Antag; - var playerInfoText = new RichTextLabel(); - playerInfoText.SetMarkup(Loc.GetString($"[color=gray]{oocName}[/color] was [color=white]{icName}[/color] playing role of [color=orange]{role}[/color].")); + var playerInfoText = new RichTextLabel() + { + SizeFlagsVertical = SizeFlags.Fill + }; + + //TODO: On Hover display a popup detailing more play info. + //For example: their antag goals and if they completed them sucessfully. + var icNameColor = plyinfo.Antag ? "red" : "white"; + playerInfoText.SetMarkup( + Loc.GetString($"[color=gray]{plyinfo.PlayerOOCName}[/color] was [color={icNameColor}]{plyinfo.PlayerICName}[/color] playing role of [color=orange]{plyinfo.Role}[/color].")); innerScrollContainer.AddChild(playerInfoText); } scrollContainer.AddChild(innerScrollContainer); //Attach the entire ScrollContainer that holds all the playerinfo. - VBox.AddChild(scrollContainer); + PlayerManifestoTab.AddChild(scrollContainer); //Finally, display the window. OpenCentered(); MoveToFront(); } + } } From 1605a500988a045cec5926d9bc18d5e961a34a96 Mon Sep 17 00:00:00 2001 From: scuffedjays Date: Tue, 14 Apr 2020 23:26:37 -0500 Subject: [PATCH 7/9] Changed duration to use TimeSpan. Using actual round realtime span to determine round length. --- Content.Client/GameTicking/ClientGameTicker.cs | 2 +- .../UserInterface/RoundEndSummaryWindow.cs | 9 +++++++-- Content.Server/GameTicking/GameTicker.cs | 5 +++-- Content.Shared/SharedGameTicker.cs | 17 ++++++++++++----- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Content.Client/GameTicking/ClientGameTicker.cs b/Content.Client/GameTicking/ClientGameTicker.cs index 621be8e936..1d3d278a67 100644 --- a/Content.Client/GameTicking/ClientGameTicker.cs +++ b/Content.Client/GameTicking/ClientGameTicker.cs @@ -73,7 +73,7 @@ namespace Content.Client.GameTicking { //This is not ideal at all, but I don't see an immediately better fit anywhere else. - var roundEnd = new RoundEndSummaryWindow(message.GamemodeTitle, message.DurationInHours, message.AllPlayersEndInfo); + var roundEnd = new RoundEndSummaryWindow(message.GamemodeTitle, message.RoundDuration, message.AllPlayersEndInfo); } } diff --git a/Content.Client/UserInterface/RoundEndSummaryWindow.cs b/Content.Client/UserInterface/RoundEndSummaryWindow.cs index 024182fab6..5e8600b188 100644 --- a/Content.Client/UserInterface/RoundEndSummaryWindow.cs +++ b/Content.Client/UserInterface/RoundEndSummaryWindow.cs @@ -13,6 +13,7 @@ using System.Linq; using System.Collections.Generic; using static Robust.Client.UserInterface.Controls.ItemList; using static Content.Shared.SharedGameTicker; +using System; namespace Content.Client.UserInterface { @@ -23,7 +24,7 @@ namespace Content.Client.UserInterface private TabContainer RoundEndWindowTabs { get; } protected override Vector2? CustomSize => (520, 580); - public RoundEndSummaryWindow(string gm, uint duration, List info ) + public RoundEndSummaryWindow(string gm, TimeSpan roundTimeSpan, List info ) { Title = Loc.GetString("Round End Summary"); @@ -55,7 +56,11 @@ namespace Content.Client.UserInterface gamemodeLabel.SetMarkup(Loc.GetString("Round of [color=white]{0}[/color] has ended.", gm)); RoundEndSummaryTab.AddChild(gamemodeLabel); - //TODO: Implement showing the duration of the round. + //Duration + var roundTimeLabel = new RichTextLabel(); + roundTimeLabel.SetMarkup(Loc.GetString("It lasted for [color=yellow]{0} hours, {1} minutes, and {2} seconds.", + roundTimeSpan.Hours,roundTimeSpan.Minutes,roundTimeSpan.Seconds)); + RoundEndSummaryTab.AddChild(roundTimeLabel); //Initialize what will be the list of players display. var scrollContainer = new ScrollContainer(); diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index a7b2b9bf61..2862b43f16 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -206,8 +206,9 @@ namespace Content.Server.GameTicking var roundEndMessage = _netManager.CreateNetMessage(); roundEndMessage.GamemodeTitle = MakeGamePreset().ModeTitle; - //TODO:Grab actual timespan of round. - roundEndMessage.DurationInHours = 1337; + //Get the timespan of the round. + var gameTime = IoCManager.Resolve(); + roundEndMessage.RoundDuration = gameTime.RealTime; //Generate a list of basic player info to display in the end round summary. var listOfPlayerInfo = new List(); diff --git a/Content.Shared/SharedGameTicker.cs b/Content.Shared/SharedGameTicker.cs index 41a1651d12..38d3e0985e 100644 --- a/Content.Shared/SharedGameTicker.cs +++ b/Content.Shared/SharedGameTicker.cs @@ -137,8 +137,8 @@ namespace Content.Shared #endregion public string GamemodeTitle; - //TODO: Change to a more detailed measurement of time. - public uint DurationInHours; + public TimeSpan RoundDuration; + public uint PlayerCount; @@ -147,7 +147,11 @@ namespace Content.Shared public override void ReadFromBuffer(NetIncomingMessage buffer) { GamemodeTitle = buffer.ReadString(); - DurationInHours = buffer.ReadUInt32(); + + var hours = buffer.ReadInt32(); + var mins = buffer.ReadInt32(); + var seconds = buffer.ReadInt32(); + RoundDuration = new TimeSpan(hours, mins, seconds); PlayerCount = buffer.ReadUInt32(); AllPlayersEndInfo = new List(); @@ -163,13 +167,16 @@ namespace Content.Shared AllPlayersEndInfo.Add(readPlayerData); } - + } public override void WriteToBuffer(NetOutgoingMessage buffer) { buffer.Write(GamemodeTitle); - buffer.Write(DurationInHours); + buffer.Write(RoundDuration.Hours); + buffer.Write(RoundDuration.Minutes); + buffer.Write(RoundDuration.Seconds); + buffer.Write(PlayerCount); foreach(var playerEndInfo in AllPlayersEndInfo) From 7ae8f8429d3d7ce87633477d9b0b9d753e4e5ec2 Mon Sep 17 00:00:00 2001 From: scuffedjays Date: Wed, 15 Apr 2020 17:46:53 -0500 Subject: [PATCH 8/9] Fixed calculation of round duration --- Content.Server/GameTicking/GameTicker.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index dccdffafd8..29662977bf 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -48,6 +48,7 @@ namespace Content.Server.GameTicking private const string PlayerPrototypeName = "HumanMob_Content"; private const string ObserverPrototypeName = "MobObserver"; private const string MapFile = "Maps/stationstation.yml"; + private static TimeSpan _roundStartTimeSpan; [ViewVariables] private readonly List _gameRules = new List(); [ViewVariables] private readonly List _manifest = new List(); @@ -194,6 +195,7 @@ namespace Content.Server.GameTicking SpawnPlayer(player, job, false); } + _roundStartTimeSpan = new TimeSpan(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second); _sendStatusToAll(); } @@ -220,14 +222,15 @@ namespace Content.Server.GameTicking roundEndMessage.GamemodeTitle = MakeGamePreset().ModeTitle; //Get the timespan of the round. - var gameTime = IoCManager.Resolve(); - roundEndMessage.RoundDuration = gameTime.RealTime; + roundEndMessage.RoundDuration = new TimeSpan(DateTime.Now.Hour, + DateTime.Now.Minute, + DateTime.Now.Second) + .Subtract(_roundStartTimeSpan); //Generate a list of basic player info to display in the end round summary. var listOfPlayerInfo = new List(); foreach(var ply in _playerManager.GetAllPlayers().OrderBy(p => p.Name)) { - if (ply == null) continue; if(ply.AttachedEntity.TryGetComponent(out var mindComponent) && mindComponent.HasMind) { @@ -235,7 +238,7 @@ namespace Content.Server.GameTicking { PlayerOOCName = ply.Name, PlayerICName = mindComponent.Mind.CurrentEntity.Name, - Role = mindComponent.Mind.AllRoles.First().Name, + Role = mindComponent.Mind.AllRoles.First() != null ? mindComponent.Mind.AllRoles.First().Name : Loc.GetString("Unkown"), Antag = false }; listOfPlayerInfo.Add(playerEndRoundInfo); From 43b27e93bc081edd4a894855161059560ed3d796 Mon Sep 17 00:00:00 2001 From: scuffedjays Date: Thu, 16 Apr 2020 13:07:58 -0500 Subject: [PATCH 9/9] Fix the duration timing again. --- Content.Server/GameTicking/GameTicker.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index 29662977bf..5d58779946 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -195,7 +195,7 @@ namespace Content.Server.GameTicking SpawnPlayer(player, job, false); } - _roundStartTimeSpan = new TimeSpan(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second); + _roundStartTimeSpan = IoCManager.Resolve().RealTime; _sendStatusToAll(); } @@ -222,10 +222,7 @@ namespace Content.Server.GameTicking roundEndMessage.GamemodeTitle = MakeGamePreset().ModeTitle; //Get the timespan of the round. - roundEndMessage.RoundDuration = new TimeSpan(DateTime.Now.Hour, - DateTime.Now.Minute, - DateTime.Now.Second) - .Subtract(_roundStartTimeSpan); + roundEndMessage.RoundDuration = IoCManager.Resolve().RealTime.Subtract(_roundStartTimeSpan); //Generate a list of basic player info to display in the end round summary. var listOfPlayerInfo = new List(); @@ -238,7 +235,7 @@ namespace Content.Server.GameTicking { PlayerOOCName = ply.Name, PlayerICName = mindComponent.Mind.CurrentEntity.Name, - Role = mindComponent.Mind.AllRoles.First() != null ? mindComponent.Mind.AllRoles.First().Name : Loc.GetString("Unkown"), + Role = mindComponent.Mind.AllRoles.FirstOrDefault()?.Name ?? Loc.GetString("Unkown"), Antag = false }; listOfPlayerInfo.Add(playerEndRoundInfo);