diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 993902559e..477a7f4054 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -256,7 +256,6 @@ namespace OpenRA { // Clear static state if we have switched mods LobbyInfoChanged = () => { }; - AddChatLine = (a, b, c) => { }; ConnectionStateChanged = om => { }; BeforeGameStart = () => { }; Ui.ResetAll(); @@ -652,7 +651,10 @@ namespace OpenRA state = RunStatus.Restart; } - public static Action AddChatLine = (c, n, s) => { }; + public static void AddChatLine(Color color, string name, string text) + { + orderManager.AddChatLine(color, name, text); + } public static void Debug(string s, params object[] args) { diff --git a/OpenRA.Game/Network/OrderManager.cs b/OpenRA.Game/Network/OrderManager.cs index cbaf220aa0..c9540f4cad 100644 --- a/OpenRA.Game/Network/OrderManager.cs +++ b/OpenRA.Game/Network/OrderManager.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using OpenRA.Primitives; @@ -44,6 +45,9 @@ namespace OpenRA.Network List localOrders = new List(); + List chatCache = new List(); + public readonly ReadOnlyList ChatCache; + public void StartGame() { if (GameStarted) return; @@ -60,6 +64,8 @@ namespace OpenRA.Network Password = password; Connection = conn; syncReport = new SyncReport(this); + ChatCache = new ReadOnlyList(chatCache); + AddChatLine += CacheChatLine; } public void IssueOrders(Order[] orders) @@ -73,6 +79,12 @@ namespace OpenRA.Network localOrders.Add(order); } + public Action AddChatLine = (c, n, s) => { }; + void CacheChatLine(Color color, string name, string text) + { + chatCache.Add(new ChatLine(color, name, text)); + } + public void TickImmediate() { var immediateOrders = localOrders.Where( o => o.IsImmediate ).ToList(); @@ -203,4 +215,18 @@ namespace OpenRA.Network Connection.Dispose(); } } + + public class ChatLine + { + public readonly Color Color; + public readonly string Name; + public readonly string Text; + + public ChatLine(Color c, string n, string t) + { + Color = c; + Name = n; + Text = t; + } + } } diff --git a/OpenRA.Mods.RA/Widgets/Logic/Ingame/LeaveMapLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/Ingame/LeaveMapLogic.cs index fcbd79e750..e6a76f6f95 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/Ingame/LeaveMapLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/Ingame/LeaveMapLogic.cs @@ -9,8 +9,9 @@ #endregion using System; -using System.Linq; using System.Drawing; +using System.Linq; +using OpenRA.Network; using OpenRA.Traits; using OpenRA.Widgets; @@ -19,13 +20,16 @@ namespace OpenRA.Mods.RA.Widgets class LeaveMapLogic { enum Tab { Objectives, Chat }; - Tab currentTab; + + OrderManager orderManager; bool newChatMessage; [ObjectCreator.UseCtor] - public LeaveMapLogic(Widget widget, World world) + public LeaveMapLogic(Widget widget, World world, OrderManager orderManager) { + this.orderManager = orderManager; + widget.Get("VERSION_LABEL").Text = Game.modData.Manifest.Mod.Version; var showStats = false; @@ -70,7 +74,7 @@ namespace OpenRA.Mods.RA.Widgets chatButton.IsHighlighted = () => currentTab == Tab.Chat || (newChatMessage && Game.LocalTick % 50 < 25); Game.BeforeGameStart += UnregisterChatNotification; - Game.AddChatLine += NotifyNewChatMessage; + orderManager.AddChatLine += NotifyNewChatMessage; } var statsButton = dialog.Get("STATS_BUTTON"); @@ -130,7 +134,7 @@ namespace OpenRA.Mods.RA.Widgets void UnregisterChatNotification() { - Game.AddChatLine -= NotifyNewChatMessage; + orderManager.AddChatLine -= NotifyNewChatMessage; Game.BeforeGameStart -= UnregisterChatNotification; } } diff --git a/OpenRA.Mods.RA/Widgets/Logic/IngameChatLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/IngameChatLogic.cs index 012d447d0f..fda765494a 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/IngameChatLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/IngameChatLogic.cs @@ -18,6 +18,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic { public class IngameChatLogic { + readonly OrderManager orderManager; readonly Ruleset modRules; readonly ContainerWidget chatOverlay; @@ -38,6 +39,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic [ObjectCreator.UseCtor] public IngameChatLogic(Widget widget, OrderManager orderManager, World world, Ruleset modRules) { + this.orderManager = orderManager; this.modRules = modRules; chatTraits = world.WorldActor.TraitsImplementing().ToList(); @@ -125,7 +127,10 @@ namespace OpenRA.Mods.RA.Widgets.Logic chatScrollPanel.RemoveChildren(); chatScrollPanel.ScrollToBottom(); - Game.AddChatLine += AddChatLine; + foreach (var chatLine in orderManager.ChatCache) + AddChatLine(chatLine.Color, chatLine.Name, chatLine.Text, true); + + orderManager.AddChatLine += AddChatLineWrapper; Game.BeforeGameStart += UnregisterEvents; CloseChat(); @@ -133,7 +138,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic void UnregisterEvents() { - Game.AddChatLine -= AddChatLine; + orderManager.AddChatLine -= AddChatLineWrapper; Game.BeforeGameStart -= UnregisterEvents; } @@ -156,9 +161,14 @@ namespace OpenRA.Mods.RA.Widgets.Logic chatOverlay.Visible = true; } - public void AddChatLine(Color c, string from, string text) + public void AddChatLineWrapper(Color c, string from, string text) { - if (!inDialog) + AddChatLine(c, from, text, false); + } + + void AddChatLine(Color c, string from, string text, bool replayCache) + { + if (!(inDialog || replayCache)) chatOverlayDisplay.AddLine(c, from, text); var template = chatTemplate.Clone(); @@ -193,7 +203,8 @@ namespace OpenRA.Mods.RA.Widgets.Logic if (scrolledToBottom) chatScrollPanel.ScrollToBottom(smooth: true); - Sound.PlayNotification(modRules, null, "Sounds", "ChatLine", null); + if (!replayCache) + Sound.PlayNotification(modRules, null, "Sounds", "ChatLine", null); } } } diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs index 0f54f8c71a..df242f6edb 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs @@ -84,10 +84,10 @@ namespace OpenRA.Mods.RA.Widgets.Logic void CloseWindow() { + orderManager.AddChatLine -= AddChatLine; Game.LobbyInfoChanged -= UpdateCurrentMap; Game.LobbyInfoChanged -= UpdatePlayerList; Game.BeforeGameStart -= OnGameStart; - Game.AddChatLine -= AddChatLine; Game.ConnectionStateChanged -= ConnectionStateChanged; Ui.CloseWindow(); @@ -104,10 +104,10 @@ namespace OpenRA.Mods.RA.Widgets.Logic this.skirmishMode = skirmishMode; this.modRules = modRules; + orderManager.AddChatLine += AddChatLine; Game.LobbyInfoChanged += UpdateCurrentMap; Game.LobbyInfoChanged += UpdatePlayerList; Game.BeforeGameStart += OnGameStart; - Game.AddChatLine += AddChatLine; Game.ConnectionStateChanged += ConnectionStateChanged; var name = lobby.GetOrNull("SERVER_NAME");