示例#1
0
        public static void SetupChatLine(ContainerWidget template, DateTime time, string name, Color nameColor, string text, Color textColor)
        {
            var nameLabel = template.Get <LabelWidget>("NAME");
            var timeLabel = template.Get <LabelWidget>("TIME");
            var textLabel = template.Get <LabelWidget>("TEXT");

            var nameText = name + ":";
            var font     = Game.Renderer.Fonts[nameLabel.Font];
            var nameSize = font.Measure(nameText);

            timeLabel.GetText = () => "{0:D2}:{1:D2}".F(time.Hour, time.Minute);

            nameLabel.GetColor     = () => nameColor;
            nameLabel.GetText      = () => nameText;
            nameLabel.Bounds.Width = nameSize.X;

            textLabel.GetColor      = () => textColor;
            textLabel.Bounds.X     += nameSize.X;
            textLabel.Bounds.Width -= nameSize.X;

            // Hack around our hacky wordwrap behavior: need to resize the widget to fit the text
            text = WidgetUtils.WrapText(text, textLabel.Bounds.Width, font);
            textLabel.GetText = () => text;
            var dh = font.Measure(text).Y - textLabel.Bounds.Height;

            if (dh > 0)
            {
                textLabel.Bounds.Height += dh;
                template.Bounds.Height  += dh;
            }
        }
示例#2
0
        public static void SetupChatLine(ContainerWidget template, DateTime time, TextNotification chatLine)
        {
            var nameLabel = template.Get <LabelWidget>("NAME");
            var timeLabel = template.Get <LabelWidget>("TIME");
            var textLabel = template.Get <LabelWidget>("TEXT");

            var nameText = chatLine.Prefix + ":";
            var font     = Game.Renderer.Fonts[nameLabel.Font];
            var nameSize = font.Measure(nameText);

            timeLabel.GetText = () => $"{time.Hour:D2}:{time.Minute:D2}";

            nameLabel.GetColor     = () => chatLine.PrefixColor;
            nameLabel.GetText      = () => nameText;
            nameLabel.Bounds.Width = nameSize.X;

            textLabel.GetColor      = () => chatLine.TextColor;
            textLabel.Bounds.X     += nameSize.X;
            textLabel.Bounds.Width -= nameSize.X;

            // Hack around our hacky wordwrap behavior: need to resize the widget to fit the text
            var text = WidgetUtils.WrapText(chatLine.Text, textLabel.Bounds.Width, font);

            textLabel.GetText = () => text;
            var dh = font.Measure(text).Y - textLabel.Bounds.Height;

            if (dh > 0)
            {
                textLabel.Bounds.Height += dh;
                template.Bounds.Height  += dh;
            }
        }
示例#3
0
        public IngameChatLogic(Widget widget, OrderManager orderManager, World world)
        {
            World = world;
            var chatPanel = (ContainerWidget) widget;

            ChatOverlay = chatPanel.Get<ContainerWidget>("CHAT_OVERLAY");
            ChatOverlayDisplay = ChatOverlay.Get<ChatDisplayWidget>("CHAT_DISPLAY");
            ChatOverlay.Visible = false;

            ChatChrome = chatPanel.Get<ContainerWidget>("CHAT_CHROME");
            ChatChrome.Visible = true;

            var chatMode = ChatChrome.Get<ButtonWidget>("CHAT_MODE");
            chatMode.GetText = () => TeamChat ? "Team" : "All";
            chatMode.OnClick = () => TeamChat = !TeamChat;

            ChatText = ChatChrome.Get<TextFieldWidget>("CHAT_TEXTFIELD");
            ChatText.OnTabKey = () => { TeamChat = !TeamChat; return true; };
            ChatText.OnEnterKey = () =>
            {
                ChatText.Text = ChatText.Text.Trim();
                if (ChatText.Text != "")
                    orderManager.IssueOrder(Order.Chat(TeamChat, ChatText.Text));
                CloseChat();
                return true;
            };
            ChatText.OnEscKey = () => {CloseChat(); return true; };

            var chatClose = ChatChrome.Get<ButtonWidget>("CHAT_CLOSE");
            chatClose.OnClick += () => CloseChat();

            chatPanel.OnKeyPress = (e) =>
            {
                if (e.Event == KeyInputEvent.Up) return false;
                if (!IsOpen && (e.KeyName == "enter" || e.KeyName == "return") )
                {

                    var shift = e.Modifiers.HasModifier(Modifiers.Shift);
                    var toggle = Game.Settings.Game.TeamChatToggle ;
                    TeamChat = (!toggle && shift) || ( toggle &&  (TeamChat ^ shift) );
                    OpenChat();
                    return true;
                }

                return false;
            };

            ChatScrollPanel = ChatChrome.Get<ScrollPanelWidget>("CHAT_SCROLLPANEL");
            ChatTemplate = ChatScrollPanel.Get<ContainerWidget>("CHAT_TEMPLATE");

            Game.AddChatLine += AddChatLine;
            Game.BeforeGameStart += UnregisterEvents;

            CloseChat();
            ChatOverlayDisplay.AddLine(Color.White, null, "Use RETURN key to open chat window...");
        }
        public GlobalChatLogic(Widget widget)
        {
            historyPanel     = widget.Get <ScrollPanelWidget>("HISTORY_PANEL");
            chatTemplate     = historyPanel.Get <ContainerWidget>("CHAT_TEMPLATE");
            nicknamePanel    = widget.Get <ScrollPanelWidget>("NICKNAME_PANEL");
            nicknameTemplate = nicknamePanel.Get("NICKNAME_TEMPLATE");

            var textColor = ChromeMetrics.Get <Color>("GlobalChatTextColor");
            var textLabel = chatTemplate.Get <LabelWidget>("TEXT");

            textLabel.GetColor = () => textColor;

            historyPanel.Bind(Game.GlobalChat.History, MakeHistoryWidget, HistoryWidgetEquals, true);
            nicknamePanel.Bind(Game.GlobalChat.Users, MakeUserWidget, UserWidgetEquals, false);

            inputBox            = widget.Get <TextFieldWidget>("CHAT_TEXTFIELD");
            inputBox.IsDisabled = () => Game.GlobalChat.ConnectionStatus != ChatConnectionStatus.Joined;
            inputBox.OnEnterKey = EnterPressed;

            // IRC protocol limits messages to 510 characters + CRLF
            inputBox.MaxLength = 510;

            var nickName    = Game.GlobalChat.SanitizedName(Game.Settings.Player.Name);
            var nicknameBox = widget.Get <TextFieldWidget>("NICKNAME_TEXTFIELD");

            nicknameBox.Text         = nickName;
            nicknameBox.OnTextEdited = () =>
            {
                nicknameBox.Text = Game.GlobalChat.SanitizedName(nicknameBox.Text);
            };

            var connectPanel = widget.Get("GLOBALCHAT_CONNECT_PANEL");

            connectPanel.IsVisible = () => Game.GlobalChat.ConnectionStatus == ChatConnectionStatus.Disconnected;

            var disconnectButton = widget.Get <ButtonWidget>("DISCONNECT_BUTTON");

            disconnectButton.OnClick = Game.GlobalChat.Disconnect;

            var connectAutomaticallyCheckBox = connectPanel.Get <CheckboxWidget>("CONNECT_AUTOMATICALLY_CHECKBOX");

            connectAutomaticallyCheckBox.IsChecked = () => Game.Settings.Chat.ConnectAutomatically;
            connectAutomaticallyCheckBox.OnClick   = () => { Game.Settings.Chat.ConnectAutomatically ^= true; Game.Settings.Save(); };

            var connectButton = connectPanel.Get <ButtonWidget>("CONNECT_BUTTON");

            connectButton.IsDisabled = () => !Game.GlobalChat.IsValidNickname(nicknameBox.Text);
            connectButton.OnClick    = () => Game.GlobalChat.Connect(nicknameBox.Text);

            var mainPanel = widget.Get("GLOBALCHAT_MAIN_PANEL");

            mainPanel.IsVisible = () => Game.GlobalChat.ConnectionStatus != ChatConnectionStatus.Disconnected;

            mainPanel.Get <LabelWidget>("CHANNEL_TOPIC").GetText = () => Game.GlobalChat.Topic;

            if (Game.Settings.Chat.ConnectAutomatically)
            {
                Game.GlobalChat.Connect(nickName);
            }
        }
示例#5
0
        public IngameChatLogic(Widget widget, OrderManager orderManager, World world, Ruleset modRules)
        {
            this.modRules = modRules;

            chatTraits = world.WorldActor.TraitsImplementing<INotifyChat>().ToList();

            var players = world.Players.Where(p => p != world.LocalPlayer && !p.NonCombatant && !p.IsBot);
            var disableTeamChat = world.LocalPlayer == null || world.LobbyInfo.IsSinglePlayer || !players.Any(p => p.IsAlliedWith(world.LocalPlayer));
            teamChat = !disableTeamChat;

            var chatPanel = (ContainerWidget)widget;
            chatOverlay = chatPanel.Get<ContainerWidget>("CHAT_OVERLAY");
            chatOverlayDisplay = chatOverlay.Get<ChatDisplayWidget>("CHAT_DISPLAY");
            chatOverlay.Visible = false;

            chatChrome = chatPanel.Get<ContainerWidget>("CHAT_CHROME");
            chatChrome.Visible = true;

            var chatMode = chatChrome.Get<ButtonWidget>("CHAT_MODE");
            chatMode.GetText = () => teamChat ? "Team" : "All";
            chatMode.OnClick = () => teamChat ^= true;
            chatMode.IsDisabled = () => disableTeamChat;

            chatText = chatChrome.Get<TextFieldWidget>("CHAT_TEXTFIELD");
            chatText.OnTabKey = () =>
            {
                if (!disableTeamChat)
                    teamChat ^= true;
                return true;
            };
            chatText.OnEnterKey = () =>
            {
                var team = teamChat && !disableTeamChat;
                if (chatText.Text != "")
                    orderManager.IssueOrder(Order.Chat(team, chatText.Text.Trim()));

                CloseChat();
                return true;
            };

            chatText.OnEscKey = () => { CloseChat(); return true; };

            var chatClose = chatChrome.Get<ButtonWidget>("CHAT_CLOSE");
            chatClose.OnClick += () => CloseChat();

            chatPanel.OnKeyPress = (e) =>
            {
                if (e.Event == KeyInputEvent.Up)
                    return false;

                if (!chatChrome.IsVisible() && (e.Key == Keycode.RETURN || e.Key == Keycode.KP_ENTER))
                {
                    OpenChat();
                    return true;
                }

                return false;
            };

            chatScrollPanel = chatChrome.Get<ScrollPanelWidget>("CHAT_SCROLLPANEL");
            chatTemplate = chatScrollPanel.Get<ContainerWidget>("CHAT_TEMPLATE");
            chatScrollPanel.RemoveChildren();

            Game.AddChatLine += AddChatLine;
            Game.BeforeGameStart += UnregisterEvents;

            CloseChat();
        }
示例#6
0
        public IngameChatLogic(Widget widget, OrderManager orderManager, World world, Ruleset modRules)
        {
            this.modRules = modRules;

            chatTraits = world.WorldActor.TraitsImplementing <INotifyChat>().ToList();

            var players         = world.Players.Where(p => p != world.LocalPlayer && !p.NonCombatant && !p.IsBot);
            var disableTeamChat = world.LocalPlayer == null || world.LobbyInfo.IsSinglePlayer || !players.Any(p => p.IsAlliedWith(world.LocalPlayer));

            teamChat = !disableTeamChat;

            var chatPanel = (ContainerWidget)widget;

            chatOverlay         = chatPanel.Get <ContainerWidget>("CHAT_OVERLAY");
            chatOverlayDisplay  = chatOverlay.Get <ChatDisplayWidget>("CHAT_DISPLAY");
            chatOverlay.Visible = false;

            chatChrome         = chatPanel.Get <ContainerWidget>("CHAT_CHROME");
            chatChrome.Visible = true;

            var chatMode = chatChrome.Get <ButtonWidget>("CHAT_MODE");

            chatMode.GetText    = () => teamChat ? "Team" : "All";
            chatMode.OnClick    = () => teamChat ^= true;
            chatMode.IsDisabled = () => disableTeamChat;

            chatText          = chatChrome.Get <TextFieldWidget>("CHAT_TEXTFIELD");
            chatText.OnTabKey = () =>
            {
                if (!disableTeamChat)
                {
                    teamChat ^= true;
                }
                return(true);
            };
            chatText.OnEnterKey = () =>
            {
                var team = teamChat && !disableTeamChat;
                if (chatText.Text != "")
                {
                    orderManager.IssueOrder(Order.Chat(team, chatText.Text.Trim()));
                }

                CloseChat();
                return(true);
            };

            chatText.OnEscKey = () => { CloseChat(); return(true); };

            var chatClose = chatChrome.Get <ButtonWidget>("CHAT_CLOSE");

            chatClose.OnClick += () => CloseChat();

            chatPanel.OnKeyPress = (e) =>
            {
                if (e.Event == KeyInputEvent.Up)
                {
                    return(false);
                }

                if (!chatChrome.IsVisible() && (e.Key == Keycode.RETURN || e.Key == Keycode.KP_ENTER))
                {
                    OpenChat();
                    return(true);
                }

                return(false);
            };

            chatScrollPanel = chatChrome.Get <ScrollPanelWidget>("CHAT_SCROLLPANEL");
            chatTemplate    = chatScrollPanel.Get <ContainerWidget>("CHAT_TEMPLATE");
            chatScrollPanel.RemoveChildren();

            Game.AddChatLine     += AddChatLine;
            Game.BeforeGameStart += UnregisterEvents;

            CloseChat();
        }
示例#7
0
        public IngameChatLogic(Widget widget, OrderManager orderManager, World world)
        {
            World = world;
            var chatPanel = (ContainerWidget)widget;


            ChatOverlay         = chatPanel.Get <ContainerWidget>("CHAT_OVERLAY");
            ChatOverlayDisplay  = ChatOverlay.Get <ChatDisplayWidget>("CHAT_DISPLAY");
            ChatOverlay.Visible = false;

            ChatChrome         = chatPanel.Get <ContainerWidget>("CHAT_CHROME");
            ChatChrome.Visible = true;

            var chatMode = ChatChrome.Get <ButtonWidget>("CHAT_MODE");

            chatMode.GetText = () => TeamChat ? "Team" : "All";
            chatMode.OnClick = () => TeamChat = !TeamChat;

            ChatText            = ChatChrome.Get <TextFieldWidget>("CHAT_TEXTFIELD");
            ChatText.OnTabKey   = () => { TeamChat = !TeamChat; return(true); };
            ChatText.OnEnterKey = () =>
            {
                ChatText.Text = ChatText.Text.Trim();
                if (ChatText.Text != "")
                {
                    orderManager.IssueOrder(Order.Chat(TeamChat, ChatText.Text));
                }
                CloseChat();
                return(true);
            };
            ChatText.OnEscKey = () => { CloseChat(); return(true); };

            var chatClose = ChatChrome.Get <ButtonWidget>("CHAT_CLOSE");

            chatClose.OnClick += () => CloseChat();

            chatPanel.OnKeyPress = (e) =>
            {
                if (e.Event == KeyInputEvent.Up)
                {
                    return(false);
                }
                if (!IsOpen && (e.KeyName == "enter" || e.KeyName == "return"))
                {
                    var shift  = e.Modifiers.HasModifier(Modifiers.Shift);
                    var toggle = Game.Settings.Game.TeamChatToggle;
                    TeamChat = (!toggle && shift) || (toggle && (TeamChat ^ shift));
                    OpenChat();
                    return(true);
                }

                return(false);
            };

            ChatScrollPanel = ChatChrome.Get <ScrollPanelWidget>("CHAT_SCROLLPANEL");
            ChatTemplate    = ChatScrollPanel.Get <ContainerWidget>("CHAT_TEMPLATE");

            Game.AddChatLine     += AddChatLine;
            Game.BeforeGameStart += UnregisterEvents;

            CloseChat();
            ChatOverlayDisplay.AddLine(Color.White, null, "Use RETURN key to open chat window...");
        }
示例#8
0
		public IngameChatLogic(Widget widget, OrderManager orderManager, World world, ModData modData)
		{
			this.orderManager = orderManager;
			this.modRules = modData.DefaultRules;

			chatTraits = world.WorldActor.TraitsImplementing<INotifyChat>().ToArray();

			var players = world.Players.Where(p => p != world.LocalPlayer && !p.NonCombatant && !p.IsBot);
			disableTeamChat = world.IsReplay || world.LobbyInfo.IsSinglePlayer || (world.LocalPlayer != null && !players.Any(p => p.IsAlliedWith(world.LocalPlayer)));
			teamChat = !disableTeamChat;

			tabCompletion.Commands = chatTraits.OfType<ChatCommands>().SelectMany(x => x.Commands.Keys).ToList();
			tabCompletion.Names = orderManager.LobbyInfo.Clients.Select(c => c.Name).Distinct().ToList();

			var chatPanel = (ContainerWidget)widget;
			chatOverlay = chatPanel.Get<ContainerWidget>("CHAT_OVERLAY");
			chatOverlayDisplay = chatOverlay.Get<ChatDisplayWidget>("CHAT_DISPLAY");
			chatOverlay.Visible = false;

			chatChrome = chatPanel.Get<ContainerWidget>("CHAT_CHROME");
			chatChrome.Visible = true;

			var chatMode = chatChrome.Get<ButtonWidget>("CHAT_MODE");
			chatMode.GetText = () => teamChat ? "Team" : "All";
			chatMode.OnClick = () => teamChat ^= true;
			chatMode.IsDisabled = () => disableTeamChat;

			chatText = chatChrome.Get<TextFieldWidget>("CHAT_TEXTFIELD");
			chatText.OnEnterKey = () =>
			{
				var team = teamChat && !disableTeamChat;
				if (chatText.Text != "")
				{
					if (!chatText.Text.StartsWith("/"))
						orderManager.IssueOrder(Order.Chat(team, chatText.Text.Trim()));
					else if (chatTraits != null)
					{
						var text = chatText.Text.Trim();
						foreach (var trait in chatTraits)
							trait.OnChat(orderManager.LocalClient.Name, text);
					}
				}

				chatText.Text = "";
				CloseChat();
				return true;
			};

			chatText.OnTabKey = () =>
			{
				var previousText = chatText.Text;
				chatText.Text = tabCompletion.Complete(chatText.Text);
				chatText.CursorPosition = chatText.Text.Length;

				if (chatText.Text == previousText)
					return SwitchTeamChat();
				else
					return true;
			};

			chatText.OnEscKey = () => { CloseChat(); return true; };

			var chatClose = chatChrome.Get<ButtonWidget>("CHAT_CLOSE");
			chatClose.OnClick += CloseChat;

			chatPanel.OnKeyPress = e =>
			{
				if (e.Event == KeyInputEvent.Up)
					return false;

				if (!chatChrome.IsVisible() && (e.Key == Keycode.RETURN || e.Key == Keycode.KP_ENTER))
				{
					OpenChat();
					return true;
				}

				return false;
			};

			chatScrollPanel = chatChrome.Get<ScrollPanelWidget>("CHAT_SCROLLPANEL");
			chatTemplate = chatScrollPanel.Get<ContainerWidget>("CHAT_TEMPLATE");
			chatScrollPanel.RemoveChildren();
			chatScrollPanel.ScrollToBottom();

			foreach (var chatLine in orderManager.ChatCache)
				AddChatLine(chatLine.Color, chatLine.Name, chatLine.Text, true);

			orderManager.AddChatLine += AddChatLineWrapper;
			Game.BeforeGameStart += UnregisterEvents;

			CloseChat();
		}
示例#9
0
        public IngameChatLogic(Widget widget, OrderManager orderManager, World world, ModData modData)
        {
            this.orderManager = orderManager;
            this.modRules = modData.DefaultRules;

            chatTraits = world.WorldActor.TraitsImplementing<INotifyChat>().ToArray();

            var players = world.Players.Where(p => p != world.LocalPlayer && !p.NonCombatant && !p.IsBot);
            disableTeamChat = world.IsReplay || world.LobbyInfo.IsSinglePlayer || (world.LocalPlayer != null && !players.Any(p => p.IsAlliedWith(world.LocalPlayer)));
            teamChat = !disableTeamChat;

            tabCompletion.Commands = chatTraits.OfType<ChatCommands>().SelectMany(x => x.Commands.Keys).ToList();
            tabCompletion.Names = orderManager.LobbyInfo.Clients.Select(c => c.Name).Distinct().ToList();

            var chatPanel = (ContainerWidget)widget;
            chatOverlay = chatPanel.Get<ContainerWidget>("CHAT_OVERLAY");
            chatOverlayDisplay = chatOverlay.Get<ChatDisplayWidget>("CHAT_DISPLAY");
            chatOverlay.Visible = false;

            chatChrome = chatPanel.Get<ContainerWidget>("CHAT_CHROME");
            chatChrome.Visible = true;

            var chatMode = chatChrome.Get<ButtonWidget>("CHAT_MODE");
            chatMode.GetText = () => teamChat ? "Team" : "All";
            chatMode.OnClick = () => teamChat ^= true;
            chatMode.IsDisabled = () => disableTeamChat;

            chatText = chatChrome.Get<TextFieldWidget>("CHAT_TEXTFIELD");
            chatText.OnEnterKey = () =>
            {
                var team = teamChat && !disableTeamChat;
                if (chatText.Text != "")
                {
                    if (!chatText.Text.StartsWith("/"))
                        orderManager.IssueOrder(Order.Chat(team, chatText.Text.Trim()));
                    else if (chatTraits != null)
                    {
                        var text = chatText.Text.Trim();
                        foreach (var trait in chatTraits)
                            trait.OnChat(orderManager.LocalClient.Name, text);
                    }
                }

                chatText.Text = "";
                CloseChat();
                return true;
            };

            chatText.OnTabKey = () =>
            {
                var previousText = chatText.Text;
                chatText.Text = tabCompletion.Complete(chatText.Text);
                chatText.CursorPosition = chatText.Text.Length;

                if (chatText.Text == previousText)
                    return SwitchTeamChat();
                else
                    return true;
            };

            chatText.OnEscKey = () => { CloseChat(); return true; };

            var chatClose = chatChrome.Get<ButtonWidget>("CHAT_CLOSE");
            chatClose.OnClick += CloseChat;

            chatPanel.OnKeyPress = e =>
            {
                if (e.Event == KeyInputEvent.Up)
                    return false;

                if (!chatChrome.IsVisible() && (e.Key == Keycode.RETURN || e.Key == Keycode.KP_ENTER))
                {
                    OpenChat();
                    return true;
                }

                return false;
            };

            chatScrollPanel = chatChrome.Get<ScrollPanelWidget>("CHAT_SCROLLPANEL");
            chatTemplate = chatScrollPanel.Get<ContainerWidget>("CHAT_TEMPLATE");
            chatScrollPanel.RemoveChildren();
            chatScrollPanel.ScrollToBottom();

            foreach (var chatLine in orderManager.ChatCache)
                AddChatLine(chatLine.Color, chatLine.Name, chatLine.Text, true);

            orderManager.AddChatLine += AddChatLineWrapper;
            Game.BeforeGameStart += UnregisterEvents;

            CloseChat();
            chatText.IsDisabled = () => world.IsReplay;

            var keyListener = chatChrome.Get<LogicKeyListenerWidget>("KEY_LISTENER");
            keyListener.OnKeyPress = e =>
            {
                if (e.Event == KeyInputEvent.Up || !chatText.IsDisabled())
                    return false;

                if ((e.Key == Keycode.RETURN || e.Key == Keycode.KP_ENTER || e.Key == Keycode.ESCAPE) && e.Modifiers == Modifiers.None)
                {
                    CloseChat();
                    return true;
                }

                return false;
            };
        }
示例#10
0
        public IngameChatLogic(Widget widget, OrderManager orderManager, World world, ModData modData, bool isMenuChat, Dictionary <string, MiniYaml> logicArgs)
        {
            this.orderManager = orderManager;
            modRules          = modData.DefaultRules;
            this.isMenuChat   = isMenuChat;
            this.world        = world;

            var chatTraits      = world.WorldActor.TraitsImplementing <INotifyChat>().ToArray();
            var players         = world.Players.Where(p => p != world.LocalPlayer && !p.NonCombatant && !p.IsBot);
            var isObserver      = orderManager.LocalClient != null && orderManager.LocalClient.IsObserver;
            var alwaysDisabled  = world.IsReplay || world.LobbyInfo.NonBotClients.Count() == 1;
            var disableTeamChat = alwaysDisabled || (world.LocalPlayer != null && !players.Any(p => p.IsAlliedWith(world.LocalPlayer)));
            var teamChat        = !disableTeamChat;

            tabCompletion.Commands = chatTraits.OfType <ChatCommands>().SelectMany(x => x.Commands.Keys).ToList();
            tabCompletion.Names    = orderManager.LobbyInfo.Clients.Select(c => c.Name).Distinct().ToList();

            if (logicArgs.TryGetValue("Templates", out var templateIds))
            {
                foreach (var item in templateIds.Nodes)
                {
                    var key = FieldLoader.GetValue <TextNotificationPool>("key", item.Key);
                    templates[key] = Ui.LoadWidget(item.Value.Value, null, new WidgetArgs());
                }
            }

            var chatPanel = (ContainerWidget)widget;

            chatOverlay = chatPanel.GetOrNull <ContainerWidget>("CHAT_OVERLAY");
            if (chatOverlay != null)
            {
                chatOverlayDisplay  = chatOverlay.Get <TextNotificationsDisplayWidget>("CHAT_DISPLAY");
                chatOverlay.Visible = false;
            }

            chatChrome         = chatPanel.Get <ContainerWidget>("CHAT_CHROME");
            chatChrome.Visible = true;

            var chatMode = chatChrome.Get <ButtonWidget>("CHAT_MODE");

            chatMode.GetText = () => teamChat && !disableTeamChat ? "Team" : "All";
            chatMode.OnClick = () => teamChat ^= true;

            // Enable teamchat if we are a player and die,
            // or disable it when we are the only one left in the team
            if (!alwaysDisabled && world.LocalPlayer != null)
            {
                chatMode.IsDisabled = () =>
                {
                    if (world.IsGameOver || !chatEnabled)
                    {
                        return(true);
                    }

                    // The game is over for us, join spectator team chat
                    if (world.LocalPlayer.WinState != WinState.Undefined)
                    {
                        disableTeamChat = false;
                        return(disableTeamChat);
                    }

                    // If team chat isn't already disabled, check if we are the only living team member
                    if (!disableTeamChat)
                    {
                        disableTeamChat = players.All(p => p.WinState != WinState.Undefined || !p.IsAlliedWith(world.LocalPlayer));
                    }

                    return(disableTeamChat);
                };
            }
            else
            {
                chatMode.IsDisabled = () => disableTeamChat || !chatEnabled;
            }

            // Disable team chat after the game ended
            world.GameOver += () => disableTeamChat = true;

            chatText            = chatChrome.Get <TextFieldWidget>("CHAT_TEXTFIELD");
            chatText.MaxLength  = UnitOrders.ChatMessageMaxLength;
            chatText.OnEnterKey = _ =>
            {
                var team = teamChat && !disableTeamChat;
                if (chatText.Text != "")
                {
                    if (!chatText.Text.StartsWith("/", StringComparison.Ordinal))
                    {
                        // This should never happen, but avoid a crash if it does somehow (chat will just stay open)
                        if (!isObserver && orderManager.LocalClient == null && world.LocalPlayer == null)
                        {
                            return(true);
                        }

                        var teamNumber = 0U;
                        if (team)
                        {
                            teamNumber = (isObserver || world.LocalPlayer.WinState != WinState.Undefined) ? uint.MaxValue : (uint)orderManager.LocalClient.Team;
                        }

                        orderManager.IssueOrder(Order.Chat(chatText.Text.Trim(), teamNumber));
                    }
                    else if (chatTraits != null)
                    {
                        var text = chatText.Text.Trim();
                        var from = world.IsReplay ? null : orderManager.LocalClient.Name;
                        foreach (var trait in chatTraits)
                        {
                            trait.OnChat(from, text);
                        }
                    }
                }

                chatText.Text = "";
                if (!isMenuChat)
                {
                    CloseChat();
                }

                return(true);
            };

            chatText.OnTabKey = e =>
            {
                if (!chatMode.Key.IsActivatedBy(e) || chatMode.IsDisabled())
                {
                    chatText.Text           = tabCompletion.Complete(chatText.Text);
                    chatText.CursorPosition = chatText.Text.Length;
                }
                else
                {
                    chatMode.OnKeyPress(e);
                }

                return(true);
            };

            chatText.OnEscKey = _ =>
            {
                if (!isMenuChat)
                {
                    CloseChat();
                }
                else
                {
                    chatText.YieldKeyboardFocus();
                }

                return(true);
            };

            chatDisabledLabel = new CachedTransform <int, string>(x => x > 0 ? $"Chat available in {x} seconds..." : "Chat Disabled");

            if (!isMenuChat)
            {
                var openTeamChatKey = new HotkeyReference();
                if (logicArgs.TryGetValue("OpenTeamChatKey", out var hotkeyArg))
                {
                    openTeamChatKey = modData.Hotkeys[hotkeyArg.Value];
                }

                var openGeneralChatKey = new HotkeyReference();
                if (logicArgs.TryGetValue("OpenGeneralChatKey", out hotkeyArg))
                {
                    openGeneralChatKey = modData.Hotkeys[hotkeyArg.Value];
                }

                var chatClose = chatChrome.Get <ButtonWidget>("CHAT_CLOSE");
                chatClose.OnClick += CloseChat;

                chatPanel.OnKeyPress = e =>
                {
                    if (e.Event == KeyInputEvent.Up)
                    {
                        return(false);
                    }

                    if (!chatChrome.IsVisible() && (openTeamChatKey.IsActivatedBy(e) || openGeneralChatKey.IsActivatedBy(e)))
                    {
                        teamChat = !disableTeamChat && !openGeneralChatKey.IsActivatedBy(e);

                        OpenChat();
                        return(true);
                    }

                    return(false);
                };
            }

            chatScrollPanel = chatChrome.Get <ScrollPanelWidget>("CHAT_SCROLLPANEL");
            chatScrollPanel.RemoveChildren();
            chatScrollPanel.ScrollToBottom();

            foreach (var notification in orderManager.NotificationsCache)
            {
                if (IsNotificationEligible(notification))
                {
                    AddNotification(notification, true);
                }
            }

            orderManager.AddTextNotification += AddNotificationWrapper;

            chatText.IsDisabled = () => !chatEnabled || (world.IsReplay && !Game.Settings.Debug.EnableDebugCommandsInReplays);

            if (!isMenuChat)
            {
                CloseChat();

                var keyListener = chatChrome.Get <LogicKeyListenerWidget>("KEY_LISTENER");
                keyListener.AddHandler(e =>
                {
                    if (e.Event == KeyInputEvent.Up || !chatText.IsDisabled())
                    {
                        return(false);
                    }

                    if ((e.Key == Keycode.RETURN || e.Key == Keycode.KP_ENTER || e.Key == Keycode.ESCAPE) && e.Modifiers == Modifiers.None)
                    {
                        CloseChat();
                        return(true);
                    }

                    return(false);
                });
            }

            if (logicArgs.TryGetValue("ChatLineSound", out var yaml))
            {
                chatLineSound = yaml.Value;
            }
        }