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);
186 : base(
item, element)
188 poweredList.Add(
this);
189 InitProjectSpecific(element);
211 if (!powerOnSoundPlayed && powerOnSound !=
null)
213 SoundPlayer.PlaySound(powerOnSound.Sound,
item.
WorldPosition, powerOnSound.Volume, powerOnSound.Range, hullGuess:
item.
CurrentHull, ignoreMuffling: powerOnSound.IgnoreMuffling, freqMult: powerOnSound.GetRandomFrequencyMultiplier());
214 powerOnSoundPlayed =
true;
219 powerOnSoundPlayed =
false;
237 if (c.
Name ==
"power_in")
241 else if (c.
Name ==
"power_out")
250 else if (c.
Name ==
"power")
259 if (c.
Name ==
"power_in")
262 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.");
264 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);
276 if (c.
Name ==
"power_out")
279 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.");
281 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);
298 if (
Grids.Count > 0 && useCache)
324 foreach (
Powered powered
in poweredList)
331 if (powered.powerOut !=
null)
333 powered.powerOut.
Grid =
null;
339 foreach (
Powered powered
in poweredList)
352 if (powered.powerOut !=
null && powered.powerOut.
Grid ==
null && powered.
Item.
Condition > 0.0f)
357 GridInfo grid = PropagateGrid(powered.powerOut);
371 int id = Rand.Int(
int.MaxValue, Rand.RandSync.Unsynced);
372 while (
Grids.ContainsKey(
id))
374 id = Rand.Int(
int.MaxValue, Rand.RandSync.Unsynced);
377 return PropagateGrid(conn,
id);
380 private static GridInfo PropagateGrid(Connection conn,
int gridID)
382 Stack<Connection> probeStack =
new Stack<Connection>();
384 GridInfo grid =
new GridInfo(gridID);
386 probeStack.Push(conn);
389 while (probeStack.Count > 0)
391 Connection c = probeStack.Pop();
396 foreach (Connection otherC
in c.Recipients)
399 if (otherC.Grid != grid && (otherC.Grid ==
null || !
Grids.ContainsKey(otherC.Grid.ID)) &&
ValidPowerConnection(c, otherC))
402 probeStack.Push(otherC);
445 System.Diagnostics.Stopwatch sw =
new System.Diagnostics.Stopwatch();
453 GameMain.PerformanceCounter.AddElapsedTicks(
"Update:Power", sw.ElapsedTicks);
467 foreach (
Powered powered
in poweredList)
475 if (powered.
powerIn !=
null && powered.powerOut != powered.
powerIn)
503 if (powered.powerOut !=
null)
511 pt.PowerLoad = currLoad;
525 if (powered.powerOut.
Grid !=
null)
527 powered.powerOut.
Grid.
Load += currLoad;
530 else if (powered.powerOut.
Grid !=
null)
533 powered.powerOut.
Grid.
AddSrc(powered.powerOut);
541 pt2.PowerLoad = loadOut;
569 foreach (var device
in c.
Item.GetComponents<
Powered>())
576 float addedPower = 0;
579 foreach (var device
in c.
Item.GetComponents<
Powered>())
586 grid.
Power += addedPower;
590 float newVoltage = MathHelper.Min(grid.
Power / MathHelper.Max(grid.
Load, 1E-10f), 1000);
591 if (
float.IsNegative(newVoltage))
601 foreach (var device
in c.
Item.GetComponents<
Powered>())
603 device?.GridResolved(c);
610 GameMain.PerformanceCounter.AddElapsedTicks(
"Update:Power", sw.ElapsedTicks);
621 if (
powerIn ==
null && powerOut ==
null)
631 else if (connection != this.powerIn || !
IsActive)
684 float availablePower = 0.0f;
690 if (battery ==
null || battery.Item.Condition <= 0.0f) {
continue; }
691 if (battery.OutputDisabled) {
continue; }
692 float maxOutputPerFrame = battery.
MaxOutPut / 60.0f;
693 float framesPerMinute = 3600.0f;
694 availablePower += Math.Min(battery.Charge * framesPerMinute, maxOutputPerFrame);
696 return availablePower;
708 yield
return battery;
728 base.RemoveComponentSpecific();
729 poweredList.Remove(
this);
735 public readonly
int ID;
740 public readonly List<Connection>
Connections =
new List<Connection>();
741 public readonly SortedList<PowerPriority, PowerSourceGroup>
PowerSourceGroups =
new SortedList<PowerPriority, PowerSourceGroup>();
782 public readonly List<Connection>
Connections =
new List<Connection>();
static GameSession GameSession
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
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...