diff --git a/Content.Client/Power/EntitySystems/PowerNetSystem.cs b/Content.Client/Power/EntitySystems/PowerNetSystem.cs new file mode 100644 index 0000000000..6fb9f482ce --- /dev/null +++ b/Content.Client/Power/EntitySystems/PowerNetSystem.cs @@ -0,0 +1,8 @@ +using Content.Shared.Power.EntitySystems; + +namespace Content.Client.Power.EntitySystems; + +public sealed class PowerNetSystem : SharedPowerNetSystem +{ + +} diff --git a/Content.Server/Power/EntitySystems/PowerNetSystem.cs b/Content.Server/Power/EntitySystems/PowerNetSystem.cs index dbc17f2b9d..666d3fcbe8 100644 --- a/Content.Server/Power/EntitySystems/PowerNetSystem.cs +++ b/Content.Server/Power/EntitySystems/PowerNetSystem.cs @@ -5,6 +5,8 @@ using Content.Server.Power.NodeGroups; using Content.Server.Power.Pow3r; using Content.Shared.CCVar; using Content.Shared.Power; +using Content.Shared.Power.Components; +using Content.Shared.Power.EntitySystems; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Configuration; @@ -16,7 +18,7 @@ namespace Content.Server.Power.EntitySystems /// Manages power networks, power state, and all power components. /// [UsedImplicitly] - public sealed class PowerNetSystem : EntitySystem + public sealed class PowerNetSystem : SharedPowerNetSystem { [Dependency] private readonly AppearanceSystem _appearance = default!; [Dependency] private readonly PowerNetConnectorSystem _powerNetConnector = default!; @@ -28,12 +30,20 @@ namespace Content.Server.Power.EntitySystems private readonly HashSet _powerNetReconnectQueue = new(); private readonly HashSet _apcNetReconnectQueue = new(); + private EntityQuery _apcBatteryQuery; + private EntityQuery _appearanceQuery; + private EntityQuery _batteryQuery; + private BatteryRampPegSolver _solver = new(); public override void Initialize() { base.Initialize(); + _apcBatteryQuery = GetEntityQuery(); + _appearanceQuery = GetEntityQuery(); + _batteryQuery = GetEntityQuery(); + UpdatesAfter.Add(typeof(NodeGroupSystem)); _solver = new(_cfg.GetCVar(CCVars.DebugPow3rDisableParallel)); @@ -309,10 +319,6 @@ namespace Content.Server.Power.EntitySystems private void UpdateApcPowerReceiver(float frameTime) { - var appearanceQuery = GetEntityQuery(); - var metaQuery = GetEntityQuery(); - var apcBatteryQuery = GetEntityQuery(); - var enumerator = AllEntityQuery(); while (enumerator.MoveNext(out var uid, out var apcReceiver)) { @@ -321,8 +327,11 @@ namespace Content.Server.Power.EntitySystems || MathHelper.CloseToPercent(apcReceiver.NetworkLoad.ReceivingPower, apcReceiver.Load)); + MetaDataComponent? metadata = null; + + // TODO: If we get archetypes would be better to split this out. // Check if the entity has an internal battery - if (apcBatteryQuery.TryComp(uid, out var apcBattery) && TryComp(uid, out var battery)) + if (_apcBatteryQuery.TryComp(uid, out var apcBattery) && _batteryQuery.TryComp(uid, out var battery)) { apcReceiver.Load = apcBattery.IdleLoad; @@ -333,7 +342,6 @@ namespace Content.Server.Power.EntitySystems { _battery.SetCharge(uid, battery.CurrentCharge - apcBattery.IdleLoad * frameTime, battery); } - // Otherwise try to charge the battery else if (powered && !_battery.IsFull(uid, battery)) { @@ -347,6 +355,8 @@ namespace Content.Server.Power.EntitySystems if (apcBattery.Enabled != enableBattery) { apcBattery.Enabled = enableBattery; + metadata = MetaData(uid); + Dirty(uid, apcBattery, metadata); var apcBatteryEv = new ApcPowerReceiverBatteryChangedEvent(enableBattery); RaiseLocalEvent(uid, ref apcBatteryEv); @@ -361,8 +371,8 @@ namespace Content.Server.Power.EntitySystems if (!apcReceiver.Recalculate && apcReceiver.Powered == powered) continue; - var metadata = metaQuery.Comp(uid); - if (metadata.EntityPaused) + metadata ??= MetaData(uid); + if (Paused(uid, metadata)) continue; apcReceiver.Recalculate = false; @@ -372,15 +382,14 @@ namespace Content.Server.Power.EntitySystems var ev = new PowerChangedEvent(powered, apcReceiver.NetworkLoad.ReceivingPower); RaiseLocalEvent(uid, ref ev); - if (appearanceQuery.TryComp(uid, out var appearance)) + if (_appearanceQuery.TryComp(uid, out var appearance)) _appearance.SetData(uid, PowerDeviceVisuals.Powered, powered, appearance); } } private void UpdatePowerConsumer() { - var metaQuery = GetEntityQuery(); - var enumerator = AllEntityQuery(); + var enumerator = EntityQueryEnumerator(); while (enumerator.MoveNext(out var uid, out var consumer)) { var newRecv = consumer.NetworkLoad.ReceivingPower; @@ -388,9 +397,6 @@ namespace Content.Server.Power.EntitySystems if (MathHelper.CloseToPercent(lastRecv, newRecv)) continue; - if (metaQuery.GetComponent(uid).EntityPaused) - continue; - lastRecv = newRecv; var msg = new PowerConsumerReceivedChanged(newRecv, consumer.DrawRate); RaiseLocalEvent(uid, ref msg); diff --git a/Content.Server/Power/Components/ApcPowerReceiverBatteryComponent.cs b/Content.Shared/Power/Components/ApcPowerReceiverBatteryChangedEvent.cs similarity index 68% rename from Content.Server/Power/Components/ApcPowerReceiverBatteryComponent.cs rename to Content.Shared/Power/Components/ApcPowerReceiverBatteryChangedEvent.cs index e2af146f26..02c8328fa1 100644 --- a/Content.Server/Power/Components/ApcPowerReceiverBatteryComponent.cs +++ b/Content.Shared/Power/Components/ApcPowerReceiverBatteryChangedEvent.cs @@ -1,21 +1,21 @@ -using Content.Server.Power.EntitySystems; using Content.Shared.Power.EntitySystems; +using Robust.Shared.GameStates; -namespace Content.Server.Power.Components; +namespace Content.Shared.Power.Components; /// /// Attached to APC powered entities that possess a rechargeable internal battery. -/// If external power is interrupted, the entity will draw power from this battery instead. -/// Requires and to function. +/// If external power is interrupted, the entity will draw power from this battery instead. +/// Requires and to function. /// -[RegisterComponent] -[Access([typeof(PowerNetSystem), typeof(SharedPowerReceiverSystem)])] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SharedPowerNetSystem), typeof(SharedPowerReceiverSystem))] public sealed partial class ApcPowerReceiverBatteryComponent : Component { /// /// Indicates whether power is currently being drawn from the battery. /// - [DataField] + [DataField, AutoNetworkedField] public bool Enabled = false; /// @@ -24,22 +24,22 @@ public sealed partial class ApcPowerReceiverBatteryComponent : Component /// of power is drained from the battery every second. /// [DataField] - public float IdleLoad { get; set; } = 5f; + public float IdleLoad = 5f; /// - /// Determines how much battery charge the entity's battery gains + /// Determines how much battery charge the entity's battery gains /// per second when connected to an active APC power network. /// [DataField] - public float BatteryRechargeRate { get; set; } = 50f; + public float BatteryRechargeRate = 50f; /// - /// While the battery is being recharged, the load this entity places on the APC + /// While the battery is being recharged, the load this entity places on the APC /// power network is increased by the multiplied /// by this factor. /// [DataField] - public float BatteryRechargeEfficiency { get; set; } = 1f; + public float BatteryRechargeEfficiency = 1f; } /// diff --git a/Content.Shared/Power/EntitySystems/SharedPowerNetSystem.cs b/Content.Shared/Power/EntitySystems/SharedPowerNetSystem.cs new file mode 100644 index 0000000000..28f74536c4 --- /dev/null +++ b/Content.Shared/Power/EntitySystems/SharedPowerNetSystem.cs @@ -0,0 +1,6 @@ +namespace Content.Shared.Power.EntitySystems; + +public abstract class SharedPowerNetSystem : EntitySystem +{ + +}