2 using Microsoft.Xna.Framework;
4 using System.Collections.Generic;
14 private readonly HashSet<Connection> signalConnections =
new HashSet<Connection>();
16 private readonly Dictionary<Connection, bool> connectionDirty =
new Dictionary<Connection, bool>();
19 private readonly Dictionary<Connection, HashSet<Connection>> connectedRecipients =
new Dictionary<Connection, HashSet<Connection>>();
21 private float overloadCooldownTimer;
22 private const float OverloadCooldown = 5.0f;
49 "How much power has to be supplied to the grid relative to the load before item starts taking damage. "
50 +
"E.g. a value of 2 means that the grid has to be receiving twice as much power as the devices in the grid are consuming.")]
64 [
Serialize(
false,
IsPropertySaveable.No, description:
"Is the item currently overloaded. Intended to be used by StatusEffect conditionals (setting the value from XML is not recommended).")]
71 private float extraLoad;
72 private float extraLoadSetTime;
80 get {
return extraLoad; }
84 extraLoadSetTime = (float)Timing.TotalTime;
89 private bool canTransfer;
92 get {
return canTransfer; }
95 if (canTransfer == value)
return;
105 return base.IsActive;
110 if (base.IsActive == value)
return;
111 base.IsActive = value;
125 : base(
item, element)
130 InitProjectSpecific(element);
133 partial
void InitProjectSpecific(XElement element);
135 private static readonly HashSet<PowerTransfer> recipientsToRefresh =
new HashSet<PowerTransfer>();
138 base.UpdateBroken(deltaTime, cam);
147 recipientsToRefresh.Clear();
148 foreach (HashSet<Connection> recipientList
in connectedRecipients.Values)
154 if (recipientPowerTransfer !=
null)
156 recipientsToRefresh.Add(recipientPowerTransfer);
160 foreach (
PowerTransfer recipientPowerTransfer
in recipientsToRefresh)
171 private int prevSentPowerValue;
172 private string powerSignal;
173 private int prevSentLoadValue;
174 private string loadSignal;
180 if (Timing.TotalTime > extraLoadSetTime + 1.0)
185 extraLoad = Math.Max(extraLoad - 1000.0f * deltaTime, 0);
189 extraLoad = Math.Min(extraLoad + 1000.0f * deltaTime, 0);
203 float powerReadingOut = 0;
211 if (powerOut !=
null && powerOut.Grid !=
null)
213 powerReadingOut = powerOut.Grid.Power;
214 loadReadingOut = powerOut.Grid.Load;
217 if (prevSentPowerValue != (
int)powerReadingOut || powerSignal ==
null)
219 prevSentPowerValue = (int)Math.Round(powerReadingOut);
220 powerSignal = prevSentPowerValue.ToString();
222 if (prevSentLoadValue != (
int)loadReadingOut || loadSignal ==
null)
224 prevSentLoadValue = (int)Math.Round(loadReadingOut);
225 loadSignal = prevSentLoadValue.ToString();
239 if (overloadCooldownTimer > 0.0f)
241 overloadCooldownTimer -= deltaTime;
248 if (Rand.Range(0.0f, 1.0f) < 0.01f)
252 item.
Condition -= deltaTime * Rand.Range(10.0f, 500.0f) * conditionFactor;
256 overloadCooldownTimer = OverloadCooldown;
259 Vector2 baseVel = Rand.Vector(300.0f);
260 for (
int i = 0; i < 10; i++)
264 if (particle !=
null) particle.Size *= Rand.Range(0.5f, 1.0f);
288 return picker !=
null;
296 if (!connectionDirty.ContainsKey(c))
298 connectionDirty[c] =
true;
300 else if (!connectionDirty[c])
306 HashSet<Connection> tempConnected;
307 if (!connectedRecipients.ContainsKey(c))
309 tempConnected =
new HashSet<Connection>();
310 connectedRecipients.Add(c, tempConnected);
314 tempConnected = connectedRecipients[c];
315 tempConnected.Clear();
317 foreach (
Connection recipient
in tempConnected)
320 if (pt !=
null) { pt.connectionDirty[recipient] =
true; }
324 tempConnected.Add(c);
327 GetConnected(c, tempConnected);
330 foreach (
Connection recipient
in tempConnected)
332 if (recipient == c) {
continue; }
334 if (recipientPowerTransfer ==
null) {
continue; }
335 if (!recipientPowerTransfer.connectedRecipients.ContainsKey(recipient))
337 recipientPowerTransfer.connectedRecipients.Add(recipient,
new HashSet<Connection>());
341 recipientPowerTransfer.connectedRecipients[recipient].Clear();
343 foreach (var connection
in tempConnected)
345 recipientPowerTransfer.connectedRecipients[recipient].Add(connection);
347 recipientPowerTransfer.connectionDirty[recipient] =
false;
350 connectionDirty[c] =
false;
355 private void GetConnected(
Connection c, HashSet<Connection> connected)
361 if (recipient ==
null || connected.Contains(recipient)) {
continue; }
364 if (it ==
null || it.
Condition <= 0.0f) {
continue; }
366 connected.Add(recipient);
369 if (powerTransfer !=
null && powerTransfer.CanTransfer && powerTransfer.IsActive)
371 GetConnected(recipient, connected);
381 connectionDirty[c] =
true;
385 if (connectedRecipients.TryGetValue(c, out var recipients))
396 if (connections ==
null || !connections.Contains(connection)) {
return; }
397 connectionDirty[connection] =
true;
401 if (connectedRecipients.TryGetValue(connection, out var recipients))
413 if (connections ==
null)
421 if (c.
Name.Length > 5 && c.
Name.Substring(0, 6) ==
"signal")
423 signalConnections.Add(c);
431 DebugConsole.ThrowError(
"Error in item \"" +
Name +
"\" - PowerTransfer components should not have separate power inputs and outputs, but transfer power between wires connected to the same power connection. " +
432 "If you want power to pass from input to output, change the component to a RelayComponent.");
442 if (!connectedRecipients.ContainsKey(connection)) {
return; }
443 if (!signalConnections.Contains(connection)) {
return; }
445 foreach (
Connection recipient
in connectedRecipients[connection])
447 if (recipient.
Item ==
item || recipient.
Item == signal.source) {
continue; }
449 signal.source?.LastSentSignalRecipients.Add(recipient);
459 if (recipient.
Effects !=
null && signal.value !=
"0" && !
string.IsNullOrEmpty(signal.value))
471 base.RemoveComponentSpecific();
472 connectedRecipients?.Clear();
473 connectionDirty?.Clear();
474 recipientsToRefresh.Clear();
static NetworkMember NetworkMember
static GameSession GameSession
readonly EventManager EventManager
void ApplyStatusEffect(StatusEffect effect, ActionType type, float deltaTime, Character character=null, Limb limb=null, Entity useTarget=null, bool isNetworkEvent=false, bool checkCondition=true, Vector2? worldPosition=null)
List< Connection > Connections
List< Repairable > Repairables
List< ItemComponent > Components
void SendSignal(string signal, string connectionName)
readonly List< StatusEffect > Effects
List< Connection > Recipients
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)
virtual void ReceiveSignal(Signal signal, Connection connection)
List< Connection > PowerConnections
float ExtraLoad
Additional load coming from somewhere else than the devices connected to the junction box (e....
PowerTransfer(Item item, ContentXElement element)
override bool Pick(Character picker)
a Character has picked the item
override void OnItemLoaded()
Called when all the components of the item have been loaded. Use to initialize connections between co...
void RefreshConnections()
override void ReceiveSignal(Signal signal, Connection connection)
void SetAllConnectionsDirty()
override void Update(float deltaTime, Camera cam)
override float GetConnectionPowerOut(Connection conn, float power, PowerRange minMaxPower, float load)
Finalize how much power the device will be outputting to the connection
override void UpdateBroken(float deltaTime, Camera cam)
void SetConnectionDirty(Connection connection)
override void RemoveComponentSpecific()
float currPowerConsumption
The amount of power currently consumed by the item. Negative values mean that the item is providing p...
static readonly HashSet< Connection > ChangedConnections
StatusEffects can be used to execute various kinds of effects: modifying the state of some entity in ...
ActionType
ActionTypes define when a StatusEffect is executed.