From 6acfe53e5fc1e35e6b1a2006b694d9ed6c1f64af Mon Sep 17 00:00:00 2001
From: deltanedas <39013340+deltanedas@users.noreply.github.com>
Date: Wed, 7 Jun 2023 19:43:54 +0000
Subject: [PATCH] add breakers to power batteries (#16903)
Co-authored-by: deltanedas <@deltanedas:kde.org>
---
.../Power/Components/BreakerComponent.cs | 14 +++++++++
.../Power/EntitySystems/ApcSystem.cs | 14 +++++++++
.../Power/EntitySystems/BreakerSystem.cs | 30 +++++++++++++++++++
.../Power/Events/BreakerPoppedEvent.cs | 8 +++++
.../en-US/apc/components/apc-component.ftl | 1 +
.../Entities/Structures/Power/apc.yml | 3 ++
6 files changed, 70 insertions(+)
create mode 100644 Content.Server/Power/Components/BreakerComponent.cs
create mode 100644 Content.Server/Power/EntitySystems/BreakerSystem.cs
create mode 100644 Content.Server/Power/Events/BreakerPoppedEvent.cs
diff --git a/Content.Server/Power/Components/BreakerComponent.cs b/Content.Server/Power/Components/BreakerComponent.cs
new file mode 100644
index 0000000000..bc58956879
--- /dev/null
+++ b/Content.Server/Power/Components/BreakerComponent.cs
@@ -0,0 +1,14 @@
+using Content.Server.Power.EntitySystems;
+
+namespace Content.Server.Power.Components;
+
+[RegisterComponent]
+[Access(typeof(BreakerSystem))]
+public sealed class BreakerComponent : Component
+{
+ ///
+ /// Once power supplied exceeds this limit the breaker will pop.
+ ///
+ [DataField("limit", required: true), ViewVariables(VVAccess.ReadWrite)]
+ public float Limit;
+}
diff --git a/Content.Server/Power/EntitySystems/ApcSystem.cs b/Content.Server/Power/EntitySystems/ApcSystem.cs
index db07eb7aa9..4df8c33c5b 100644
--- a/Content.Server/Power/EntitySystems/ApcSystem.cs
+++ b/Content.Server/Power/EntitySystems/ApcSystem.cs
@@ -1,6 +1,7 @@
using Content.Server.Emp;
using Content.Server.Popups;
using Content.Server.Power.Components;
+using Content.Server.Power.Events;
using Content.Server.Power.Pow3r;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
@@ -36,6 +37,7 @@ namespace Content.Server.Power.EntitySystems
SubscribeLocalEvent(OnBatteryChargeChanged);
SubscribeLocalEvent(OnToggleMainBreaker);
SubscribeLocalEvent(OnEmagged);
+ SubscribeLocalEvent(OnBreakerPopped);
SubscribeLocalEvent(OnEmpPulse);
}
@@ -111,6 +113,18 @@ namespace Content.Server.Power.EntitySystems
args.Handled = true;
}
+ private void OnBreakerPopped(EntityUid uid, ApcComponent comp, BreakerPoppedEvent args)
+ {
+ // already disabled, do nothing
+ if (!comp.MainBreakerEnabled)
+ return;
+
+ ApcToggleBreaker(uid, comp);
+
+ // popup so its clear what happened
+ _popup.PopupEntity(Loc.GetString("apc-component-breaker-popped"), uid);
+ }
+
public void UpdateApcState(EntityUid uid,
ApcComponent? apc=null,
PowerNetworkBatteryComponent? battery = null)
diff --git a/Content.Server/Power/EntitySystems/BreakerSystem.cs b/Content.Server/Power/EntitySystems/BreakerSystem.cs
new file mode 100644
index 0000000000..f8333c3147
--- /dev/null
+++ b/Content.Server/Power/EntitySystems/BreakerSystem.cs
@@ -0,0 +1,30 @@
+using Content.Server.Administration.Logs;
+using Content.Server.Power.Components;
+using Content.Server.Power.Events;
+using Content.Shared.Database;
+
+namespace Content.Server.Power.EntitySystems;
+
+///
+/// Handles raising BreakerPopEvent when a power provider exceeds its maximum power.
+///
+public sealed class BreakerSystem : EntitySystem
+{
+ [Dependency] private readonly IAdminLogManager _adminLogger = default!;
+
+ ///
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var uid, out var breaker, out var battery))
+ {
+ if (battery.CurrentSupply > breaker.Limit)
+ {
+ _adminLogger.Add(LogType.Action, LogImpact.Low, $"Breaker of {ToPrettyString(uid):battery)} popped from supplying {battery.CurrentSupply} with a breaker limit of {breaker.Limit}");
+ RaiseLocalEvent(uid, new BreakerPoppedEvent());
+ }
+ }
+ }
+}
diff --git a/Content.Server/Power/Events/BreakerPoppedEvent.cs b/Content.Server/Power/Events/BreakerPoppedEvent.cs
new file mode 100644
index 0000000000..930d1fa2bb
--- /dev/null
+++ b/Content.Server/Power/Events/BreakerPoppedEvent.cs
@@ -0,0 +1,8 @@
+namespace Content.Server.Power.Events;
+
+///
+/// Invoked on a target power provider when its power exceeds BreakerComponent MaxPower, popping the breaker or blowing the fuse.
+///
+public sealed class BreakerPoppedEvent : EntityEventArgs
+{
+}
diff --git a/Resources/Locale/en-US/apc/components/apc-component.ftl b/Resources/Locale/en-US/apc/components/apc-component.ftl
index 6e152adb1d..8348bbf00d 100644
--- a/Resources/Locale/en-US/apc/components/apc-component.ftl
+++ b/Resources/Locale/en-US/apc/components/apc-component.ftl
@@ -2,3 +2,4 @@ apc-component-insufficient-access = Insufficient access!
apc-component-on-examine-panel-open = The [color=lightgray]APC electronics panel[/color] is [color=red]open[/color].
apc-component-on-examine-panel-closed = The [color=lightgray]APC electronics panel[/color] is [color=darkgreen]closed[/color].
apc-component-on-toggle-cancel = It does nothing!
+apc-component-breaker-popped = The APC's breaker popped!
diff --git a/Resources/Prototypes/Entities/Structures/Power/apc.yml b/Resources/Prototypes/Entities/Structures/Power/apc.yml
index 45d08af354..236c066762 100644
--- a/Resources/Prototypes/Entities/Structures/Power/apc.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/apc.yml
@@ -70,6 +70,9 @@
voltage: Medium
- type: PowerProvider
voltage: Apc
+ - type: Breaker
+ # 100A at 240V - 24kW
+ limit: 24000
- type: Apc
voltage: Apc
- type: ExtensionCableProvider