Client LuaCsForBarotrauma
BarotraumaShared/SharedSource/Items/Components/Signal/Terminal.cs
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Xml.Linq;
5 using Microsoft.Xna.Framework;
6 
8 {
9  readonly struct TerminalMessage
10  {
11  public readonly string Text;
12  public readonly Color Color;
13  public readonly bool IsWelcomeMessage;
14 
15  public TerminalMessage(string text, Color color, bool isWelcomeMessage)
16  {
17  Text = text;
18  Color = color;
19  IsWelcomeMessage = isWelcomeMessage;
20  }
21 
22  public void Deconstruct(out string text, out Color color)
23  {
24  text = Text;
25  color = Color;
26  }
27  }
28 
29  partial class Terminal : ItemComponent
30  {
31  private const int MaxMessageLength = ChatMessage.MaxLength;
32 
33  private const int MaxMessages = 60;
34 
35  private readonly List<TerminalMessage> messageHistory = new List<TerminalMessage>(MaxMessages);
36 
38  {
39  get;
40  private set;
41  }
42 
43  private string welcomeMessage;
44  [InGameEditable, Serialize("", IsPropertySaveable.Yes, "Message to be displayed on the terminal display when it is first opened.", translationTextTag: "terminalwelcomemsg.", alwaysUseInstanceValues: true)]
45  public string WelcomeMessage
46  {
47  get { return welcomeMessage; }
48  set
49  {
50  if (welcomeMessage == value) { return; }
51  welcomeMessage = value;
52  DisplayedWelcomeMessage = TextManager.Get(welcomeMessage).Fallback(welcomeMessage.Replace("\\n", "\n"));
53  }
54  }
55 
59  public string ShowMessage
60  {
61  get { return messageHistory.Count == 0 ? string.Empty : messageHistory.Last().Text; }
62  set
63  {
64  if (string.IsNullOrEmpty(value)) { return; }
65  ShowOnDisplay(value, addToHistory: true, TextColor, isWelcomeMessage: false);
66  }
67  }
68 
69  [Editable, Serialize(false, IsPropertySaveable.Yes, description: "The terminal will use a monospace font if this box is ticked.", alwaysUseInstanceValues: true)]
70  public bool UseMonospaceFont { get; set; }
71 
72  [Serialize(false, IsPropertySaveable.No)]
73  public bool AutoHideScrollbar { get; set; }
74 
75  [Serialize(false, IsPropertySaveable.Yes, alwaysUseInstanceValues: true)]
76  public bool WelcomeMessageDisplayed { get; set; }
77 
78  private Color textColor = Color.LimeGreen;
79 
80  [Editable, Serialize("50,205,50,255", IsPropertySaveable.Yes, description: "Color of the terminal text.", alwaysUseInstanceValues: true)]
81  public Color TextColor
82  {
83  get => textColor;
84  set
85  {
86  textColor = value;
87 #if CLIENT
88  if (inputBox is { } input)
89  {
90  input.TextColor = value;
91  }
92 #endif
93  }
94  }
95 
97  public string LineStartSymbol { get; set; }
98 
100  public bool Readonly { get; set; }
101 
102  [Serialize(true, IsPropertySaveable.No)]
103  public bool AutoScrollToBottom { get; set; }
104 
105  private string OutputValue { get; set; }
106 
107  private string prevColorSignal;
108 
110  : base(item, element)
111  {
112  IsActive = true;
113  InitProjSpecific(element);
114  }
115 
116  partial void InitProjSpecific(XElement element);
117 
118  partial void ShowOnDisplay(string input, bool addToHistory, Color color, bool isWelcomeMessage);
119 
120  public override void ReceiveSignal(Signal signal, Connection connection)
121  {
122  switch (connection.Name)
123  {
124  case "set_text":
125  case "signal_in":
126  if (string.IsNullOrEmpty(signal.value)) { return; }
127  if (signal.value.Length > MaxMessageLength)
128  {
129  signal.value = signal.value.Substring(0, MaxMessageLength);
130  }
131  string inputSignal = signal.value.Replace("\\n", "\n");
132  ShowOnDisplay(inputSignal, addToHistory: true, TextColor, isWelcomeMessage: false);
133  break;
134  case "set_text_color":
135  if (signal.value != prevColorSignal)
136  {
137  TextColor = XMLExtensions.ParseColor(signal.value, false);
138  prevColorSignal = signal.value;
139  }
140  break;
141  case "clear_text" when signal.value != "0":
142  messageHistory.Clear();
143 #if CLIENT
144  if (historyBox?.Content is { } history)
145  {
146  history.ClearChildren();
147  }
148 
150 #endif
151  break;
152  }
153  }
154 
155  public override void OnItemLoaded()
156  {
157  bool isSubEditor = false;
158 #if CLIENT
160 #endif
161 
162  base.OnItemLoaded();
163  if (!DisplayedWelcomeMessage.IsNullOrEmpty() && !WelcomeMessageDisplayed)
164  {
165  ShowOnDisplay(DisplayedWelcomeMessage.Value, addToHistory: !isSubEditor, TextColor, isWelcomeMessage: true);
167  //disable welcome message if a game session is running so it doesn't reappear on successive rounds
168  if (GameMain.GameSession != null && !isSubEditor)
169  {
171  }
172  }
173  }
174 
175  public override XElement Save(XElement parentElement)
176  {
177  var componentElement = base.Save(parentElement);
178  for (int i = 0; i < messageHistory.Count; i++)
179  {
180  var msg = messageHistory[i];
181  componentElement.Add(new XAttribute("msg" + i, msg.Text));
182  componentElement.Add(new XAttribute("color" + i, msg.Color.ToStringHex()));
183  if (msg.IsWelcomeMessage)
184  {
185  componentElement.Add(new XAttribute("welcomemessage" + i, true));
186  }
187  }
188  return componentElement;
189  }
190 
191  public override void Load(ContentXElement componentElement, bool usePrefabValues, IdRemap idRemap, bool isItemSwap)
192  {
193  base.Load(componentElement, usePrefabValues, idRemap, isItemSwap);
194  for (int i = 0; i < MaxMessages; i++)
195  {
196  string msg = componentElement.GetAttributeString("msg" + i, null);
197  if (msg is null) { break; }
198  Color color = componentElement.GetAttributeColor("color" + i, TextColor);
199  bool isWelcomeMessage = componentElement.GetAttributeBool("welcomemessage" + i, false);
200  ShowOnDisplay(msg, addToHistory: true, color, isWelcomeMessage);
201  }
202  }
203  }
204 }
string? GetAttributeString(string key, string? def)
Color GetAttributeColor(string key, in Color def)
bool GetAttributeBool(string key, bool def)
static GameSession?? GameSession
Definition: GameMain.cs:88
static SubEditorScreen SubEditorScreen
Definition: GameMain.cs:68
The base class for components holding the different functionalities of the item
override void OnItemLoaded()
Called when all the components of the item have been loaded. Use to initialize connections between co...
string? ShowMessage
Can be used to display messages on the terminal via status effects
override void Load(ContentXElement componentElement, bool usePrefabValues, IdRemap idRemap, bool isItemSwap)
LocalizedString Fallback(LocalizedString fallback, bool useDefaultLanguageIfFound=true)
Use this text instead if the original text cannot be found.