(3dc4135ce) v0.9.5.1

This commit is contained in:
Regalis
2019-11-21 18:22:25 +01:00
parent b39922a074
commit 5c95c53118
287 changed files with 12655 additions and 5048 deletions
@@ -14,7 +14,7 @@ namespace Barotrauma.Items.Components
private float charge;
private float rechargeVoltage;
//private float rechargeVoltage;
//how fast the battery can be recharged
private float maxRechargeSpeed;
@@ -28,10 +28,7 @@ namespace Barotrauma.Items.Components
protected Vector2 indicatorPosition, indicatorSize;
protected bool isHorizontal;
//a list of powered devices connected directly to this item
private readonly List<Pair<Powered, Connection>> directlyConnected = new List<Pair<Powered, Connection>>(10);
public float CurrPowerOutput
{
get;
@@ -107,12 +104,18 @@ namespace Barotrauma.Items.Components
if (!MathUtils.IsValid(value)) return;
rechargeSpeed = MathHelper.Clamp(value, 0.0f, maxRechargeSpeed);
rechargeSpeed = MathUtils.RoundTowardsClosest(rechargeSpeed, Math.Max(maxRechargeSpeed * 0.1f, 1.0f));
if (isRunning)
{
HasBeenTuned = true;
}
}
}
public float RechargeRatio => RechargeSpeed / MaxRechargeSpeed;
public const float aiRechargeTargetRatio = 0.5f;
private bool isRunning;
public bool HasBeenTuned { get; private set; }
public PowerContainer(Item item, XElement element)
: base(item, element)
@@ -131,14 +134,13 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
isRunning = true;
float chargeRatio = charge / capacity;
float gridPower = 0.0f;
float gridLoad = 0.0f;
directlyConnected.Clear();
foreach (Connection c in item.Connections)
{
if (c.Name == "power_in") continue;
if (!c.IsPower || !c.IsOutput) { continue; }
foreach (Connection c2 in c.Recipients)
{
if (c2.Item.Condition <= 0.0f) { continue; }
@@ -149,15 +151,13 @@ namespace Barotrauma.Items.Components
foreach (Powered powered in c2.Item.GetComponents<Powered>())
{
if (!powered.IsActive) continue;
directlyConnected.Add(new Pair<Powered, Connection>(powered, c2));
gridLoad += powered.CurrPowerConsumption;
}
continue;
}
if (!pt.IsActive || !pt.CanTransfer) { continue; }
gridLoad += pt.PowerLoad;
gridPower -= pt.CurrPowerConsumption;
gridLoad += pt.PowerLoad;
}
}
@@ -168,66 +168,51 @@ namespace Barotrauma.Items.Components
if (charge >= capacity)
{
rechargeVoltage = 0.0f;
//rechargeVoltage = 0.0f;
charge = capacity;
CurrPowerConsumption = 0.0f;
}
else
{
currPowerConsumption = MathHelper.Lerp(currPowerConsumption, rechargeSpeed, 0.05f);
Charge += currPowerConsumption * rechargeVoltage / 3600.0f;
Charge += currPowerConsumption * Voltage / 3600.0f;
}
//provide power to the grid
if (gridLoad > 0.0f)
if (charge <= 0.0f)
{
if (charge <= 0.0f)
{
CurrPowerOutput = 0.0f;
charge = 0.0f;
return;
}
if (gridPower < gridLoad)
{
//output starts dropping when the charge is less than 10%
float maxOutputRatio = 1.0f;
if (chargeRatio < 0.1f)
{
maxOutputRatio = Math.Max(chargeRatio * 10.0f, 0.0f);
}
CurrPowerOutput = MathHelper.Lerp(
CurrPowerOutput,
Math.Min(MaxOutPut * maxOutputRatio, gridLoad),
deltaTime * 10.0f);
}
else
{
CurrPowerOutput = MathHelper.Lerp(CurrPowerOutput, 0.0f, deltaTime * 10.0f);
}
Charge -= CurrPowerOutput / 3600.0f;
CurrPowerOutput = 0.0f;
charge = 0.0f;
return;
}
item.SendSignal(0, ((int)Charge).ToString(), "charge", null);
item.SendSignal(0, ((int)((Charge / capacity) * 100)).ToString(), "charge_%", null);
item.SendSignal(0, ((int)((RechargeSpeed / maxRechargeSpeed) * 100)).ToString(), "charge_rate", null);
foreach (Pair<Powered, Connection> connected in directlyConnected)
//output starts dropping when the charge is less than 10%
float maxOutputRatio = 1.0f;
if (chargeRatio < 0.1f)
{
connected.First.ReceiveSignal(0, "", connected.Second, source: item, sender: null,
power: gridLoad <= 0.0f ? 1.0f : CurrPowerOutput / gridLoad);
maxOutputRatio = Math.Max(chargeRatio * 10.0f, 0.0f);
}
rechargeVoltage = 0.0f;
CurrPowerOutput += (gridLoad - gridPower) * deltaTime;
float maxOutput = Math.Min(MaxOutPut * maxOutputRatio, gridLoad);
CurrPowerOutput = MathHelper.Clamp(CurrPowerOutput, 0.0f, maxOutput);
Charge -= CurrPowerOutput / 3600.0f;
item.SendSignal(0, ((int)Math.Round(Charge)).ToString(), "charge", null);
item.SendSignal(0, ((int)Math.Round((Charge / capacity) * 100)).ToString(), "charge_%", null);
item.SendSignal(0, ((int)Math.Round((RechargeSpeed / maxRechargeSpeed) * 100)).ToString(), "charge_rate", null);
}
public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
{
#if CLIENT
if (GameMain.Client != null) return false;
#endif
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return false; }
if (objective.Override)
{
HasBeenTuned = false;
}
if (HasBeenTuned) { return true; }
if (string.IsNullOrEmpty(objective.Option) || objective.Option.ToLowerInvariant() == "charge")
{
@@ -274,6 +259,8 @@ namespace Barotrauma.Items.Components
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power, float signalStrength = 1.0f)
{
if (connection.IsPower) { return; }
if (connection.Name == "set_rate")
{
if (float.TryParse(signal, NumberStyles.Any, CultureInfo.InvariantCulture, out float tempSpeed))
@@ -290,12 +277,6 @@ namespace Barotrauma.Items.Components
#endif
}
}
if (!connection.IsPower) { return; }
if (connection.Name == "power_in")
{
rechargeVoltage = Math.Min(power, 1.0f);
}
}
}
}
@@ -8,37 +8,21 @@ namespace Barotrauma.Items.Components
{
partial class PowerTransfer : Powered
{
private static float fullPower;
private static float fullLoad;
public List<Connection> PowerConnections { get; private set; }
private int updateCount;
//affects how fast changes in power/load are carried over the grid
static float inertia = 5.0f;
private static HashSet<Powered> connectedList = new HashSet<Powered>();
private List<Connection> powerConnections;
public List<Connection> PowerConnections
{
get
{
return powerConnections;
}
}
private Dictionary<Connection, bool> connectionDirty = new Dictionary<Connection, bool>();
private readonly Dictionary<Connection, bool> connectionDirty = new Dictionary<Connection, bool>();
//a list of connections a given connection is connected to, either directly or via other power transfer components
private Dictionary<Connection, HashSet<Connection>> connectedRecipients = new Dictionary<Connection, HashSet<Connection>>();
private readonly Dictionary<Connection, HashSet<Connection>> connectedRecipients = new Dictionary<Connection, HashSet<Connection>>();
private float powerLoad;
protected float powerLoad;
private bool isBroken;
protected bool isBroken;
public float PowerLoad
{
get { return powerLoad; }
set { powerLoad = value; }
}
[Editable, Serialize(true, true, description: "Can the item be damaged if too much power is supplied to the power grid.")]
@@ -145,97 +129,43 @@ namespace Barotrauma.Items.Components
SetAllConnectionsDirty();
isBroken = false;
}
if (updateCount > 0)
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
//if the item can't be fixed, don't allow it to break
if (!item.Repairables.Any() || !CanBeOverloaded) { return; }
float maxOverVoltage = Math.Max(OverloadVoltage, 1.0f);
Overload = -currPowerConsumption > Math.Max(powerLoad, 200.0f) * maxOverVoltage;
if (Overload && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer))
{
//this junction box has already been updated this frame
updateCount--;
return;
}
//damage the item if voltage is too high (except if running as a client)
float prevCondition = item.Condition;
item.Condition -= deltaTime * 10.0f;
Overload = false;
//reset and recalculate the power generated/consumed
//by the constructions connected to the grid
fullPower = 0.0f;
fullLoad = 0.0f;
connectedList.Clear();
updateCount = 0;
CheckJunctions(deltaTime);
foreach (Powered p in connectedList)
{
PowerTransfer pt = p as PowerTransfer;
if (pt == null || pt.updateCount == 0) { continue; }
if (pt is RelayComponent != this is RelayComponent) { continue; }
pt.Overload = false;
pt.powerLoad += (fullLoad - pt.powerLoad) / inertia;
pt.currPowerConsumption += (-fullPower - pt.currPowerConsumption) / inertia;
float voltage = fullPower / Math.Max(fullLoad, 1.0f);
if (this is RelayComponent)
{
pt.currPowerConsumption = Math.Max(-fullLoad, pt.currPowerConsumption);
voltage = Math.Min(voltage, 1.0f);
}
pt.Item.SendSignal(0, "", "power", null, voltage);
pt.Item.SendSignal(0, "", "power_out", null, voltage);
//items in a bad condition are more sensitive to overvoltage
float maxOverVoltage = MathHelper.Lerp(OverloadVoltage * 0.75f, OverloadVoltage, pt.item.Condition / pt.item.MaxCondition);
maxOverVoltage = Math.Max(OverloadVoltage, 1.0f);
//if the item can't be fixed, don't allow it to break
if (!pt.item.Repairables.Any() || !pt.CanBeOverloaded) { continue; }
//relays don't blow up if the power is higher than load, only if the output is high enough
//(i.e. enough power passing through the relay)
if (pt is RelayComponent) { continue; }
if (-pt.currPowerConsumption < Math.Max(pt.powerLoad, 200.0f) * maxOverVoltage) { continue; }
pt.Overload = true;
#if CLIENT
//damage the item if voltage is too high
//(except if running as a client)
if (GameMain.Client != null) { continue; }
#endif
float prevCondition = pt.item.Condition;
pt.item.Condition -= deltaTime * 10.0f;
if (pt.item.Condition <= 0.0f && prevCondition > 0.0f)
if (item.Condition <= 0.0f && prevCondition > 0.0f)
{
#if CLIENT
SoundPlayer.PlaySound("zap", item.WorldPosition, hullGuess: pt.item.CurrentHull);
SoundPlayer.PlaySound("zap", item.WorldPosition, hullGuess: item.CurrentHull);
Vector2 baseVel = Rand.Vector(300.0f);
for (int i = 0; i < 10; i++)
{
var particle = GameMain.ParticleManager.CreateParticle("spark", pt.item.WorldPosition,
baseVel + Rand.Vector(100.0f), 0.0f, pt.item.CurrentHull);
var particle = GameMain.ParticleManager.CreateParticle("spark", item.WorldPosition,
baseVel + Rand.Vector(100.0f), 0.0f, item.CurrentHull);
if (particle != null) particle.Size *= Rand.Range(0.5f, 1.0f);
}
#endif
float currentIntensity = GameMain.GameSession?.EventManager != null ?
float currentIntensity = GameMain.GameSession?.EventManager != null ?
GameMain.GameSession.EventManager.CurrentIntensity : 0.5f;
//higher probability for fires if the current intensity is low
if (pt.FireProbability > 0.0f &&
Rand.Range(0.0f, 1.0f) < MathHelper.Lerp(pt.FireProbability, pt.FireProbability * 0.1f, currentIntensity))
if (FireProbability > 0.0f &&
Rand.Range(0.0f, 1.0f) < MathHelper.Lerp(FireProbability, FireProbability * 0.1f, currentIntensity))
{
new FireSource(pt.item.WorldPosition);
new FireSource(item.WorldPosition);
}
}
}
updateCount = 0;
}
public override bool Pick(Character picker)
@@ -243,7 +173,7 @@ namespace Barotrauma.Items.Components
return picker != null;
}
private void RefreshConnections()
protected void RefreshConnections()
{
var connections = item.Connections;
foreach (Connection c in connections)
@@ -317,102 +247,6 @@ namespace Barotrauma.Items.Components
}
}
//a recursive function that goes through all the junctions and adds up
//all the generated/consumed power of the constructions connected to the grid
private void CheckJunctions(float deltaTime, bool increaseUpdateCount = true, float clampPower = float.MaxValue, float clampLoad = float.MaxValue)
{
if (increaseUpdateCount)
{
updateCount = 1;
}
connectedList.Add(this);
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
//float maxPower = this is RelayComponent relayComponent ? relayComponent.MaxPower : float.PositiveInfinity;
RelayComponent thisRelayComponent = this as RelayComponent;
if (thisRelayComponent != null)
{
clampPower = Math.Min(Math.Min(clampPower, thisRelayComponent.MaxPower), powerLoad);
clampLoad = Math.Min(clampLoad, thisRelayComponent.MaxPower);
}
foreach (Connection c in PowerConnections)
{
var recipients = c.Recipients;
foreach (Connection recipient in recipients)
{
if (recipient?.Item == null || !recipient.IsPower) { continue; }
Item it = recipient.Item;
if (it.Condition <= 0.0f) { continue; }
foreach (ItemComponent ic in it.Components)
{
if (!(ic is Powered powered) || !powered.IsActive) { continue; }
if (connectedList.Contains(powered)) { continue; }
if (powered is PowerTransfer powerTransfer)
{
RelayComponent otherRelayComponent = powerTransfer as RelayComponent;
if ((thisRelayComponent == null) == (otherRelayComponent == null))
{
if (!powerTransfer.CanTransfer) { continue; }
powerTransfer.CheckJunctions(deltaTime, increaseUpdateCount, clampPower, clampLoad);
}
else
{
if (!powerTransfer.CanTransfer) continue;
float maxPowerIn = (thisRelayComponent != null && c.IsOutput) ? 0.0f : clampPower;
float maxPowerOut = (thisRelayComponent != null && !c.IsOutput) ? 0.0f : clampLoad;
if (maxPowerIn > 0.0f || maxPowerOut > 0.0f)
{
powerTransfer.CheckJunctions(deltaTime, false, maxPowerIn, maxPowerOut);
}
}
continue;
}
float addLoad = 0.0f;
float addPower = 0.0f;
if (powered is PowerContainer powerContainer)
{
if (recipient.Name == "power_in")
{
addLoad = powerContainer.CurrPowerConsumption;
}
else
{
addPower = powerContainer.CurrPowerOutput;
}
}
else
{
connectedList.Add(powered);
//positive power consumption = the construction requires power -> increase load
if (powered.CurrPowerConsumption > 0.0f)
{
addLoad = powered.CurrPowerConsumption;
}
else if (powered.CurrPowerConsumption < 0.0f)
//negative power consumption = the construction is a
//generator/battery or another junction box
{
addPower -= powered.CurrPowerConsumption;
}
}
if (addPower + fullPower > clampPower) { addPower -= (addPower + fullPower) - clampPower; };
if (addPower > 0) { fullPower += addPower; }
if (addLoad + fullLoad > clampLoad) { addLoad -= (addLoad + fullLoad) - clampLoad; };
if (addLoad > 0) { fullLoad += addLoad; }
}
}
}
}
public void SetAllConnectionsDirty()
{
if (item.Connections == null) return;
@@ -431,8 +265,9 @@ namespace Barotrauma.Items.Components
public override void OnItemLoaded()
{
base.OnItemLoaded();
var connections = Item.Connections;
powerConnections = connections == null ? new List<Connection>() : connections.FindAll(c => c.IsPower);
PowerConnections = connections == null ? new List<Connection>() : connections.FindAll(c => c.IsPower);
if (connections == null)
{
IsActive = false;
@@ -440,33 +275,45 @@ namespace Barotrauma.Items.Components
}
SetAllConnectionsDirty();
}
public override void ReceivePowerProbeSignal(Connection connection, Item source, float power)
{
//we've already received this signal
if (lastPowerProbeRecipients.Contains(this)) { return; }
lastPowerProbeRecipients.Add(this);
if (power < 0.0f)
{
powerLoad -= power;
}
else
{
currPowerConsumption -= power;
}
powerOut?.SendPowerProbeSignal(source, power);
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power, float signalStrength = 1.0f)
{
if (connection.IsPower) return;
base.ReceiveSignal(stepsTaken, signal, connection, source, sender, power);
if (!connectedRecipients.ContainsKey(connection)) return;
if (item.Condition <= 0.0f || connection.IsPower) { return; }
if (!connectedRecipients.ContainsKey(connection)) { return; }
if (connection.Name.Length > 5 && connection.Name.Substring(0, 6) == "signal")
{
foreach (Connection recipient in connectedRecipients[connection])
{
if (recipient.Item == item || recipient.Item == source) continue;
if (recipient.Item == item || recipient.Item == source) { continue; }
foreach (ItemComponent ic in recipient.Item.Components)
{
//powertransfer components don't need to receive the signal in the pass-through signal connections
//because we relay it straight to the connected items without going through the whole chain of junction boxes
if (ic is PowerTransfer && connection.Name.Contains("signal")) continue;
if (ic is PowerTransfer && connection.Name.Contains("signal")) { continue; }
ic.ReceiveSignal(stepsTaken, signal, recipient, source, sender, 0.0f, signalStrength);
}
bool broken = recipient.Item.Condition <= 0.0f;
foreach (StatusEffect effect in recipient.Effects)
{
if (broken && effect.type != ActionType.OnBroken) continue;
recipient.Item.ApplyStatusEffect(effect, ActionType.OnUse, 1.0f, null, null, false, false);
}
}
@@ -1,6 +1,7 @@
using System;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
#if CLIENT
using Barotrauma.Sounds;
#endif
@@ -9,25 +10,47 @@ namespace Barotrauma.Items.Components
{
partial class Powered : ItemComponent
{
//the amount of power CURRENTLY consumed by the item
//negative values mean that the item is providing power to connected items
private static float updateTimer;
protected static float UpdateInterval = 0.2f;
/// <summary>
/// List of all powered ItemComponents
/// </summary>
private static readonly List<Powered> poweredList = new List<Powered>();
/// <summary>
/// Items that have already received the "probe signal" that's used to distribute power and load across the grid
/// </summary>
protected static HashSet<PowerTransfer> lastPowerProbeRecipients = new HashSet<PowerTransfer>();
/// <summary>
/// The amount of power currently consumed by the item. Negative values mean that the item is providing power to connected items
/// </summary>
protected float currPowerConsumption;
//current voltage of the item (load / power)
protected float voltage;
/// <summary>
/// Current voltage of the item (load / power)
/// </summary>
private float voltage;
//the minimum voltage required for the item to work
protected float minVoltage;
/// <summary>
/// The minimum voltage required for the item to work
/// </summary>
private float minVoltage;
//the maximum amount of power the item can draw from connected items
/// <summary>
/// The maximum amount of power the item can draw from connected items
/// </summary>
protected float powerConsumption;
protected Connection powerIn, powerOut;
[Editable, Serialize(0.5f, true, description: "The minimum voltage required for the device to function. " +
"The voltage is calculated as power / powerconsumption, meaning that a device " +
"with a power consumption of 1000 kW would need at least 500 kW of power to work if the minimum voltage is set to 0.5.")]
public float MinVoltage
{
get { return minVoltage; }
get { return powerConsumption <= 0.0f ? 0.0f : minVoltage; }
set { minVoltage = value; }
}
@@ -76,34 +99,32 @@ namespace Barotrauma.Items.Components
public Powered(Item item, XElement element)
: base(item, element)
{
poweredList.Add(this);
InitProjectSpecific(element);
}
partial void InitProjectSpecific(XElement element);
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0, float signalStrength = 1.0f)
{
if (currPowerConsumption == 0.0f) voltage = 0.0f;
if (connection.IsPower) voltage = Math.Max(0.0f, power);
}
protected void UpdateOnActiveEffects(float deltaTime)
{
if (currPowerConsumption == 0.0f)
if (currPowerConsumption <= 0.0f)
{
//if the item consumes no power, ignore the voltage requirement and
//apply OnActive statuseffects as long as this component is active
if (powerConsumption == 0.0f)
if (powerConsumption <= 0.0f)
{
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
}
return;
}
#if CLIENT
if (voltage > minVoltage)
{
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
}
#if CLIENT
if (voltage > minVoltage)
{
if (!powerOnSoundPlayed && powerOnSound != null)
{
SoundPlayer.PlaySound(powerOnSound.Sound, item.WorldPosition, powerOnSound.Volume, powerOnSound.Range, item.CurrentHull);
@@ -114,21 +135,160 @@ namespace Barotrauma.Items.Components
{
powerOnSoundPlayed = false;
}
#else
if (voltage > minVoltage)
{
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
}
#endif
}
public override void Update(float deltaTime, Camera cam)
{
UpdateOnActiveEffects(deltaTime);
voltage = 0.0f;
}
public override void OnItemLoaded()
{
if (item.Connections == null) { return; }
foreach (Connection c in item.Connections)
{
if (!c.IsPower) { continue; }
if (this is PowerTransfer pt)
{
if (c.Name == "power_in")
{
powerIn = c;
}
else if (c.Name == "power_out")
{
powerOut = c;
}
else if (c.Name == "power")
{
powerIn = powerOut = c;
}
}
else
{
if (c.IsOutput)
{
if (c.Name == "power_in")
{
#if DEBUG
DebugConsole.ThrowError($"Item \"{item.Name}\" has a power output connection called power_in. If the item is supposed to receive power through the connection, change it to an input connection.");
#else
DebugConsole.NewMessage($"Item \"{item.Name}\" has a power output connection called power_in. If the item is supposed to receive power through the connection, change it to an input connection.", Color.Orange);
#endif
}
powerOut = c;
}
else
{
if (c.Name == "power_out")
{
#if DEBUG
DebugConsole.ThrowError($"Item \"{item.Name}\" has a power input connection called power_out. If the item is supposed to output power through the connection, change it to an output connection.");
#else
DebugConsole.NewMessage($"Item \"{item.Name}\" has a power input connection called power_out. If the item is supposed to output power through the connection, change it to an output connection.", Color.Orange);
#endif
}
powerIn = c;
}
}
}
}
public virtual void ReceivePowerProbeSignal(Connection connection, Item source, float power) { }
public static void UpdatePower(float deltaTime)
{
if (updateTimer > 0.0f)
{
updateTimer -= deltaTime;
return;
}
updateTimer = UpdateInterval;
//reset power first
foreach (Powered powered in poweredList)
{
if (powered is PowerTransfer pt)
{
powered.CurrPowerConsumption = 0.0f;
pt.PowerLoad = 0.0f;
if (pt is RelayComponent relay)
{
relay.DisplayLoad = 0.0f;
}
}
//only reset voltage if the item has a power connector
//(other items, such as handheld devices, get power through other means and shouldn't be updated here)
if (powered.powerIn != null || powered.powerOut != null) { powered.voltage = 0.0f; }
}
//go through all the devices that are consuming/providing power
//and send out a "probe signal" which the PowerTransfer components use to add up the grid power/load
foreach (Powered powered in poweredList)
{
if (powered is PowerTransfer) { continue; }
if (powered.currPowerConsumption > 0.0f)
{
//consuming power
lastPowerProbeRecipients.Clear();
powered.powerIn?.SendPowerProbeSignal(powered.item, -powered.currPowerConsumption);
}
}
foreach (Powered powered in poweredList)
{
if (powered is PowerTransfer) { continue; }
else if (powered.currPowerConsumption < 0.0f)
{
//providing power
lastPowerProbeRecipients.Clear();
powered.powerOut?.SendPowerProbeSignal(powered.item, -powered.currPowerConsumption);
}
if (powered is PowerContainer pc)
{
if (pc.CurrPowerOutput <= 0.0f) { continue; }
//providing power
lastPowerProbeRecipients.Clear();
powered.powerOut?.SendPowerProbeSignal(powered.item, pc.CurrPowerOutput);
}
}
//go through powered items and calculate their current voltage
foreach (Powered powered in poweredList)
{
if (powered is PowerTransfer pt1 || (pt1 = powered.Item.GetComponent<PowerTransfer>()) != null)
{
powered.voltage = -pt1.CurrPowerConsumption / Math.Max(pt1.PowerLoad, 1.0f);
continue;
}
if (powered.powerConsumption <= 0.0f && !(powered is PowerContainer))
{
powered.voltage = 1.0f;
continue;
}
if (powered.powerIn == null) { continue; }
foreach (Connection powerSource in powered.powerIn.Recipients)
{
if (!powerSource.IsPower || !powerSource.IsOutput) { continue; }
var pt = powerSource.Item.GetComponent<PowerTransfer>();
if (pt != null)
{
float voltage = -pt.CurrPowerConsumption / Math.Max(pt.PowerLoad, 1.0f);
powered.voltage = Math.Max(powered.voltage, voltage);
continue;
}
var pc = powerSource.Item.GetComponent<PowerContainer>();
if (pc != null)
{
float voltage = -pc.CurrPowerOutput / Math.Max(powered.CurrPowerConsumption, 1.0f);
powered.voltage += voltage;
}
}
}
}
protected override void RemoveComponentSpecific()
{
poweredList.Remove(this);
}
}
}