4 using Microsoft.Xna.Framework;
5 using Microsoft.Xna.Framework.Graphics;
7 using System.Collections.Generic;
20 private const int GraphSize = 25;
21 private float graphTimer;
22 private readonly
int updateGraphInterval = 500;
24 private Sprite fissionRateMeter, turbineOutputMeter;
25 private Sprite meterPointer;
26 private Sprite sectorSprite;
28 private Sprite tempMeterFrame, tempMeterBar;
29 private Sprite tempRangeIndicator;
38 private Color optimalRangeColor =
new Color(74,238,104,255);
39 private Color offRangeColor = Color.Orange;
40 private Color warningColor = Color.Red;
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;
46 private RoundSound temperatureBoostSoundUp, temperatureBoostSoundDown;
47 private GUIButton temperatureBoostUpButton, temperatureBoostDownButton;
53 private readonly
float[] outputGraph =
new float[GraphSize];
54 private readonly
float[] loadGraph =
new float[GraphSize];
64 private readonly Dictionary<string, GUIButton> warningButtons =
new Dictionary<string, GUIButton>();
66 private static readonly
string[] warningTexts =
new string[]
68 "ReactorWarningLowTemp",
"ReactorWarningLowOutput",
"ReactorWarningLowFuel",
"ReactorWarningMeltdown",
69 "ReactorWarningOverheating",
"ReactorWarningHighOutput",
"ReactorWarningFuelOut",
"ReactorWarningSCRAM"
90 foreach (var subElement
in element.Elements())
92 switch (subElement.Name.ToString().ToLowerInvariant())
94 case "temperatureboostsoundup":
97 case "temperatureboostsounddown":
106 warningButtons.Clear();
110 { AbsoluteOffset = GUIStyle.ItemFrameOffset },
115 AlwaysOverrideCursor =
true,
116 RelativeSpacing = 0.012f,
122 RelativeSpacing = 0.012f,
128 RelativeSpacing = 0.012f,
138 MinSize = new Point(85, 220),
139 RelativeOffset = new Vector2(-0.02f, 0)
143 { AbsoluteOffset = GUIStyle.ItemFrameOffset },
144 childAnchor:
Anchor.TopCenter)
158 isHorizontal:
true, childAnchor:
Anchor.CenterLeft)
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")
170 ToolTip = TextManager.Get(
"ReactorHeatTip")
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")
177 ToolTip = TextManager.Get(
"ReactorOutputTip")
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")
184 ToolTip = TextManager.Get(
"ReactorTempTip")
186 List<GUITickBox> indicatorLights =
new List<GUITickBox>() { criticalHeatWarning, lowTemperatureWarning, criticalOutputWarning };
187 indicatorLights.ForEach(l => l.TextBlock.OverrideTextColor(GUIStyle.TextColorNormal));
188 topLeftArea.Recalculate();
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);
198 var leftArea =
new GUIFrame(
new RectTransform(
new Vector2(0.49f, 1), meterArea.RectTransform), style:
null);
202 TextManager.Get(
"ReactorFissionRate"), textColor: GUIStyle.TextColorNormal, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
204 AutoScaleHorizontal =
true
208 RelativeOffset = new Vector2(0.0f, relativeTextSize.Y + relativeYMargin)
210 DrawFissionRateMeter,
null)
212 ToolTip = TextManager.Get(
"ReactorTipFissionRate")
216 TextManager.Get(
"ReactorTurbineOutput"), textColor: GUIStyle.TextColorNormal, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
218 AutoScaleHorizontal =
true
224 RelativeOffset = new Vector2(0.0f, relativeTextSize.Y + relativeYMargin)
226 DrawTurbineOutputMeter,
null)
228 ToolTip = TextManager.Get(
"ReactorTipTurbineOutput")
233 RelativeOffset = new Vector2(0, fissionMeter.RectTransform.RelativeOffset.Y + meterSize.Y + relativeYMargin)
235 style:
"DeviceSlider", barSize: 0.15f)
242 unsentChanges =
true;
252 RelativeOffset = new Vector2(0, turbineMeter.RectTransform.RelativeOffset.Y + meterSize.Y + relativeYMargin)
254 style:
"DeviceSlider", barSize: 0.15f, isHorizontal:
true)
261 unsentChanges =
true;
272 RelativeSpacing = 0.02f
277 RelativeSpacing = 0.01f
282 RelativeSpacing = 0.01f
284 int buttonCount = warningTexts.Length;
285 for (
int i = 0; i < buttonCount; i++)
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")
291 Font = GUIStyle.SubHeadingFont,
294 warningButtons.Add(text, b);
296 upperButtons.Recalculate();
297 lowerButtons.Recalculate();
299 warningButtons.Values.ForEach(b => b.TextBlock.Wrap = b.Text.Contains(
' ') && b.TextBlock.TextSize.X > b.TextBlock.Rect.Width * 1.5f);
308 isHorizontal:
true, childAnchor:
Anchor.CenterLeft)
311 RelativeSpacing = 0.02f
314 topRightArea.RectTransform.MaxSize =
new Point(
int.MaxValue, topLeftArea.Rect.Height);
316 new GUIFrame(
new RectTransform(
new Vector2(0.01f, 1.0f), topRightArea.RectTransform), style:
"VerticalLine");
319 style:
"SwitchVertical")
325 OnClicked = (button, data) =>
329 unsentChanges =
true;
336 TextManager.Get(
"ReactorAutoTemp"), font: GUIStyle.SubHeadingFont, style:
"IndicatorLightYellow")
338 ToolTip = TextManager.Get(
"ReactorTipAutoTemp"),
339 CanBeFocused =
false,
345 new GUIFrame(
new RectTransform(
new Vector2(0.01f, 1.0f), topRightArea.RectTransform), style:
"VerticalLine");
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");
351 TextManager.Get(
"PowerLabel"), font: GUIStyle.SubHeadingFont, style:
"IndicatorLightPower")
353 CanBeFocused =
false,
361 RelativeOffset = new Vector2(0, 0.1f)
362 }, style:
"PowerButton")
365 OnClicked = (button, data) =>
369 unsentChanges =
true;
374 topRightArea.Recalculate();
388 RelativeSpacing = 0.02f
391 new GUIFrame(
new RectTransform(
new Vector2(0.01f, 1.0f), bottomRightArea.RectTransform), style:
"VerticalLine");
396 RelativeSpacing = 0.01f
399 temperatureBoostUpButton =
new GUIButton(
new RectTransform(Vector2.One, temperatureArea.RectTransform, scaleBasis:
ScaleBasis.BothWidth), style:
"GUIPlusButton")
401 ToolTip = TextManager.Get(
"reactor.temperatureboostup"),
402 OnClicked = (_, __) =>
404 unsentChanges =
true;
405 sendUpdateTimer = 0.0f;
406 ApplyTemperatureBoost(TemperatureBoostAmount);
412 temperatureBoostDownButton =
new GUIButton(
new RectTransform(Vector2.One, temperatureArea.RectTransform, scaleBasis:
ScaleBasis.BothWidth), style:
"GUIMinusButton")
414 ToolTip = TextManager.Get(
"reactor.temperatureboostdown"),
415 OnClicked = (_, __) =>
417 unsentChanges =
true;
418 sendUpdateTimer = 0.0f;
419 ApplyTemperatureBoost(-TemperatureBoostAmount);
427 RelativeSpacing = 0.02f
430 relativeTextSize =
new Vector2(1.0f, 0.15f);
432 "Load", textColor: loadColor, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft)
434 ToolTip = TextManager.Get(
"ReactorTipLoad")
438 loadText.TextGetter += () => $
"{loadStr.Replace("[kw]
", ((int)Load).ToString())} {kW}";
440 var graphFrame =
new GUIFrame(
new RectTransform(
new Vector2(1.0f, 0.9f), graphArea.RectTransform), style:
"InnerFrameRed");
444 "Output", textColor: outputColor, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft)
446 ToolTip = TextManager.Get(
"ReactorTipPower")
449 outputText.TextGetter += () => $
"{outputStr.Replace("[kw]
", ((int)-currPowerConsumption).ToString())} {kW}";
454 int buttonHeight = (int)(GUIStyle.ItemFrameMargin.Y * 0.4f);
457 AbsoluteOffset =
new Point(buttonHeight / 4),
458 MinSize =
new Point(buttonHeight)
460 new GUIButton(helpButtonRt,
"", style:
"HelpIcon")
462 OnClicked = (_, _) =>
464 CreateInfrographic();
469 private void ApplyTemperatureBoost(
float amount)
471 if (Math.Abs(temperatureBoost) <= TemperatureBoostAmount * 0.9f &&
472 Math.Abs(amount) > TemperatureBoostAmount * 0.9f)
474 var sound = amount > 0 ? temperatureBoostSoundUp : temperatureBoostSoundDown;
477 SoundPlayer.PlaySound(
482 freqMult: sound.GetRandomFrequencyMultiplier(),
486 temperatureBoost = amount;
489 private void InitInventoryUI()
491 var itemContainer =
item.GetComponent<ItemContainer>();
492 if (itemContainer !=
null)
494 itemContainer.UILabel =
"";
495 itemContainer.AllowUIOverlap =
true;
496 itemContainer.Inventory.RectTransform = inventoryContainer.
RectTransform;
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);
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)
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);
523 meterBarPos.Y -= tempMeterBar.
size.Y * meterBarScale + spacing;
526 if (temperature > optimalTemperature.Y)
528 GUI.DrawRectangle(spriteBatch,
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);
533 if (temperature < optimalTemperature.X)
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);
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);
546 private void DrawGraph(SpriteBatch spriteBatch, GUICustomComponent container)
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);
556 private void UpdateGraph(
float deltaTime)
558 graphTimer += deltaTime * 1000.0f;
560 if (graphTimer > updateGraphInterval)
563 UpdateGraph(loadGraph,
Load);
575 private void DrawFissionRateMeter(SpriteBatch spriteBatch, GUICustomComponent container)
579 Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
581 spriteBatch.GraphicsDevice.ScissorRectangle = container.Rect;
582 spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
589 float t = graphTimer / updateGraphInterval;
591 jitter = (PerlinNoise.GetPerlin(t * 0.5f, t * 0.1f) - 0.5f) * jitterAmount;
594 DrawMeter(spriteBatch, container.Rect,
595 fissionRateMeter,
FissionRate + jitter,
new Vector2(0.0f, 100.0f), optimalFissionRate, allowedFissionRate);
598 spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
599 spriteBatch.Begin(SpriteSortMode.Deferred);
602 private void DrawTurbineOutputMeter(SpriteBatch spriteBatch, GUICustomComponent container)
606 Vector2 clampedOptimalTurbineOutput = optimalTurbineOutput;
607 Vector2 clampedAllowedTurbineOutput = allowedTurbineOutput;
608 if (clampedOptimalTurbineOutput.X > 100.0f)
610 clampedOptimalTurbineOutput =
new Vector2(92.0f, 110.0f);
611 clampedAllowedTurbineOutput =
new Vector2(85.0f, 110.0f);
614 DrawMeter(spriteBatch, container.Rect,
615 turbineOutputMeter,
TurbineOutput,
new Vector2(0.0f, 100.0f), clampedOptimalTurbineOutput, clampedAllowedTurbineOutput);
622 bool lightOn = Timing.TotalTime % 0.5f < 0.25f &&
PowerOn;
624 criticalHeatWarning.
Selected = temperature > allowedTemperature.Y && lightOn;
625 lowTemperatureWarning.
Selected = temperature < allowedTemperature.X && lightOn;
628 warningButtons[
"ReactorWarningOverheating"].Selected = temperature > optimalTemperature.Y && lightOn;
630 warningButtons[
"ReactorWarningLowTemp"].Selected = temperature < optimalTemperature.X && 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;
650 Vector2 input = Vector2.Zero;
666 if (input.LengthSquared() > 0)
669 unsentChanges =
true;
685 CreateInfrographic();
690 private void DrawMeter(SpriteBatch spriteBatch, Rectangle rect,
Sprite meterSprite,
float value, Vector2 range, Vector2 optimalRange, Vector2 allowedRange)
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);
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));
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));
703 Vector2 sectorRad =
new Vector2(-1.35f, 1.35f);
705 Vector2 optimalSectorRad =
new Vector2(
706 MathHelper.Lerp(sectorRad.X, sectorRad.Y, optimalRangeNormalized.X),
707 MathHelper.Lerp(sectorRad.X, sectorRad.Y, optimalRangeNormalized.Y));
709 Vector2 allowedSectorRad =
new Vector2(
710 MathHelper.Lerp(sectorRad.X, sectorRad.Y, allowedRangeNormalized.X),
711 MathHelper.Lerp(sectorRad.X, sectorRad.Y, allowedRangeNormalized.Y));
713 Vector2 pointerPos = pos -
new Vector2(0, 30) * scale;
715 float scaleMultiplier = 0.95f;
716 if (optimalRangeNormalized.X == optimalRangeNormalized.Y)
718 sectorSprite.
Draw(spriteBatch, pointerPos, GUIStyle.Red, MathHelper.PiOver2, scale * scaleMultiplier);
723 Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
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);
734 spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
735 spriteBatch.Begin(SpriteSortMode.Deferred);
738 meterSprite.
Draw(spriteBatch, pos, 0, scale);
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);
745 static void UpdateGraph<T>(IList<T> graph, T newValue)
747 for (
int i = graph.Count - 1; i > 0; i--)
749 graph[i] = graph[i - 1];
754 private void DrawGraph(IList<float> graph, SpriteBatch spriteBatch, Rectangle rect,
float maxVal,
float xOffset, Color color)
756 Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
758 spriteBatch.GraphicsDevice.ScissorRectangle = rect;
759 spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
761 float lineWidth = (float)rect.Width / (
float)(graph.Count - 2);
762 float yScale = (float)rect.Height / maxVal;
764 Vector2 prevPoint =
new Vector2(rect.Right, rect.Bottom - (graph[1] + (graph[0] - graph[1]) * xOffset) * yScale);
766 float currX = rect.Right - ((xOffset - 1.0f) * lineWidth);
768 for (
int i = 1; i < graph.Count - 1; i++)
772 Vector2 newPoint =
new Vector2(currX, rect.Bottom - graph[i] * yScale);
774 if (graphLine?.Texture ==
null)
776 GUI.DrawLine(spriteBatch, prevPoint, newPoint -
new Vector2(1.0f, 0), color);
780 Vector2 dir = Vector2.Normalize(newPoint - prevPoint);
781 GUI.DrawLine(spriteBatch, graphLine.
Texture, prevPoint - dir, newPoint + dir, color, 0, 5);
784 prevPoint = newPoint;
787 Vector2 lastPoint =
new Vector2(rect.X,
788 rect.Bottom - (graph[graph.Count - 1] + (graph[graph.Count - 2] - graph[graph.Count - 1]) * xOffset) * yScale);
790 if (graphLine?.Texture ==
null)
792 GUI.DrawLine(spriteBatch, prevPoint, lastPoint, color);
796 GUI.DrawLine(spriteBatch, graphLine.
Texture, prevPoint, lastPoint + (lastPoint - prevPoint), color, 0, 5);
800 spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
801 spriteBatch.Begin(SpriteSortMode.Deferred);
804 private enum InfographicArrowStyle {
Straight, Curved };
806 private void CreateInfrographic()
808 if (infographic !=
null) {
return; }
809 var dimColor = Color.Lerp(Color.Black, Color.TransparentBlack, 0.25f);
813 CanBeFocused =
false,
817 new GUIFrame(
new RectTransform(inventoryWindow.
Rect.Size, infographic.
RectTransform) { AbsoluteOffset = inventoryWindow.Rect.Location - GuiFrame.Rect.Location}, color: dimColor)
821 int arrowSize = (int)(70 * GUI.Scale);
822 var arrows =
new Dictionary<string, GUIImage>()
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) }
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),
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);
843 void DrawToolTip(string textTag, Anchor anchor, Pivot pivot, GUIComponent targetComponent)
845 GUIComponent.DrawToolTip(sb,
846 TextManager.Get($
"infographic.reactor.{textTag}"),
847 targetComponent.Rect,
855 var closeButtonRt =
new RectTransform(
new Point(200, 50).Multiply(GUI.Scale), infographic.
RectTransform,
Anchor.TopRight,
Pivot.BottomRight)
857 AbsoluteOffset =
new Point(0, -50).Multiply(GUI.Scale)
859 new GUIButton(closeButtonRt, TextManager.Get(
"closeinfographic"))
862 OnClicked = (_, _) =>
870 GUIImage CreateArrow(InfographicArrowStyle arrowStyle, GUIComponent parent,
Anchor anchor,
Pivot pivot, SpriteEffects spriteEffects = SpriteEffects.None,
float rotationDegrees = 0f, Point? additionalOffset =
null)
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)
875 AbsoluteOffset = offset
877 string style = arrowStyle == InfographicArrowStyle.Straight ?
"InfographicArrow" :
"InfographicArrowCurved";
878 return new GUIImage(rt, style)
880 CanBeFocused =
false,
881 Rotation = MathHelper.ToRadians(rotationDegrees),
882 SpriteEffects = spriteEffects
886 void CloseInfographic(Character character)
888 if (character !=
Character.Controlled) {
return; }
897 base.RemoveComponentSpecific();
899 fissionRateMeter?.
Remove();
900 turbineOutputMeter?.
Remove();
905 tempRangeIndicator?.
Remove();
914 msg.
WriteRangedSingle(temperatureBoost, -TemperatureBoostAmount, TemperatureBoostAmount, 8);
916 correctionTimer = CorrectionDelay;
921 if (correctionTimer > 0.0f)
923 StartDelayedCorrection(msg.ExtractBits(1 + 1 + 8 + 8 + 8 + 8 + 8), sendingTime);
933 ApplyTemperatureBoost(msg.
ReadRangedSingle(-TemperatureBoostAmount, TemperatureBoostAmount, 8));
935 if (Math.Abs(FissionRateScrollBar.BarScroll - TargetFissionRate / 100.0f) > 0.01f)
937 FissionRateScrollBar.BarScroll = TargetFissionRate / 100.0f;
939 if (Math.Abs(TurbineOutputScrollBar.BarScroll - TargetTurbineOutput / 100.0f) > 0.01f)
941 TurbineOutputScrollBar.BarScroll = TargetTurbineOutput / 100.0f;
947 private void UpdateUIElementStates()
949 if (powerLight !=
null)
953 if (AutoTempSwitch !=
null)
955 AutoTempSwitch.Selected = autoTemp;
956 AutoTempSwitch.Enabled = _powerOn;
958 if (autoTempLight !=
null)
960 autoTempLight.
Selected = autoTemp && _powerOn;
962 if (FissionRateScrollBar !=
null)
964 FissionRateScrollBar.Enabled = _powerOn && !autoTemp;
966 if (TurbineOutputScrollBar !=
null)
968 TurbineOutputScrollBar.Enabled = _powerOn && !autoTemp;
static bool DisableControls
static Character? Controlled
ContentXElement? GetChildElement(string name)
virtual void RemoveChild(GUIComponent child)
RectTransform RectTransform
GUIComponent that can be used to render custom content on the UI
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...
static RasterizerState ScissorTestEnable
Action< Character > OnDeselect
float currPowerConsumption
The amount of power currently consumed by the item. Negative values mean that the item is providing p...
bool IsInfographicVisible
void ClientEventRead(IReadMessage msg, float sendingTime)
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 RemoveComponentSpecific()
GUIScrollBar TurbineOutputScrollBar
override void CreateGUI()
Overload this method and implement. The method is automatically called when the resolution changes.
float TargetTurbineOutput
GUIScrollBar FissionRateScrollBar
override bool RecreateGUIOnResolutionChange
void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData=null)
RichString Replace(string from, string to, StringComparison stringComparison=StringComparison.Ordinal)
static ? RoundSound Load(ContentXElement element, bool stream=false)
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)
void WriteBoolean(bool val)