Client LuaCsForBarotrauma
BarotraumaClient/ClientSource/Items/Components/Machines/Reactor.cs
3 using Barotrauma.Sounds;
4 using Microsoft.Xna.Framework;
5 using Microsoft.Xna.Framework.Graphics;
6 using System;
7 using System.Collections.Generic;
8 using System.Linq;
9 
11 {
12  partial class Reactor : Powered, IServerSerializable, IClientSerializable
13  {
14  public GUIButton AutoTempSwitch { get; private set; }
15 
16  public GUIButton PowerButton { get; private set; }
17  private GUITickBox powerLight;
18  private GUITickBox autoTempLight;
19 
20  private const int GraphSize = 25;
21  private float graphTimer;
22  private readonly int updateGraphInterval = 500;
23 
24  private Sprite fissionRateMeter, turbineOutputMeter;
25  private Sprite meterPointer;
26  private Sprite sectorSprite;
27 
28  private Sprite tempMeterFrame, tempMeterBar;
29  private Sprite tempRangeIndicator;
30 
31  private Sprite graphLine;
32  private GUICustomComponent graph;
33 
34  private GUIFrame inventoryWindow;
35  private GUILayoutGroup buttonArea;
36  private GUIFrame infographic;
37 
38  private Color optimalRangeColor = new Color(74,238,104,255);
39  private Color offRangeColor = Color.Orange;
40  private Color warningColor = Color.Red;
41 
42  private readonly Color[] temperatureColors = new Color[] { Color.Blue, Color.LightBlue, Color.Orange, Color.Red };
43  private Color outputColor = Color.Goldenrod;
44  private Color loadColor = Color.LightSteelBlue;
45 
46  private RoundSound temperatureBoostSoundUp, temperatureBoostSoundDown;
47  private GUIButton temperatureBoostUpButton, temperatureBoostDownButton;
48 
49  public GUIScrollBar FissionRateScrollBar { get; private set; }
50 
51  public GUIScrollBar TurbineOutputScrollBar { get; private set; }
52 
53  private readonly float[] outputGraph = new float[GraphSize];
54  private readonly float[] loadGraph = new float[GraphSize];
55 
56  private GUITickBox criticalHeatWarning;
57  private GUITickBox lowTemperatureWarning;
58  private GUITickBox criticalOutputWarning;
59 
60  private GUIFrame inventoryContainer;
61 
62  private GUILayoutGroup paddedFrame;
63 
64  private readonly Dictionary<string, GUIButton> warningButtons = new Dictionary<string, GUIButton>();
65 
66  private static readonly string[] warningTexts = new string[]
67  {
68  "ReactorWarningLowTemp", "ReactorWarningLowOutput", "ReactorWarningLowFuel", "ReactorWarningMeltdown",
69  "ReactorWarningOverheating", "ReactorWarningHighOutput", "ReactorWarningFuelOut", "ReactorWarningSCRAM"
70  };
71 
72  public override bool RecreateGUIOnResolutionChange => true;
73 
74  public bool TriggerInfographic { get; set; }
75 
76  public bool IsInfographicVisible => infographic != null && infographic.Visible;
77 
78  partial void InitProjSpecific(ContentXElement element)
79  {
80  CreateGUI();
81  fissionRateMeter = new Sprite(element.GetChildElement("fissionratemeter")?.GetChildElement("sprite"));
82  turbineOutputMeter = new Sprite(element.GetChildElement("turbineoutputmeter")?.GetChildElement("sprite"));
83  meterPointer = new Sprite(element.GetChildElement("meterpointer")?.GetChildElement("sprite"));
84  sectorSprite = new Sprite(element.GetChildElement("sectorsprite")?.GetChildElement("sprite"));
85  tempMeterFrame = new Sprite(element.GetChildElement("tempmeterframe")?.GetChildElement("sprite"));
86  tempMeterBar = new Sprite(element.GetChildElement("tempmeterbar")?.GetChildElement("sprite"));
87  tempRangeIndicator = new Sprite(element.GetChildElement("temprangeindicator")?.GetChildElement("sprite"));
88  graphLine = new Sprite(element.GetChildElement("graphline")?.GetChildElement("sprite"));
89 
90  foreach (var subElement in element.Elements())
91  {
92  switch (subElement.Name.ToString().ToLowerInvariant())
93  {
94  case "temperatureboostsoundup":
95  temperatureBoostSoundUp = RoundSound.Load(subElement, false);
96  break;
97  case "temperatureboostsounddown":
98  temperatureBoostSoundDown = RoundSound.Load(subElement, false);
99  break;
100  }
101  }
102  }
103 
104  protected override void CreateGUI()
105  {
106  warningButtons.Clear();
107 
108  paddedFrame = new GUILayoutGroup(new RectTransform(
109  GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin, GuiFrame.RectTransform, Anchor.Center)
110  { AbsoluteOffset = GUIStyle.ItemFrameOffset },
111  isHorizontal: true)
112  {
113  CanBeFocused = true,
114  HoverCursor = CursorState.Default,
115  AlwaysOverrideCursor = true,
116  RelativeSpacing = 0.012f,
117  Stretch = true
118  };
119 
120  GUILayoutGroup columnLeft = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), paddedFrame.RectTransform))
121  {
122  RelativeSpacing = 0.012f,
123  Stretch = true
124  };
125  GUILayoutGroup columnRight = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 1.0f), paddedFrame.RectTransform))
126  {
127  CanBeFocused = true,
128  RelativeSpacing = 0.012f,
129  Stretch = true
130  };
131 
132  //----------------------------------------------------------
133  //left column
134  //----------------------------------------------------------
135 
136  inventoryWindow = new GUIFrame(new RectTransform(new Vector2(0.1f, 0.75f), GuiFrame.RectTransform, Anchor.TopLeft, Pivot.TopRight)
137  {
138  MinSize = new Point(85, 220),
139  RelativeOffset = new Vector2(-0.02f, 0)
140  }, style: "ItemUI");
141 
142  GUILayoutGroup inventoryContent = new GUILayoutGroup(new RectTransform(inventoryWindow.Rect.Size - GUIStyle.ItemFrameMargin, inventoryWindow.RectTransform, Anchor.Center)
143  { AbsoluteOffset = GUIStyle.ItemFrameOffset },
144  childAnchor: Anchor.TopCenter)
145  {
146  Stretch = true
147  };
148 
149  /*new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), inventoryContent.RectTransform), "",
150  textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont, wrap: true);*/
151  inventoryContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.9f), inventoryContent.RectTransform), style: null);
152 
153  //----------------------------------------------------------
154  //mid column
155  //----------------------------------------------------------
156 
157  var topLeftArea = new GUILayoutGroup(new RectTransform(new Vector2(1, 0.2f), columnLeft.RectTransform),
158  isHorizontal: true, childAnchor: Anchor.CenterLeft)
159  {
160  Stretch = true
161  };
162 
163 
164  Point maxIndicatorSize = new Point(int.MaxValue, (int)(40 * GUI.Scale));
165  criticalHeatWarning = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), topLeftArea.RectTransform) { MaxSize = maxIndicatorSize },
166  TextManager.Get("ReactorWarningCriticalTemp"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightRed")
167  {
168  Selected = false,
169  Enabled = false,
170  ToolTip = TextManager.Get("ReactorHeatTip")
171  };
172  criticalOutputWarning = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), topLeftArea.RectTransform) { MaxSize = maxIndicatorSize },
173  TextManager.Get("ReactorWarningCriticalOutput"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightRed")
174  {
175  Selected = false,
176  Enabled = false,
177  ToolTip = TextManager.Get("ReactorOutputTip")
178  };
179  lowTemperatureWarning = new GUITickBox(new RectTransform(new Vector2(0.4f, 1.0f), topLeftArea.RectTransform) { MaxSize = maxIndicatorSize },
180  TextManager.Get("ReactorWarningCriticalLowTemp"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightRed")
181  {
182  Selected = false,
183  Enabled = false,
184  ToolTip = TextManager.Get("ReactorTempTip")
185  };
186  List<GUITickBox> indicatorLights = new List<GUITickBox>() { criticalHeatWarning, lowTemperatureWarning, criticalOutputWarning };
187  indicatorLights.ForEach(l => l.TextBlock.OverrideTextColor(GUIStyle.TextColorNormal));
188  topLeftArea.Recalculate();
189 
190  new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), columnLeft.RectTransform), style: "HorizontalLine");
191 
192  float relativeYMargin = 0.02f;
193  Vector2 relativeTextSize = new Vector2(0.9f, 0.15f);
194  Vector2 sliderSize = new Vector2(1.0f, 0.125f);
195  Vector2 meterSize = new Vector2(1, 1 - relativeTextSize.Y - relativeYMargin - sliderSize.Y - 0.1f);
196 
197  var meterArea = new GUIFrame(new RectTransform(new Vector2(1, 0.6f - relativeYMargin * 2), columnLeft.RectTransform), style: null);
198  var leftArea = new GUIFrame(new RectTransform(new Vector2(0.49f, 1), meterArea.RectTransform), style: null);
199  var rightArea = new GUIFrame(new RectTransform(new Vector2(0.49f, 1), meterArea.RectTransform, Anchor.TopCenter, Pivot.TopLeft), style: null);
200 
201  var fissionRateTextBox = new GUITextBlock(new RectTransform(relativeTextSize, leftArea.RectTransform, Anchor.TopCenter),
202  TextManager.Get("ReactorFissionRate"), textColor: GUIStyle.TextColorNormal, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
203  {
204  AutoScaleHorizontal = true
205  };
206  var fissionMeter = new GUICustomComponent(new RectTransform(meterSize, leftArea.RectTransform, Anchor.TopCenter)
207  {
208  RelativeOffset = new Vector2(0.0f, relativeTextSize.Y + relativeYMargin)
209  },
210  DrawFissionRateMeter, null)
211  {
212  ToolTip = TextManager.Get("ReactorTipFissionRate")
213  };
214 
215  var turbineOutputTextBox = new GUITextBlock(new RectTransform(relativeTextSize, rightArea.RectTransform, Anchor.TopCenter),
216  TextManager.Get("ReactorTurbineOutput"), textColor: GUIStyle.TextColorNormal, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
217  {
218  AutoScaleHorizontal = true
219  };
220  GUITextBlock.AutoScaleAndNormalize(turbineOutputTextBox, fissionRateTextBox);
221 
222  var turbineMeter = new GUICustomComponent(new RectTransform(meterSize, rightArea.RectTransform, Anchor.TopCenter)
223  {
224  RelativeOffset = new Vector2(0.0f, relativeTextSize.Y + relativeYMargin)
225  },
226  DrawTurbineOutputMeter, null)
227  {
228  ToolTip = TextManager.Get("ReactorTipTurbineOutput")
229  };
230 
231  FissionRateScrollBar = new GUIScrollBar(new RectTransform(sliderSize, leftArea.RectTransform, Anchor.TopCenter)
232  {
233  RelativeOffset = new Vector2(0, fissionMeter.RectTransform.RelativeOffset.Y + meterSize.Y + relativeYMargin)
234  },
235  style: "DeviceSlider", barSize: 0.15f)
236  {
237  Enabled = false,
238  Step = 1.0f / 255,
239  OnMoved = (GUIScrollBar bar, float scrollAmount) =>
240  {
242  unsentChanges = true;
243  TargetFissionRate = scrollAmount * 100.0f;
244 
245  return false;
246  }
247  };
249 
250  TurbineOutputScrollBar = new GUIScrollBar(new RectTransform(sliderSize, rightArea.RectTransform, Anchor.TopCenter)
251  {
252  RelativeOffset = new Vector2(0, turbineMeter.RectTransform.RelativeOffset.Y + meterSize.Y + relativeYMargin)
253  },
254  style: "DeviceSlider", barSize: 0.15f, isHorizontal: true)
255  {
256  Enabled = false,
257  Step = 1.0f / 255,
258  OnMoved = (GUIScrollBar bar, float scrollAmount) =>
259  {
261  unsentChanges = true;
262  TargetTurbineOutput = scrollAmount * 100.0f;
263 
264  return false;
265  }
266  };
268 
269  buttonArea = new GUILayoutGroup(new RectTransform(new Vector2(1, 0.2f), columnLeft.RectTransform))
270  {
271  Stretch = true,
272  RelativeSpacing = 0.02f
273  };
274  var upperButtons = new GUILayoutGroup(new RectTransform(new Vector2(1, 0.5f), buttonArea.RectTransform), isHorizontal: true)
275  {
276  Stretch = true,
277  RelativeSpacing = 0.01f
278  };
279  var lowerButtons = new GUILayoutGroup(new RectTransform(new Vector2(1, 0.5f), buttonArea.RectTransform), isHorizontal: true)
280  {
281  Stretch = true,
282  RelativeSpacing = 0.01f
283  };
284  int buttonCount = warningTexts.Length;
285  for (int i = 0; i < buttonCount; i++)
286  {
287  string text = warningTexts[i];
288  var b = new GUIButton(new RectTransform(Vector2.One, (i < 4) ? upperButtons.RectTransform : lowerButtons.RectTransform),
289  TextManager.Get(text), style: "IndicatorButton")
290  {
291  Font = GUIStyle.SubHeadingFont,
292  CanBeFocused = false
293  };
294  warningButtons.Add(text, b);
295  }
296  upperButtons.Recalculate();
297  lowerButtons.Recalculate();
298  //only wrap texts that consist of multiple words and are way too big to fit otherwise
299  warningButtons.Values.ForEach(b => b.TextBlock.Wrap = b.Text.Contains(' ') && b.TextBlock.TextSize.X > b.TextBlock.Rect.Width * 1.5f);
300  GUITextBlock.AutoScaleAndNormalize(warningButtons.Values.Select(b => b.TextBlock));
301 
302  //----------------------------------------------------------
303  //right column
304  //----------------------------------------------------------
305 
306  // Auto temp
307  var topRightArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), columnRight.RectTransform),
308  isHorizontal: true, childAnchor: Anchor.CenterLeft)
309  {
310  Stretch = true,
311  RelativeSpacing = 0.02f
312  };
313  topRightArea.RectTransform.MinSize = new Point(0, topLeftArea.Rect.Height);
314  topRightArea.RectTransform.MaxSize = new Point(int.MaxValue, topLeftArea.Rect.Height);
315 
316  new GUIFrame(new RectTransform(new Vector2(0.01f, 1.0f), topRightArea.RectTransform), style: "VerticalLine");
317 
318  AutoTempSwitch = new GUIButton(new RectTransform(new Vector2(0.15f, 0.9f), topRightArea.RectTransform),
319  style: "SwitchVertical")
320  {
321  UserData = UIHighlightAction.ElementId.AutoTempSwitch,
322  Enabled = false,
323  Selected = AutoTemp,
324  ClickSound = GUISoundType.UISwitch,
325  OnClicked = (button, data) =>
326  {
327  AutoTemp = !AutoTemp;
329  unsentChanges = true;
330  return true;
331  }
332  };
333  AutoTempSwitch.RectTransform.MaxSize = new Point((int)(AutoTempSwitch.Rect.Height * 0.4f), int.MaxValue);
334 
335  autoTempLight = new GUITickBox(new RectTransform(new Vector2(0.4f, 1.0f), topRightArea.RectTransform),
336  TextManager.Get("ReactorAutoTemp"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightYellow")
337  {
338  ToolTip = TextManager.Get("ReactorTipAutoTemp"),
339  CanBeFocused = false,
341  };
342  autoTempLight.RectTransform.MaxSize = new Point(int.MaxValue, criticalHeatWarning.Rect.Height);
343  autoTempLight.TextBlock.OverrideTextColor(GUIStyle.TextColorNormal);
344 
345  new GUIFrame(new RectTransform(new Vector2(0.01f, 1.0f), topRightArea.RectTransform), style: "VerticalLine");
346 
347  // Power button
348  var powerArea = new GUIFrame(new RectTransform(new Vector2(0.4f, 1.0f), topRightArea.RectTransform), style: null);
349  var paddedPowerArea = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), powerArea.RectTransform, Anchor.Center, scaleBasis: ScaleBasis.BothHeight), style: "PowerButtonFrame");
350  powerLight = new GUITickBox(new RectTransform(new Vector2(0.87f, 0.3f), paddedPowerArea.RectTransform, Anchor.TopCenter, Pivot.Center),
351  TextManager.Get("PowerLabel"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightPower")
352  {
353  CanBeFocused = false,
354  Selected = _powerOn
355  };
356  powerLight.TextBlock.Padding = new Vector4(5.0f, 0.0f, 0.0f, 0.0f);
357  powerLight.TextBlock.AutoScaleHorizontal = true;
358  powerLight.TextBlock.OverrideTextColor(GUIStyle.TextColorNormal);
359  PowerButton = new GUIButton(new RectTransform(new Vector2(0.8f, 0.75f), paddedPowerArea.RectTransform, Anchor.BottomCenter)
360  {
361  RelativeOffset = new Vector2(0, 0.1f)
362  }, style: "PowerButton")
363  {
364  UserData = UIHighlightAction.ElementId.PowerButton,
365  OnClicked = (button, data) =>
366  {
367  PowerOn = !PowerOn;
369  unsentChanges = true;
370  return true;
371  }
372  };
373 
374  topRightArea.Recalculate();
375  autoTempLight.TextBlock.Padding = new Vector4(autoTempLight.TextBlock.Padding.X, 0.0f, 0.0f, 0.0f);
376  autoTempLight.TextBlock.Text = autoTempLight.TextBlock.Text.Replace(" ", "\n");
377  autoTempLight.TextBlock.AutoScaleHorizontal = true;
378  GUITextBlock.AutoScaleAndNormalize(indicatorLights.Select(l => l.TextBlock));
379 
380  // right bottom (graph area) -----------------------
381 
382  new GUIFrame(new RectTransform(new Vector2(0.95f, 0.01f), columnRight.RectTransform), style: "HorizontalLine");
383 
384  var bottomRightArea = new GUILayoutGroup(new RectTransform(Vector2.One, columnRight.RectTransform), isHorizontal: true)
385  {
386  Stretch = true,
387  CanBeFocused = true,
388  RelativeSpacing = 0.02f
389  };
390 
391  new GUIFrame(new RectTransform(new Vector2(0.01f, 1.0f), bottomRightArea.RectTransform), style: "VerticalLine");
392 
393  var temperatureArea = new GUILayoutGroup(new RectTransform(new Vector2(0.1f, 1), bottomRightArea.RectTransform, Anchor.Center), isHorizontal: false)
394  {
395  Stretch = true,
396  RelativeSpacing = 0.01f
397  };
398 
399  temperatureBoostUpButton = new GUIButton(new RectTransform(Vector2.One, temperatureArea.RectTransform, scaleBasis: ScaleBasis.BothWidth), style: "GUIPlusButton")
400  {
401  ToolTip = TextManager.Get("reactor.temperatureboostup"),
402  OnClicked = (_, __) =>
403  {
404  unsentChanges = true;
405  sendUpdateTimer = 0.0f;
406  ApplyTemperatureBoost(TemperatureBoostAmount);
407  return true;
408  }
409  };
410  new GUICustomComponent(new RectTransform(Vector2.One, temperatureArea.RectTransform, Anchor.Center), DrawTempMeter, null);
411 
412  temperatureBoostDownButton = new GUIButton(new RectTransform(Vector2.One, temperatureArea.RectTransform, scaleBasis: ScaleBasis.BothWidth), style: "GUIMinusButton")
413  {
414  ToolTip = TextManager.Get("reactor.temperatureboostdown"),
415  OnClicked = (_, __) =>
416  {
417  unsentChanges = true;
418  sendUpdateTimer = 0.0f;
419  ApplyTemperatureBoost(-TemperatureBoostAmount);
420  return true;
421  }
422  };
423 
424  var graphArea = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), bottomRightArea.RectTransform))
425  {
426  Stretch = true,
427  RelativeSpacing = 0.02f
428  };
429 
430  relativeTextSize = new Vector2(1.0f, 0.15f);
431  var loadText = new GUITextBlock(new RectTransform(relativeTextSize, graphArea.RectTransform),
432  "Load", textColor: loadColor, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft)
433  {
434  ToolTip = TextManager.Get("ReactorTipLoad")
435  };
436  LocalizedString loadStr = TextManager.Get("ReactorLoad");
437  LocalizedString kW = TextManager.Get("kilowatt");
438  loadText.TextGetter += () => $"{loadStr.Replace("[kw]", ((int)Load).ToString())} {kW}";
439 
440  var graphFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.9f), graphArea.RectTransform), style: "InnerFrameRed");
441  graph = new GUICustomComponent(new RectTransform(new Vector2(0.9f, 0.98f), graphFrame.RectTransform, Anchor.Center), DrawGraph, null);
442 
443  var outputText = new GUITextBlock(new RectTransform(relativeTextSize, graphArea.RectTransform),
444  "Output", textColor: outputColor, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft)
445  {
446  ToolTip = TextManager.Get("ReactorTipPower")
447  };
448  LocalizedString outputStr = TextManager.Get("ReactorOutput");
449  outputText.TextGetter += () => $"{outputStr.Replace("[kw]", ((int)-currPowerConsumption).ToString())} {kW}";
450 
451  InitInventoryUI();
452 
453  // Infographic overlay ---------------------
454  int buttonHeight = (int)(GUIStyle.ItemFrameMargin.Y * 0.4f);
455  var helpButtonRt = new RectTransform(new Point(buttonHeight), parent: GuiFrame.RectTransform, anchor: Anchor.TopRight)
456  {
457  AbsoluteOffset = new Point(buttonHeight / 4),
458  MinSize = new Point(buttonHeight)
459  };
460  new GUIButton(helpButtonRt, "", style: "HelpIcon")
461  {
462  OnClicked = (_, _) =>
463  {
464  CreateInfrographic();
465  return true;
466  }
467  };
468  }
469  private void ApplyTemperatureBoost(float amount)
470  {
471  if (Math.Abs(temperatureBoost) <= TemperatureBoostAmount * 0.9f &&
472  Math.Abs(amount) > TemperatureBoostAmount * 0.9f)
473  {
474  var sound = amount > 0 ? temperatureBoostSoundUp : temperatureBoostSoundDown;
475  if (sound != null)
476  {
477  SoundPlayer.PlaySound(
478  sound.Sound,
480  sound.Volume,
481  sound.Range,
482  freqMult: sound.GetRandomFrequencyMultiplier(),
483  hullGuess: item.CurrentHull);
484  }
485  }
486  temperatureBoost = amount;
487  }
488 
489  private void InitInventoryUI()
490  {
491  var itemContainer = item.GetComponent<ItemContainer>();
492  if (itemContainer != null)
493  {
494  itemContainer.UILabel = "";
495  itemContainer.AllowUIOverlap = true;
496  itemContainer.Inventory.RectTransform = inventoryContainer.RectTransform;
497  }
498  }
499 
500  public override void OnItemLoaded()
501  {
502  base.OnItemLoaded();
505  InitInventoryUI();
506  }
507 
508  private void DrawTempMeter(SpriteBatch spriteBatch, GUICustomComponent container)
509  {
510  Vector2 meterPos = new Vector2(container.Rect.X, container.Rect.Y);
511  Vector2 meterScale = new Vector2(container.Rect.Width / (float)tempMeterFrame.SourceRect.Width, container.Rect.Height / (float)tempMeterFrame.SourceRect.Height);
512  tempMeterFrame.Draw(spriteBatch, meterPos, Color.White, tempMeterFrame.Origin, 0.0f, scale: meterScale);
513 
514  float tempFill = temperature / 100.0f;
515  float meterBarScale = container.Rect.Width / (float)tempMeterBar.SourceRect.Width;
516  Vector2 meterBarPos = new Vector2(container.Center.X, container.Rect.Bottom - tempMeterBar.size.Y * meterBarScale - (int)(5 * GUI.yScale));
517  while (meterBarPos.Y > container.Rect.Bottom + (int)(5 * GUI.yScale) - container.Rect.Height * tempFill)
518  {
519  float tempRatio = 1.0f - ((meterBarPos.Y - container.Rect.Y) / container.Rect.Height);
520  Color color = ToolBox.GradientLerp(tempRatio, temperatureColors);
521  tempMeterBar.Draw(spriteBatch, meterBarPos, color: color, scale: meterBarScale);
522  int spacing = 2;
523  meterBarPos.Y -= tempMeterBar.size.Y * meterBarScale + spacing;
524  }
525 
526  if (temperature > optimalTemperature.Y)
527  {
528  GUI.DrawRectangle(spriteBatch,
529  meterPos,
530  new Vector2(container.Rect.Width, (container.Rect.Bottom - container.Rect.Height * optimalTemperature.Y / 100.0f) - container.Rect.Y),
531  warningColor * (float)Math.Sin(Timing.TotalTime * 5.0f) * 0.7f, isFilled: true);
532  }
533  if (temperature < optimalTemperature.X)
534  {
535  GUI.DrawRectangle(spriteBatch,
536  new Vector2(meterPos.X, container.Rect.Bottom - container.Rect.Height * optimalTemperature.X / 100.0f),
537  new Vector2(container.Rect.Width, container.Rect.Bottom - (container.Rect.Bottom - container.Rect.Height * optimalTemperature.X / 100.0f)),
538  warningColor * (float)Math.Sin(Timing.TotalTime * 5.0f) * 0.7f, isFilled: true);
539  }
540 
541  float tempRangeIndicatorScale = container.Rect.Width / (float)tempRangeIndicator.SourceRect.Width;
542  tempRangeIndicator.Draw(spriteBatch, new Vector2(container.Center.X, container.Rect.Bottom - container.Rect.Height * optimalTemperature.X / 100.0f), Color.White, tempRangeIndicator.Origin, 0, scale: tempRangeIndicatorScale);
543  tempRangeIndicator.Draw(spriteBatch, new Vector2(container.Center.X, container.Rect.Bottom - container.Rect.Height * optimalTemperature.Y / 100.0f), Color.White, tempRangeIndicator.Origin, 0, scale: tempRangeIndicatorScale);
544  }
545 
546  private void DrawGraph(SpriteBatch spriteBatch, GUICustomComponent container)
547  {
548  if (item.Removed) { return; }
549  float maxLoad = loadGraph.Max();
550  float xOffset = graphTimer / updateGraphInterval;
551  Rectangle graphRect = new Rectangle(container.Rect.X, container.Rect.Y, container.Rect.Width, container.Rect.Height - (int)(5 * GUI.yScale));
552  DrawGraph(outputGraph, spriteBatch, graphRect, Math.Max(10000.0f, maxLoad), xOffset, outputColor);
553  DrawGraph(loadGraph, spriteBatch, graphRect, Math.Max(10000.0f, maxLoad), xOffset, loadColor);
554  }
555 
556  private void UpdateGraph(float deltaTime)
557  {
558  graphTimer += deltaTime * 1000.0f;
559 
560  if (graphTimer > updateGraphInterval)
561  {
562  UpdateGraph(outputGraph, -currPowerConsumption);
563  UpdateGraph(loadGraph, Load);
564 
565  graphTimer = 0.0f;
566  }
567 
568  if (autoTemp)
569  {
572  }
573  }
574 
575  private void DrawFissionRateMeter(SpriteBatch spriteBatch, GUICustomComponent container)
576  {
577  if (item.Removed) { return; }
578 
579  Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
580  spriteBatch.End();
581  spriteBatch.GraphicsDevice.ScissorRectangle = container.Rect;
582  spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
583 
584  //make the pointer jitter a bit if it's at the upper limit of the fission rate
585  float jitter = 0.0f;
586  if (FissionRate > allowedFissionRate.Y - 5.0f)
587  {
588  float jitterAmount = Math.Min(TargetFissionRate - allowedFissionRate.Y, 10.0f);
589  float t = graphTimer / updateGraphInterval;
590 
591  jitter = (PerlinNoise.GetPerlin(t * 0.5f, t * 0.1f) - 0.5f) * jitterAmount;
592  }
593 
594  DrawMeter(spriteBatch, container.Rect,
595  fissionRateMeter, FissionRate + jitter, new Vector2(0.0f, 100.0f), optimalFissionRate, allowedFissionRate);
596 
597  spriteBatch.End();
598  spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
599  spriteBatch.Begin(SpriteSortMode.Deferred);
600  }
601 
602  private void DrawTurbineOutputMeter(SpriteBatch spriteBatch, GUICustomComponent container)
603  {
604  if (item.Removed) { return; }
605 
606  Vector2 clampedOptimalTurbineOutput = optimalTurbineOutput;
607  Vector2 clampedAllowedTurbineOutput = allowedTurbineOutput;
608  if (clampedOptimalTurbineOutput.X > 100.0f)
609  {
610  clampedOptimalTurbineOutput = new Vector2(92.0f, 110.0f);
611  clampedAllowedTurbineOutput = new Vector2(85.0f, 110.0f);
612  }
613 
614  DrawMeter(spriteBatch, container.Rect,
615  turbineOutputMeter, TurbineOutput, new Vector2(0.0f, 100.0f), clampedOptimalTurbineOutput, clampedAllowedTurbineOutput);
616  }
617 
618  public override void UpdateHUDComponentSpecific(Character character, float deltaTime, Camera cam)
619  {
620  IsActive = true;
621 
622  bool lightOn = Timing.TotalTime % 0.5f < 0.25f && PowerOn;
623 
624  criticalHeatWarning.Selected = temperature > allowedTemperature.Y && lightOn;
625  lowTemperatureWarning.Selected = temperature < allowedTemperature.X && lightOn;
626  criticalOutputWarning.Selected = -currPowerConsumption > Load * 1.5f && lightOn;
627 
628  warningButtons["ReactorWarningOverheating"].Selected = temperature > optimalTemperature.Y && lightOn;
629  warningButtons["ReactorWarningHighOutput"].Selected = -currPowerConsumption > Load * 1.1f && lightOn;
630  warningButtons["ReactorWarningLowTemp"].Selected = temperature < optimalTemperature.X && lightOn;
631  warningButtons["ReactorWarningLowOutput"].Selected = -currPowerConsumption < Load * 0.9f && lightOn;
632  warningButtons["ReactorWarningFuelOut"].Selected = prevAvailableFuel < fissionRate * 0.01f && lightOn;
633  warningButtons["ReactorWarningLowFuel"].Selected = prevAvailableFuel < fissionRate && lightOn;
634  warningButtons["ReactorWarningMeltdown"].Selected = meltDownTimer > MeltdownDelay * 0.5f || item.Condition == 0.0f && lightOn;
635  warningButtons["ReactorWarningSCRAM"].Selected = temperature > 0.1f && !PowerOn;
636 
637  if (paddedFrame.Rect.Contains(PlayerInput.MousePosition) &&
638  !PlayerInput.KeyDown(InputType.Deselect) && !PlayerInput.KeyHit(InputType.Deselect))
639  {
640  Character.DisableControls = true;
641  }
642 
643  if (!PowerOn)
644  {
647  }
648  else if (!autoTemp && Character.DisableControls && GUI.KeyboardDispatcher.Subscriber == null)
649  {
650  Vector2 input = Vector2.Zero;
651  float rate = 50.0f; //percentage per second
652 
653  if (PlayerInput.KeyDown(InputType.Left)) input.X += -1.0f;
654  if (PlayerInput.KeyDown(InputType.Right)) input.X += 1.0f;
655  if (PlayerInput.KeyDown(InputType.Up)) input.Y += 1.0f;
656  if (PlayerInput.KeyDown(InputType.Down)) input.Y += -1.0f;
657  if (PlayerInput.KeyDown(InputType.Run))
658  rate = 200.0f;
659  else if (PlayerInput.KeyDown(InputType.Crouch))
660  rate = 20.0f;
661 
662  rate *= deltaTime;
663  input.X *= rate;
664  input.Y *= rate;
665 
666  if (input.LengthSquared() > 0)
667  {
669  unsentChanges = true;
670  if (input.X != 0.0f && GUIScrollBar.DraggingBar != FissionRateScrollBar)
671  {
672  TargetFissionRate = MathHelper.Clamp(TargetFissionRate + input.X, 0.0f, 100.0f);
673  FissionRateScrollBar.BarScroll += input.X / 100.0f;
674  }
675  if (input.Y != 0.0f && GUIScrollBar.DraggingBar != TurbineOutputScrollBar)
676  {
677  TargetTurbineOutput = MathHelper.Clamp(TargetTurbineOutput + input.Y, 0.0f, 100.0f);
678  TurbineOutputScrollBar.BarScroll += input.Y / 100.0f;
679  }
680  }
681  }
682 
683  if (GuiFrame is not null && GuiFrame.Visible && TriggerInfographic)
684  {
685  CreateInfrographic();
686  TriggerInfographic = false;
687  }
688  }
689 
690  private void DrawMeter(SpriteBatch spriteBatch, Rectangle rect, Sprite meterSprite, float value, Vector2 range, Vector2 optimalRange, Vector2 allowedRange)
691  {
692  float scale = Math.Min(rect.Width / meterSprite.size.X, rect.Height / meterSprite.size.Y);
693  Vector2 pos = new Vector2(rect.Center.X, rect.Y + meterSprite.Origin.Y * scale);
694 
695  Vector2 optimalRangeNormalized = new Vector2(
696  MathHelper.Clamp((optimalRange.X - range.X) / (range.Y - range.X), 0.0f, 0.95f),
697  MathHelper.Clamp((optimalRange.Y - range.X) / (range.Y - range.X), 0.0f, 1.0f));
698 
699  Vector2 allowedRangeNormalized = new Vector2(
700  MathHelper.Clamp((allowedRange.X - range.X) / (range.Y - range.X), 0.0f, 0.95f),
701  MathHelper.Clamp((allowedRange.Y - range.X) / (range.Y - range.X), 0.0f, 1.0f));
702 
703  Vector2 sectorRad = new Vector2(-1.35f, 1.35f);
704 
705  Vector2 optimalSectorRad = new Vector2(
706  MathHelper.Lerp(sectorRad.X, sectorRad.Y, optimalRangeNormalized.X),
707  MathHelper.Lerp(sectorRad.X, sectorRad.Y, optimalRangeNormalized.Y));
708 
709  Vector2 allowedSectorRad = new Vector2(
710  MathHelper.Lerp(sectorRad.X, sectorRad.Y, allowedRangeNormalized.X),
711  MathHelper.Lerp(sectorRad.X, sectorRad.Y, allowedRangeNormalized.Y));
712 
713  Vector2 pointerPos = pos - new Vector2(0, 30) * scale;
714 
715  float scaleMultiplier = 0.95f;
716  if (optimalRangeNormalized.X == optimalRangeNormalized.Y)
717  {
718  sectorSprite.Draw(spriteBatch, pointerPos, GUIStyle.Red, MathHelper.PiOver2, scale * scaleMultiplier);
719  }
720  else
721  {
722  spriteBatch.End();
723  Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
724  spriteBatch.GraphicsDevice.ScissorRectangle = new Rectangle(0, 0, GameMain.GraphicsWidth, (int)(pointerPos.Y + (meterSprite.size.Y - meterSprite.Origin.Y) * scale) - 3);
725  spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
726 
727  sectorSprite.Draw(spriteBatch, pointerPos, optimalRangeColor, MathHelper.PiOver2 + (allowedSectorRad.X + allowedSectorRad.Y) / 2.0f, scale * scaleMultiplier);
728  sectorSprite.Draw(spriteBatch, pointerPos, offRangeColor, optimalSectorRad.X, scale * scaleMultiplier);
729  sectorSprite.Draw(spriteBatch, pointerPos, warningColor, allowedSectorRad.X, scale * scaleMultiplier);
730  sectorSprite.Draw(spriteBatch, pointerPos, offRangeColor, MathHelper.Pi + optimalSectorRad.Y, scale * scaleMultiplier);
731  sectorSprite.Draw(spriteBatch, pointerPos, warningColor, MathHelper.Pi + allowedSectorRad.Y, scale * scaleMultiplier);
732 
733  spriteBatch.End();
734  spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
735  spriteBatch.Begin(SpriteSortMode.Deferred);
736  }
737 
738  meterSprite.Draw(spriteBatch, pos, 0, scale);
739 
740  float normalizedValue = (value - range.X) / (range.Y - range.X);
741  float valueRad = MathHelper.Lerp(sectorRad.X, sectorRad.Y, normalizedValue);
742  meterPointer.Draw(spriteBatch, pointerPos, valueRad, scale);
743  }
744 
745  static void UpdateGraph<T>(IList<T> graph, T newValue)
746  {
747  for (int i = graph.Count - 1; i > 0; i--)
748  {
749  graph[i] = graph[i - 1];
750  }
751  graph[0] = newValue;
752  }
753 
754  private void DrawGraph(IList<float> graph, SpriteBatch spriteBatch, Rectangle rect, float maxVal, float xOffset, Color color)
755  {
756  Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
757  spriteBatch.End();
758  spriteBatch.GraphicsDevice.ScissorRectangle = rect;
759  spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
760 
761  float lineWidth = (float)rect.Width / (float)(graph.Count - 2);
762  float yScale = (float)rect.Height / maxVal;
763 
764  Vector2 prevPoint = new Vector2(rect.Right, rect.Bottom - (graph[1] + (graph[0] - graph[1]) * xOffset) * yScale);
765 
766  float currX = rect.Right - ((xOffset - 1.0f) * lineWidth);
767 
768  for (int i = 1; i < graph.Count - 1; i++)
769  {
770  currX -= lineWidth;
771 
772  Vector2 newPoint = new Vector2(currX, rect.Bottom - graph[i] * yScale);
773 
774  if (graphLine?.Texture == null)
775  {
776  GUI.DrawLine(spriteBatch, prevPoint, newPoint - new Vector2(1.0f, 0), color);
777  }
778  else
779  {
780  Vector2 dir = Vector2.Normalize(newPoint - prevPoint);
781  GUI.DrawLine(spriteBatch, graphLine.Texture, prevPoint - dir, newPoint + dir, color, 0, 5);
782  }
783 
784  prevPoint = newPoint;
785  }
786 
787  Vector2 lastPoint = new Vector2(rect.X,
788  rect.Bottom - (graph[graph.Count - 1] + (graph[graph.Count - 2] - graph[graph.Count - 1]) * xOffset) * yScale);
789 
790  if (graphLine?.Texture == null)
791  {
792  GUI.DrawLine(spriteBatch, prevPoint, lastPoint, color);
793  }
794  else
795  {
796  GUI.DrawLine(spriteBatch, graphLine.Texture, prevPoint, lastPoint + (lastPoint - prevPoint), color, 0, 5);
797  }
798 
799  spriteBatch.End();
800  spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
801  spriteBatch.Begin(SpriteSortMode.Deferred);
802  }
803 
804  private enum InfographicArrowStyle { Straight, Curved };
805 
806  private void CreateInfrographic()
807  {
808  if (infographic != null) { return; }
809  var dimColor = Color.Lerp(Color.Black, Color.TransparentBlack, 0.25f);
810  // Dim reactor interface
811  infographic = new GUIFrame(new RectTransform(Vector2.One, GuiFrame.RectTransform))
812  {
813  CanBeFocused = false,
814  Color = dimColor
815  };
816  // Dim inventory window
817  new GUIFrame(new RectTransform(inventoryWindow.Rect.Size, infographic.RectTransform) { AbsoluteOffset = inventoryWindow.Rect.Location - GuiFrame.Rect.Location}, color: dimColor)
818  {
819  CanBeFocused = false
820  };
821  int arrowSize = (int)(70 * GUI.Scale);
822  var arrows = new Dictionary<string, GUIImage>()
823  {
824  { "fuelslots", CreateArrow(InfographicArrowStyle.Curved, inventoryWindow, Anchor.TopLeft, Pivot.TopRight, SpriteEffects.FlipVertically) },
825  { "temperature", CreateArrow(InfographicArrowStyle.Straight, temperatureBoostDownButton, Anchor.Center, Pivot.Center) },
826  { "automaticcontrol", CreateArrow(InfographicArrowStyle.Curved, AutoTempSwitch, Anchor.TopRight, Pivot.BottomRight, rotationDegrees: 90f) },
827  { "power", CreateArrow(InfographicArrowStyle.Straight, PowerButton, Anchor.BottomCenter, Pivot.TopCenter) }
828  };
829  CreateArrow(InfographicArrowStyle.Straight, FissionRateScrollBar, Anchor.Center, Pivot.Center);
830  CreateArrow(InfographicArrowStyle.Straight, TurbineOutputScrollBar, Anchor.Center, Pivot.Center);
831  CreateArrow(InfographicArrowStyle.Straight, graph, Anchor.TopLeft, Pivot.TopLeft, SpriteEffects.FlipHorizontally, additionalOffset: new Point(arrowSize / 2, 0));
832  CreateArrow(InfographicArrowStyle.Straight, graph, Anchor.BottomLeft, Pivot.BottomLeft, SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically, additionalOffset: new Point(arrowSize / 2, 0));
833  new GUICustomComponent(new RectTransform(Vector2.One, infographic.RectTransform),
834  onDraw: (sb, c) =>
835  {
836  DrawToolTip("fuelslots", Anchor.TopLeft, Pivot.BottomCenter, arrows["fuelslots"]);
837  DrawToolTip("fissionrate", Anchor.TopCenter, Pivot.TopCenter, buttonArea);
838  DrawToolTip("temperature", Anchor.BottomLeft, Pivot.TopLeft, arrows["temperature"]);
839  DrawToolTip("automaticcontrol", Anchor.TopLeft, Pivot.CenterRight, arrows["automaticcontrol"]);
840  DrawToolTip("power", Anchor.BottomCenter, Pivot.TopCenter, arrows["power"]);
841  DrawToolTip("load", Anchor.CenterLeft, Pivot.CenterLeft, graph);
842 
843  void DrawToolTip(string textTag, Anchor anchor, Pivot pivot, GUIComponent targetComponent)
844  {
845  GUIComponent.DrawToolTip(sb,
846  TextManager.Get($"infographic.reactor.{textTag}"),
847  targetComponent.Rect,
848  anchor: anchor,
849  pivot: pivot);
850  }
851  })
852  {
853  CanBeFocused = false
854  };
855  var closeButtonRt = new RectTransform(new Point(200, 50).Multiply(GUI.Scale), infographic.RectTransform, Anchor.TopRight, Pivot.BottomRight)
856  {
857  AbsoluteOffset = new Point(0, -50).Multiply(GUI.Scale)
858  };
859  new GUIButton(closeButtonRt, TextManager.Get("closeinfographic"))
860  {
861  UserData = UIHighlightAction.ElementId.CloseButton,
862  OnClicked = (_, _) =>
863  {
864  CloseInfographic(Character.Controlled);
865  return true;
866  }
867  };
868  item.OnDeselect += CloseInfographic;
869 
870  GUIImage CreateArrow(InfographicArrowStyle arrowStyle, GUIComponent parent, Anchor anchor, Pivot pivot, SpriteEffects spriteEffects = SpriteEffects.None, float rotationDegrees = 0f, Point? additionalOffset = null)
871  {
872  Point offset = (additionalOffset ?? Point.Zero) + RectTransform.CalculateAnchorPoint(anchor, parent.Rect) - GuiFrame.Rect.Location;
873  var rt = new RectTransform(new Point(arrowSize), infographic.RectTransform, pivot: pivot)
874  {
875  AbsoluteOffset = offset
876  };
877  string style = arrowStyle == InfographicArrowStyle.Straight ? "InfographicArrow" : "InfographicArrowCurved";
878  return new GUIImage(rt, style)
879  {
880  CanBeFocused = false,
881  Rotation = MathHelper.ToRadians(rotationDegrees),
882  SpriteEffects = spriteEffects
883  };
884  }
885 
886  void CloseInfographic(Character character)
887  {
888  if (character != Character.Controlled) { return; }
889  GuiFrame.RemoveChild(infographic);
890  infographic = null;
891  item.OnDeselect -= CloseInfographic;
892  }
893  }
894 
895  protected override void RemoveComponentSpecific()
896  {
897  base.RemoveComponentSpecific();
898  graphLine?.Remove();
899  fissionRateMeter?.Remove();
900  turbineOutputMeter?.Remove();
901  meterPointer?.Remove();
902  sectorSprite?.Remove();
903  tempMeterFrame?.Remove();
904  tempMeterBar?.Remove();
905  tempRangeIndicator?.Remove();
906  }
907 
908  public void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData = null)
909  {
910  msg.WriteBoolean(autoTemp);
911  msg.WriteBoolean(PowerOn);
912  msg.WriteRangedSingle(TargetFissionRate, 0.0f, 100.0f, 8);
913  msg.WriteRangedSingle(TargetTurbineOutput, 0.0f, 100.0f, 8);
914  msg.WriteRangedSingle(temperatureBoost, -TemperatureBoostAmount, TemperatureBoostAmount, 8);
915 
916  correctionTimer = CorrectionDelay;
917  }
918 
919  public void ClientEventRead(IReadMessage msg, float sendingTime)
920  {
921  if (correctionTimer > 0.0f)
922  {
923  StartDelayedCorrection(msg.ExtractBits(1 + 1 + 8 + 8 + 8 + 8 + 8), sendingTime);
924  return;
925  }
926 
927  AutoTemp = msg.ReadBoolean();
928  PowerOn = msg.ReadBoolean();
929  Temperature = msg.ReadRangedSingle(0.0f, 100.0f, 8);
930  TargetFissionRate = msg.ReadRangedSingle(0.0f, 100.0f, 8);
931  TargetTurbineOutput = msg.ReadRangedSingle(0.0f, 100.0f, 8);
932  degreeOfSuccess = msg.ReadRangedSingle(0.0f, 1.0f, 8);
933  ApplyTemperatureBoost(msg.ReadRangedSingle(-TemperatureBoostAmount, TemperatureBoostAmount, 8));
934 
935  if (Math.Abs(FissionRateScrollBar.BarScroll - TargetFissionRate / 100.0f) > 0.01f)
936  {
937  FissionRateScrollBar.BarScroll = TargetFissionRate / 100.0f;
938  }
939  if (Math.Abs(TurbineOutputScrollBar.BarScroll - TargetTurbineOutput / 100.0f) > 0.01f)
940  {
941  TurbineOutputScrollBar.BarScroll = TargetTurbineOutput / 100.0f;
942  }
943 
944  IsActive = true;
945  }
946 
947  private void UpdateUIElementStates()
948  {
949  if (powerLight != null)
950  {
951  powerLight.Selected = _powerOn;
952  }
953  if (AutoTempSwitch != null)
954  {
955  AutoTempSwitch.Selected = autoTemp;
956  AutoTempSwitch.Enabled = _powerOn;
957  }
958  if (autoTempLight != null)
959  {
960  autoTempLight.Selected = autoTemp && _powerOn;
961  }
962  if (FissionRateScrollBar != null)
963  {
964  FissionRateScrollBar.Enabled = _powerOn && !autoTemp;
965  }
966  if (TurbineOutputScrollBar != null)
967  {
968  TurbineOutputScrollBar.Enabled = _powerOn && !autoTemp;
969  }
970  }
971  }
972 }
ContentXElement? GetChildElement(string name)
virtual void RemoveChild(GUIComponent child)
Definition: GUIComponent.cs:87
virtual Rectangle Rect
RectTransform RectTransform
GUIComponent that can be used to render custom content on the UI
static GUIScrollBar DraggingBar
Definition: GUIScrollBar.cs:10
void OverrideTextColor(Color color)
Overrides the color for all the states.
bool AutoScaleHorizontal
When enabled, the text is automatically scaled down to fit the textblock horizontally.
static void AutoScaleAndNormalize(params GUITextBlock[] textBlocks)
Set the text scale of the GUITextBlocks so that they all use the same scale and can fit the text with...
GUITextBlock TextBlock
Definition: GUITickBox.cs:93
override bool Selected
Definition: GUITickBox.cs:18
static int GraphicsWidth
Definition: GameMain.cs:162
static RasterizerState ScissorTestEnable
Definition: GameMain.cs:195
float currPowerConsumption
The amount of power currently consumed by the item. Negative values mean that the item is providing p...
override void UpdateHUDComponentSpecific(Character character, float deltaTime, Camera cam)
override void OnItemLoaded()
Called when all the components of the item have been loaded. Use to initialize connections between co...
override void CreateGUI()
Overload this method and implement. The method is automatically called when the resolution changes.
void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData=null)
static bool KeyDown(InputType inputType)
Point?? MinSize
Min size in pixels. Does not affect scaling.
Point?? MaxSize
Max size in pixels. Does not affect scaling.
RichString Replace(string from, string to, StringComparison stringComparison=StringComparison.Ordinal)
Definition: RichString.cs:139
static ? RoundSound Load(ContentXElement element, bool stream=false)
Definition: RoundSound.cs:61
void Draw(ISpriteBatch spriteBatch, Vector2 pos, float rotate=0.0f, float scale=1.0f, SpriteEffects spriteEffect=SpriteEffects.None)
Highlights an UI element of some kind. Generally used in tutorials.
Interface for entities that the clients can send events to the server
Single ReadRangedSingle(Single min, Single max, int bitCount)
Interface for entities that the server can send events to the clients
void WriteRangedSingle(Single val, Single min, Single max, int bitCount)
GUISoundType
Definition: GUI.cs:21
CursorState
Definition: GUI.cs:40