10 protected const string STR_AVAILABLE_CHANNELS =
"#AR-Chat_AvailableChannels";
11 protected const string STR_CHANNEL_DISABLED =
"#AR-Chat_ChannelDisabled";
12 protected const string STR_CHANNEL_UNKNOWN =
"#AR-Chat_ChannelUnknown";
13 protected const string STR_MESSAGE_LIMIT_REACHED =
"#AR-Chat_LimitReached";
16 protected ref ScriptInvoker m_OnChatOpen;
17 protected ref ScriptInvoker m_OnChatClosed;
47 [
Attribute(
"9", UIWidgets.EditBox,
"Max amount of message line widgets")]
48 protected int m_iMessageLineCount;
50 [
Attribute(
"20", UIWidgets.EditBox,
"Amount of time till whole chat fades out, seconds")]
51 protected float m_fFadeOutThreshold_s;
53 [
Attribute(
"false", UIWidgets.CheckBox,
"When true, chat is always visible. When false, chat will fade out if msg box is hidden for more than m_fFadeOutThreshold_s time")]
54 protected bool m_bAlwaysVisible;
56 [
Attribute(
"{973C90F6B6135A50}UI/layouts/HUD/Chat/ChatMessage.layout", UIWidgets.ResourceNamePicker,
params:
"layout")]
57 protected ResourceName m_sChatMessageLineLayout;
60 protected int m_iHistoryId = 0;
61 protected int m_iHistoryIdLowestMessage = 0;
62 protected bool m_bHistoryMode =
false;
63 protected ref array<SCR_ChatMessageLineComponent> m_aMessageLines = {};
64 protected bool m_bOpen =
false;
74 protected Widget m_wRoot;
83 void OnUpdateChat(
float timeSlice)
85 m_MessageHistoryAnimator.ForceVisible(m_bOpen || m_bAlwaysVisible);
90 GetGame().GetInputManager().ActivateContext(
"ChatContext", 1);
92 if (
m_Widgets.m_MessageEditBox.GetText().Length() >= m_MessageEditBoxComponent.GetNumLimitOfCharacters())
94 ShowChannelWarning(
null, STR_MESSAGE_LIMIT_REACHED);
95 m_Widgets.m_WarningChannelMessage.SetVisible(
true);
99 m_Widgets.m_WarningChannelMessage.SetVisible(
false);
103 m_MessageHistoryAnimator.Update(timeSlice);
108 void OnHUDResize(
int newMessageLineCount)
110 m_iMessageLineCount = newMessageLineCount;
111 int count = m_aMessageLines.Count();
113 if (count == m_iMessageLineCount)
116 if (count > m_iMessageLineCount)
118 for (
int i = count - 1; i >= m_iMessageLineCount; i--)
124 w.GetRootWidget().RemoveFromHierarchy();
125 m_aMessageLines.RemoveItemOrdered(w);
132 for (
int i = count; i < m_iMessageLineCount; i++)
134 Widget lineWidget =
GetGame().GetWorkspace().CreateWidgets(m_sChatMessageLineLayout,
m_Widgets.m_MessageHistory);
136 comp.SetEmptyMessage();
137 m_aMessageLines.Insert(comp);
141 UpdateChatMessages();
154 int state = m_MessageHistoryAnimator.GetState();
162 int state = m_MessageHistoryAnimator.GetState();
176 if (m_bOpen || m_OnChatOpen && !
m_wRoot.GetParent().IsEnabled())
182 m_bHistoryMode =
false;
183 m_iHistoryId = mgr.GetMessages().Count();
184 m_iHistoryIdLowestMessage = m_iHistoryId;
188 m_OnChatOpen.Invoke();
194 Color colorStart = Color.FromSRGBA(226, 167, 79, 255);
195 Color colorEnd = Color.FromSRGBA(0, 0, 0, 140);
196 m_Widgets.m_EditBackgroundImage.SetColor(colorStart);
199 m_Widgets.m_MessageEditBox.SetEnabled(
true);
208 m_Widgets.m_MessageEditBox.ActivateWriteMode();
213 if (!m_ActiveChannel.IsAvailable(GetChatComponent()))
221 m_Widgets.m_ChannelTagOverlay.SetVisible(
true);
225 m_Widgets.m_WarningChannelMessage.SetVisible(
false);
226 UpdateChatMessages();
232 void Internal_Close()
237 WorkspaceWidget workspace =
GetGame().GetWorkspace();
238 if (workspace.GetFocusedWidget() ==
m_Widgets.m_MessageEditBox)
240 workspace.SetFocusedWidget(
null);
245 m_OnChatClosed.Invoke();
249 m_Widgets.m_MessageEditBox.SetText(
string.Empty);
250 m_Widgets.m_MessageEditBox.SetEnabled(
false);
253 AnimateWidget.StopAnimation(
m_Widgets.m_EditOverlay, WidgetAnimationOpacity);
256 m_Widgets.m_WarningChannelMessage.SetVisible(
false);
259 m_iHistoryIdLowestMessage = m_iHistoryId;
261 UpdateChatMessages();
272 m_iHistoryIdLowestMessage = m_iHistoryId;
275 m_MessageHistoryAnimator.FadeIn();
276 this.UpdateChatMessages();
280 notnull Widget GetWidget()
286 override void HandlerAttached(Widget w)
299 Print(
"[Chat] SCR_ChatPanelManager is not found. Chat will not work.", LogLevel.ERROR);
304 m_MessageEditBoxComponent =
m_Widgets.m_MessageEditBoxComponent0;
306 VerifyChannelStyles();
309 m_Widgets.m_MessageEditBox.SetEnabled(
false);
312 m_Widgets.m_MessageEditBoxComponent1.GetOnChange().Insert(Callback_OnEditBoxChange);
317 for (
int i = 0; i < m_iMessageLineCount; i++)
319 Widget lineWidget =
GetGame().GetWorkspace().CreateWidgets(m_sChatMessageLineLayout,
m_Widgets.m_MessageHistory);
322 comp.SetEmptyMessage();
323 m_aMessageLines.Insert(comp);
327 InputManager inputMgr =
GetGame().GetInputManager();
328 inputMgr.AddActionListener(
"ChatSendMessage", EActionTrigger.DOWN, Callback_OnSendMessageAction);
329 inputMgr.AddActionListener(
"ChatEscape", EActionTrigger.DOWN, Callback_OnCloseAction);
330 inputMgr.AddActionListener(
"ChatConfirm", EActionTrigger.DOWN, Callback_OnGamepadConfirmAction);
331 inputMgr.AddActionListener(
"ChatHistoryBrowse", EActionTrigger.VALUE, Callback_OnHistoryAction);
332 inputMgr.AddActionListener(
"ChatSwitchChannel", EActionTrigger.VALUE, Callback_OnSwitchChannelAction);
333 inputMgr.AddActionListener(
"ChatSwitchChannelSpace", EActionTrigger.DOWN, Callback_OnPressSpaceAfterCommand);
341 chatPanelMgr.Internal_EnableAllChannels();
348 if (chatPanelMgr.GetAnyPanelFadedIn())
350 m_iHistoryId = chatPanelMgr.GetMessages().Count() - 1;
351 m_iHistoryIdLowestMessage = m_iHistoryId;
352 m_MessageHistoryAnimator.FadeIn();
353 UpdateChatMessages();
358 chatPanelMgr.Register(
this);
364 override void HandlerDeattached(Widget w)
370 InputManager inputMgr =
GetGame().GetInputManager();
371 inputMgr.RemoveActionListener(
"ChatSendMessage", EActionTrigger.DOWN, Callback_OnSendMessageAction);
372 inputMgr.RemoveActionListener(
"ChatEscape", EActionTrigger.DOWN, Callback_OnCloseAction);
373 inputMgr.RemoveActionListener(
"ChatConfirm", EActionTrigger.DOWN, Callback_OnGamepadConfirmAction);
374 inputMgr.RemoveActionListener(
"ChatHistoryBrowse", EActionTrigger.VALUE, Callback_OnHistoryAction);
375 inputMgr.RemoveActionListener(
"ChatSwitchChannel", EActionTrigger.VALUE, Callback_OnSwitchChannelAction);
376 inputMgr.RemoveActionListener(
"ChatSwitchChannelSpace", EActionTrigger.DOWN, Callback_OnPressSpaceAfterCommand);
381 chatPanelMgr.Unregister(
this);
389 protected void UpdateChatMessages()
393 int messageCount = messages.Count();
395 if (messageCount > 0)
397 int lastMessageId = m_iHistoryId;
399 lastMessageId = m_iHistoryIdLowestMessage;
401 lastMessageId = Math.ClampInt(lastMessageId, 0, messageCount - 1);
402 int currentMessageCount = m_iMessageLineCount;
404 for (
int i = 0; i < currentMessageCount; i++)
406 int messageId = lastMessageId - i;
409 if (i > m_aMessageLines.Count() - 1 || i < 0)
414 if (messageId >= 0 && messageId <= lastMessageId)
418 lineComp.SetVisible(
true);
419 lineComp.SetMessage(msg, style);
426 lineComp.SetVisible(
false);
432 for (
int i = 0; i < m_iMessageLineCount; i++)
434 if (i > m_aMessageLines.Count() - 1 || i < 0)
441 lineComp.SetVisible(
false);
448 protected void SendMessage()
452 SCR_ChatComponent chatComponent = GetChatComponent();
454 if (!chatComponent || !m_ActiveChannel)
459 message =
m_Widgets.m_MessageEditBox.GetText();
464 string cmd = this.GetCommand(message);
472 message = message.Substring(cmd.Length() + 1, message.Length() - cmd.Length() - 1);
473 message.TrimInPlace();
475 mgr.Internal_OnChatCommand(
this, cmd, message);
480 if (!m_ActiveChannel.IsAvailable(chatComponent))
491 int playerId = this.GetPlayerIdByName(cmd);
496 message = message.Substring(nameLength + 1, message.Length() - nameLength - 1);
498 chatComponent.SendPrivateMessage(message, playerId);
503 int channelId = GetChannelId(m_ActiveChannel);
504 chatComponent.SendMessage(message, channelId);
513 protected void CycleChannels(
bool next)
518 SCR_ChatComponent chatComponent = GetChatComponent();
526 id = GetChannelId(m_ActiveChannel);
531 while (nTries < channelCount)
536 if (
id == channelCount)
543 id = channelCount - 1;
548 if (channel.IsAvailable(chatComponent))
550 this.SetActiveChannel(channel);
561 protected void ShowChannelWarning(
BaseChatChannel Chatchannel =
null,
string message =
"")
563 if (Chatchannel && message ==
string.Empty)
564 m_Widgets.m_WarningText.SetText(STR_CHANNEL_DISABLED);
566 m_Widgets.m_WarningText.SetText(message);
568 m_Widgets.m_WarningChannelMessage.SetVisible(
true);
576 protected string GetCommand(
string s)
581 int cmdEnd = s.IndexOf(
" ");
587 string ret = s.Substring(1, cmdEnd - 1);
597 string Internal_GetChannelListHelpMessage()
599 SCR_ChatComponent chatComponent = GetChatComponent();
605 string help_message = STR_AVAILABLE_CHANNELS +
": ";
606 for (
int j = 0; j <
m_ChatEntity.GetChannelsCount(); j++)
608 if (chatComponent.GetChannelState(j))
611 if (chatChannel.IsAvailable(chatComponent))
616 Color imageColor = Color.FromInt(Color.WHITE);
617 if (style.m_bColoredIcon)
618 imageColor = style.m_Color;
620 string tagImage =
string.Format(
"<image set=\"%1\" name=\"%2\" scale=\"1\"/>",
621 style.m_IconImageset,
626 help_message +=
string.Format(
"\n /%1 %2 %3",
649 while (!found && i < channelCount)
656 if (style.m_sPrefix == prefix)
668 protected int GetPlayerIdByName(
string name)
676 pm.GetAllPlayers(players);
678 for (
int i = pm.GetAllPlayerCount() - 1; i >= 0; --i)
680 if (pm.GetPlayerName(i) == name)
691 protected void SetActiveChannel(notnull
BaseChatChannel channel,
string ReceiverName =
string.Empty)
693 SCR_ChatComponent chatComponent = GetChatComponent();
699 m_Widgets.m_WarningChannelMessage.SetVisible(
false);
700 m_ActiveChannel = channel;
707 style = GetChannelStyle(m_ActiveChannel);
709 Color color = Color.FromInt(Color.WHITE);
710 if (style.m_bColoredIcon)
712 color = style.m_Color;
714 m_Widgets.m_ChannelTypeImage.SetColor(color);
715 m_Widgets.m_ChannelTagEditor.SetColor(color);
716 string chatTypeImageName = style.m_sIconName;
717 if (!chatTypeImageName.IsEmpty())
718 m_Widgets.m_ChannelTypeImage.LoadImageFromSet(0, style.m_IconImageset, chatTypeImageName);
720 string channelName = style.m_sName;
724 if (ReceiverName !=
string.Empty)
726 m_Widgets.m_ChannelTagEditor.SetText(channelName +
" " + ReceiverName);
727 m_Widgets.m_ChannelTagOverlay.SetText(channelName +
" " + ReceiverName);
730 else if (chatComponent.GetChannelState(channel))
736 m_Widgets.m_ChannelTagEditor.SetText(channelName);
737 string tagOverlayText =
string.Format(WidgetManager.Translate(
"#AR-Chat_SendToChannel", WidgetManager.Translate(style.m_sNameLower)));
738 m_Widgets.m_ChannelTagOverlay.SetText(tagOverlayText);
747 protected void VerifyChannelStyles()
752 if (!m_SystemChannelStyle)
759 array<Managed> styles = {
760 m_SystemChannelStyle,
761 m_RadioProtocolStyle,
762 m_GlobalChannelStyle,
763 m_FactionChannelStyle,
764 m_VehicleChannelStyle,
769 foreach (Managed style : styles)
777 string s =
string.Format(
"[Chat] %1 chat channel styles are not configured.", n);
778 Print(s, LogLevel.ERROR);
789 return m_SystemChannelStyle;
792 switch (channel.Type())
796 if (channel.GetName() ==
"Global")
797 style = m_GlobalChannelStyle;
801 case GroupChatChannel:
802 style = m_GroupChannelStyle;
804 case FactionChatChannel:
805 style = m_FactionChannelStyle;
808 style = m_VehicleChannelStyle;
810 case LocalChatChannel:
811 style = m_LocalChannelStyle;
814 style = m_DirectChannelStyle;
819 return m_SystemChannelStyle;
831 return m_RadioProtocolStyle;
837 if (generalMsg.m_Channel)
839 return GetChannelStyle(generalMsg.m_Channel);
844 return m_SystemChannelStyle;
850 protected SCR_ChatComponent GetChatComponent()
852 PlayerController pc =
GetGame().GetPlayerController();
857 return SCR_ChatComponent.Cast(pc.FindComponent(SCR_ChatComponent));
871 ScriptInvoker GetOnChatOpen()
874 m_OnChatOpen =
new ScriptInvoker();
879 ScriptInvoker GetOnChatClosed()
882 m_OnChatClosed =
new ScriptInvoker();
883 return m_OnChatClosed;
889 return m_MessageHistoryAnimator;
902 protected void Callback_OnPressSpaceAfterCommand()
907 SCR_ChatComponent chatComponent = GetChatComponent();
914 message =
m_Widgets.m_MessageEditBox.GetText();
915 string cmd = this.GetCommand(message);
919 if (cmd.IsEmpty() || cmd.Length() != 1 || !(
"0123456789".Contains(cmd)))
926 ShowChannelWarning(
null, STR_CHANNEL_UNKNOWN);
931 message = message.Substring(cmd.Length() + 1, message.Length() - cmd.Length() - 1);
932 message.TrimInPlace();
934 if (channel.IsAvailable(chatComponent))
936 this.SetActiveChannel(channel);
937 m_Widgets.m_MessageEditBox.SetText(message);
941 Callback_OnEditBoxChange();
945 ShowChannelWarning(channel, STR_CHANNEL_DISABLED);
951 protected void Callback_OnCloseAction()
959 protected void Callback_OnSendMessageAction()
964 if (!
m_Widgets.m_MessageEditBox.GetText().IsEmpty())
976 protected void Callback_OnGamepadConfirmAction()
981 Widget wFocused =
GetGame().GetWorkspace().GetFocusedWidget();
982 if (wFocused !=
m_Widgets.m_MessageEditBox)
985 if (!
m_Widgets.m_MessageEditBox.IsInWriteMode())
986 m_Widgets.m_MessageEditBox.ActivateWriteMode();
992 protected void Callback_OnHistoryAction(
float value)
1003 int minHistoryOffset = m_iMessageLineCount;
1005 array<ref SCR_ChatMessage> messages = mgr.GetMessages();
1006 int messagesCount = messages.Count();
1010 if (messagesCount < minHistoryOffset)
1013 m_iHistoryId = messagesCount - 1;
1014 m_iHistoryIdLowestMessage = m_iHistoryId;
1015 m_bHistoryMode =
false;
1019 m_iHistoryId -= value;
1020 int lastMessageId = messagesCount - 1;
1021 m_iHistoryId = Math.ClampInt(m_iHistoryId, minHistoryOffset - 1, lastMessageId);
1025 bool increasing =
true;
1029 while (linesCount < m_iMessageLineCount && messagesCount > m_iHistoryId - offset && m_iHistoryId - offset >= -1)
1032 if (m_iHistoryId - offset > m_iHistoryId)
1033 m_iHistoryIdLowestMessage = m_iHistoryId - offset;
1035 m_iHistoryIdLowestMessage = m_iHistoryId;
1040 hadToIncrease =
true;
1042 if (m_iHistoryId - offset < 0)
1047 if (linesCount >= m_iMessageLineCount)
1048 m_iHistoryIdLowestMessage = m_iHistoryId;
1050 else if (m_iHistoryId - offset >= messagesCount)
1055 m_iHistoryId += value;
1057 m_bHistoryMode = m_iHistoryId != lastMessageId;
1058 UpdateChatMessages();
1065 protected void Callback_OnSwitchChannelAction(
float value, EActionTrigger reason)
1079 protected void Callback_OnEditBoxChange()
1084 int textLen =
m_Widgets.m_MessageEditBox.GetText().Length();
1085 m_Widgets.m_ChannelTagOverlay.SetVisible(textLen == 0);