]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Power Consumers Rebalance: Simple Dynamic Power Loading (#41961)
authorArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
Wed, 21 Jan 2026 04:05:44 +0000 (20:05 -0800)
committerGitHub <noreply@github.com>
Wed, 21 Jan 2026 04:05:44 +0000 (04:05 +0000)
* initial commit

* misc additions and fixes

* final tests and additions

* cleanup 1

* fix tests and add a test

* fix tests AGAIN

* abject horror and misery

* cleanup

* cleanup 2

* address some issues

21 files changed:
Content.Client/Power/EntitySystems/PowerStateSystem.cs [new file with mode: 0644]
Content.IntegrationTests/Tests/Power/PowerStatePrototypeTest.cs [new file with mode: 0644]
Content.IntegrationTests/Tests/Power/PowerStateTest.cs
Content.Server/Holopad/HolopadSystem.cs
Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs
Content.Server/Kitchen/EntitySystems/ReagentGrinderSystem.cs
Content.Server/Lathe/LatheProducingSystem.cs [new file with mode: 0644]
Content.Server/Power/EntitySystems/PowerStateSystem.cs [new file with mode: 0644]
Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerMixerSystem.cs
Content.Shared/Power/EntitySystems/PowerStateSystem.cs
Content.Shared/Power/EntitySystems/UIPowerStateSystem.cs
Resources/Maps/Misc/terminal.yml
Resources/Prototypes/Entities/Structures/Machines/Computers/arcades.yml
Resources/Prototypes/Entities/Structures/Machines/Computers/base_structurecomputers.yml
Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml
Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml
Resources/Prototypes/Entities/Structures/Machines/holopad.yml
Resources/Prototypes/Entities/Structures/Machines/lathe.yml
Resources/Prototypes/Entities/Structures/Machines/microwave.yml
Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml
Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/station_map.yml

diff --git a/Content.Client/Power/EntitySystems/PowerStateSystem.cs b/Content.Client/Power/EntitySystems/PowerStateSystem.cs
new file mode 100644 (file)
index 0000000..b17f174
--- /dev/null
@@ -0,0 +1,6 @@
+using Content.Shared.Power.EntitySystems;
+
+namespace Content.Client.Power.EntitySystems;
+
+/// <inheritdoc/>
+public sealed class PowerStateSystem : SharedPowerStateSystem;
diff --git a/Content.IntegrationTests/Tests/Power/PowerStatePrototypeTest.cs b/Content.IntegrationTests/Tests/Power/PowerStatePrototypeTest.cs
new file mode 100644 (file)
index 0000000..288e976
--- /dev/null
@@ -0,0 +1,59 @@
+using System.Linq;
+using Content.Server.Power.Components;
+using Content.Shared.Power.Components;
+using Content.Shared.Power.EntitySystems;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Prototypes;
+
+namespace Content.IntegrationTests.Tests.Power;
+
+[TestFixture, TestOf(typeof(SharedPowerStateSystem))]
+public sealed class PowerStatePrototypeTest
+{
+    /// <summary>
+    /// Asserts that the <see cref="SharedApcPowerReceiverComponent"/>'s load is the same
+    /// as the idle or working power draw from <see cref="PowerStateComponent"/>,
+    /// depending on the current power state.
+    /// </summary>
+    [Test]
+    public async Task AssertApcPowerMatchesPowerState()
+    {
+        await using var pair = await PoolManager.GetServerClient();
+        var server = pair.Server;
+
+        var protoMan = server.ResolveDependency<IPrototypeManager>();
+        var entMan = server.ResolveDependency<IEntityManager>();
+
+        await server.WaitAssertion(() =>
+        {
+            Assert.Multiple(delegate
+            {
+                foreach (var prototype in protoMan.EnumeratePrototypes<EntityPrototype>()
+                             .Where(p => !p.Abstract)
+                             .Where(p => !pair.IsTestPrototype(p)))
+                {
+                    if (!prototype.TryGetComponent<PowerStateComponent>(out var powerStateComp, entMan.ComponentFactory))
+                        continue;
+
+                    // LESSON LEARNED:
+                    // ENSURE THAT THE COMPONENT YOU ARE TRYING TO GET IS THE SERVER-SIDE VARIANT
+                    if (!prototype.TryGetComponent<ApcPowerReceiverComponent>(out var powerReceiverComp, entMan.ComponentFactory))
+                    {
+                        Assert.Fail(
+                            $"Entity prototype '{prototype.ID}' has a PowerStateComponent but is missing the required ApcPowerReceiverComponent.");
+                    }
+
+                    var expectedLoad = powerStateComp.IsWorking
+                        ? powerStateComp.WorkingPowerDraw
+                        : powerStateComp.IdlePowerDraw;
+
+                    Assert.That(powerReceiverComp.Load,
+                        Is.EqualTo(expectedLoad),
+                        $"Entity prototype '{prototype.ID}' has mismatched power draw between PowerStateComponent and SharedApcPowerReceiverComponent.");
+                }
+            });
+        });
+
+        await pair.CleanReturnAsync();
+    }
+}
index dec398212d1f499af7a7b19000cebf67548971f9..edec6f3d2117bcf8d125473ded8669e4bb27a52b 100644 (file)
@@ -56,7 +56,7 @@ public sealed class PowerStateTest
                 Assert.That(receiver.Load, Is.EqualTo(powerState.IdlePowerDraw).Within(0.01f));
             });
 
-            var system = entManager.System<PowerStateSystem>();
+            var system = entManager.System<SharedPowerStateSystem>();
             system.SetWorkingState((ent, powerState), true);
 
             Assert.Multiple(() =>
@@ -93,7 +93,7 @@ public sealed class PowerStateTest
 
             var receiver = entManager.GetComponent<Server.Power.Components.ApcPowerReceiverComponent>(ent);
             var powerState = entManager.GetComponent<PowerStateComponent>(ent);
-            var system = entManager.System<PowerStateSystem>();
+            var system = entManager.System<SharedPowerStateSystem>();
             Entity<PowerStateComponent> newEnt = (ent, powerState);
 
             Assert.Multiple(() =>
@@ -146,7 +146,7 @@ public sealed class PowerStateTest
 
             var receiver = entManager.GetComponent<Server.Power.Components.ApcPowerReceiverComponent>(ent);
             var powerState = entManager.GetComponent<PowerStateComponent>(ent);
-            var system = entManager.System<PowerStateSystem>();
+            var system = entManager.System<SharedPowerStateSystem>();
             Entity<PowerStateComponent> valueTuple = (ent, powerState);
 
             Assert.Multiple(() =>
index c634d14f2f82fd31ba2faaeb1dcc245853ca1ddc..c2aaf827dae66285fd3bb0d44b026cc00e1ac271 100644 (file)
@@ -23,6 +23,7 @@ using Robust.Shared.Containers;
 using Robust.Shared.Timing;
 using Robust.Shared.Utility;
 using System.Linq;
+using Content.Shared.Power.EntitySystems;
 
 namespace Content.Server.Holopad;
 
@@ -40,6 +41,7 @@ public sealed class HolopadSystem : SharedHolopadSystem
     [Dependency] private readonly PopupSystem _popupSystem = default!;
     [Dependency] private readonly IGameTiming _timing = default!;
     [Dependency] private readonly PvsOverrideSystem _pvs = default!;
+    [Dependency] private readonly SharedPowerStateSystem _powerState = default!;
 
     private float _updateTimer = 1.0f;
     private const float UpdateTime = 1.0f;
@@ -548,10 +550,14 @@ public sealed class HolopadSystem : SharedHolopadSystem
         {
             _telephoneSystem.SetSpeakerForTelephone((entity, entityTelephone), (hologramUid, hologramSpeech));
         }
+
+        _powerState.SetWorkingState(entity.Owner, true);
     }
 
     private void DeleteHologram(Entity<HolopadHologramComponent> hologram, Entity<HolopadComponent> attachedHolopad)
     {
+        _powerState.SetWorkingState(attachedHolopad.Owner, false);
+
         attachedHolopad.Comp.Hologram = null;
 
         QueueDel(hologram);
index 6f3d39320903237695287f4e831b5e9ec1662a56..d1df5177d1ecf049866541fa9ac6f3d28d26ba66 100644 (file)
@@ -37,6 +37,7 @@ using Content.Shared.Stacks;
 using Content.Server.Construction.Components;
 using Content.Shared.Chat;
 using Content.Shared.Damage.Components;
+using Content.Shared.Power.EntitySystems;
 using Content.Shared.Temperature.Components;
 
 namespace Content.Server.Kitchen.EntitySystems
@@ -64,6 +65,7 @@ namespace Content.Server.Kitchen.EntitySystems
         [Dependency] private readonly IPrototypeManager _prototype = default!;
         [Dependency] private readonly IAdminLogManager _adminLogger = default!;
         [Dependency] private readonly SharedSuicideSystem _suicide = default!;
+        [Dependency] private readonly SharedPowerStateSystem _powerState = default!;
 
         private static readonly EntProtoId MalfunctionSpark = "Spark";
 
@@ -112,6 +114,7 @@ namespace Content.Server.Kitchen.EntitySystems
 
             microwaveComponent.PlayingStream =
                 _audio.PlayPvs(microwaveComponent.LoopingSound, ent, AudioParams.Default.WithLoop(true).WithMaxDistance(5))?.Entity;
+            _powerState.SetWorkingState(ent.Owner, true);
         }
 
         private void OnCookStop(Entity<ActiveMicrowaveComponent> ent, ref ComponentShutdown args)
@@ -121,6 +124,7 @@ namespace Content.Server.Kitchen.EntitySystems
 
             SetAppearance(ent.Owner, MicrowaveVisualState.Idle, microwaveComponent);
             microwaveComponent.PlayingStream = _audio.Stop(microwaveComponent.PlayingStream);
+            _powerState.SetWorkingState(ent.Owner, false);
         }
 
         private void OnActiveMicrowaveInsert(Entity<ActiveMicrowaveComponent> ent, ref EntInsertedIntoContainerMessage args)
index a709f4b8d98e244647ab691c0f13d8edcb40fc5b..bf9e4e1434d64b00d9efa649fa479d458c9a7988 100644 (file)
@@ -22,6 +22,7 @@ using Content.Server.Jittering;
 using Content.Shared.Jittering;
 using Content.Shared.Kitchen.EntitySystems;
 using Content.Shared.Power;
+using Content.Shared.Power.EntitySystems;
 
 namespace Content.Server.Kitchen.EntitySystems
 {
@@ -40,6 +41,7 @@ namespace Content.Server.Kitchen.EntitySystems
         [Dependency] private readonly SharedDestructibleSystem _destructible = default!;
         [Dependency] private readonly RandomHelperSystem _randomHelper = default!;
         [Dependency] private readonly JitteringSystem _jitter = default!;
+        [Dependency] private readonly SharedPowerStateSystem _powerState = default!;
 
         public override void Initialize()
         {
@@ -136,11 +138,15 @@ namespace Content.Server.Kitchen.EntitySystems
         private void OnActiveGrinderStart(Entity<ActiveReagentGrinderComponent> ent, ref ComponentStartup args)
         {
             _jitter.AddJitter(ent, -10, 100);
+
+            // Not all grinders need power.
+            _powerState.TrySetWorkingState(ent.Owner, true);
         }
 
         private void OnActiveGrinderRemove(Entity<ActiveReagentGrinderComponent> ent, ref ComponentRemove args)
         {
             RemComp<JitteringComponent>(ent);
+            _powerState.TrySetWorkingState(ent.Owner, false);
         }
 
         private void OnEntRemoveAttempt(Entity<ReagentGrinderComponent> entity, ref ContainerIsRemovingAttemptEvent args)
diff --git a/Content.Server/Lathe/LatheProducingSystem.cs b/Content.Server/Lathe/LatheProducingSystem.cs
new file mode 100644 (file)
index 0000000..ce81ed6
--- /dev/null
@@ -0,0 +1,34 @@
+using Content.Server.Lathe.Components;
+using Content.Shared.Power.EntitySystems;
+
+namespace Content.Server.Lathe;
+
+/// <summary>
+/// System for handling lathes that are actively producing items.
+/// The component is used more so as a marker for EntityQueryEnumerator,
+/// however it's also used to set the power state of the lathe when producing.
+/// </summary>
+public sealed class LatheProducingSystem : EntitySystem
+{
+    [Dependency] private readonly SharedPowerStateSystem _powerState = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<LatheProducingComponent, ComponentStartup>(OnComponentStartup);
+        SubscribeLocalEvent<LatheProducingComponent, ComponentShutdown>(OnComponentShutdown);
+    }
+
+    private void OnComponentShutdown(Entity<LatheProducingComponent> ent, ref ComponentShutdown args)
+    {
+        // use the Try variant of this here
+        // or else you get trolled by AllComponentsOneToOneDeleteTest
+        _powerState.TrySetWorkingState(ent.Owner, false);
+    }
+
+    private void OnComponentStartup(Entity<LatheProducingComponent> ent, ref ComponentStartup args)
+    {
+        _powerState.TrySetWorkingState(ent.Owner, true);
+    }
+}
diff --git a/Content.Server/Power/EntitySystems/PowerStateSystem.cs b/Content.Server/Power/EntitySystems/PowerStateSystem.cs
new file mode 100644 (file)
index 0000000..92c103b
--- /dev/null
@@ -0,0 +1,21 @@
+using Content.Server.Power.Components;
+using Content.Shared.Power.Components;
+using Content.Shared.Power.EntitySystems;
+
+namespace Content.Server.Power.EntitySystems;
+
+public sealed class PowerStateSystem : SharedPowerStateSystem
+{
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<PowerStateComponent, ComponentStartup>(OnComponentStartup);
+    }
+
+    private void OnComponentStartup(Entity<PowerStateComponent> ent, ref ComponentStartup args)
+    {
+        EnsureComp<ApcPowerReceiverComponent>(ent);
+        SetWorkingState(ent.Owner, ent.Comp.IsWorking);
+    }
+}
index c8e8e89ce53bbb1afd32de2957493108301233c6..3128623fc34492f79ee491550acf6890e1e9aa60 100644 (file)
@@ -2,6 +2,7 @@ using Content.Shared.Chemistry.Components;
 using Content.Shared.Chemistry.Reaction;
 using Content.Shared.Interaction;
 using Content.Shared.Popups;
+using Content.Shared.Power.EntitySystems;
 using Robust.Shared.Audio.Systems;
 using Robust.Shared.Containers;
 using Robust.Shared.Network;
@@ -21,6 +22,7 @@ public abstract class SharedSolutionContainerMixerSystem : EntitySystem
     [Dependency] private readonly SharedContainerSystem _container = default!;
     [Dependency] private readonly SharedPopupSystem _popup = default!;
     [Dependency] private readonly SharedSolutionContainerSystem _solution = default!;
+    [Dependency] private readonly SharedPowerStateSystem _powerState = default!;
 
     /// <inheritdoc/>
     public override void Initialize()
@@ -74,6 +76,7 @@ public abstract class SharedSolutionContainerMixerSystem : EntitySystem
             comp.MixingSoundEntity = _audio.PlayPvs(comp.MixingSound, entity, comp.MixingSound?.Params.WithLoop(true));
         comp.MixTimeEnd = _timing.CurTime + comp.MixDuration;
         _appearance.SetData(entity, SolutionContainerMixerVisuals.Mixing, true);
+        _powerState.SetWorkingState(entity.Owner, true);
         Dirty(uid, comp);
     }
 
@@ -86,6 +89,7 @@ public abstract class SharedSolutionContainerMixerSystem : EntitySystem
         _appearance.SetData(entity, SolutionContainerMixerVisuals.Mixing, false);
         comp.Mixing = false;
         comp.MixingSoundEntity = null;
+        _powerState.SetWorkingState(entity.Owner, false);
         Dirty(uid, comp);
     }
 
index dd47708d2d390b7ae82d62437f6f369e3a56821c..aba41e2432abd0e9e58c075e648f8ea430b76f35 100644 (file)
@@ -7,7 +7,7 @@ namespace Content.Shared.Power.EntitySystems;
 /// Generic system that handles entities with <see cref="PowerStateComponent"/>.
 /// Used for simple machines that only need to switch between "idle" and "working" power states.
 /// </summary>
-public sealed class PowerStateSystem : EntitySystem
+public abstract class SharedPowerStateSystem : EntitySystem
 {
     [Dependency] private readonly SharedPowerReceiverSystem _powerReceiverSystem = default!;
 
@@ -17,16 +17,9 @@ public sealed class PowerStateSystem : EntitySystem
     {
         base.Initialize();
 
-        SubscribeLocalEvent<PowerStateComponent, ComponentStartup>(OnComponentStartup);
-
         _powerStateQuery = GetEntityQuery<PowerStateComponent>();
     }
 
-    private void OnComponentStartup(Entity<PowerStateComponent> ent, ref ComponentStartup args)
-    {
-        SetWorkingState(ent.Owner, ent.Comp.IsWorking);
-    }
-
     /// <summary>
     /// Sets the working state of the entity, adjusting its power draw accordingly.
     /// </summary>
@@ -41,4 +34,22 @@ public sealed class PowerStateSystem : EntitySystem
         _powerReceiverSystem.SetLoad(ent.Owner, working ? ent.Comp.WorkingPowerDraw : ent.Comp.IdlePowerDraw);
         ent.Comp.IsWorking = working;
     }
+
+    /// <summary>
+    /// Tries to set the working state of the entity, adjusting its power draw accordingly.
+    /// Use this for if you're not sure if the entity has a <see cref="PowerStateComponent"/>.
+    /// </summary>
+    /// <param name="ent">The entity to set the working state for.</param>
+    /// <param name="working">Whether the entity should be in the working state.</param>
+    [PublicAPI]
+    public void TrySetWorkingState(Entity<PowerStateComponent?> ent, bool working)
+    {
+        // Sometimes systems calling this API handle generic objects that can or can't consume power,
+        // so to reduce boilerplate we don't log an error. Any entity that *should* have an ApcPowerRecieverComponent
+        // will log an error in tests if someone tries to add an entity that doesn't have one.
+        if (!_powerStateQuery.Resolve(ent, ref ent.Comp, false))
+            return;
+
+        SetWorkingState(ent, working);
+    }
 }
index bf2d08adbf492ace9666afa876e946cfd38d2c06..6bd5af591ed6e8b00e9ad87b4a2f9f0800c0a9fc 100644 (file)
@@ -10,7 +10,7 @@ namespace Content.Shared.Power.EntitySystems;
 public sealed class UIPowerStateSystem : EntitySystem
 {
     [Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
-    [Dependency] private readonly PowerStateSystem _powerState = default!;
+    [Dependency] private readonly SharedPowerStateSystem _powerState = default!;
 
     public override void Initialize()
     {
index bb0491e9cec8159dcc179a165f8fb77c4614c1b0..1a736bac2696ede639990946afa21b172be9c99a 100644 (file)
@@ -1583,6 +1583,7 @@ entities:
     - type: Godmode
     missingComponents:
     - ApcPowerReceiver
+    - PowerState
     - Anchorable
     - Construction
     - Destructible
@@ -1595,6 +1596,7 @@ entities:
     - type: Godmode
     missingComponents:
     - ApcPowerReceiver
+    - PowerState
     - Anchorable
     - Construction
     - Destructible
@@ -7904,6 +7906,7 @@ entities:
     - type: Godmode
     missingComponents:
     - ApcPowerReceiver
+    - PowerState
     - Anchorable
     - Construction
     - Destructible
@@ -7916,6 +7919,7 @@ entities:
     - type: Godmode
     missingComponents:
     - ApcPowerReceiver
+    - PowerState
     - Anchorable
     - Construction
     - Destructible
index 8c7872c23f6e31a6b3767f6c7d7458b89a7ea4f7..8e852273ef88894338543eee1d4bc90360c9689b 100644 (file)
@@ -5,8 +5,6 @@
   name: arcade
   parent: BaseComputer
   components:
-  - type: ApcPowerReceiver
-    powerLoad: 350
   - type: ExtensionCableReceiver
   - type: PointLight
     radius: 1.8
index bbd6ea8302c5ecb110d246d5eed896e19076f807..e4c8293fcb32872b61d6733018d8b65854aaecc9 100644 (file)
       - board
   - type: Computer
   - type: ApcPowerReceiver
-    powerLoad: 200
+    powerLoad: 50
+  - type: PowerState
+    idlePowerDraw: 50
+    workingPowerDraw: 500
+  - type: UIPowerState
   - type: ExtensionCableReceiver
   - type: ActivatableUIRequiresPower
   - type: Sprite
index 396452fdb147ba8519504b346703489db985b9cb..96e30a5aa7692650f6a7334abf99db7a741352cb 100644 (file)
       enum.WiresUiKey.Key:
         type: WiresBoundUserInterface
   - type: ApcPowerReceiver
-    powerLoad: 1000
+    powerLoad: 50
+  - type: PowerState
+    idlePowerDraw: 50
+    workingPowerDraw: 1000
   - type: Computer
     board: ResearchComputerCircuitboard
   - type: AccessReader
       enum.WiresUiKey.Key:
         type: WiresBoundUserInterface
   - type: ApcPowerReceiver
-    powerLoad: 1000
+    powerLoad: 50
+  - type: PowerState
+    idlePowerDraw: 50
+    workingPowerDraw: 1000
   - type: Computer
     board: AnalysisComputerCircuitboard
   - type: PointLight
   name: body scanner computer
   description: A body scanner.
   components:
-  - type: ApcPowerReceiver
-    powerLoad: 500
   - type: Computer
     board: BodyScannerComputerCircuitboard
   - type: PointLight
       state: generic_keys
     - map: [ "enum.WiresVisualLayers.MaintenancePanel" ]
       state: generic_panel_open
-  - type: ApcPowerReceiver
-    powerLoad: 3100 #We want this to fail first so I transferred most of the scanner and pod's power here. (3500 in total)
   - type: Computer
     board: CloningConsoleComputerCircuitboard
   - type: PointLight
       enum.WiresUiKey.Key:
         type: WiresBoundUserInterface
   - type: ApcPowerReceiver
-    powerLoad: 1000
+    powerLoad: 5
+  - type: PowerState
+    idlePowerDraw: 5
+    workingPowerDraw: 1000
+  - type: UIPowerState
   - type: DeviceNetwork
     deviceNetId: Wireless
     receiveFrequencyId: RoboticsConsole
     channels:
     - Xenoborg
   - type: ApcPowerReceiver
-    powerLoad: 1000
+    powerLoad: 50
+  - type: PowerState
+    idlePowerDraw: 50
+    workingPowerDraw: 1000
   - type: DeviceNetwork
     deviceNetId: Wireless
     receiveFrequencyId: Mothership
     - map: [ "enum.WiresVisualLayers.MaintenancePanel" ]
       state: generic_panel_open
   - type: ApcPowerReceiver
-    powerLoad: 1000
+    powerLoad: 50
+  - type: PowerState
+    idlePowerDraw: 50
+    workingPowerDraw: 1000
   - type: Computer
     board: StationAiUploadCircuitboard
   - type: AccessReader
           True: { visible: false }
           False: { visible: true }
   - type: ApcPowerReceiver
-    powerLoad: 1000
+    powerLoad: 50
+  - type: PowerState
+    idlePowerDraw: 50
+    workingPowerDraw: 1000
   - type: Computer
     board: StationAiFixerCircuitboard
   - type: AccessReader
index 65a84c86aa697627db8871bdc6ba95c549e1de95..c88c2482329bd10abc17ffd397cb639ddb891b1c 100644 (file)
           False: { visible: False }
   - type: Machine
     board: ElectrolysisUnitMachineCircuitboard
+  - type: ApcPowerReceiver
+    powerLoad: 0
+  - type: PowerState
+    idlePowerDraw: 0
+    workingPowerDraw: 1000 # for a lab-grade machine
 
 # TODO centrifuge should spill the vial if the lid is off
 - type: entity
             - CentrifugeCompatible
   - type: Machine
     board: CentrifugeMachineCircuitboard
+  - type: ApcPowerReceiver
+    powerLoad: 0
+  - type: PowerState
+    idlePowerDraw: 0
+    workingPowerDraw: 500
index 8c68710d76e233a64d0339e480c37e74e19bdf9b..5c9c5c21b674e12e0057ec89cb8e49a80443e441 100644 (file)
         mask:
         - Impassable
   - type: ApcPowerReceiver
-    powerLoad: 300
+    powerLoad: 5
+  - type: PowerState
+    idlePowerDraw: 5
+    workingPowerDraw: 300
   - type: StationAiVision
     range: 1
     needsAnchoring: true
index 412126af5f15feeec6782346c653a5e554b23538..e59e2d86e778dfb9a22553c61de995205edd9b3a 100644 (file)
     price: 800
   - type: ResearchClient
   - type: TechnologyDatabase
+  - type: ApcPowerReceiver
+    powerLoad: 150
+  - type: PowerState
+    idlePowerDraw: 150
+    workingPowerDraw: 1000
 
 # a lathe that can be sped up with space lube / slowed down with glue
 - type: entity
index b7c5b194efb0f838af526da0e33e739250dab639..edc367a934e6f931ff5f13e58a615b51f6b76088 100644 (file)
     canCreateVacuum: false
     deleteAfterExplosion: false
   - type: ApcPowerReceiver
-    powerLoad: 400
+    powerLoad: 5
+  - type: PowerState
+    idlePowerDraw: 5
+    workingPowerDraw: 1000
   - type: Machine
     board: MicrowaveMachineCircuitboard
   - type: ContainerContainer
index d423a47ae95ff626119d444c64c446b7929a8819..cd3d8dab835a1047dac4980f8716a53b72fbe1b2 100644 (file)
     - map: [ "grinder" ]
       state: "grinder_empty"
   - type: ApcPowerReceiver
-    powerLoad: 300
+    powerLoad: 0
+  - type: PowerState
+    idlePowerDraw: 0
+    workingPowerDraw: 750 # medium power blender
   - type: ItemSlots
     slots:
       beakerSlot:
index 39643fb85020fc68132c68d39724c6824d5bdb3a..889cbb3003881af33f6021cb17761f9945b7b0e0 100644 (file)
       containers:
         board: !type:Container
     - type: ApcPowerReceiver
-      powerLoad: 200
+      powerLoad: 50
+    - type: PowerState
+      idlePowerDraw: 50
+      workingPowerDraw: 200
+    - type: UIPowerState
     - type: Construction
       graph: StationMap
       node: station_map