2 using Microsoft.Xna.Framework;
3 using System.Collections.Generic;
26 public readonly
float Min;
27 public readonly
float Max;
34 public PowerRange(
float min,
float max) : this(min, max, 0.0f)
38 public PowerRange(
float min,
float max,
float reactorMaxOutput)
40 System.Diagnostics.Debug.Assert(max >= min);
41 System.Diagnostics.Debug.Assert(min >= 0);
42 System.Diagnostics.Debug.Assert(max >= 0);
66 private static readonly List<Powered> poweredList =
new List<Powered>();
69 get {
return poweredList; }
74 public readonly
static Dictionary<int, GridInfo>
Grids =
new Dictionary<int, GridInfo>();
84 private float voltage;
89 private float minVoltage;
105 [
Header(localizedTextTag:
"sp.powered.propertyheader")]
107 "The voltage is calculated as power / powerconsumption, meaning that a device " +
108 "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.")]
112 set { minVoltage = value; }
125 get {
return base.IsActive; }
128 base.IsActive = value;
136 [
Serialize(0.0f,
IsPropertySaveable.Yes, description:
"The current power consumption of the device. Intended to be used by StatusEffect conditionals (setting the value from XML is not recommended).")]
143 [
Serialize(0.0f,
IsPropertySaveable.Yes, description:
"The current voltage of the item (calculated as power consumption / available power). Intended to be used by StatusEffect conditionals (setting the value from XML is not recommended).")]
156 else if (powerOut !=
null)
158 if (powerOut?.Grid !=
null) {
return powerOut.
Grid.
Voltage; }
164 voltage = Math.Max(0.0f, value);
184 : base(
item, element)
186 poweredList.Add(
this);
187 InitProjectSpecific(element);
209 if (!powerOnSoundPlayed && powerOnSound !=
null)
212 powerOnSoundPlayed =
true;
217 powerOnSoundPlayed =
false;
235 if (c.
Name ==
"power_in")
239 else if (c.
Name ==
"power_out")
248 else if (c.
Name ==
"power")
257 if (c.
Name ==
"power_in")
260 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.");
262 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);
274 if (c.
Name ==
"power_out")
277 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.");
279 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);
296 if (
Grids.Count > 0 && useCache)
322 foreach (
Powered powered
in poweredList)
329 if (powered.powerOut !=
null)
331 powered.powerOut.
Grid =
null;
337 foreach (
Powered powered
in poweredList)
350 if (powered.powerOut !=
null && powered.powerOut.
Grid ==
null && powered.
Item.
Condition > 0.0f)
355 GridInfo grid = PropagateGrid(powered.powerOut);
369 int id = Rand.Int(
int.MaxValue, Rand.RandSync.Unsynced);
370 while (
Grids.ContainsKey(
id))
372 id = Rand.Int(
int.MaxValue, Rand.RandSync.Unsynced);
375 return PropagateGrid(conn,
id);
378 private static GridInfo PropagateGrid(Connection conn,
int gridID)
380 Stack<Connection> probeStack =
new Stack<Connection>();
382 GridInfo grid =
new GridInfo(gridID);
384 probeStack.Push(conn);
387 while (probeStack.Count > 0)
389 Connection c = probeStack.Pop();
394 foreach (Connection otherC
in c.Recipients)
397 if (otherC.Grid != grid && (otherC.Grid ==
null || !
Grids.ContainsKey(otherC.Grid.ID)) &&
ValidPowerConnection(c, otherC))
400 probeStack.Push(otherC);
443 System.Diagnostics.Stopwatch sw =
new System.Diagnostics.Stopwatch();
465 foreach (
Powered powered
in poweredList)
473 if (powered.
powerIn !=
null && powered.powerOut != powered.
powerIn)
501 if (powered.powerOut !=
null)
509 pt.PowerLoad = currLoad;
523 if (powered.powerOut.
Grid !=
null)
525 powered.powerOut.
Grid.
Load += currLoad;
528 else if (powered.powerOut.
Grid !=
null)
531 powered.powerOut.
Grid.
AddSrc(powered.powerOut);
539 pt2.PowerLoad = loadOut;
567 foreach (var device
in c.
Item.GetComponents<
Powered>())
574 float addedPower = 0;
577 foreach (var device
in c.
Item.GetComponents<
Powered>())
584 grid.
Power += addedPower;
588 float newVoltage = MathHelper.Min(grid.
Power / MathHelper.Max(grid.
Load, 1E-10f), 1000);
589 if (
float.IsNegative(newVoltage))
599 foreach (var device
in c.
Item.GetComponents<
Powered>())
601 device?.GridResolved(c);
619 if (
powerIn ==
null && powerOut ==
null)
629 else if (connection != this.powerIn || !
IsActive)
680 float availablePower = 0.0f;
686 if (battery ==
null || battery.Item.Condition <= 0.0f) {
continue; }
687 if (battery.OutputDisabled) {
continue; }
688 float maxOutputPerFrame = battery.
MaxOutPut / 60.0f;
689 float framesPerMinute = 3600.0f;
690 availablePower += Math.Min(battery.Charge * framesPerMinute, maxOutputPerFrame);
692 return availablePower;
704 yield
return battery;
724 base.RemoveComponentSpecific();
725 poweredList.Remove(
this);
731 public readonly
int ID;
736 public readonly List<Connection>
Connections =
new List<Connection>();
737 public readonly SortedList<PowerPriority, PowerSourceGroup>
PowerSourceGroups =
new SortedList<PowerPriority, PowerSourceGroup>();
778 public readonly List<Connection>
Connections =
new List<Connection>();
static GameSession?? GameSession
static PerformanceCounter PerformanceCounter
List< Connection > Connections
bool HasTag(Identifier tag)
List< Connection > Recipients
void RemoveConnection(Connection c)
void AddSrc(Connection c)
void AddConnection(Connection c)
readonly List< Connection > Connections
readonly SortedList< PowerPriority, PowerSourceGroup > PowerSourceGroups
The base class for components holding the different functionalities of the item
void ApplyStatusEffects(ActionType type, float deltaTime, Character character=null, Limb targetLimb=null, Entity useTarget=null, Character user=null, Vector2? worldPosition=null, float afflictionMultiplier=1.0f)
readonly List< Connection > Connections
const float MaxOverVoltageFactor
Maximum voltage factor when the device is being overvolted. I.e. how many times more effectively the ...
float RelativeVoltage
Essentially Voltage / MinVoltage (= how much of the minimum required voltage has been satisfied),...
float CurrPowerConsumption
virtual float GetCurrentPowerConsumption(Connection connection=null)
Current power consumption of the device (or amount of generated power if negative)
virtual PowerRange MinMaxPowerOut(Connection conn, float load=0)
Minimum and maximum power the connection can provide
IEnumerable< PowerContainer > GetDirectlyConnectedBatteries()
static readonly Dictionary< int, GridInfo > Grids
Powered(Item item, ContentXElement element)
float powerConsumption
The maximum amount of power the item can draw from connected items
virtual void GridResolved(Connection conn)
Can be overridden to perform updates for the device after the connected grid has resolved its power c...
override void OnItemLoaded()
Called when all the components of the item have been loaded. Use to initialize connections between co...
virtual PowerPriority Priority
const float UpdateInterval
static void UpdateGrids(bool useCache=true)
Allocate electrical devices into their grids based on connections
float currPowerConsumption
The amount of power currently consumed by the item. Negative values mean that the item is providing p...
float GetAvailableInstantaneousBatteryPower()
Returns the amount of power that can be supplied by batteries directly connected to the item
override void Update(float deltaTime, Camera cam)
virtual float GetConnectionPowerOut(Connection conn, float power, PowerRange minMaxPower, float load)
Finalize how much power the device will be outputting to the connection
void UpdateOnActiveEffects(float deltaTime)
static void UpdatePower(float deltaTime)
Update the power calculations of all devices and grids Updates grids in the order of ConnCurrConsumpt...
static readonly HashSet< Connection > ChangedConnections
static bool ValidPowerConnection(Connection conn1, Connection conn2)
override void RemoveComponentSpecific()
static IEnumerable< Powered > PoweredList
float GetRandomFrequencyMultiplier()
readonly bool IgnoreMuffling
PowerPriority
Order in which power sources will provide to a grid, lower number is higher priority
ActionType
ActionTypes define when a StatusEffect is executed.
PowerRange(float min, float max, float reactorMaxOutput)
PowerRange(float min, float max)
static PowerRange operator+(PowerRange a, PowerRange b)
static readonly PowerRange Zero
static PowerRange operator-(PowerRange a, PowerRange b)
readonly float ReactorMaxOutput
Used by reactors to communicate their maximum output to each other so they can divide the grid load b...