970 lines
47 KiB
C#
970 lines
47 KiB
C#
using Barotrauma.Extensions;
|
|
using Barotrauma.Networking;
|
|
using Barotrauma.Sounds;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Barotrauma.Items.Components
|
|
{
|
|
partial class Reactor : Powered, IServerSerializable, IClientSerializable
|
|
{
|
|
public GUIButton AutoTempSwitch { get; private set; }
|
|
|
|
public GUIButton PowerButton { get; private set; }
|
|
private GUITickBox powerLight;
|
|
private GUITickBox autoTempLight;
|
|
|
|
private const int GraphSize = 25;
|
|
private float graphTimer;
|
|
private readonly int updateGraphInterval = 500;
|
|
|
|
private Sprite fissionRateMeter, turbineOutputMeter;
|
|
private Sprite meterPointer;
|
|
private Sprite sectorSprite;
|
|
|
|
private Sprite tempMeterFrame, tempMeterBar;
|
|
private Sprite tempRangeIndicator;
|
|
|
|
private Sprite graphLine;
|
|
private GUICustomComponent graph;
|
|
|
|
private GUIFrame inventoryWindow;
|
|
private GUILayoutGroup buttonArea;
|
|
private GUIFrame infographic;
|
|
|
|
private Color optimalRangeColor = new Color(74,238,104,255);
|
|
private Color offRangeColor = Color.Orange;
|
|
private Color warningColor = Color.Red;
|
|
|
|
private readonly Color[] temperatureColors = new Color[] { Color.Blue, Color.LightBlue, Color.Orange, Color.Red };
|
|
private Color outputColor = Color.Goldenrod;
|
|
private Color loadColor = Color.LightSteelBlue;
|
|
|
|
private RoundSound temperatureBoostSoundUp, temperatureBoostSoundDown;
|
|
private GUIButton temperatureBoostUpButton, temperatureBoostDownButton;
|
|
|
|
public GUIScrollBar FissionRateScrollBar { get; private set; }
|
|
|
|
public GUIScrollBar TurbineOutputScrollBar { get; private set; }
|
|
|
|
private readonly float[] outputGraph = new float[GraphSize];
|
|
private readonly float[] loadGraph = new float[GraphSize];
|
|
|
|
private GUITickBox criticalHeatWarning;
|
|
private GUITickBox lowTemperatureWarning;
|
|
private GUITickBox criticalOutputWarning;
|
|
|
|
private GUIFrame inventoryContainer;
|
|
|
|
private GUILayoutGroup paddedFrame;
|
|
|
|
private readonly Dictionary<string, GUIButton> warningButtons = new Dictionary<string, GUIButton>();
|
|
|
|
private static readonly string[] warningTexts = new string[]
|
|
{
|
|
"ReactorWarningLowTemp", "ReactorWarningLowOutput", "ReactorWarningLowFuel", "ReactorWarningMeltdown",
|
|
"ReactorWarningOverheating", "ReactorWarningHighOutput", "ReactorWarningFuelOut", "ReactorWarningSCRAM"
|
|
};
|
|
|
|
public override bool RecreateGUIOnResolutionChange => true;
|
|
|
|
public bool TriggerInfographic { get; set; }
|
|
|
|
public bool IsInfographicVisible => infographic != null && infographic.Visible;
|
|
|
|
partial void InitProjSpecific(ContentXElement element)
|
|
{
|
|
CreateGUI();
|
|
fissionRateMeter = new Sprite(element.GetChildElement("fissionratemeter")?.GetChildElement("sprite"));
|
|
turbineOutputMeter = new Sprite(element.GetChildElement("turbineoutputmeter")?.GetChildElement("sprite"));
|
|
meterPointer = new Sprite(element.GetChildElement("meterpointer")?.GetChildElement("sprite"));
|
|
sectorSprite = new Sprite(element.GetChildElement("sectorsprite")?.GetChildElement("sprite"));
|
|
tempMeterFrame = new Sprite(element.GetChildElement("tempmeterframe")?.GetChildElement("sprite"));
|
|
tempMeterBar = new Sprite(element.GetChildElement("tempmeterbar")?.GetChildElement("sprite"));
|
|
tempRangeIndicator = new Sprite(element.GetChildElement("temprangeindicator")?.GetChildElement("sprite"));
|
|
graphLine = new Sprite(element.GetChildElement("graphline")?.GetChildElement("sprite"));
|
|
|
|
foreach (var subElement in element.Elements())
|
|
{
|
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
|
{
|
|
case "temperatureboostsoundup":
|
|
temperatureBoostSoundUp = RoundSound.Load(subElement);
|
|
break;
|
|
case "temperatureboostsounddown":
|
|
temperatureBoostSoundDown = RoundSound.Load(subElement);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void CreateGUI()
|
|
{
|
|
warningButtons.Clear();
|
|
|
|
paddedFrame = new GUILayoutGroup(new RectTransform(
|
|
GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin, GuiFrame.RectTransform, Anchor.Center)
|
|
{ AbsoluteOffset = GUIStyle.ItemFrameOffset },
|
|
isHorizontal: true)
|
|
{
|
|
CanBeFocused = true,
|
|
HoverCursor = CursorState.Default,
|
|
AlwaysOverrideCursor = true,
|
|
RelativeSpacing = 0.012f,
|
|
Stretch = true
|
|
};
|
|
|
|
GUILayoutGroup columnLeft = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), paddedFrame.RectTransform))
|
|
{
|
|
RelativeSpacing = 0.012f,
|
|
Stretch = true
|
|
};
|
|
GUILayoutGroup columnRight = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 1.0f), paddedFrame.RectTransform))
|
|
{
|
|
CanBeFocused = true,
|
|
RelativeSpacing = 0.012f,
|
|
Stretch = true
|
|
};
|
|
|
|
//----------------------------------------------------------
|
|
//left column
|
|
//----------------------------------------------------------
|
|
|
|
inventoryWindow = new GUIFrame(new RectTransform(new Vector2(0.1f, 0.75f), GuiFrame.RectTransform, Anchor.TopLeft, Pivot.TopRight)
|
|
{
|
|
MinSize = new Point(85, 220),
|
|
RelativeOffset = new Vector2(-0.02f, 0)
|
|
}, style: "ItemUI");
|
|
|
|
GUILayoutGroup inventoryContent = new GUILayoutGroup(new RectTransform(inventoryWindow.Rect.Size - GUIStyle.ItemFrameMargin, inventoryWindow.RectTransform, Anchor.Center)
|
|
{ AbsoluteOffset = GUIStyle.ItemFrameOffset },
|
|
childAnchor: Anchor.TopCenter)
|
|
{
|
|
Stretch = true
|
|
};
|
|
|
|
/*new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), inventoryContent.RectTransform), "",
|
|
textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont, wrap: true);*/
|
|
inventoryContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.9f), inventoryContent.RectTransform), style: null);
|
|
|
|
//----------------------------------------------------------
|
|
//mid column
|
|
//----------------------------------------------------------
|
|
|
|
var topLeftArea = new GUILayoutGroup(new RectTransform(new Vector2(1, 0.2f), columnLeft.RectTransform),
|
|
isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
|
{
|
|
Stretch = true
|
|
};
|
|
|
|
|
|
Point maxIndicatorSize = new Point(int.MaxValue, (int)(40 * GUI.Scale));
|
|
criticalHeatWarning = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), topLeftArea.RectTransform) { MaxSize = maxIndicatorSize },
|
|
TextManager.Get("ReactorWarningCriticalTemp"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightRed")
|
|
{
|
|
Selected = false,
|
|
Enabled = false,
|
|
ToolTip = TextManager.Get("ReactorHeatTip")
|
|
};
|
|
criticalOutputWarning = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), topLeftArea.RectTransform) { MaxSize = maxIndicatorSize },
|
|
TextManager.Get("ReactorWarningCriticalOutput"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightRed")
|
|
{
|
|
Selected = false,
|
|
Enabled = false,
|
|
ToolTip = TextManager.Get("ReactorOutputTip")
|
|
};
|
|
lowTemperatureWarning = new GUITickBox(new RectTransform(new Vector2(0.4f, 1.0f), topLeftArea.RectTransform) { MaxSize = maxIndicatorSize },
|
|
TextManager.Get("ReactorWarningCriticalLowTemp"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightRed")
|
|
{
|
|
Selected = false,
|
|
Enabled = false,
|
|
ToolTip = TextManager.Get("ReactorTempTip")
|
|
};
|
|
List<GUITickBox> indicatorLights = new List<GUITickBox>() { criticalHeatWarning, lowTemperatureWarning, criticalOutputWarning };
|
|
indicatorLights.ForEach(l => l.TextBlock.OverrideTextColor(GUIStyle.TextColorNormal));
|
|
topLeftArea.Recalculate();
|
|
|
|
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), columnLeft.RectTransform), style: "HorizontalLine");
|
|
|
|
float relativeYMargin = 0.02f;
|
|
Vector2 relativeTextSize = new Vector2(0.9f, 0.15f);
|
|
Vector2 sliderSize = new Vector2(1.0f, 0.125f);
|
|
Vector2 meterSize = new Vector2(1, 1 - relativeTextSize.Y - relativeYMargin - sliderSize.Y - 0.1f);
|
|
|
|
var meterArea = new GUIFrame(new RectTransform(new Vector2(1, 0.6f - relativeYMargin * 2), columnLeft.RectTransform), style: null);
|
|
var leftArea = new GUIFrame(new RectTransform(new Vector2(0.49f, 1), meterArea.RectTransform), style: null);
|
|
var rightArea = new GUIFrame(new RectTransform(new Vector2(0.49f, 1), meterArea.RectTransform, Anchor.TopCenter, Pivot.TopLeft), style: null);
|
|
|
|
var fissionRateTextBox = new GUITextBlock(new RectTransform(relativeTextSize, leftArea.RectTransform, Anchor.TopCenter),
|
|
TextManager.Get("ReactorFissionRate"), textColor: GUIStyle.TextColorNormal, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
|
|
{
|
|
AutoScaleHorizontal = true
|
|
};
|
|
var fissionMeter = new GUICustomComponent(new RectTransform(meterSize, leftArea.RectTransform, Anchor.TopCenter)
|
|
{
|
|
RelativeOffset = new Vector2(0.0f, relativeTextSize.Y + relativeYMargin)
|
|
},
|
|
DrawFissionRateMeter, null)
|
|
{
|
|
ToolTip = TextManager.Get("ReactorTipFissionRate")
|
|
};
|
|
|
|
var turbineOutputTextBox = new GUITextBlock(new RectTransform(relativeTextSize, rightArea.RectTransform, Anchor.TopCenter),
|
|
TextManager.Get("ReactorTurbineOutput"), textColor: GUIStyle.TextColorNormal, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
|
|
{
|
|
AutoScaleHorizontal = true
|
|
};
|
|
GUITextBlock.AutoScaleAndNormalize(turbineOutputTextBox, fissionRateTextBox);
|
|
|
|
var turbineMeter = new GUICustomComponent(new RectTransform(meterSize, rightArea.RectTransform, Anchor.TopCenter)
|
|
{
|
|
RelativeOffset = new Vector2(0.0f, relativeTextSize.Y + relativeYMargin)
|
|
},
|
|
DrawTurbineOutputMeter, null)
|
|
{
|
|
ToolTip = TextManager.Get("ReactorTipTurbineOutput")
|
|
};
|
|
|
|
FissionRateScrollBar = new GUIScrollBar(new RectTransform(sliderSize, leftArea.RectTransform, Anchor.TopCenter)
|
|
{
|
|
RelativeOffset = new Vector2(0, fissionMeter.RectTransform.RelativeOffset.Y + meterSize.Y + relativeYMargin)
|
|
},
|
|
style: "DeviceSlider", barSize: 0.15f)
|
|
{
|
|
Enabled = false,
|
|
Step = 1.0f / 255,
|
|
OnMoved = (GUIScrollBar bar, float scrollAmount) =>
|
|
{
|
|
LastUser = Character.Controlled;
|
|
unsentChanges = true;
|
|
TargetFissionRate = scrollAmount * 100.0f;
|
|
|
|
return false;
|
|
}
|
|
};
|
|
FissionRateScrollBar.Frame.UserData = UIHighlightAction.ElementId.FissionRateSlider;
|
|
|
|
TurbineOutputScrollBar = new GUIScrollBar(new RectTransform(sliderSize, rightArea.RectTransform, Anchor.TopCenter)
|
|
{
|
|
RelativeOffset = new Vector2(0, turbineMeter.RectTransform.RelativeOffset.Y + meterSize.Y + relativeYMargin)
|
|
},
|
|
style: "DeviceSlider", barSize: 0.15f, isHorizontal: true)
|
|
{
|
|
Enabled = false,
|
|
Step = 1.0f / 255,
|
|
OnMoved = (GUIScrollBar bar, float scrollAmount) =>
|
|
{
|
|
LastUser = Character.Controlled;
|
|
unsentChanges = true;
|
|
TargetTurbineOutput = scrollAmount * 100.0f;
|
|
|
|
return false;
|
|
}
|
|
};
|
|
TurbineOutputScrollBar.Frame.UserData = UIHighlightAction.ElementId.TurbineOutputSlider;
|
|
|
|
buttonArea = new GUILayoutGroup(new RectTransform(new Vector2(1, 0.2f), columnLeft.RectTransform))
|
|
{
|
|
Stretch = true,
|
|
RelativeSpacing = 0.02f
|
|
};
|
|
var upperButtons = new GUILayoutGroup(new RectTransform(new Vector2(1, 0.5f), buttonArea.RectTransform), isHorizontal: true)
|
|
{
|
|
Stretch = true,
|
|
RelativeSpacing = 0.01f
|
|
};
|
|
var lowerButtons = new GUILayoutGroup(new RectTransform(new Vector2(1, 0.5f), buttonArea.RectTransform), isHorizontal: true)
|
|
{
|
|
Stretch = true,
|
|
RelativeSpacing = 0.01f
|
|
};
|
|
int buttonCount = warningTexts.Length;
|
|
for (int i = 0; i < buttonCount; i++)
|
|
{
|
|
string text = warningTexts[i];
|
|
var b = new GUIButton(new RectTransform(Vector2.One, (i < 4) ? upperButtons.RectTransform : lowerButtons.RectTransform),
|
|
TextManager.Get(text), style: "IndicatorButton")
|
|
{
|
|
Font = GUIStyle.SubHeadingFont,
|
|
CanBeFocused = false
|
|
};
|
|
warningButtons.Add(text, b);
|
|
}
|
|
upperButtons.Recalculate();
|
|
lowerButtons.Recalculate();
|
|
//only wrap texts that consist of multiple words and are way too big to fit otherwise
|
|
warningButtons.Values.ForEach(b => b.TextBlock.Wrap = b.Text.Contains(' ') && b.TextBlock.TextSize.X > b.TextBlock.Rect.Width * 1.5f);
|
|
GUITextBlock.AutoScaleAndNormalize(warningButtons.Values.Select(b => b.TextBlock));
|
|
|
|
//----------------------------------------------------------
|
|
//right column
|
|
//----------------------------------------------------------
|
|
|
|
// Auto temp
|
|
var topRightArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), columnRight.RectTransform),
|
|
isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
|
{
|
|
Stretch = true,
|
|
RelativeSpacing = 0.02f
|
|
};
|
|
topRightArea.RectTransform.MinSize = new Point(0, topLeftArea.Rect.Height);
|
|
topRightArea.RectTransform.MaxSize = new Point(int.MaxValue, topLeftArea.Rect.Height);
|
|
|
|
new GUIFrame(new RectTransform(new Vector2(0.01f, 1.0f), topRightArea.RectTransform), style: "VerticalLine");
|
|
|
|
AutoTempSwitch = new GUIButton(new RectTransform(new Vector2(0.15f, 0.9f), topRightArea.RectTransform),
|
|
style: "SwitchVertical")
|
|
{
|
|
UserData = UIHighlightAction.ElementId.AutoTempSwitch,
|
|
Enabled = false,
|
|
Selected = AutoTemp,
|
|
ClickSound = GUISoundType.UISwitch,
|
|
OnClicked = (button, data) =>
|
|
{
|
|
AutoTemp = !AutoTemp;
|
|
LastUser = Character.Controlled;
|
|
unsentChanges = true;
|
|
return true;
|
|
}
|
|
};
|
|
AutoTempSwitch.RectTransform.MaxSize = new Point((int)(AutoTempSwitch.Rect.Height * 0.4f), int.MaxValue);
|
|
|
|
autoTempLight = new GUITickBox(new RectTransform(new Vector2(0.4f, 1.0f), topRightArea.RectTransform),
|
|
TextManager.Get("ReactorAutoTemp"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightYellow")
|
|
{
|
|
ToolTip = TextManager.Get("ReactorTipAutoTemp"),
|
|
CanBeFocused = false,
|
|
Selected = AutoTemp
|
|
};
|
|
autoTempLight.RectTransform.MaxSize = new Point(int.MaxValue, criticalHeatWarning.Rect.Height);
|
|
autoTempLight.TextBlock.OverrideTextColor(GUIStyle.TextColorNormal);
|
|
|
|
new GUIFrame(new RectTransform(new Vector2(0.01f, 1.0f), topRightArea.RectTransform), style: "VerticalLine");
|
|
|
|
// Power button
|
|
var powerArea = new GUIFrame(new RectTransform(new Vector2(0.4f, 1.0f), topRightArea.RectTransform), style: null);
|
|
var paddedPowerArea = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), powerArea.RectTransform, Anchor.Center, scaleBasis: ScaleBasis.BothHeight), style: "PowerButtonFrame");
|
|
powerLight = new GUITickBox(new RectTransform(new Vector2(0.87f, 0.3f), paddedPowerArea.RectTransform, Anchor.TopCenter, Pivot.Center),
|
|
TextManager.Get("PowerLabel"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightPower")
|
|
{
|
|
CanBeFocused = false,
|
|
Selected = _powerOn
|
|
};
|
|
powerLight.TextBlock.Padding = new Vector4(5.0f, 0.0f, 0.0f, 0.0f);
|
|
powerLight.TextBlock.AutoScaleHorizontal = true;
|
|
powerLight.TextBlock.OverrideTextColor(GUIStyle.TextColorNormal);
|
|
PowerButton = new GUIButton(new RectTransform(new Vector2(0.8f, 0.75f), paddedPowerArea.RectTransform, Anchor.BottomCenter)
|
|
{
|
|
RelativeOffset = new Vector2(0, 0.1f)
|
|
}, style: "PowerButton")
|
|
{
|
|
UserData = UIHighlightAction.ElementId.PowerButton,
|
|
OnClicked = (button, data) =>
|
|
{
|
|
PowerOn = !PowerOn;
|
|
LastUser = Character.Controlled;
|
|
unsentChanges = true;
|
|
return true;
|
|
}
|
|
};
|
|
|
|
topRightArea.Recalculate();
|
|
autoTempLight.TextBlock.Padding = new Vector4(autoTempLight.TextBlock.Padding.X, 0.0f, 0.0f, 0.0f);
|
|
autoTempLight.TextBlock.Text = autoTempLight.TextBlock.Text.Replace(" ", "\n");
|
|
autoTempLight.TextBlock.AutoScaleHorizontal = true;
|
|
GUITextBlock.AutoScaleAndNormalize(indicatorLights.Select(l => l.TextBlock));
|
|
|
|
// right bottom (graph area) -----------------------
|
|
|
|
new GUIFrame(new RectTransform(new Vector2(0.95f, 0.01f), columnRight.RectTransform), style: "HorizontalLine");
|
|
|
|
var bottomRightArea = new GUILayoutGroup(new RectTransform(Vector2.One, columnRight.RectTransform), isHorizontal: true)
|
|
{
|
|
Stretch = true,
|
|
CanBeFocused = true,
|
|
RelativeSpacing = 0.02f
|
|
};
|
|
|
|
new GUIFrame(new RectTransform(new Vector2(0.01f, 1.0f), bottomRightArea.RectTransform), style: "VerticalLine");
|
|
|
|
var temperatureArea = new GUILayoutGroup(new RectTransform(new Vector2(0.1f, 1), bottomRightArea.RectTransform, Anchor.Center), isHorizontal: false)
|
|
{
|
|
Stretch = true,
|
|
RelativeSpacing = 0.01f
|
|
};
|
|
|
|
temperatureBoostUpButton = new GUIButton(new RectTransform(Vector2.One, temperatureArea.RectTransform, scaleBasis: ScaleBasis.BothWidth), style: "GUIPlusButton")
|
|
{
|
|
ToolTip = TextManager.Get("reactor.temperatureboostup"),
|
|
OnClicked = (_, __) =>
|
|
{
|
|
unsentChanges = true;
|
|
sendUpdateTimer = 0.0f;
|
|
ApplyTemperatureBoost(TemperatureBoostAmount);
|
|
return true;
|
|
}
|
|
};
|
|
new GUICustomComponent(new RectTransform(Vector2.One, temperatureArea.RectTransform, Anchor.Center), DrawTempMeter, null);
|
|
|
|
temperatureBoostDownButton = new GUIButton(new RectTransform(Vector2.One, temperatureArea.RectTransform, scaleBasis: ScaleBasis.BothWidth), style: "GUIMinusButton")
|
|
{
|
|
ToolTip = TextManager.Get("reactor.temperatureboostdown"),
|
|
OnClicked = (_, __) =>
|
|
{
|
|
unsentChanges = true;
|
|
sendUpdateTimer = 0.0f;
|
|
ApplyTemperatureBoost(-TemperatureBoostAmount);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
var graphArea = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), bottomRightArea.RectTransform))
|
|
{
|
|
Stretch = true,
|
|
RelativeSpacing = 0.02f
|
|
};
|
|
|
|
relativeTextSize = new Vector2(1.0f, 0.15f);
|
|
var loadText = new GUITextBlock(new RectTransform(relativeTextSize, graphArea.RectTransform),
|
|
"Load", textColor: loadColor, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft)
|
|
{
|
|
ToolTip = TextManager.Get("ReactorTipLoad")
|
|
};
|
|
LocalizedString loadStr = TextManager.Get("ReactorLoad");
|
|
LocalizedString kW = TextManager.Get("kilowatt");
|
|
loadText.TextGetter += () => $"{loadStr.Replace("[kw]", ((int)Load).ToString())} {kW}";
|
|
|
|
var graphFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.9f), graphArea.RectTransform), style: "InnerFrameRed");
|
|
graph = new GUICustomComponent(new RectTransform(new Vector2(0.9f, 0.98f), graphFrame.RectTransform, Anchor.Center), DrawGraph, null);
|
|
|
|
var outputText = new GUITextBlock(new RectTransform(relativeTextSize, graphArea.RectTransform),
|
|
"Output", textColor: outputColor, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft)
|
|
{
|
|
ToolTip = TextManager.Get("ReactorTipPower")
|
|
};
|
|
LocalizedString outputStr = TextManager.Get("ReactorOutput");
|
|
outputText.TextGetter += () => $"{outputStr.Replace("[kw]", ((int)-currPowerConsumption).ToString())} {kW}";
|
|
|
|
InitInventoryUI();
|
|
|
|
// Infographic overlay ---------------------
|
|
int buttonHeight = (int)(GUIStyle.ItemFrameMargin.Y * 0.4f);
|
|
var helpButtonRt = new RectTransform(new Point(buttonHeight), parent: GuiFrame.RectTransform, anchor: Anchor.TopRight)
|
|
{
|
|
AbsoluteOffset = new Point(buttonHeight / 4),
|
|
MinSize = new Point(buttonHeight)
|
|
};
|
|
new GUIButton(helpButtonRt, "", style: "HelpIcon")
|
|
{
|
|
OnClicked = (_, _) =>
|
|
{
|
|
CreateInfrographic();
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
private void ApplyTemperatureBoost(float amount)
|
|
{
|
|
if (Math.Abs(temperatureBoost) <= TemperatureBoostAmount * 0.9f &&
|
|
Math.Abs(amount) > TemperatureBoostAmount * 0.9f)
|
|
{
|
|
var sound = amount > 0 ? temperatureBoostSoundUp : temperatureBoostSoundDown;
|
|
if (sound != null)
|
|
{
|
|
SoundPlayer.PlaySound(
|
|
sound,
|
|
item.WorldPosition,
|
|
hullGuess: item.CurrentHull);
|
|
}
|
|
}
|
|
temperatureBoost = amount;
|
|
}
|
|
|
|
private void InitInventoryUI()
|
|
{
|
|
var itemContainer = item.GetComponent<ItemContainer>();
|
|
if (itemContainer != null)
|
|
{
|
|
itemContainer.UILabel = "";
|
|
itemContainer.AllowUIOverlap = true;
|
|
itemContainer.Inventory.RectTransform = inventoryContainer.RectTransform;
|
|
}
|
|
}
|
|
|
|
public override void OnItemLoaded()
|
|
{
|
|
base.OnItemLoaded();
|
|
TurbineOutputScrollBar.BarScroll = TargetTurbineOutput / 100.0f;
|
|
FissionRateScrollBar.BarScroll = TargetFissionRate / 100.0f;
|
|
InitInventoryUI();
|
|
}
|
|
|
|
private void DrawTempMeter(SpriteBatch spriteBatch, GUICustomComponent container)
|
|
{
|
|
Vector2 meterPos = new Vector2(container.Rect.X, container.Rect.Y);
|
|
Vector2 meterScale = new Vector2(container.Rect.Width / (float)tempMeterFrame.SourceRect.Width, container.Rect.Height / (float)tempMeterFrame.SourceRect.Height);
|
|
tempMeterFrame.Draw(spriteBatch, meterPos, Color.White, tempMeterFrame.Origin, 0.0f, scale: meterScale);
|
|
|
|
float tempFill = temperature / 100.0f;
|
|
float meterBarScale = container.Rect.Width / (float)tempMeterBar.SourceRect.Width;
|
|
Vector2 meterBarPos = new Vector2(container.Center.X, container.Rect.Bottom - tempMeterBar.size.Y * meterBarScale - (int)(5 * GUI.yScale));
|
|
while (meterBarPos.Y > container.Rect.Bottom + (int)(5 * GUI.yScale) - container.Rect.Height * tempFill)
|
|
{
|
|
float tempRatio = 1.0f - ((meterBarPos.Y - container.Rect.Y) / container.Rect.Height);
|
|
Color color = ToolBox.GradientLerp(tempRatio, temperatureColors);
|
|
tempMeterBar.Draw(spriteBatch, meterBarPos, color: color, scale: meterBarScale);
|
|
int spacing = 2;
|
|
meterBarPos.Y -= tempMeterBar.size.Y * meterBarScale + spacing;
|
|
}
|
|
|
|
if (temperature > optimalTemperature.Y)
|
|
{
|
|
GUI.DrawRectangle(spriteBatch,
|
|
meterPos,
|
|
new Vector2(container.Rect.Width, (container.Rect.Bottom - container.Rect.Height * optimalTemperature.Y / 100.0f) - container.Rect.Y),
|
|
warningColor * (float)Math.Sin(Timing.TotalTime * 5.0f) * 0.7f, isFilled: true);
|
|
}
|
|
if (temperature < optimalTemperature.X)
|
|
{
|
|
GUI.DrawRectangle(spriteBatch,
|
|
new Vector2(meterPos.X, container.Rect.Bottom - container.Rect.Height * optimalTemperature.X / 100.0f),
|
|
new Vector2(container.Rect.Width, container.Rect.Bottom - (container.Rect.Bottom - container.Rect.Height * optimalTemperature.X / 100.0f)),
|
|
warningColor * (float)Math.Sin(Timing.TotalTime * 5.0f) * 0.7f, isFilled: true);
|
|
}
|
|
|
|
float tempRangeIndicatorScale = container.Rect.Width / (float)tempRangeIndicator.SourceRect.Width;
|
|
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);
|
|
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);
|
|
}
|
|
|
|
private void DrawGraph(SpriteBatch spriteBatch, GUICustomComponent container)
|
|
{
|
|
if (item.Removed) { return; }
|
|
float maxLoad = loadGraph.Max();
|
|
float xOffset = graphTimer / updateGraphInterval;
|
|
Rectangle graphRect = new Rectangle(container.Rect.X, container.Rect.Y, container.Rect.Width, container.Rect.Height - (int)(5 * GUI.yScale));
|
|
DrawGraph(outputGraph, spriteBatch, graphRect, Math.Max(10000.0f, maxLoad), xOffset, outputColor);
|
|
DrawGraph(loadGraph, spriteBatch, graphRect, Math.Max(10000.0f, maxLoad), xOffset, loadColor);
|
|
}
|
|
|
|
private void UpdateGraph(float deltaTime)
|
|
{
|
|
graphTimer += deltaTime * 1000.0f;
|
|
|
|
if (graphTimer > updateGraphInterval)
|
|
{
|
|
UpdateGraph(outputGraph, -currPowerConsumption);
|
|
UpdateGraph(loadGraph, Load);
|
|
|
|
graphTimer = 0.0f;
|
|
}
|
|
|
|
if (autoTemp)
|
|
{
|
|
FissionRateScrollBar.BarScroll = FissionRate / 100.0f;
|
|
TurbineOutputScrollBar.BarScroll = TurbineOutput / 100.0f;
|
|
}
|
|
}
|
|
|
|
private void DrawFissionRateMeter(SpriteBatch spriteBatch, GUICustomComponent container)
|
|
{
|
|
if (item.Removed) { return; }
|
|
|
|
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
|
|
spriteBatch.End();
|
|
spriteBatch.GraphicsDevice.ScissorRectangle = container.Rect;
|
|
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
|
|
|
|
//make the pointer jitter a bit if it's at the upper limit of the fission rate
|
|
float jitter = 0.0f;
|
|
if (FissionRate > allowedFissionRate.Y - 5.0f)
|
|
{
|
|
float jitterAmount = Math.Min(TargetFissionRate - allowedFissionRate.Y, 10.0f);
|
|
float t = graphTimer / updateGraphInterval;
|
|
|
|
jitter = (PerlinNoise.GetPerlin(t * 0.5f, t * 0.1f) - 0.5f) * jitterAmount;
|
|
}
|
|
|
|
DrawMeter(spriteBatch, container.Rect,
|
|
fissionRateMeter, FissionRate + jitter, new Vector2(0.0f, 100.0f), optimalFissionRate, allowedFissionRate);
|
|
|
|
spriteBatch.End();
|
|
spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
|
|
spriteBatch.Begin(SpriteSortMode.Deferred);
|
|
}
|
|
|
|
private void DrawTurbineOutputMeter(SpriteBatch spriteBatch, GUICustomComponent container)
|
|
{
|
|
if (item.Removed) { return; }
|
|
|
|
Vector2 clampedOptimalTurbineOutput = optimalTurbineOutput;
|
|
Vector2 clampedAllowedTurbineOutput = allowedTurbineOutput;
|
|
if (clampedOptimalTurbineOutput.X > 100.0f)
|
|
{
|
|
clampedOptimalTurbineOutput = new Vector2(92.0f, 110.0f);
|
|
clampedAllowedTurbineOutput = new Vector2(85.0f, 110.0f);
|
|
}
|
|
|
|
DrawMeter(spriteBatch, container.Rect,
|
|
turbineOutputMeter, TurbineOutput, new Vector2(0.0f, 100.0f), clampedOptimalTurbineOutput, clampedAllowedTurbineOutput);
|
|
}
|
|
|
|
public override void UpdateHUDComponentSpecific(Character character, float deltaTime, Camera cam)
|
|
{
|
|
IsActive = true;
|
|
|
|
bool lightOn = Timing.TotalTime % 0.5f < 0.25f && PowerOn;
|
|
|
|
criticalHeatWarning.Selected = temperature > allowedTemperature.Y && lightOn;
|
|
lowTemperatureWarning.Selected = temperature < allowedTemperature.X && lightOn;
|
|
criticalOutputWarning.Selected = -currPowerConsumption > Load * 1.5f && lightOn;
|
|
|
|
warningButtons["ReactorWarningOverheating"].Selected = temperature > optimalTemperature.Y && lightOn;
|
|
warningButtons["ReactorWarningHighOutput"].Selected = -currPowerConsumption > Load * 1.1f && lightOn;
|
|
warningButtons["ReactorWarningLowTemp"].Selected = temperature < optimalTemperature.X && lightOn;
|
|
warningButtons["ReactorWarningLowOutput"].Selected = -currPowerConsumption < Load * 0.9f && lightOn;
|
|
warningButtons["ReactorWarningFuelOut"].Selected = prevAvailableFuel < fissionRate * 0.01f && lightOn;
|
|
warningButtons["ReactorWarningLowFuel"].Selected = prevAvailableFuel < fissionRate && lightOn;
|
|
warningButtons["ReactorWarningMeltdown"].Selected = meltDownTimer > MeltdownDelay * 0.5f || item.Condition == 0.0f && lightOn;
|
|
warningButtons["ReactorWarningSCRAM"].Selected = temperature > 0.1f && !PowerOn;
|
|
|
|
if (paddedFrame.Rect.Contains(PlayerInput.MousePosition) &&
|
|
!PlayerInput.KeyDown(InputType.Deselect) && !PlayerInput.KeyHit(InputType.Deselect))
|
|
{
|
|
Character.DisableControls = true;
|
|
}
|
|
|
|
if (!PowerOn)
|
|
{
|
|
FissionRateScrollBar.BarScroll = FissionRate / 100.0f;
|
|
TurbineOutputScrollBar.BarScroll = TurbineOutput / 100.0f;
|
|
}
|
|
else if (!autoTemp && Character.DisableControls && GUI.KeyboardDispatcher.Subscriber == null)
|
|
{
|
|
Vector2 input = Vector2.Zero;
|
|
float rate = 50.0f; //percentage per second
|
|
|
|
if (PlayerInput.KeyDown(InputType.Left)) input.X += -1.0f;
|
|
if (PlayerInput.KeyDown(InputType.Right)) input.X += 1.0f;
|
|
if (PlayerInput.KeyDown(InputType.Up)) input.Y += 1.0f;
|
|
if (PlayerInput.KeyDown(InputType.Down)) input.Y += -1.0f;
|
|
if (PlayerInput.KeyDown(InputType.Run))
|
|
rate = 200.0f;
|
|
else if (PlayerInput.KeyDown(InputType.Crouch))
|
|
rate = 20.0f;
|
|
|
|
rate *= deltaTime;
|
|
input.X *= rate;
|
|
input.Y *= rate;
|
|
|
|
if (input.LengthSquared() > 0)
|
|
{
|
|
LastUser = Character.Controlled;
|
|
unsentChanges = true;
|
|
if (input.X != 0.0f && GUIScrollBar.DraggingBar != FissionRateScrollBar)
|
|
{
|
|
TargetFissionRate = MathHelper.Clamp(TargetFissionRate + input.X, 0.0f, 100.0f);
|
|
FissionRateScrollBar.BarScroll += input.X / 100.0f;
|
|
}
|
|
if (input.Y != 0.0f && GUIScrollBar.DraggingBar != TurbineOutputScrollBar)
|
|
{
|
|
TargetTurbineOutput = MathHelper.Clamp(TargetTurbineOutput + input.Y, 0.0f, 100.0f);
|
|
TurbineOutputScrollBar.BarScroll += input.Y / 100.0f;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (GuiFrame is not null && GuiFrame.Visible && TriggerInfographic)
|
|
{
|
|
CreateInfrographic();
|
|
TriggerInfographic = false;
|
|
}
|
|
}
|
|
|
|
private void DrawMeter(SpriteBatch spriteBatch, Rectangle rect, Sprite meterSprite, float value, Vector2 range, Vector2 optimalRange, Vector2 allowedRange)
|
|
{
|
|
float scale = Math.Min(rect.Width / meterSprite.size.X, rect.Height / meterSprite.size.Y);
|
|
Vector2 pos = new Vector2(rect.Center.X, rect.Y + meterSprite.Origin.Y * scale);
|
|
|
|
Vector2 optimalRangeNormalized = new Vector2(
|
|
MathHelper.Clamp((optimalRange.X - range.X) / (range.Y - range.X), 0.0f, 0.95f),
|
|
MathHelper.Clamp((optimalRange.Y - range.X) / (range.Y - range.X), 0.0f, 1.0f));
|
|
|
|
Vector2 allowedRangeNormalized = new Vector2(
|
|
MathHelper.Clamp((allowedRange.X - range.X) / (range.Y - range.X), 0.0f, 0.95f),
|
|
MathHelper.Clamp((allowedRange.Y - range.X) / (range.Y - range.X), 0.0f, 1.0f));
|
|
|
|
Vector2 sectorRad = new Vector2(-1.35f, 1.35f);
|
|
|
|
Vector2 optimalSectorRad = new Vector2(
|
|
MathHelper.Lerp(sectorRad.X, sectorRad.Y, optimalRangeNormalized.X),
|
|
MathHelper.Lerp(sectorRad.X, sectorRad.Y, optimalRangeNormalized.Y));
|
|
|
|
Vector2 allowedSectorRad = new Vector2(
|
|
MathHelper.Lerp(sectorRad.X, sectorRad.Y, allowedRangeNormalized.X),
|
|
MathHelper.Lerp(sectorRad.X, sectorRad.Y, allowedRangeNormalized.Y));
|
|
|
|
Vector2 pointerPos = pos - new Vector2(0, 30) * scale;
|
|
|
|
float scaleMultiplier = 0.95f;
|
|
if (optimalRangeNormalized.X == optimalRangeNormalized.Y)
|
|
{
|
|
sectorSprite.Draw(spriteBatch, pointerPos, GUIStyle.Red, MathHelper.PiOver2, scale * scaleMultiplier);
|
|
}
|
|
else
|
|
{
|
|
spriteBatch.End();
|
|
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
|
|
spriteBatch.GraphicsDevice.ScissorRectangle = new Rectangle(0, 0, GameMain.GraphicsWidth, (int)(pointerPos.Y + (meterSprite.size.Y - meterSprite.Origin.Y) * scale) - 3);
|
|
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
|
|
|
|
sectorSprite.Draw(spriteBatch, pointerPos, optimalRangeColor, MathHelper.PiOver2 + (allowedSectorRad.X + allowedSectorRad.Y) / 2.0f, scale * scaleMultiplier);
|
|
sectorSprite.Draw(spriteBatch, pointerPos, offRangeColor, optimalSectorRad.X, scale * scaleMultiplier);
|
|
sectorSprite.Draw(spriteBatch, pointerPos, warningColor, allowedSectorRad.X, scale * scaleMultiplier);
|
|
sectorSprite.Draw(spriteBatch, pointerPos, offRangeColor, MathHelper.Pi + optimalSectorRad.Y, scale * scaleMultiplier);
|
|
sectorSprite.Draw(spriteBatch, pointerPos, warningColor, MathHelper.Pi + allowedSectorRad.Y, scale * scaleMultiplier);
|
|
|
|
spriteBatch.End();
|
|
spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
|
|
spriteBatch.Begin(SpriteSortMode.Deferred);
|
|
}
|
|
|
|
meterSprite.Draw(spriteBatch, pos, 0, scale);
|
|
|
|
float normalizedValue = (value - range.X) / (range.Y - range.X);
|
|
float valueRad = MathHelper.Lerp(sectorRad.X, sectorRad.Y, normalizedValue);
|
|
meterPointer.Draw(spriteBatch, pointerPos, valueRad, scale);
|
|
}
|
|
|
|
static void UpdateGraph<T>(IList<T> graph, T newValue)
|
|
{
|
|
for (int i = graph.Count - 1; i > 0; i--)
|
|
{
|
|
graph[i] = graph[i - 1];
|
|
}
|
|
graph[0] = newValue;
|
|
}
|
|
|
|
private void DrawGraph(IList<float> graph, SpriteBatch spriteBatch, Rectangle rect, float maxVal, float xOffset, Color color)
|
|
{
|
|
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
|
|
spriteBatch.End();
|
|
spriteBatch.GraphicsDevice.ScissorRectangle = rect;
|
|
spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable);
|
|
|
|
float lineWidth = (float)rect.Width / (float)(graph.Count - 2);
|
|
float yScale = (float)rect.Height / maxVal;
|
|
|
|
Vector2 prevPoint = new Vector2(rect.Right, rect.Bottom - (graph[1] + (graph[0] - graph[1]) * xOffset) * yScale);
|
|
|
|
float currX = rect.Right - ((xOffset - 1.0f) * lineWidth);
|
|
|
|
for (int i = 1; i < graph.Count - 1; i++)
|
|
{
|
|
currX -= lineWidth;
|
|
|
|
Vector2 newPoint = new Vector2(currX, rect.Bottom - graph[i] * yScale);
|
|
|
|
if (graphLine?.Texture == null)
|
|
{
|
|
GUI.DrawLine(spriteBatch, prevPoint, newPoint - new Vector2(1.0f, 0), color);
|
|
}
|
|
else
|
|
{
|
|
Vector2 dir = Vector2.Normalize(newPoint - prevPoint);
|
|
GUI.DrawLine(spriteBatch, graphLine.Texture, prevPoint - dir, newPoint + dir, color, 0, 5);
|
|
}
|
|
|
|
prevPoint = newPoint;
|
|
}
|
|
|
|
Vector2 lastPoint = new Vector2(rect.X,
|
|
rect.Bottom - (graph[graph.Count - 1] + (graph[graph.Count - 2] - graph[graph.Count - 1]) * xOffset) * yScale);
|
|
|
|
if (graphLine?.Texture == null)
|
|
{
|
|
GUI.DrawLine(spriteBatch, prevPoint, lastPoint, color);
|
|
}
|
|
else
|
|
{
|
|
GUI.DrawLine(spriteBatch, graphLine.Texture, prevPoint, lastPoint + (lastPoint - prevPoint), color, 0, 5);
|
|
}
|
|
|
|
spriteBatch.End();
|
|
spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect;
|
|
spriteBatch.Begin(SpriteSortMode.Deferred);
|
|
}
|
|
|
|
private enum InfographicArrowStyle { Straight, Curved };
|
|
|
|
private void CreateInfrographic()
|
|
{
|
|
if (infographic != null) { return; }
|
|
var dimColor = Color.Lerp(Color.Black, Color.TransparentBlack, 0.25f);
|
|
// Dim reactor interface
|
|
infographic = new GUIFrame(new RectTransform(Vector2.One, GuiFrame.RectTransform))
|
|
{
|
|
CanBeFocused = false,
|
|
Color = dimColor
|
|
};
|
|
// Dim inventory window
|
|
new GUIFrame(new RectTransform(inventoryWindow.Rect.Size, infographic.RectTransform) { AbsoluteOffset = inventoryWindow.Rect.Location - GuiFrame.Rect.Location}, color: dimColor)
|
|
{
|
|
CanBeFocused = false
|
|
};
|
|
int arrowSize = (int)(70 * GUI.Scale);
|
|
var arrows = new Dictionary<string, GUIImage>()
|
|
{
|
|
{ "fuelslots", CreateArrow(InfographicArrowStyle.Curved, inventoryWindow, Anchor.TopLeft, Pivot.TopRight, SpriteEffects.FlipVertically) },
|
|
{ "temperature", CreateArrow(InfographicArrowStyle.Straight, temperatureBoostDownButton, Anchor.Center, Pivot.Center) },
|
|
{ "automaticcontrol", CreateArrow(InfographicArrowStyle.Curved, AutoTempSwitch, Anchor.TopRight, Pivot.BottomRight, rotationDegrees: 90f) },
|
|
{ "power", CreateArrow(InfographicArrowStyle.Straight, PowerButton, Anchor.BottomCenter, Pivot.TopCenter) }
|
|
};
|
|
CreateArrow(InfographicArrowStyle.Straight, FissionRateScrollBar, Anchor.Center, Pivot.Center);
|
|
CreateArrow(InfographicArrowStyle.Straight, TurbineOutputScrollBar, Anchor.Center, Pivot.Center);
|
|
CreateArrow(InfographicArrowStyle.Straight, graph, Anchor.TopLeft, Pivot.TopLeft, SpriteEffects.FlipHorizontally, additionalOffset: new Point(arrowSize / 2, 0));
|
|
CreateArrow(InfographicArrowStyle.Straight, graph, Anchor.BottomLeft, Pivot.BottomLeft, SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically, additionalOffset: new Point(arrowSize / 2, 0));
|
|
new GUICustomComponent(new RectTransform(Vector2.One, infographic.RectTransform),
|
|
onDraw: (sb, c) =>
|
|
{
|
|
DrawToolTip("fuelslots", Anchor.TopLeft, Pivot.BottomCenter, arrows["fuelslots"]);
|
|
DrawToolTip("fissionrate", Anchor.TopCenter, Pivot.TopCenter, buttonArea);
|
|
DrawToolTip("temperature", Anchor.BottomLeft, Pivot.TopLeft, arrows["temperature"]);
|
|
DrawToolTip("automaticcontrol", Anchor.TopLeft, Pivot.CenterRight, arrows["automaticcontrol"]);
|
|
DrawToolTip("power", Anchor.BottomCenter, Pivot.TopCenter, arrows["power"]);
|
|
DrawToolTip("load", Anchor.CenterLeft, Pivot.CenterLeft, graph);
|
|
|
|
void DrawToolTip(string textTag, Anchor anchor, Pivot pivot, GUIComponent targetComponent)
|
|
{
|
|
GUIComponent.DrawToolTip(sb,
|
|
TextManager.Get($"infographic.reactor.{textTag}"),
|
|
targetComponent.Rect,
|
|
anchor: anchor,
|
|
pivot: pivot);
|
|
}
|
|
})
|
|
{
|
|
CanBeFocused = false
|
|
};
|
|
var closeButtonRt = new RectTransform(new Point(200, 50).Multiply(GUI.Scale), infographic.RectTransform, Anchor.TopRight, Pivot.BottomRight)
|
|
{
|
|
AbsoluteOffset = new Point(0, -50).Multiply(GUI.Scale)
|
|
};
|
|
new GUIButton(closeButtonRt, TextManager.Get("closeinfographic"))
|
|
{
|
|
UserData = UIHighlightAction.ElementId.CloseButton,
|
|
OnClicked = (_, _) =>
|
|
{
|
|
CloseInfographic(Character.Controlled);
|
|
return true;
|
|
}
|
|
};
|
|
item.OnDeselect += CloseInfographic;
|
|
|
|
GUIImage CreateArrow(InfographicArrowStyle arrowStyle, GUIComponent parent, Anchor anchor, Pivot pivot, SpriteEffects spriteEffects = SpriteEffects.None, float rotationDegrees = 0f, Point? additionalOffset = null)
|
|
{
|
|
Point offset = (additionalOffset ?? Point.Zero) + RectTransform.CalculateAnchorPoint(anchor, parent.Rect) - GuiFrame.Rect.Location;
|
|
var rt = new RectTransform(new Point(arrowSize), infographic.RectTransform, pivot: pivot)
|
|
{
|
|
AbsoluteOffset = offset
|
|
};
|
|
string style = arrowStyle == InfographicArrowStyle.Straight ? "InfographicArrow" : "InfographicArrowCurved";
|
|
return new GUIImage(rt, style)
|
|
{
|
|
CanBeFocused = false,
|
|
Rotation = MathHelper.ToRadians(rotationDegrees),
|
|
SpriteEffects = spriteEffects
|
|
};
|
|
}
|
|
|
|
void CloseInfographic(Character character)
|
|
{
|
|
if (character != Character.Controlled) { return; }
|
|
GuiFrame.RemoveChild(infographic);
|
|
infographic = null;
|
|
item.OnDeselect -= CloseInfographic;
|
|
}
|
|
}
|
|
|
|
protected override void RemoveComponentSpecific()
|
|
{
|
|
base.RemoveComponentSpecific();
|
|
graphLine?.Remove();
|
|
fissionRateMeter?.Remove();
|
|
turbineOutputMeter?.Remove();
|
|
meterPointer?.Remove();
|
|
sectorSprite?.Remove();
|
|
tempMeterFrame?.Remove();
|
|
tempMeterBar?.Remove();
|
|
tempRangeIndicator?.Remove();
|
|
}
|
|
|
|
public void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData = null)
|
|
{
|
|
msg.WriteBoolean(autoTemp);
|
|
msg.WriteBoolean(PowerOn);
|
|
msg.WriteRangedSingle(TargetFissionRate, 0.0f, 100.0f, 8);
|
|
msg.WriteRangedSingle(TargetTurbineOutput, 0.0f, 100.0f, 8);
|
|
msg.WriteRangedSingle(temperatureBoost, -TemperatureBoostAmount, TemperatureBoostAmount, 8);
|
|
|
|
correctionTimer = CorrectionDelay;
|
|
}
|
|
|
|
public void ClientEventRead(IReadMessage msg, float sendingTime)
|
|
{
|
|
if (correctionTimer > 0.0f)
|
|
{
|
|
StartDelayedCorrection(msg.ExtractBits(1 + 1 + 8 + 8 + 8 + 8 + 8), sendingTime);
|
|
return;
|
|
}
|
|
|
|
AutoTemp = msg.ReadBoolean();
|
|
PowerOn = msg.ReadBoolean();
|
|
Temperature = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
|
TargetFissionRate = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
|
TargetTurbineOutput = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
|
degreeOfSuccess = msg.ReadRangedSingle(0.0f, 1.0f, 8);
|
|
ApplyTemperatureBoost(msg.ReadRangedSingle(-TemperatureBoostAmount, TemperatureBoostAmount, 8));
|
|
|
|
if (Math.Abs(FissionRateScrollBar.BarScroll - TargetFissionRate / 100.0f) > 0.01f)
|
|
{
|
|
FissionRateScrollBar.BarScroll = TargetFissionRate / 100.0f;
|
|
}
|
|
if (Math.Abs(TurbineOutputScrollBar.BarScroll - TargetTurbineOutput / 100.0f) > 0.01f)
|
|
{
|
|
TurbineOutputScrollBar.BarScroll = TargetTurbineOutput / 100.0f;
|
|
}
|
|
|
|
IsActive = true;
|
|
}
|
|
|
|
private void UpdateUIElementStates()
|
|
{
|
|
if (powerLight != null)
|
|
{
|
|
powerLight.Selected = _powerOn;
|
|
}
|
|
if (AutoTempSwitch != null)
|
|
{
|
|
AutoTempSwitch.Selected = autoTemp;
|
|
AutoTempSwitch.Enabled = _powerOn;
|
|
}
|
|
if (autoTempLight != null)
|
|
{
|
|
autoTempLight.Selected = autoTemp && _powerOn;
|
|
}
|
|
if (FissionRateScrollBar != null)
|
|
{
|
|
FissionRateScrollBar.Enabled = _powerOn && !autoTemp;
|
|
}
|
|
if (TurbineOutputScrollBar != null)
|
|
{
|
|
TurbineOutputScrollBar.Enabled = _powerOn && !autoTemp;
|
|
}
|
|
}
|
|
}
|
|
}
|