1 using Microsoft.Xna.Framework;
3 using System.Collections.Generic;
13 private readonly HashSet<Connection> signalConnections =
new HashSet<Connection>();
15 private readonly Dictionary<Connection, bool> connectionDirty =
new Dictionary<Connection, bool>();
18 private readonly Dictionary<Connection, HashSet<Connection>> connectedRecipients =
new Dictionary<Connection, HashSet<Connection>>();
20 private float overloadCooldownTimer;
21 private const float OverloadCooldown = 5.0f;
48 "How much power has to be supplied to the grid relative to the load before item starts taking damage. "
49 +
"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.")]
63 [
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).")]
70 private float extraLoad;
71 private float extraLoadSetTime;
79 get {
return extraLoad; }
83 extraLoadSetTime = (float)Timing.TotalTime;
88 private bool canTransfer;
91 get {
return canTransfer; }
94 if (canTransfer == value)
return;
104 return base.IsActive;
109 if (base.IsActive == value)
return;
110 base.IsActive = value;
124 : base(
item, element)
129 InitProjectSpecific(element);
132 partial
void InitProjectSpecific(XElement element);
134 private static readonly HashSet<PowerTransfer> recipientsToRefresh =
new HashSet<PowerTransfer>();
137 base.UpdateBroken(deltaTime, cam);
146 recipientsToRefresh.Clear();
147 foreach (HashSet<Connection> recipientList
in connectedRecipients.Values)
153 if (recipientPowerTransfer !=
null)
155 recipientsToRefresh.Add(recipientPowerTransfer);
159 foreach (
PowerTransfer recipientPowerTransfer
in recipientsToRefresh)
170 private int prevSentPowerValue;
171 private string powerSignal;
172 private int prevSentLoadValue;
173 private string loadSignal;
179 if (Timing.TotalTime > extraLoadSetTime + 1.0)
184 extraLoad = Math.Max(extraLoad - 1000.0f * deltaTime, 0);
188 extraLoad = Math.Min(extraLoad + 1000.0f * deltaTime, 0);
202 float powerReadingOut = 0;
210 if (powerOut !=
null && powerOut.Grid !=
null)
212 powerReadingOut = powerOut.Grid.Power;
213 loadReadingOut = powerOut.Grid.Load;
216 if (prevSentPowerValue != (
int)powerReadingOut || powerSignal ==
null)
218 prevSentPowerValue = (int)Math.Round(powerReadingOut);
219 powerSignal = prevSentPowerValue.ToString();
221 if (prevSentLoadValue != (
int)loadReadingOut || loadSignal ==
null)
223 prevSentLoadValue = (int)Math.Round(loadReadingOut);
224 loadSignal = prevSentLoadValue.ToString();
238 if (overloadCooldownTimer > 0.0f)
240 overloadCooldownTimer -= deltaTime;
247 if (Rand.Range(0.0f, 1.0f) < 0.01f)
251 item.
Condition -= deltaTime * Rand.Range(10.0f, 500.0f) * conditionFactor;
255 overloadCooldownTimer = OverloadCooldown;
258 Vector2 baseVel = Rand.Vector(300.0f);
259 for (
int i = 0; i < 10; i++)
263 if (particle !=
null) particle.Size *= Rand.Range(0.5f, 1.0f);
287 return picker !=
null;
295 if (!connectionDirty.ContainsKey(c))
297 connectionDirty[c] =
true;
299 else if (!connectionDirty[c])
305 HashSet<Connection> tempConnected;
306 if (!connectedRecipients.ContainsKey(c))
308 tempConnected =
new HashSet<Connection>();
309 connectedRecipients.Add(c, tempConnected);
313 tempConnected = connectedRecipients[c];
314 tempConnected.Clear();
316 foreach (
Connection recipient
in tempConnected)
319 if (pt !=
null) { pt.connectionDirty[recipient] =
true; }
323 tempConnected.Add(c);
326 GetConnected(c, tempConnected);
329 foreach (
Connection recipient
in tempConnected)
331 if (recipient == c) {
continue; }
333 if (recipientPowerTransfer ==
null) {
continue; }
334 if (!recipientPowerTransfer.connectedRecipients.ContainsKey(recipient))
336 recipientPowerTransfer.connectedRecipients.Add(recipient,
new HashSet<Connection>());
340 recipientPowerTransfer.connectedRecipients[recipient].Clear();
342 foreach (var connection
in tempConnected)
344 recipientPowerTransfer.connectedRecipients[recipient].Add(connection);
346 recipientPowerTransfer.connectionDirty[recipient] =
false;
349 connectionDirty[c] =
false;
354 private void GetConnected(
Connection c, HashSet<Connection> connected)
360 if (recipient ==
null || connected.Contains(recipient)) {
continue; }
363 if (it ==
null || it.
Condition <= 0.0f) {
continue; }
365 connected.Add(recipient);
368 if (powerTransfer !=
null && powerTransfer.CanTransfer && powerTransfer.IsActive)
370 GetConnected(recipient, connected);
380 connectionDirty[c] =
true;
387 if (connections ==
null || !connections.Contains(connection))
return;
388 connectionDirty[connection] =
true;
396 if (connections ==
null)
404 if (c.
Name.Length > 5 && c.
Name.Substring(0, 6) ==
"signal")
406 signalConnections.Add(c);
414 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. " +
415 "If you want power to pass from input to output, change the component to a RelayComponent.");
425 if (!connectedRecipients.ContainsKey(connection)) {
return; }
426 if (!signalConnections.Contains(connection)) {
return; }
428 foreach (
Connection recipient
in connectedRecipients[connection])
430 if (recipient.
Item ==
item || recipient.
Item == signal.source) {
continue; }
432 signal.source?.LastSentSignalRecipients.Add(recipient);
442 if (recipient.
Effects !=
null && signal.value !=
"0" && !
string.IsNullOrEmpty(signal.value))
454 base.RemoveComponentSpecific();
455 connectedRecipients?.Clear();
456 connectionDirty?.Clear();
457 recipientsToRefresh.Clear();
static GameSession?? GameSession
static NetworkMember NetworkMember
static ParticleManager ParticleManager
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...
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.