[DataField("onReceiveMessageSound")]
public SoundSpecifier OnReceiveMessageSound = new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg");
- [DataField("lastChargeState")]
public ApcChargeState LastChargeState;
- [DataField("lastChargeStateTime", customTypeSerializer: typeof(TimeOffsetSerializer))]
- public TimeSpan LastChargeStateTime;
+ public TimeSpan? LastChargeStateTime;
- [DataField("lastExternalState")]
public ApcExternalPowerState LastExternalState;
/// <summary>
/// Done after every <see cref="VisualsChangeDelay"/> to show the latest load.
/// If charge state changes it will be instantly updated.
/// </summary>
- [DataField("lastUiUpdate", customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan LastUiUpdate;
[DataField("enabled")]
[DataField("hasAccess")]
public bool HasAccess = false;
+ /// <summary>
+ /// APC state needs to always be updated after first processing tick.
+ /// </summary>
+ public bool NeedStateUpdate;
+
public const float HighPowerThreshold = 0.9f;
public static TimeSpan VisualsChangeDelay = TimeSpan.FromSeconds(1);
UpdatesAfter.Add(typeof(PowerNetSystem));
SubscribeLocalEvent<ApcComponent, BoundUIOpenedEvent>(OnBoundUiOpen);
- SubscribeLocalEvent<ApcComponent, MapInitEvent>(OnApcInit);
+ SubscribeLocalEvent<ApcComponent, ComponentStartup>(OnApcStartup);
SubscribeLocalEvent<ApcComponent, ChargeChangedEvent>(OnBatteryChargeChanged);
SubscribeLocalEvent<ApcComponent, ApcToggleMainBreakerMessage>(OnToggleMainBreaker);
SubscribeLocalEvent<ApcComponent, GotEmaggedEvent>(OnEmagged);
apc.LastUiUpdate = _gameTiming.CurTime;
UpdateUIState(uid, apc, battery);
}
+
+ if (apc.NeedStateUpdate)
+ {
+ UpdateApcState(uid, apc, battery);
+ }
}
}
UpdateApcState(uid, component);
}
- private void OnApcInit(EntityUid uid, ApcComponent component, MapInitEvent args)
+ private static void OnApcStartup(EntityUid uid, ApcComponent component, ComponentStartup args)
{
- UpdateApcState(uid, component);
+ // We cannot update immediately, as various network/battery state is not valid yet.
+ // Defer until the next tick.
+ component.NeedStateUpdate = true;
}
//Update the HasAccess var for UI to read
if (!Resolve(uid, ref apc, ref battery, false))
return;
- var newState = CalcChargeState(uid, battery.NetworkBattery);
- if (newState != apc.LastChargeState && apc.LastChargeStateTime + ApcComponent.VisualsChangeDelay < _gameTiming.CurTime)
+ if (apc.LastChargeStateTime == null || apc.LastChargeStateTime + ApcComponent.VisualsChangeDelay < _gameTiming.CurTime)
{
- apc.LastChargeState = newState;
- apc.LastChargeStateTime = _gameTiming.CurTime;
-
- if (TryComp(uid, out AppearanceComponent? appearance))
+ var newState = CalcChargeState(uid, battery.NetworkBattery);
+ if (newState != apc.LastChargeState)
{
- _appearance.SetData(uid, ApcVisuals.ChargeState, newState, appearance);
+ apc.LastChargeState = newState;
+ apc.LastChargeStateTime = _gameTiming.CurTime;
+
+ if (TryComp(uid, out AppearanceComponent? appearance))
+ {
+ _appearance.SetData(uid, ApcVisuals.ChargeState, newState, appearance);
+ }
}
}
apc.LastExternalState = extPowerState;
UpdateUIState(uid, apc, battery);
}
+
+ apc.NeedStateUpdate = false;
}
public void UpdateUIState(EntityUid uid,