diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameChatLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameChatLogic.cs index c368fb28d9..1cf7d588c0 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameChatLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameChatLogic.cs @@ -40,8 +40,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic readonly string chatLineSound = ChromeMetrics.Get("ChatLineSound"); - TextNotification lastLine; - int repetitions; bool chatEnabled; readonly bool isMenuChat; @@ -211,8 +209,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic chatScrollPanel.RemoveChildren(); chatScrollPanel.ScrollToBottom(); - foreach (var chatLine in orderManager.NotificationsCache) - AddChatLine(chatLine, true); + foreach (var notification in orderManager.NotificationsCache) + if (IsNotificationEligible(notification)) + AddNotification(notification, true); orderManager.AddTextNotification += AddNotificationWrapper; @@ -261,36 +260,19 @@ namespace OpenRA.Mods.Common.Widgets.Logic Ui.ResetTooltips(); } - public void AddNotificationWrapper(TextNotification chatLine) + public void AddNotificationWrapper(TextNotification notification) { - var chatLineToDisplay = chatLine; + if (!IsNotificationEligible(notification)) + return; - if (chatLine.CanIncrementOnDuplicate() && chatLine.Equals(lastLine)) - { - repetitions++; - chatLineToDisplay = new TextNotification( - chatLine.Pool, - chatLine.Prefix, - $"{chatLine.Text} ({repetitions + 1})", - chatLine.PrefixColor, - chatLine.TextColor); - - chatScrollPanel.RemoveChild(chatScrollPanel.Children[chatScrollPanel.Children.Count - 1]); - chatOverlayDisplay?.RemoveMostRecentNotification(); - } - else - repetitions = 0; - - lastLine = chatLine; - - chatOverlayDisplay?.AddNotification(chatLineToDisplay); + chatOverlayDisplay?.AddNotification(notification); // HACK: Force disable the chat notification sound for the in-menu chat dialog // This works around our inability to disable the sounds for the in-game dialog when it is hidden - AddChatLine(chatLineToDisplay, chatOverlay == null); + AddNotification(notification, chatOverlay == null); } - void AddChatLine(TextNotification notification, bool suppressSound) + void AddNotification(TextNotification notification, bool suppressSound) { var chatLine = templates[notification.Pool].Clone(); WidgetUtils.SetupTextNotification(chatLine, notification, chatScrollPanel.Bounds.Width - chatScrollPanel.ScrollbarWidth, isMenuChat && !world.IsReplay); @@ -325,6 +307,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic } } + static bool IsNotificationEligible(TextNotification notification) + { + return notification.Pool == TextNotificationPool.Chat || + notification.Pool == TextNotificationPool.System || + notification.Pool == TextNotificationPool.Mission; + } + bool disposed = false; protected override void Dispose(bool disposing) { diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameTransientNotificationsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameTransientNotificationsLogic.cs new file mode 100644 index 0000000000..ab89de9895 --- /dev/null +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameTransientNotificationsLogic.cs @@ -0,0 +1,98 @@ +#region Copyright & License Information +/* + * Copyright 2007-2021 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System.Collections.Generic; +using OpenRA.Network; +using OpenRA.Widgets; + +namespace OpenRA.Mods.Common.Widgets.Logic +{ + public class IngameTransientNotificationsLogic : ChromeLogic + { + readonly OrderManager orderManager; + readonly Ruleset modRules; + + readonly TextNotificationsDisplayWidget displayWidget; + + readonly string transientLineSound; + + TextNotification lastLine; + int repetitions; + + [ObjectCreator.UseCtor] + public IngameTransientNotificationsLogic(Widget widget, OrderManager orderManager, ModData modData, Dictionary logicArgs) + { + this.orderManager = orderManager; + modRules = modData.DefaultRules; + + displayWidget = widget.Get("TRANSIENTS_DISPLAY"); + + orderManager.AddTextNotification += AddNotificationWrapper; + + if (logicArgs.TryGetValue("TransientLineSound", out var yaml)) + transientLineSound = yaml.Value; + else + ChromeMetrics.TryGet("TransientLineSound", out transientLineSound); + } + + public void AddNotificationWrapper(TextNotification notification) + { + if (!IsNotificationEligible(notification)) + return; + + var lineToDisplay = notification; + + if (displayWidget.Children.Count > 0 && notification.CanIncrementOnDuplicate() && notification == lastLine) + { + repetitions++; + lineToDisplay = new TextNotification( + notification.Pool, + notification.Prefix, + $"{notification.Text} ({repetitions + 1})", + notification.PrefixColor, + notification.TextColor); + + displayWidget.RemoveMostRecentNotification(); + } + else + repetitions = 0; + + lastLine = notification; + + AddNotification(lineToDisplay); + } + + void AddNotification(TextNotification notification, bool suppressSound = false) + { + displayWidget.AddNotification(notification); + + if (!suppressSound && !string.IsNullOrEmpty(transientLineSound)) + Game.Sound.PlayNotification(modRules, null, "Sounds", transientLineSound, null); + } + + static bool IsNotificationEligible(TextNotification notification) + { + return notification.Pool == TextNotificationPool.Feedback; + } + + bool disposed = false; + protected override void Dispose(bool disposing) + { + if (!disposed) + { + orderManager.AddTextNotification -= AddNotificationWrapper; + disposed = true; + } + + base.Dispose(disposing); + } + } +} diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/LoadIngamePlayerOrObserverUILogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/LoadIngamePlayerOrObserverUILogic.cs index f8a638ae56..1b510dd521 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/LoadIngamePlayerOrObserverUILogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/LoadIngamePlayerOrObserverUILogic.cs @@ -54,6 +54,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic } Game.LoadWidget(world, "DEBUG_WIDGETS", worldRoot, new WidgetArgs()); + Game.LoadWidget(world, "TRANSIENTS_PANEL", worldRoot, new WidgetArgs()); world.GameOver += () => { diff --git a/OpenRA.Mods.Common/Widgets/TextNotificationsDisplayWidget.cs b/OpenRA.Mods.Common/Widgets/TextNotificationsDisplayWidget.cs index 1fbe0401bc..10424d1dd5 100644 --- a/OpenRA.Mods.Common/Widgets/TextNotificationsDisplayWidget.cs +++ b/OpenRA.Mods.Common/Widgets/TextNotificationsDisplayWidget.cs @@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Widgets public string ChatTemplate = "CHAT_LINE_TEMPLATE"; public string SystemTemplate = "SYSTEM_LINE_TEMPLATE"; public string MissionTemplate = "SYSTEM_LINE_TEMPLATE"; - public string FeedbackTemplate = "SYSTEM_LINE_TEMPLATE"; + public string FeedbackTemplate = "TRANSIENT_LINE_TEMPLATE"; readonly Dictionary templates = new Dictionary(); readonly List expirations = new List(); diff --git a/mods/cnc/chrome/ingame-chat.yaml b/mods/cnc/chrome/ingame-chat.yaml index f3fedbd320..462a26fe03 100644 --- a/mods/cnc/chrome/ingame-chat.yaml +++ b/mods/cnc/chrome/ingame-chat.yaml @@ -10,7 +10,6 @@ Container@CHAT_PANEL: Chat: CHAT_LINE_TEMPLATE System: SYSTEM_LINE_TEMPLATE Mission: SYSTEM_LINE_TEMPLATE - Feedback: SYSTEM_LINE_TEMPLATE Children: Container@CHAT_OVERLAY: Width: PARENT_RIGHT - 24 diff --git a/mods/cnc/chrome/ingame-infochat.yaml b/mods/cnc/chrome/ingame-infochat.yaml index db99fe9dfd..ae15662794 100644 --- a/mods/cnc/chrome/ingame-infochat.yaml +++ b/mods/cnc/chrome/ingame-infochat.yaml @@ -7,7 +7,6 @@ Container@CHAT_CONTAINER: Chat: CHAT_LINE_TEMPLATE System: SYSTEM_LINE_TEMPLATE Mission: SYSTEM_LINE_TEMPLATE - Feedback: SYSTEM_LINE_TEMPLATE Children: Container@CHAT_CHROME: X: 15 diff --git a/mods/cnc/chrome/ingame.yaml b/mods/cnc/chrome/ingame.yaml index 6c5e95276b..17cddf2034 100644 --- a/mods/cnc/chrome/ingame.yaml +++ b/mods/cnc/chrome/ingame.yaml @@ -59,7 +59,7 @@ Container@PERF_WIDGETS: Background@GRAPH_BG: Logic: AddFactionSuffixLogic X: 5 - Y: WINDOW_BOTTOM - HEIGHT - 56 + Y: WINDOW_BOTTOM - HEIGHT - 156 Width: 220 Height: 220 Background: panel-black diff --git a/mods/cnc/chrome/lobby.yaml b/mods/cnc/chrome/lobby.yaml index 5e77cff98e..ab45ed6231 100644 --- a/mods/cnc/chrome/lobby.yaml +++ b/mods/cnc/chrome/lobby.yaml @@ -4,7 +4,7 @@ Container@SERVER_LOBBY: Chat: CHAT_LINE_TEMPLATE System: SYSTEM_LINE_TEMPLATE Mission: SYSTEM_LINE_TEMPLATE - Feedback: SYSTEM_LINE_TEMPLATE + Feedback: TRANSIENT_LINE_TEMPLATE X: (WINDOW_RIGHT - WIDTH) / 2 Y: (WINDOW_BOTTOM - 560) / 2 Width: 900 diff --git a/mods/cnc/chrome/settings-display.yaml b/mods/cnc/chrome/settings-display.yaml index 1d39d97c1c..a1f4a37515 100644 --- a/mods/cnc/chrome/settings-display.yaml +++ b/mods/cnc/chrome/settings-display.yaml @@ -115,7 +115,7 @@ Container@DISPLAY_PANEL: Width: 200 Height: 20 Font: Regular - Text: UI Feedback in Chat + Text: UI Feedback in Transients Panel Label@VIDEO_TITLE: Y: 190 Width: PARENT_RIGHT diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index 5862f5abf1..d3e23131e4 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -115,6 +115,7 @@ ChromeLayout: cnc|chrome/gamesave-loading.yaml cnc|chrome/ingame.yaml cnc|chrome/ingame-chat.yaml + common|chrome/ingame-transients.yaml cnc|chrome/ingame-menu.yaml cnc|chrome/ingame-debug.yaml cnc|chrome/ingame-infochat.yaml diff --git a/mods/common/chrome/ingame-chat.yaml b/mods/common/chrome/ingame-chat.yaml index 580df8c82e..0d75ea6ad2 100644 --- a/mods/common/chrome/ingame-chat.yaml +++ b/mods/common/chrome/ingame-chat.yaml @@ -10,7 +10,6 @@ Container@CHAT_PANEL: Chat: CHAT_LINE_TEMPLATE System: SYSTEM_LINE_TEMPLATE Mission: SYSTEM_LINE_TEMPLATE - Feedback: SYSTEM_LINE_TEMPLATE Children: Container@CHAT_OVERLAY: Width: PARENT_RIGHT - 24 diff --git a/mods/common/chrome/ingame-infochat.yaml b/mods/common/chrome/ingame-infochat.yaml index 65164131f6..88906eb142 100644 --- a/mods/common/chrome/ingame-infochat.yaml +++ b/mods/common/chrome/ingame-infochat.yaml @@ -7,7 +7,6 @@ Container@CHAT_CONTAINER: Chat: CHAT_LINE_TEMPLATE System: SYSTEM_LINE_TEMPLATE Mission: SYSTEM_LINE_TEMPLATE - Feedback: SYSTEM_LINE_TEMPLATE Children: Container@CHAT_CHROME: X: 20 diff --git a/mods/common/chrome/ingame-perf.yaml b/mods/common/chrome/ingame-perf.yaml index e179d3a8c0..7551230433 100644 --- a/mods/common/chrome/ingame-perf.yaml +++ b/mods/common/chrome/ingame-perf.yaml @@ -11,7 +11,7 @@ Container@PERF_WIDGETS: ClickThrough: true Background: dialog4 X: 10 - Y: WINDOW_BOTTOM - 265 + Y: WINDOW_BOTTOM - HEIGHT - 156 Width: 210 Height: 210 Children: diff --git a/mods/common/chrome/ingame-transients.yaml b/mods/common/chrome/ingame-transients.yaml new file mode 100644 index 0000000000..b6f3313ae4 --- /dev/null +++ b/mods/common/chrome/ingame-transients.yaml @@ -0,0 +1,13 @@ +Container@TRANSIENTS_PANEL: + X: 5 + Y: WINDOW_BOTTOM - HEIGHT - 55 + Width: 550 + Height: 80 + Logic: IngameTransientNotificationsLogic + Children: + TextNotificationsDisplay@TRANSIENTS_DISPLAY: + Width: PARENT_RIGHT + Height: PARENT_BOTTOM + RemoveTime: 100 + LogLength: 5 + HideOverflow: False diff --git a/mods/common/chrome/lobby.yaml b/mods/common/chrome/lobby.yaml index b0ea150e3a..5f967474d9 100644 --- a/mods/common/chrome/lobby.yaml +++ b/mods/common/chrome/lobby.yaml @@ -4,7 +4,7 @@ Background@SERVER_LOBBY: Chat: CHAT_LINE_TEMPLATE System: SYSTEM_LINE_TEMPLATE Mission: SYSTEM_LINE_TEMPLATE - Feedback: SYSTEM_LINE_TEMPLATE + Feedback: TRANSIENT_LINE_TEMPLATE X: (WINDOW_RIGHT - WIDTH) / 2 Y: (WINDOW_BOTTOM - HEIGHT) / 2 Width: 900 diff --git a/mods/common/chrome/settings-display.yaml b/mods/common/chrome/settings-display.yaml index 400ca7138f..8f44ef10bb 100644 --- a/mods/common/chrome/settings-display.yaml +++ b/mods/common/chrome/settings-display.yaml @@ -116,7 +116,7 @@ Container@DISPLAY_PANEL: Width: 200 Height: 20 Font: Regular - Text: UI Feedback in Chat + Text: UI Feedback in Transients Panel Label@VIDEO_TITLE: Y: 190 Width: PARENT_RIGHT diff --git a/mods/common/chrome/text-notifications.yaml b/mods/common/chrome/text-notifications.yaml index 3ed93a09d5..b1a77599ba 100644 --- a/mods/common/chrome/text-notifications.yaml +++ b/mods/common/chrome/text-notifications.yaml @@ -37,3 +37,19 @@ Container@SYSTEM_LINE_TEMPLATE: WordWrap: True Shadow: True TextColor: FFFF00 + +Container@TRANSIENT_LINE_TEMPLATE: + Width: PARENT_RIGHT + Height: 16 + Children: + Label@TIME: + X: 5 + Width: 37 + Height: 16 + Shadow: True + Label@TEXT: + X: 5 + Height: 16 + WordWrap: True + Shadow: True + TextColor: AFEEEE diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index b622702915..212c7fc71d 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -69,6 +69,7 @@ Assemblies: ChromeLayout: common|chrome/ingame.yaml common|chrome/ingame-chat.yaml + common|chrome/ingame-transients.yaml common|chrome/ingame-fmvplayer.yaml d2k|chrome/ingame-menu.yaml common|chrome/ingame-info.yaml diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index 1de50d6c49..13b2a94869 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -86,6 +86,7 @@ Assemblies: ChromeLayout: common|chrome/ingame.yaml common|chrome/ingame-chat.yaml + common|chrome/ingame-transients.yaml common|chrome/ingame-fmvplayer.yaml common|chrome/ingame-info.yaml common|chrome/ingame-infoscripterror.yaml diff --git a/mods/ts/mod.yaml b/mods/ts/mod.yaml index 716621a199..94db110b96 100644 --- a/mods/ts/mod.yaml +++ b/mods/ts/mod.yaml @@ -131,6 +131,7 @@ Assemblies: ChromeLayout: common|chrome/ingame.yaml common|chrome/ingame-chat.yaml + common|chrome/ingame-transients.yaml common|chrome/ingame-fmvplayer.yaml common|chrome/ingame-menu.yaml common|chrome/ingame-info.yaml