From 6fcf2f573be693334f972fab75b14baef36e32f1 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Sat, 24 Feb 2018 20:46:28 +0200 Subject: [PATCH] Fixed relays burning out when connected to the main power grid. The changes in bb98767 caused relay components to be considered parts of whichever power grid they're connected to, causing their power and load to match the rest of the grid which usually causes them to go over the max power value. Closes #279 + Fixed "powerConnections" field not being updated when creating PowerTransfer components mid-round, which made fabricated relays unusable for power transfer. --- .../Items/Components/Power/PowerTransfer.cs | 76 +++++++++++++------ .../Items/Components/Signal/Connection.cs | 20 +---- .../Items/Components/Signal/RelayComponent.cs | 17 +---- 3 files changed, 56 insertions(+), 57 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Power/PowerTransfer.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Power/PowerTransfer.cs index fabdbf224..f43187986 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Power/PowerTransfer.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Power/PowerTransfer.cs @@ -10,7 +10,7 @@ namespace Barotrauma.Items.Components static float fullPower; static float fullLoad; - private int updateTimer; + private int updateCount; const float FireProbability = 0.15f; @@ -19,6 +19,20 @@ namespace Barotrauma.Items.Components private HashSet connectedPoweredList = new HashSet(); private List powerConnections; + public List PowerConnections + { + get + { + if (powerConnections == null) + { + var connections = Item.Connections; + powerConnections = connectedPoweredList == null ? new List() : connections.FindAll(c => c.IsPower); + + } + return powerConnections; + } + } + private Dictionary connectionDirty = new Dictionary(); @@ -58,6 +72,8 @@ namespace Barotrauma.Items.Components { if (base.IsActive == value) return; base.IsActive = value; + powerLoad = 0.0f; + currPowerConsumption = 0.0f; SetAllConnectionsDirty(); if (!base.IsActive) @@ -73,8 +89,6 @@ namespace Barotrauma.Items.Components { IsActive = true; canTransfer = true; - - powerConnections = new List(); } public override void UpdateBroken(float deltaTime, Camera cam) @@ -83,6 +97,8 @@ namespace Barotrauma.Items.Components if (!isBroken) { + powerLoad = 0.0f; + currPowerConsumption = 0.0f; SetAllConnectionsDirty(); RefreshConnections(); isBroken = true; @@ -100,10 +116,10 @@ namespace Barotrauma.Items.Components isBroken = false; } - if (updateTimer > 0) + if (updateCount > 0) { //this junction box has already been updated this frame - updateTimer--; + updateCount--; return; } @@ -115,7 +131,7 @@ namespace Barotrauma.Items.Components connectedPoweredList.Clear(); CheckPower(deltaTime); - updateTimer = 0; + updateCount = 0; int n = 0; foreach (PowerTransfer pt in connectedPoweredList) @@ -125,9 +141,11 @@ namespace Barotrauma.Items.Components pt.Item.SendSignal(0, "", "power", null, fullPower / Math.Max(fullLoad, 1.0f)); pt.Item.SendSignal(0, "", "power_out", null, fullPower / Math.Max(fullLoad, 1.0f)); - //damage the item if voltage is too high - //(except if running as a client) - if (GameMain.Client != null) continue; + //damage the item if voltage is too high (except if running as a client) + + //relay components work differently, they can be connected to a high-powered junction box + //and only break if the output (~the power running through the relay) is too high + if (GameMain.Client != null || this is RelayComponent) continue; if (-pt.currPowerConsumption < Math.Max(pt.powerLoad * Rand.Range(1.9f, 2.1f), 200.0f)) continue; float prevCondition = pt.item.Condition; @@ -214,7 +232,7 @@ namespace Barotrauma.Items.Components { connectedRecipients.Add(recipient, connected); } - + recipientPowerTransfer.connectedRecipients[recipient] = connected; recipientPowerTransfer.connectionDirty[recipient] = false; } @@ -247,11 +265,10 @@ namespace Barotrauma.Items.Components //all the generated/consumed power of the constructions connected to the grid private void CheckPower(float deltaTime) { - updateTimer = 1; - + updateCount = 1; connectedPoweredList.Clear(); - foreach (Connection c in powerConnections) + foreach (Connection c in PowerConnections) { HashSet recipients = connectedRecipients[c]; foreach (Connection recipient in recipients) @@ -260,15 +277,28 @@ namespace Barotrauma.Items.Components Item it = recipient.Item; if (it == null || it.Condition <= 0.0f) continue; - + foreach (Powered powered in it.GetComponents()) { - if (powered == null || !powered.IsActive) continue; + if (powered == null || !powered.IsActive) continue; PowerTransfer powerTransfer = powered as PowerTransfer; if (powerTransfer != null) { - connectedPoweredList.Add(powerTransfer); - powerTransfer.updateTimer = 1; + if (!powerTransfer.CanTransfer) continue; + if (powerTransfer is RelayComponent != this is RelayComponent && c.IsPower) + { + //relay components and junction boxes aren't treated as parts of the same power grid + //connected relays simply increase the load of the grid (and jbs connected to relays increase the load of the relay) + if (c.IsOutput) + { + fullLoad += powerTransfer.powerLoad; + } + } + else + { + connectedPoweredList.Add(powerTransfer); + powerTransfer.updateCount = 1; + } continue; } @@ -277,7 +307,8 @@ namespace Barotrauma.Items.Components { if (recipient.Name == "power_in") { - fullLoad += powerContainer.CurrPowerConsumption; + //batteries connected to power_in never increase load + if (c.IsOutput) fullLoad += powerContainer.CurrPowerConsumption; } else { @@ -289,10 +320,10 @@ namespace Barotrauma.Items.Components //positive power consumption = the construction requires power -> increase load if (powered.CurrPowerConsumption > 0.0f) { - fullLoad += powered.CurrPowerConsumption; + //items connected to power_in never increase load + if (c.IsOutput) fullLoad += powered.CurrPowerConsumption; } - else if (powered.CurrPowerConsumption < 0.0f) - //negative power consumption = the construction is a /generator/battery + else if (powered.CurrPowerConsumption < 0.0f) //negative power consumption = the construction is a generator/battery { fullPower -= powered.CurrPowerConsumption; } @@ -327,9 +358,6 @@ namespace Barotrauma.Items.Components return; } - powerConnections = connections.FindAll(c => c.IsPower); - if (powerConnections.Count == 0) IsActive = false; - SetAllConnectionsDirty(); } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Connection.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Connection.cs index 8b3b988b6..eea444c2b 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Connection.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Connection.cs @@ -41,28 +41,10 @@ namespace Barotrauma.Items.Components Connection recipient = Wires[i].OtherConnection(this); if (recipient != null) recipients.Add(recipient); } - if (internalConnection != null) recipients.Add(internalConnection); return recipients; } } - - //another connection in the same connection panel - private Connection internalConnection; - public Connection InternalConnection - { - get - { - return internalConnection; - } - set - { - if (internalConnection != null) internalConnection.internalConnection = null; - - internalConnection = value; - if (internalConnection != null) internalConnection.internalConnection = this; - } - } - + public Item Item { get { return item; } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/RelayComponent.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/RelayComponent.cs index 417b287d3..0801295ed 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/RelayComponent.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/RelayComponent.cs @@ -44,25 +44,14 @@ namespace Barotrauma.Items.Components { IsActive = true; } - - public override void OnMapLoaded() - { - base.OnMapLoaded(); - - ConnectionPanel connectionPanel = item.GetComponent(); - var powerIn = connectionPanel.Connections.Find(c => c.Name == "power_in"); - var powerOut = connectionPanel.Connections.Find(c => c.Name == "power_out"); - - if (powerIn != null) powerIn.InternalConnection = powerOut; - } - + public override void Update(float deltaTime, Camera cam) { base.Update(deltaTime, cam); item.SendSignal(0, IsOn ? "1" : "0", "state_out", null); - if (-currPowerConsumption > maxPower) item.Condition = 0.0f; + if (Math.Min(-currPowerConsumption, PowerLoad) > maxPower) item.Condition = 0.0f; } public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f) @@ -82,7 +71,7 @@ namespace Barotrauma.Items.Components if (connectionNumber > 0) outConnection += connectionNumber; - item.SendSignal(stepsTaken, signal, outConnection, sender, power); + item.SendSignal(stepsTaken, signal, outConnection, sender, power); } else if (connection.Name == "toggle") {