From 80d4dc430dfe7359957a5e20f690c891fe0c8a35 Mon Sep 17 00:00:00 2001
From: Rane <60792108+Elijahrane@users.noreply.github.com>
Date: Fri, 20 Jan 2023 11:05:54 -0500
Subject: [PATCH] Generic power switch component (#11999)
---
.../Unit/EntitySystems/DisposalUnitSystem.cs | 25 ++-----
.../Power/Components/PowerSwitchComponent.cs | 9 +++
.../EntitySystems/PowerReceiverSystem.cs | 67 +++++++++++++++++-
.../components/power-switch-component.ftl | 1 +
.../Structures/Piping/Disposal/units.yml | 2 +-
.../Interface/VerbIcons/Spare/path4.svg | 40 +++++++++++
.../Interface/VerbIcons/Spare/poweronoff.svg | 55 +++++++++++++-
.../VerbIcons/Spare/poweronoff.svg.192dpi.png | Bin 0 -> 2010 bytes
8 files changed, 175 insertions(+), 24 deletions(-)
create mode 100644 Content.Server/Power/Components/PowerSwitchComponent.cs
create mode 100644 Resources/Locale/en-US/power/components/power-switch-component.ftl
create mode 100644 Resources/Textures/Interface/VerbIcons/Spare/path4.svg
create mode 100644 Resources/Textures/Interface/VerbIcons/Spare/poweronoff.svg.192dpi.png
diff --git a/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs b/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs
index bd91aab4a2..102128b178 100644
--- a/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs
+++ b/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs
@@ -8,6 +8,7 @@ using Content.Server.DoAfter;
using Content.Server.Hands.Components;
using Content.Server.Popups;
using Content.Server.Power.Components;
+using Content.Server.Power.EntitySystems;
using Content.Shared.ActionBlocker;
using Content.Shared.Atmos;
using Content.Shared.Construction.Components;
@@ -25,13 +26,11 @@ using Content.Shared.Popups;
using Content.Shared.Throwing;
using Content.Shared.Verbs;
using Robust.Server.GameObjects;
-using Robust.Shared.Audio;
using Robust.Shared.Containers;
-using Robust.Shared.Map;
-using Robust.Shared.Map.Components;
using Robust.Shared.Physics.Components;
using Robust.Shared.Player;
using Robust.Shared.Random;
+using Robust.Shared.Map.Components;
namespace Content.Server.Disposal.Unit.EntitySystems
{
@@ -50,6 +49,7 @@ namespace Content.Server.Disposal.Unit.EntitySystems
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[Dependency] private readonly TransformSystem _transformSystem = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!;
+ [Dependency] private readonly PowerReceiverSystem _power = default!;
public override void Initialize()
{
@@ -223,13 +223,7 @@ namespace Content.Server.Disposal.Unit.EntitySystems
_adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(player):player} hit flush button on {ToPrettyString(uid)}, it's now {(component.Engaged ? "on" : "off")}");
break;
case SharedDisposalUnitComponent.UiButton.Power:
- TogglePower(component);
- _audio.PlayPvs(new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg"), component.Owner,
- AudioParams.Default.WithVolume(-2f));
- if (EntityManager.TryGetComponent(component.Owner, out ApcPowerReceiverComponent? receiver))
- {
- _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(player):player} hit power button on {ToPrettyString(uid)}, it's now {(!receiver.PowerDisabled ? "on" : "off")}");
- }
+ _power.TogglePower(uid, user: args.Session.AttachedEntity);
break;
default:
throw new ArgumentOutOfRangeException();
@@ -249,17 +243,6 @@ namespace Content.Server.Disposal.Unit.EntitySystems
Disengage(component);
}
}
-
- public void TogglePower(DisposalUnitComponent component)
- {
- if (!EntityManager.TryGetComponent(component.Owner, out ApcPowerReceiverComponent? receiver))
- {
- return;
- }
-
- receiver.PowerDisabled = !receiver.PowerDisabled;
- UpdateInterface(component, receiver.Powered);
- }
#endregion
#region Eventbus Handlers
diff --git a/Content.Server/Power/Components/PowerSwitchComponent.cs b/Content.Server/Power/Components/PowerSwitchComponent.cs
new file mode 100644
index 0000000000..3124557f81
--- /dev/null
+++ b/Content.Server/Power/Components/PowerSwitchComponent.cs
@@ -0,0 +1,9 @@
+namespace Content.Server.Power.Components
+{
+ ///
+ /// Provides an alt verb to toggle power.
+ ///
+ [RegisterComponent]
+ public sealed class PowerSwitchComponent : Component
+ {}
+}
diff --git a/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs b/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs
index 467b29c5e1..1e605efb12 100644
--- a/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs
+++ b/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs
@@ -1,14 +1,20 @@
using Content.Server.Power.Components;
+using Content.Server.Hands.Components;
+using Content.Server.Administration.Logs;
using Content.Shared.Examine;
using Content.Shared.Power;
+using Content.Shared.Verbs;
+using Content.Shared.Database;
using Robust.Server.GameObjects;
+using Robust.Shared.Audio;
namespace Content.Server.Power.EntitySystems
{
public sealed class PowerReceiverSystem : EntitySystem
{
+ [Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly AppearanceSystem _appearance = default!;
-
+ [Dependency] private readonly AudioSystem _audio = default!;
public override void Initialize()
{
base.Initialize();
@@ -20,6 +26,8 @@ namespace Content.Server.Power.EntitySystems
SubscribeLocalEvent(OnProviderShutdown);
SubscribeLocalEvent(OnReceiverConnected);
SubscribeLocalEvent(OnReceiverDisconnected);
+
+ SubscribeLocalEvent>(AddSwitchPowerVerb);
}
///
@@ -78,6 +86,33 @@ namespace Content.Server.Power.EntitySystems
}
}
+ private void AddSwitchPowerVerb(EntityUid uid, PowerSwitchComponent component, GetVerbsEvent args)
+ {
+ if(!args.CanAccess || !args.CanInteract)
+ return;
+
+ if (!HasComp(args.User))
+ return;
+
+ if (!TryComp(uid, out var receiver))
+ return;
+
+ if (!receiver.NeedsPower)
+ return;
+
+ AlternativeVerb verb = new()
+ {
+ Act = () =>
+ {
+ TogglePower(uid, user: args.User);
+ },
+ IconTexture = "/Textures/Interface/VerbIcons/Spare/poweronoff.svg.192dpi.png",
+ Text = Loc.GetString("power-switch-component-toggle-verb"),
+ Priority = -3
+ };
+ args.Verbs.Add(verb);
+ }
+
private void ProviderChanged(ApcPowerReceiverComponent receiver)
{
receiver.NetworkLoad.LinkedNetwork = default;
@@ -99,5 +134,35 @@ namespace Content.Server.Power.EntitySystems
return receiver.Powered;
}
+
+ ///
+ /// Turn this machine on or off.
+ /// Returns true if we turned it on, false if we turned it off.
+ ///
+ public bool TogglePower(EntityUid uid, bool playSwitchSound = true, ApcPowerReceiverComponent? receiver = null, EntityUid? user = null)
+ {
+ if (!Resolve(uid, ref receiver, false))
+ return true;
+
+ // it'll save a lot of confusion if 'always powered' means 'always powered'
+ if (!receiver.NeedsPower)
+ {
+ receiver.PowerDisabled = false;
+ return true;
+ }
+
+ receiver.PowerDisabled = !receiver.PowerDisabled;
+
+ if (user != null)
+ _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(user.Value):player} hit power button on {ToPrettyString(uid)}, it's now {(!receiver.PowerDisabled ? "on" : "off")}");
+
+ if (playSwitchSound)
+ {
+ _audio.PlayPvs(new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg"), uid,
+ AudioParams.Default.WithVolume(-2f));
+ }
+
+ return !receiver.PowerDisabled; // i.e. PowerEnabled
+ }
}
}
diff --git a/Resources/Locale/en-US/power/components/power-switch-component.ftl b/Resources/Locale/en-US/power/components/power-switch-component.ftl
new file mode 100644
index 0000000000..826b5c9fd0
--- /dev/null
+++ b/Resources/Locale/en-US/power/components/power-switch-component.ftl
@@ -0,0 +1 @@
+power-switch-component-toggle-verb = Toggle power
diff --git a/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml b/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml
index 76eaa94707..139c08d32f 100644
--- a/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml
+++ b/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml
@@ -76,6 +76,7 @@
DisposalUnit: !type:Container
- type: StaticPrice
price: 100
+ - type: PowerSwitch
- type: entity
id: DisposalUnit
@@ -92,7 +93,6 @@
- key: enum.DisposalUnitUiKey.Key
type: DisposalUnitBoundUserInterface
-
- type: entity
id: MailingUnit
parent: DisposalUnitBase
diff --git a/Resources/Textures/Interface/VerbIcons/Spare/path4.svg b/Resources/Textures/Interface/VerbIcons/Spare/path4.svg
new file mode 100644
index 0000000000..e34684a6fd
--- /dev/null
+++ b/Resources/Textures/Interface/VerbIcons/Spare/path4.svg
@@ -0,0 +1,40 @@
+
+
diff --git a/Resources/Textures/Interface/VerbIcons/Spare/poweronoff.svg b/Resources/Textures/Interface/VerbIcons/Spare/poweronoff.svg
index ce880e4a57..18ba878ced 100644
--- a/Resources/Textures/Interface/VerbIcons/Spare/poweronoff.svg
+++ b/Resources/Textures/Interface/VerbIcons/Spare/poweronoff.svg
@@ -1 +1,54 @@
-
\ No newline at end of file
+
+
diff --git a/Resources/Textures/Interface/VerbIcons/Spare/poweronoff.svg.192dpi.png b/Resources/Textures/Interface/VerbIcons/Spare/poweronoff.svg.192dpi.png
new file mode 100644
index 0000000000000000000000000000000000000000..dbacdd4abfc2bae33f713e28e28d2c99d1128755
GIT binary patch
literal 2010
zcmV<02POE4P)EX>4Tx04R}tkv&MmKpe$iQ>9WWqRk-UkfAzR5EXIMDionYs1;guFdzMbCJjl7
zi=*ILaPVWX>fqw6tAnc`2!4P#Iyou2NQwVT3N2zhIPS;0dyl(!0N1D}n$t~4AUmwAfDc|
z4aWP#yi$@>;&b9LlP*a7$aLA`H^xPmIhM(rne;p{Pb?HWSngn@WNO4y#4%OVDWA)F
ztTNtWtW|1C>z?d|k-WaL%ygQ=NMaF75FtQD4P{hdBTlPMiiI@oCw%-vu3sdVOs+B%
zax9<<4U+2z`-9)zT7}68FDa4$x?ddUV+0880?oSPd>=bb^8^S!16O+6Uu^(0pQP8@
zTI>ku+XgPK+nT%wTHLthUK29Hi40V;d0S*p<
z(IRE9`@FlSv$ucGwEFu2L058&y76B~+S_HHRXc15-kvS=jfSxFdI+_4}9)QgNf@5@@1z@!o0dX8J1~9*%
zB9ldA>*2$PPj4Xjxd7e*&{lBB8j@!fB7kH7V2!6v)3ny>8w9=`z^ee-J%*hK;K4!!
zBuTOazzk2l_B!WQHG%*UsQ|bQKut+l?{LH!%&k2fzW3{u2Q#
zs7e4y5s@1`ggKI{MTE^lFCxDI==L0TQ&j@2wX*=6<{{|ywzjsfN>Bhj3*aY@{@0LH
zg9vcWUF%gxE48i+<)4ToISD>)aPc4lL}a#yklkAA4@*=A`v$`~)q-HBM>5jWOy93!
z1-k)!>oH_TKLSW<0Oxp2_(2H|L*Do3+u4tRN~LnDM_vs8-;|I5ADyQ3BOnNZ@jf$!
zVfbSS3GmTrd_Mw2WSqy~R74J!kbplt`u>Mk=UdvjS(afmw=Byhk%i-Od!G1FABk%o
zb7_)VL{d*34+7X#uy4he0O#CP4+3~(7t{GJ(C0bd*#N%t+^U`jFk*Fsh@4TB01D2$t^{W9AnnV4icXr^cw^T6*
zN!HqZ1Mkv2t)WjT)g1)E(=`Aelcwofk}F7_a2#dw_hA@LAM*V%g3S$Cmc3brT0Iew
z&q%&ujM*e2eZ!dfGLrL2c6uJvRGT+8#+)_Oe1%Se(llM4W!Z{4A6{etViAe*YpS+<
zm8Fi;FbIN$TI(&t>QY3KwYJAOHxHwzDWx7T#yon=#V9J!TD!wJcgZLL|ClkR(1#v{
zYiMK4rAn!-qX7JxqTo@B&!uVlQkG>)%LZIToKorzt@TE)aW$r*OPzBYhx-7r!K;3V
z{HthL)nPH!T1Dy81mS}&^Mp29B%R57_dVHkF3t-JD1*BZU*`$S~6
zF=j!n;E&4!s-&yk`B&RxM;Q145xHM$U6&GE>aAdwWp`y+b~nk6ddU}&R75@k&~1!)
zx30l+Bu{M8H0=VgkmO8H%b-%~Ab?Lr