]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Telecom server panel check (#14523)
authorSlava0135 <40753025+Slava0135@users.noreply.github.com>
Fri, 24 Mar 2023 00:09:45 +0000 (03:09 +0300)
committerGitHub <noreply@github.com>
Fri, 24 Mar 2023 00:09:45 +0000 (20:09 -0400)
17 files changed:
Content.Client/Wires/WiresSystem.cs [new file with mode: 0644]
Content.IntegrationTests/Tests/VendingMachineRestockTest.cs
Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs
Content.Server/Construction/Conditions/WirePanel.cs
Content.Server/Construction/PartExchangerSystem.cs
Content.Server/Doors/Systems/AirlockSystem.cs
Content.Server/Mech/Systems/MechSystem.cs
Content.Server/Power/EntitySystems/ActivatableUIRequiresPowerSystem.cs
Content.Server/VendingMachines/Restock/VendingMachineRestockSystem.cs
Content.Server/Wires/WiresComponent.cs
Content.Server/Wires/WiresSystem.cs
Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs
Content.Shared/Wires/SharedWiresSystem.cs [new file with mode: 0644]
Content.Shared/Wires/WiresPanelComponent.cs [new file with mode: 0644]
Resources/Locale/en-US/radio/components/encryption-key-component.ftl
Resources/Locale/en-US/wires/components/wires-component.ftl
Resources/Locale/en-US/wires/components/wires-panel-component.ftl [new file with mode: 0644]

diff --git a/Content.Client/Wires/WiresSystem.cs b/Content.Client/Wires/WiresSystem.cs
new file mode 100644 (file)
index 0000000..c2ffa97
--- /dev/null
@@ -0,0 +1,7 @@
+using Content.Shared.Wires;
+
+namespace Content.Client.Wires;
+
+public sealed class WiresSystem : SharedWiresSystem
+{
+}
index 49207b5f5586f84b96a67673c37cbed694b1668b..6ff6b23dc76fe6d29b779b9fdb7d9539caf3d070 100644 (file)
@@ -9,11 +9,12 @@ using Robust.Shared.Prototypes;
 using Content.Server.Storage.Components;
 using Content.Server.VendingMachines;
 using Content.Server.VendingMachines.Restock;
-using Content.Server.Wires;
 using Content.Shared.Cargo.Prototypes;
 using Content.Shared.Damage;
 using Content.Shared.Damage.Prototypes;
 using Content.Shared.VendingMachines;
+using Content.Shared.Wires;
+using Content.Server.Wires;
 
 namespace Content.IntegrationTests.Tests
 {
@@ -188,7 +189,7 @@ namespace Content.IntegrationTests.Tests
             VendingMachineComponent machineComponent;
             VendingMachineRestockComponent restockRightComponent;
             VendingMachineRestockComponent restockWrongComponent;
-            WiresComponent machineWires;
+            WiresPanelComponent machineWiresPanel;
 
             var testMap = await PoolManager.CreateTestMap(pairTracker);
 
@@ -206,7 +207,7 @@ namespace Content.IntegrationTests.Tests
                 Assert.True(entityManager.TryGetComponent(machine, out machineComponent!), $"Machine has no {nameof(VendingMachineComponent)}");
                 Assert.True(entityManager.TryGetComponent(packageRight, out restockRightComponent!), $"Correct package has no {nameof(VendingMachineRestockComponent)}");
                 Assert.True(entityManager.TryGetComponent(packageWrong, out restockWrongComponent!), $"Wrong package has no {nameof(VendingMachineRestockComponent)}");
-                Assert.True(entityManager.TryGetComponent(machine, out machineWires!), $"Machine has no {nameof(WiresComponent)}");
+                Assert.True(entityManager.TryGetComponent(machine, out machineWiresPanel!), $"Machine has no {nameof(WiresPanelComponent)}");
 
                 var systemRestock = entitySystemManager.GetEntitySystem<VendingMachineRestockSystem>();
                 var systemMachine = entitySystemManager.GetEntitySystem<VendingMachineSystem>();
@@ -215,8 +216,9 @@ namespace Content.IntegrationTests.Tests
                 Assert.That(systemRestock.TryAccessMachine(packageRight, restockRightComponent, machineComponent, user, machine), Is.False, "Right package is able to restock without opened access panel");
                 Assert.That(systemRestock.TryAccessMachine(packageWrong, restockWrongComponent, machineComponent, user, machine), Is.False, "Wrong package is able to restock without opened access panel");
 
+                var systemWires = entitySystemManager.GetEntitySystem<WiresSystem>();
                 // Open the panel.
-                machineWires.IsPanelOpen = true;
+                systemWires.TogglePanel(machine, machineWiresPanel, true);
 
                 // Test that the right package works for the right machine.
                 Assert.That(systemRestock.TryAccessMachine(packageRight, restockRightComponent, machineComponent, user, machine), Is.True, "Correct package is unable to restock with access panel opened");
index 94ff71ba77f37858291e8ceb3f299a2d708123c7..8f6cf55deca04d7d67090eaf4b5783d275a304da 100644 (file)
@@ -7,7 +7,6 @@ using Content.Server.DeviceNetwork.Systems;
 using Content.Server.Popups;
 using Content.Server.Power.Components;
 using Content.Server.Power.EntitySystems;
-using Content.Server.Wires;
 using Content.Shared.Access.Components;
 using Content.Shared.Access.Systems;
 using Content.Shared.Atmos;
@@ -16,8 +15,8 @@ using Content.Shared.Atmos.Monitor.Components;
 using Content.Shared.Atmos.Piping.Unary.Components;
 using Content.Shared.DeviceNetwork;
 using Content.Shared.Interaction;
+using Content.Shared.Wires;
 using Robust.Server.GameObjects;
-using Robust.Shared.Player;
 
 namespace Content.Server.Atmos.Monitor.Systems;
 
@@ -227,10 +226,10 @@ public sealed class AirAlarmSystem : EntitySystem
         if (!_interactionSystem.InRangeUnobstructed(args.User, args.Target))
             return;
 
-        if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
+        if (!TryComp<ActorComponent>(args.User, out var actor))
             return;
 
-        if (EntityManager.TryGetComponent(uid, out WiresComponent? wire) && wire.IsPanelOpen)
+        if (TryComp<WiresPanelComponent>(uid, out var panel) && panel.Open)
         {
             args.Handled = false;
             return;
@@ -239,7 +238,9 @@ public sealed class AirAlarmSystem : EntitySystem
         if (!this.IsPowered(uid, EntityManager))
             return;
 
-        _uiSystem.GetUiOrNull(component.Owner, SharedAirAlarmInterfaceKey.Key)?.Open(actor.PlayerSession);
+        var ui = _uiSystem.GetUiOrNull(uid, SharedAirAlarmInterfaceKey.Key);
+        if (ui != null)
+            _uiSystem.OpenUi(ui, actor.PlayerSession);
         component.ActivePlayers.Add(actor.PlayerSession.UserId);
         AddActiveInterface(uid);
         SyncAllDevices(uid);
index 224ad32938586ea13c12539c25287ca71ed8d5db..a4c478026e0aec0bf41554d54c8c8fe48a9be3f6 100644 (file)
@@ -1,6 +1,6 @@
-using Content.Server.Wires;
 using Content.Shared.Construction;
 using Content.Shared.Examine;
+using Content.Shared.Wires;
 using JetBrains.Annotations;
 
 namespace Content.Server.Construction.Conditions
@@ -14,24 +14,23 @@ namespace Content.Server.Construction.Conditions
         public bool Condition(EntityUid uid, IEntityManager entityManager)
         {
             //if it doesn't have a wire panel, then just let it work.
-            if (!entityManager.TryGetComponent(uid, out WiresComponent? wires))
+            if (!entityManager.TryGetComponent<WiresPanelComponent>(uid, out var wires))
                 return true;
 
-            return wires.IsPanelOpen == Open;
+            return wires.Open == Open;
         }
 
         public bool DoExamine(ExaminedEvent args)
         {
             var entity = args.Examined;
-
-            if (!IoCManager.Resolve<IEntityManager>().TryGetComponent(entity, out WiresComponent? wires)) return false;
+            if (!IoCManager.Resolve<IEntityManager>().TryGetComponent<WiresPanelComponent>(entity, out var panel)) return false;
 
             switch (Open)
             {
-                case true when !wires.IsPanelOpen:
+                case true when !panel.Open:
                     args.PushMarkup(Loc.GetString("construction-examine-condition-wire-panel-open"));
                     return true;
-                case false when wires.IsPanelOpen:
+                case false when panel.Open:
                     args.PushMarkup(Loc.GetString("construction-examine-condition-wire-panel-close"));
                     return true;
             }
index 837bf808dbda0e2477e1ded10df72504bd1d9198..c865f47926494d9ee19f3a8d0fd6971147d50edc 100644 (file)
@@ -3,13 +3,13 @@ using Content.Server.Construction.Components;
 using Content.Server.DoAfter;
 using Content.Server.Storage.Components;
 using Content.Server.Storage.EntitySystems;
-using Content.Server.Wires;
 using Content.Shared.DoAfter;
 using Content.Shared.Construction.Components;
 using Content.Shared.Interaction;
 using Content.Shared.Popups;
 using Robust.Shared.Containers;
 using Robust.Shared.Utility;
+using Content.Shared.Wires;
 
 namespace Content.Server.Construction;
 
@@ -103,7 +103,7 @@ public sealed class PartExchangerSystem : EntitySystem
         if (!HasComp<MachineComponent>(args.Target))
             return;
 
-        if (TryComp<WiresComponent>(args.Target, out var wires) && !wires.IsPanelOpen)
+        if (TryComp<WiresPanelComponent>(args.Target, out var panel) && !panel.Open)
         {
             _popup.PopupEntity(Loc.GetString("construction-step-condition-wire-panel-open"),
                 args.Target.Value);
index e39f5bd9c2029a91e1e77092aabfff40f0197b4e..e5e73204fc25f5256156e266b758e685bfcbe5d3 100644 (file)
@@ -7,6 +7,7 @@ using Content.Shared.Doors.Components;
 using Content.Shared.Doors.Systems;
 using Content.Shared.Interaction;
 using Robust.Server.GameObjects;
+using Content.Shared.Wires;
 
 namespace Content.Server.Doors.Systems
 {
@@ -71,11 +72,9 @@ namespace Content.Server.Doors.Systems
             // means that sometimes the panels & bolt lights may be visible despite a door being completely open.
 
             // Only show the maintenance panel if the airlock is closed
-            if (TryComp<WiresComponent>(uid, out var wiresComponent))
+            if (TryComp<WiresPanelComponent>(uid, out var wiresPanel))
             {
-                wiresComponent.IsPanelVisible =
-                    component.OpenPanelVisible
-                    ||  args.State != DoorState.Open;
+                _wiresSystem.ChangePanelVisibility(uid, wiresPanel, component.OpenPanelVisible || args.State != DoorState.Open);
             }
             // If the door is closed, we should look if the bolt was locked while closing
             UpdateBoltLightStatus(uid, component);
@@ -144,8 +143,8 @@ namespace Content.Server.Doors.Systems
 
         private void OnActivate(EntityUid uid, AirlockComponent component, ActivateInWorldEvent args)
         {
-            if (TryComp<WiresComponent>(uid, out var wiresComponent) && wiresComponent.IsPanelOpen &&
-                EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
+            if (TryComp<WiresPanelComponent>(uid, out var panel) && panel.Open &&
+                TryComp<ActorComponent>(args.User, out var actor))
             {
                 _wiresSystem.OpenUserInterface(uid, actor.PlayerSession);
                 args.Handled = true;
index 90a929aaba8c99cad23a93bf1b4f277bab679f6a..ab307673c62d689a3a4d55c29ee7a13d5c276dae 100644 (file)
@@ -3,7 +3,6 @@ using Content.Server.Atmos.EntitySystems;
 using Content.Server.DoAfter;
 using Content.Server.Mech.Components;
 using Content.Server.Power.Components;
-using Content.Server.Wires;
 using Content.Shared.ActionBlocker;
 using Content.Shared.Damage;
 using Content.Shared.DoAfter;
@@ -15,6 +14,7 @@ using Content.Shared.Mech.EntitySystems;
 using Content.Shared.Movement.Events;
 using Content.Shared.Tools.Components;
 using Content.Shared.Verbs;
+using Content.Shared.Wires;
 using Robust.Server.Containers;
 using Robust.Server.GameObjects;
 using Robust.Shared.Map;
@@ -72,7 +72,7 @@ public sealed class MechSystem : SharedMechSystem
     }
     private void OnInteractUsing(EntityUid uid, MechComponent component, InteractUsingEvent args)
     {
-        if (TryComp<WiresComponent>(uid, out var wires) && !wires.IsPanelOpen)
+        if (TryComp<WiresPanelComponent>(uid, out var panel) && !panel.Open)
             return;
 
         if (component.BatterySlot.ContainedEntity == null && TryComp<BatteryComponent>(args.Used, out var battery))
index 828789f53577a7ecd4d7e7e54c214155d3376a22..5f32b4b06bd2592b56341041f0681413c24d399d 100644 (file)
@@ -1,37 +1,38 @@
 using Content.Shared.Popups;
 using Content.Server.Power.Components;
 using Content.Server.UserInterface;
-using Content.Server.Wires;
 using JetBrains.Annotations;
+using Content.Shared.Wires;
 
-namespace Content.Server.Power.EntitySystems
+namespace Content.Server.Power.EntitySystems;
+
+[UsedImplicitly]
+internal sealed class ActivatableUIRequiresPowerSystem : EntitySystem
 {
-    [UsedImplicitly]
-    internal sealed class ActivatableUIRequiresPowerSystem : EntitySystem
+    [Dependency] private readonly ActivatableUISystem _activatableUI = default!;
+    [Dependency] private readonly SharedPopupSystem _popup = default!;
+
+    public override void Initialize()
     {
-        [Dependency] private readonly ActivatableUISystem _activatableUISystem = default!;
-        public override void Initialize()
-        {
-            base.Initialize();
+        base.Initialize();
 
-            SubscribeLocalEvent<ActivatableUIRequiresPowerComponent, ActivatableUIOpenAttemptEvent>(OnActivate);
-            SubscribeLocalEvent<ActivatableUIRequiresPowerComponent, PowerChangedEvent>(OnPowerChanged);
-        }
+        SubscribeLocalEvent<ActivatableUIRequiresPowerComponent, ActivatableUIOpenAttemptEvent>(OnActivate);
+        SubscribeLocalEvent<ActivatableUIRequiresPowerComponent, PowerChangedEvent>(OnPowerChanged);
+    }
 
-        private void OnActivate(EntityUid uid, ActivatableUIRequiresPowerComponent component, ActivatableUIOpenAttemptEvent args)
-        {
-            if (args.Cancelled) return;
-            if (this.IsPowered(uid, EntityManager)) return;
-            if (TryComp<WiresComponent>(uid, out var wires) && wires.IsPanelOpen)
-                return;
-            args.User.PopupMessageCursor(Loc.GetString("base-computer-ui-component-not-powered", ("machine", uid)));
-            args.Cancel();
-        }
+    private void OnActivate(EntityUid uid, ActivatableUIRequiresPowerComponent component, ActivatableUIOpenAttemptEvent args)
+    {
+        if (args.Cancelled) return;
+        if (this.IsPowered(uid, EntityManager)) return;
+        if (TryComp<WiresPanelComponent>(uid, out var panel) && panel.Open)
+            return;
+        _popup.PopupCursor(Loc.GetString("base-computer-ui-component-not-powered", ("machine", uid)), args.User);
+        args.Cancel();
+    }
 
-        private void OnPowerChanged(EntityUid uid, ActivatableUIRequiresPowerComponent component, ref PowerChangedEvent args)
-        {
-            if (!args.Powered)
-                _activatableUISystem.CloseAll(uid);
-        }
+    private void OnPowerChanged(EntityUid uid, ActivatableUIRequiresPowerComponent component, ref PowerChangedEvent args)
+    {
+        if (!args.Powered)
+            _activatableUI.CloseAll(uid);
     }
 }
index e8528edadf82bbcc0ad514e2ca8ccde72f0b150f..39ae6739022bce2ed2577cd5a9308bd9b163f5ae 100644 (file)
@@ -1,11 +1,11 @@
 using System.Linq;
 using Content.Server.Cargo.Systems;
 using Content.Server.DoAfter;
-using Content.Server.Wires;
 using Content.Shared.DoAfter;
 using Content.Shared.Interaction;
 using Content.Shared.Popups;
 using Content.Shared.VendingMachines;
+using Content.Shared.Wires;
 using Robust.Server.GameObjects;
 using Robust.Shared.Audio;
 using Robust.Shared.Prototypes;
@@ -35,7 +35,7 @@ namespace Content.Server.VendingMachines.Restock
             EntityUid user,
             EntityUid target)
         {
-            if (!TryComp<WiresComponent>(target, out var wires) || !wires.IsPanelOpen)
+            if (!TryComp<WiresPanelComponent>(target, out var panel) || !panel.Open)
             {
                 _popupSystem.PopupCursor(Loc.GetString("vending-machine-restock-needs-panel-open",
                         ("this", uid),
index 2a96c19c1e2eed815c40e65bb3c8d1a69a3ddf9d..1221e618637ad6abdceb22e95b0be3087382bdc0 100644 (file)
@@ -5,18 +5,6 @@ namespace Content.Server.Wires;
 [RegisterComponent]
 public sealed class WiresComponent : Component
 {
-    /// <summary>
-    ///     Is the panel open for this entity's wires?
-    /// </summary>
-    [ViewVariables]
-    public bool IsPanelOpen { get; set; }
-
-    /// <summary>
-    ///     Should this entity's wires panel be visible at all?
-    /// </summary>
-    [ViewVariables]
-    public bool IsPanelVisible { get; set; } = true;
-
     /// <summary>
     ///     The name of this entity's internal board.
     /// </summary>
@@ -62,13 +50,6 @@ public sealed class WiresComponent : Component
     [DataField("alwaysRandomize")]
     public bool AlwaysRandomize { get; }
 
-    /// <summary>
-    ///     Marks if maintenance panel being open/closed by someone with a screwdriver.
-    ///     Prevents do after spam.
-    /// </summary>
-    [ViewVariables(VVAccess.ReadWrite)]
-    public bool IsScrewing;
-
     /// <summary>
     ///     Per wire status, keyed by an object.
     /// </summary>
@@ -85,10 +66,4 @@ public sealed class WiresComponent : Component
 
     [DataField("pulseSound")]
     public SoundSpecifier PulseSound = new SoundPathSpecifier("/Audio/Effects/multitool_pulse.ogg");
-
-    [DataField("screwdriverOpenSound")]
-    public SoundSpecifier ScrewdriverOpenSound = new SoundPathSpecifier("/Audio/Machines/screwdriveropen.ogg");
-
-    [DataField("screwdriverCloseSound")]
-    public SoundSpecifier ScrewdriverCloseSound = new SoundPathSpecifier("/Audio/Machines/screwdriverclose.ogg");
 }
index 9d6a7c1966ce2f7e272076a7df8599b51fbf7d64..7a3f5f7a05f5e29fd29b78fb74955ef3784b7405 100644 (file)
@@ -7,7 +7,6 @@ using Content.Server.Hands.Components;
 using Content.Server.Power.Components;
 using Content.Shared.DoAfter;
 using Content.Shared.Database;
-using Content.Shared.Examine;
 using Content.Shared.GameTicking;
 using Content.Shared.Interaction;
 using Content.Shared.Popups;
@@ -21,17 +20,17 @@ using Robust.Shared.Random;
 
 namespace Content.Server.Wires;
 
-public sealed class WiresSystem : EntitySystem
+public sealed class WiresSystem : SharedWiresSystem
 {
     [Dependency] private readonly IPrototypeManager _protoMan = default!;
     [Dependency] private readonly IAdminLogManager _adminLogger = default!;
-    [Dependency] private readonly AppearanceSystem _appearance = default!;
     [Dependency] private readonly DoAfterSystem _doAfter = default!;
     [Dependency] private readonly SharedToolSystem _toolSystem = default!;
     [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
     [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
     [Dependency] private readonly SharedAudioSystem _audio = default!;
     [Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
+    [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
 
     private IRobustRandom _random = new RobustRandom();
 
@@ -44,6 +43,8 @@ public sealed class WiresSystem : EntitySystem
     #region Initialization
     public override void Initialize()
     {
+        base.Initialize();
+
         SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset);
 
         // this is a broadcast event
@@ -52,7 +53,6 @@ public sealed class WiresSystem : EntitySystem
         SubscribeLocalEvent<WiresComponent, ComponentStartup>(OnWiresStartup);
         SubscribeLocalEvent<WiresComponent, WiresActionMessage>(OnWiresActionMessage);
         SubscribeLocalEvent<WiresComponent, InteractUsingEvent>(OnInteractUsing);
-        SubscribeLocalEvent<WiresComponent, ExaminedEvent>(OnExamine);
         SubscribeLocalEvent<WiresComponent, MapInitEvent>(OnMapInit);
         SubscribeLocalEvent<WiresComponent, TimedWireEvent>(OnTimedWire);
         SubscribeLocalEvent<WiresComponent, PowerChangedEvent>(OnWiresPowered);
@@ -244,7 +244,6 @@ public sealed class WiresSystem : EntitySystem
             SetOrCreateWireLayout(uid, component);
 
         UpdateUserInterface(uid);
-        UpdateAppearance(uid);
     }
     #endregion
 
@@ -456,75 +455,71 @@ public sealed class WiresSystem : EntitySystem
 
     private void OnInteractUsing(EntityUid uid, WiresComponent component, InteractUsingEvent args)
     {
-        if (!EntityManager.TryGetComponent(args.Used, out ToolComponent? tool))
+        if (!TryComp<ToolComponent>(args.Used, out var tool) || !TryComp<WiresPanelComponent>(uid, out var panel))
             return;
-
-        if (component.IsPanelOpen &&
+        if (panel.Open &&
             (_toolSystem.HasQuality(args.Used, "Cutting", tool) ||
             _toolSystem.HasQuality(args.Used, "Pulsing", tool)))
         {
             if (EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
             {
-                _uiSystem.GetUiOrNull(uid, WiresUiKey.Key)?.Open(actor.PlayerSession);
+                var ui = _uiSystem.GetUiOrNull(uid, WiresUiKey.Key);
+                if (ui != null)
+                    _uiSystem.OpenUi(ui, actor.PlayerSession);
                 args.Handled = true;
             }
         }
-        else if (!component.IsScrewing && _toolSystem.HasQuality(args.Used, "Screwing", tool))
+        else if (!panel.IsScrewing && _toolSystem.HasQuality(args.Used, "Screwing", tool))
         {
             var toolEvData = new ToolEventData(new WireToolFinishedEvent(uid, args.User), cancelledEv: new WireToolCanceledEvent(uid));
 
-            component.IsScrewing = _toolSystem.UseTool(args.Used, args.User, uid, ScrewTime, new[] { "Screwing" }, toolEvData, toolComponent: tool);
-            args.Handled = component.IsScrewing;
+            panel.IsScrewing = _toolSystem.UseTool(args.Used, args.User, uid, ScrewTime, new[] { "Screwing" }, toolEvData, toolComponent: tool);
+            args.Handled = panel.IsScrewing;
 
             // Log attempt
-            _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.User):user} is screwing {ToPrettyString(uid):target}'s {(component.IsPanelOpen ? "open" : "closed")} maintenance panel at {Transform(uid).Coordinates:targetlocation}");
+            _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.User):user} is screwing {ToPrettyString(uid):target}'s {(panel.Open ? "open" : "closed")} maintenance panel at {Transform(uid).Coordinates:targetlocation}");
         }
     }
 
     private void OnToolFinished(WireToolFinishedEvent args)
     {
-        if (!EntityManager.TryGetComponent(args.Target, out WiresComponent? component))
+        if (!TryComp<WiresPanelComponent>((args.Target), out var panel))
             return;
 
-        component.IsScrewing = false;
-        component.IsPanelOpen = !component.IsPanelOpen;
-        UpdateAppearance(args.Target);
+        panel.IsScrewing = false;
+        TogglePanel(args.Target, panel, !panel.Open);
 
         // Log success
-        _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.User):user} screwed {ToPrettyString(args.Target):target}'s maintenance panel {(component.IsPanelOpen ? "open" : "closed")}");
+        _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.User):user} screwed {ToPrettyString(args.Target):target}'s maintenance panel {(panel.Open ? "open" : "closed")}");
 
-        if (component.IsPanelOpen)
+        if (panel.Open)
         {
-            _audio.PlayPvs(component.ScrewdriverOpenSound, args.Target);
+            _audio.PlayPvs(panel.ScrewdriverOpenSound, args.Target);
         }
         else
         {
-            _audio.PlayPvs(component.ScrewdriverCloseSound, args.Target);
+            _audio.PlayPvs(panel.ScrewdriverCloseSound, args.Target);
             var ui = _uiSystem.GetUiOrNull(args.Target, WiresUiKey.Key);
             if (ui != null)
             {
                 _uiSystem.CloseAll(ui);
             }
         }
+
+        Dirty(panel);
     }
 
     private void OnToolCanceled(WireToolCanceledEvent ev)
     {
-        if (!TryComp(ev.Target, out WiresComponent? component))
+        if (!TryComp<WiresPanelComponent>(ev.Target, out var component))
             return;
 
         component.IsScrewing = false;
     }
 
-    private void OnExamine(EntityUid uid, WiresComponent component, ExaminedEvent args)
-    {
-        args.PushMarkup(Loc.GetString(component.IsPanelOpen
-            ? "wires-component-on-examine-panel-open"
-            : "wires-component-on-examine-panel-closed"));
-    }
-
     private void OnMapInit(EntityUid uid, WiresComponent component, MapInitEvent args)
     {
+        EnsureComp<WiresPanelComponent>(uid);
         if (component.SerialNumber == null)
         {
             GenerateSerialNumber(uid, component);
@@ -574,14 +569,6 @@ public sealed class WiresSystem : EntitySystem
         UpdateUserInterface(uid);
     }
 
-    private void UpdateAppearance(EntityUid uid, AppearanceComponent? appearance = null, WiresComponent? wires = null)
-    {
-        if (!Resolve(uid, ref appearance, ref wires, false))
-            return;
-
-        _appearance.SetData(uid, WiresVisuals.MaintenancePanelState, wires.IsPanelOpen && wires.IsPanelVisible, appearance);
-    }
-
     private void UpdateUserInterface(EntityUid uid, WiresComponent? wires = null, ServerUserInterfaceComponent? ui = null)
     {
         if (!Resolve(uid, ref wires, ref ui, false)) // logging this means that we get a bunch of errors
@@ -655,6 +642,26 @@ public sealed class WiresSystem : EntitySystem
         }
     }
 
+    public void ChangePanelVisibility(EntityUid uid, WiresPanelComponent component, bool visible)
+    {
+        component.Visible = visible;
+        UpdateAppearance(uid, component);
+        Dirty(component);
+    }
+
+    public void TogglePanel(EntityUid uid, WiresPanelComponent component, bool open)
+    {
+        component.Open = open;
+        UpdateAppearance(uid, component);
+        Dirty(component);
+    }
+
+    private void UpdateAppearance(EntityUid uid, WiresPanelComponent panel)
+    {
+        if (TryComp<AppearanceComponent>(uid, out var appearance))
+            _appearance.SetData(uid, WiresVisuals.MaintenancePanelState, panel.Open && panel.Visible, appearance);
+    }
+
     private void TryDoWireAction(EntityUid used, EntityUid user, EntityUid toolEntity, int id, WiresAction action, WiresComponent? wires = null, ToolComponent? tool = null)
     {
         if (!Resolve(used, ref wires)
@@ -720,7 +727,7 @@ public sealed class WiresSystem : EntitySystem
         if (_toolTime > 0f)
         {
             var data = new WireExtraData(action, id);
-            var args = new DoAfterEventArgs(user, _toolTime, target:used, used:toolEntity)
+            var args = new DoAfterEventArgs(user, _toolTime, target: used, used: toolEntity)
             {
                 NeedHand = true,
                 BreakOnStun = true,
index 1ecf2a97949bd2d27aaba37e3c7ae6c1d9796a38..cb10ec07f2106920d33b8f89de21856ff1b732d5 100644 (file)
@@ -7,7 +7,9 @@ using Content.Shared.Popups;
 using Content.Shared.Radio.Components;
 using Content.Shared.Tools;
 using Content.Shared.Tools.Components;
+using Content.Shared.Wires;
 using Robust.Shared.Containers;
+using Robust.Shared.Network;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Timing;
 
@@ -20,8 +22,9 @@ public sealed class EncryptionKeySystem : EntitySystem
 {
     [Dependency] private readonly IPrototypeManager _protoManager = default!;
     [Dependency] private readonly IGameTiming _timing = default!;
-    [Dependency] private readonly SharedToolSystem _toolSystem = default!;
-    [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
+    [Dependency] private readonly INetManager _net = default!;
+    [Dependency] private readonly SharedToolSystem _tool = default!;
+    [Dependency] private readonly SharedPopupSystem _popup = default!;
     [Dependency] private readonly SharedContainerSystem _container = default!;
     [Dependency] private readonly SharedAudioSystem _audio = default!;
     [Dependency] private readonly SharedHandsSystem _hands = default!;
@@ -55,7 +58,7 @@ public sealed class EncryptionKeySystem : EntitySystem
         }
 
         // if tool use ever gets predicted this needs changing.
-        _popupSystem.PopupEntity(Loc.GetString("encryption-keys-all-extracted"), uid, args.User);
+        _popup.PopupEntity(Loc.GetString("encryption-keys-all-extracted"), uid, args.User);
         _audio.PlayPvs(component.KeyExtractionSound, uid);
         component.Removing = false;
     }
@@ -92,8 +95,8 @@ public sealed class EncryptionKeySystem : EntitySystem
             return;
         if (!component.KeysUnlocked)
         {
-            if (_timing.IsFirstTimePredicted)
-                _popupSystem.PopupEntity(Loc.GetString("encryption-keys-are-locked"), uid, args.User);
+            if (_net.IsClient && _timing.IsFirstTimePredicted)
+                _popup.PopupEntity(Loc.GetString("encryption-keys-are-locked"), uid, args.User);
             return;
         }
         if (TryComp<EncryptionKeyComponent>(args.Used, out var key))
@@ -108,20 +111,26 @@ public sealed class EncryptionKeySystem : EntitySystem
 
     private void TryInsertKey(EntityUid uid, EncryptionKeyHolderComponent component, InteractUsingEvent args)
     {
-        args.Handled = true;
+        if (TryComp<WiresPanelComponent>(uid, out var panel) && !panel.Open)
+        {
+            if (_net.IsClient && _timing.IsFirstTimePredicted)
+                _popup.PopupEntity(Loc.GetString("encryption-keys-panel-locked"), uid, args.User);
+            return;
+        }
 
         if (component.KeySlots <= component.KeyContainer.ContainedEntities.Count)
         {
-            if (_timing.IsFirstTimePredicted)
-                _popupSystem.PopupEntity(Loc.GetString("encryption-key-slots-already-full"), uid, args.User);
+            if (_net.IsClient && _timing.IsFirstTimePredicted)
+                _popup.PopupEntity(Loc.GetString("encryption-key-slots-already-full"), uid, args.User);
             return;
         }
 
         if (component.KeyContainer.Insert(args.Used))
         {
-            if (_timing.IsFirstTimePredicted)
-                _popupSystem.PopupEntity(Loc.GetString("encryption-key-successfully-installed"), uid, args.User);
+            if (_net.IsClient&& _timing.IsFirstTimePredicted)
+                _popup.PopupEntity(Loc.GetString("encryption-key-successfully-installed"), uid, args.User);
             _audio.PlayPredicted(component.KeyInsertionSound, args.Target, args.User);
+            args.Handled = true;
             return;
         }
     }
@@ -131,21 +140,28 @@ public sealed class EncryptionKeySystem : EntitySystem
         if (!TryComp<ToolComponent>(args.Used, out var tool) || !tool.Qualities.Contains(component.KeysExtractionMethod))
             return;
 
-        args.Handled = true;
+        if (TryComp<WiresPanelComponent>(uid, out var panel) && !panel.Open)
+        {
+            if (_net.IsClient && _timing.IsFirstTimePredicted)
+                _popup.PopupEntity(Loc.GetString("encryption-keys-panel-locked"), uid, args.User);
+            return;
+        }
 
         if (component.KeyContainer.ContainedEntities.Count == 0)
         {
-            if (_timing.IsFirstTimePredicted)
-                _popupSystem.PopupEntity(Loc.GetString("encryption-keys-no-keys"), uid, args.User);
+            if (_net.IsClient && _timing.IsFirstTimePredicted)
+                _popup.PopupEntity(Loc.GetString("encryption-keys-no-keys"), uid, args.User);
             return;
         }
 
-        //This is honestly the poor mans fix because the InteractUsingEvent fires off 12 times
-        component.Removing = true;
-
-        var toolEvData = new ToolEventData(new EncryptionRemovalFinishedEvent(args.User), cancelledEv: new EncryptionRemovalCancelledEvent(), targetEntity: uid);
-
-        _toolSystem.UseTool(args.Used, args.User, uid, 1f, new[] { component.KeysExtractionMethod }, toolEvData, toolComponent: tool);
+        if (_net.IsServer)
+        {
+            //This is honestly the poor mans fix because the InteractUsingEvent fires off 12 times
+            component.Removing = true;
+            var toolEvData = new ToolEventData(new EncryptionRemovalFinishedEvent(args.User), cancelledEv: new EncryptionRemovalCancelledEvent(), targetEntity: uid);
+            if (_tool.UseTool(args.Used, args.User, uid, 1f, new[] { component.KeysExtractionMethod }, toolEvData, toolComponent: tool))
+                args.Handled = true;
+        }
     }
 
     private void OnStartup(EntityUid uid, EncryptionKeyHolderComponent component, ComponentStartup args)
diff --git a/Content.Shared/Wires/SharedWiresSystem.cs b/Content.Shared/Wires/SharedWiresSystem.cs
new file mode 100644 (file)
index 0000000..d7ddac4
--- /dev/null
@@ -0,0 +1,39 @@
+using Content.Shared.Examine;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Wires;
+
+public abstract class SharedWiresSystem : EntitySystem
+{
+    public override void Initialize()
+    {
+        base.Initialize();
+        SubscribeLocalEvent<WiresPanelComponent, ExaminedEvent>(OnExamine);
+        SubscribeLocalEvent<WiresPanelComponent, ComponentGetState>(OnGetState);
+        SubscribeLocalEvent<WiresPanelComponent, ComponentHandleState>(OnHandleState);
+    }
+
+    private void OnExamine(EntityUid uid, WiresPanelComponent component, ExaminedEvent args)
+    {
+        args.PushMarkup(Loc.GetString(component.Open
+            ? "wires-panel-component-on-examine-open"
+            : "wires-panel-component-on-examine-closed"));
+    }
+
+    private void OnGetState(EntityUid uid, WiresPanelComponent component, ref ComponentGetState args)
+    {
+        args.State = new WiresPanelComponentState
+        {
+            Open = component.Open,
+            Visible = component.Visible
+        };
+    }
+
+    private void OnHandleState(EntityUid uid, WiresPanelComponent component, ref ComponentHandleState args)
+    {
+        if (args.Current is not WiresPanelComponentState state)
+            return;
+        component.Open = state.Open;
+        component.Visible = state.Visible;
+    }
+}
\ No newline at end of file
diff --git a/Content.Shared/Wires/WiresPanelComponent.cs b/Content.Shared/Wires/WiresPanelComponent.cs
new file mode 100644 (file)
index 0000000..a1519b6
--- /dev/null
@@ -0,0 +1,41 @@
+using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Wires;
+
+[NetworkedComponent, RegisterComponent]
+[Access(typeof(SharedWiresSystem))]
+public sealed class WiresPanelComponent : Component
+{
+    /// <summary>
+    ///     Is the panel open for this entity's wires?
+    /// </summary>
+    [ViewVariables]
+    public bool Open;
+
+    /// <summary>
+    ///     Should this entity's wires panel be visible at all?
+    /// </summary>
+    [ViewVariables]
+    public bool Visible = true;
+
+    /// <summary>
+    ///     Marks if maintenance panel being open/closed by someone with a screwdriver.
+    ///     Prevents do after spam.
+    /// </summary>
+    public bool IsScrewing;
+
+    [DataField("screwdriverOpenSound")]
+    public SoundSpecifier ScrewdriverOpenSound = new SoundPathSpecifier("/Audio/Machines/screwdriveropen.ogg");
+
+    [DataField("screwdriverCloseSound")]
+    public SoundSpecifier ScrewdriverCloseSound = new SoundPathSpecifier("/Audio/Machines/screwdriverclose.ogg");
+}
+
+[Serializable, NetSerializable]
+public sealed class WiresPanelComponentState : ComponentState
+{
+    public bool Open;
+    public bool Visible;
+}
index 6d9dc5261cfd9bbc164b744e4635a6a442696148..d595cd3790713b25415ea3d3e7278a304a836c1d 100644 (file)
@@ -3,6 +3,7 @@ encryption-key-slots-already-full = There is no place for another encryption key
 encryption-keys-all-extracted = You pop out the encryption keys!
 encryption-keys-no-keys = This device has no encryption keys!
 encryption-keys-are-locked = Encryption key slots are locked!
+encryption-keys-panel-locked = Open maintenance panel first!
 
 examine-encryption-channels-prefix = Available frequencies:
 examine-encryption-channel = [color={$color}]{$key} for {$id} ({$freq})[/color]
index 496a0d0f6a93dc96ca041c394925fe5d6f6575c4..be27c270bb4d587198225d80cb89c84f863c56be 100644 (file)
@@ -5,8 +5,6 @@ wires-component-ui-on-receive-message-need-multitool = You need to hold a multit
 wires-component-ui-on-receive-message-cannot-pulse-cut-wire = You can't pulse a wire that's been cut!
 wires-component-ui-on-receive-message-cannot-cut-cut-wire = You can't cut a wire that's been cut!
 wires-component-ui-on-receive-message-cannot-mend-uncut-wire = You can't mend a wire that's been mended!
-wires-component-on-examine-panel-open = The [color=lightgray]maintenance panel[/color] is [color=red]open[/color].
-wires-component-on-examine-panel-closed = The [color=lightgray]maintenance panel[/color] is [color=darkgreen]closed[/color].
 
 ## UI
 
diff --git a/Resources/Locale/en-US/wires/components/wires-panel-component.ftl b/Resources/Locale/en-US/wires/components/wires-panel-component.ftl
new file mode 100644 (file)
index 0000000..cd8867f
--- /dev/null
@@ -0,0 +1,2 @@
+wires-panel-component-on-examine-open = The [color=lightgray]maintenance panel[/color] is [color=red]open[/color].
+wires-panel-component-on-examine-closed = The [color=lightgray]maintenance panel[/color] is [color=darkgreen]closed[/color].