From fab5aed3b870187aa108018de6a8276ab6cc7bb2 Mon Sep 17 00:00:00 2001 From: Flipp Syder <76629141+vulppine@users.noreply.github.com> Date: Sun, 24 Jul 2022 21:53:30 -0700 Subject: [PATCH] Fixes power wire action electrocution (#8520) --- Content.Client/Wires/UI/WiresMenu.cs | 10 +-- .../Doors/WireActions/DoorTimingWireAction.cs | 4 +- Content.Server/Power/PowerWireAction.cs | 80 ++++++++++++------- Content.Server/Wires/WiresSystem.cs | 61 ++++++++++++-- .../wires/components/wires-component.ftl | 2 + 5 files changed, 111 insertions(+), 46 deletions(-) diff --git a/Content.Client/Wires/UI/WiresMenu.cs b/Content.Client/Wires/UI/WiresMenu.cs index 08b84a6f90..bfbb2ebd22 100644 --- a/Content.Client/Wires/UI/WiresMenu.cs +++ b/Content.Client/Wires/UI/WiresMenu.cs @@ -267,16 +267,8 @@ namespace Content.Client.Wires.UI _statusContainer.RemoveAllChildren(); - var originalStatuses = new List(state.Statuses); // TODO: maybe not this way? - var shuffledStatuses = new List(); - for (var i = originalStatuses.Count; i > 0; i--) - { - var index = random.Next(originalStatuses.Count); - shuffledStatuses.Add(originalStatuses[index]); - originalStatuses.RemoveAt(index); - } - foreach (var status in shuffledStatuses) + foreach (var status in state.Statuses) { if (status.Value is StatusLightData statusLightData) { diff --git a/Content.Server/Doors/WireActions/DoorTimingWireAction.cs b/Content.Server/Doors/WireActions/DoorTimingWireAction.cs index 04ad89d720..51dc41bd81 100644 --- a/Content.Server/Doors/WireActions/DoorTimingWireAction.cs +++ b/Content.Server/Doors/WireActions/DoorTimingWireAction.cs @@ -25,7 +25,7 @@ public sealed class DoorTimingWireAction : BaseWireAction { switch (door.AutoCloseDelayModifier) { - case 0f: + case 0.01f: lightState = StatusLightState.Off; break; case <= 0.5f: @@ -50,7 +50,7 @@ public sealed class DoorTimingWireAction : BaseWireAction if (EntityManager.TryGetComponent(wire.Owner, out var door)) { WiresSystem.TryCancelWireAction(wire.Owner, PulseTimeoutKey.Key); - door.AutoCloseDelayModifier = 0f; + door.AutoCloseDelayModifier = 0.01f; } return true; diff --git a/Content.Server/Power/PowerWireAction.cs b/Content.Server/Power/PowerWireAction.cs index 6be7195804..85409c9775 100644 --- a/Content.Server/Power/PowerWireAction.cs +++ b/Content.Server/Power/PowerWireAction.cs @@ -83,30 +83,33 @@ public sealed class PowerWireAction : BaseWireAction return; } - if (WiresSystem.TryGetData(owner, PowerWireActionKey.CutWires, out int? cut) - && WiresSystem.TryGetData(owner, PowerWireActionKey.WireCount, out int? count)) + if (AllWiresCut(owner)) { - if (AllWiresCut(owner)) + power.PowerDisabled = true; + } + else + { + if (WiresSystem.TryGetData(owner, PowerWireActionKey.Pulsed, out bool isPulsed) + && isPulsed) { - power.PowerDisabled = true; + return; } - else - { - if (WiresSystem.TryGetData(owner, PowerWireActionKey.Pulsed, out bool isPulsed) - && isPulsed) - { - return; - } - power.PowerDisabled = false; - } + power.PowerDisabled = false; } } private void SetWireCuts(EntityUid owner, bool isCut) { - if (WiresSystem.TryGetData(owner, PowerWireActionKey.CutWires, out int? cut)) + if (WiresSystem.TryGetData(owner, PowerWireActionKey.CutWires, out int? cut) + && WiresSystem.TryGetData(owner, PowerWireActionKey.WireCount, out int? count)) { + if (cut == count && isCut + || cut <= 0 && !isCut) + { + return; + } + cut = isCut ? cut + 1 : cut - 1; WiresSystem.SetData(owner, PowerWireActionKey.CutWires, cut); } @@ -129,30 +132,44 @@ public sealed class PowerWireAction : BaseWireAction return true; } - var allCut = AllWiresCut(wire.Owner); // always set this to true SetElectrified(wire.Owner, true, electrified); - // if we were electrified, then return false var electrifiedAttempt = _electrocutionSystem.TryDoElectrifiedAct(wire.Owner, user); - // if this is timed, we set up a doAfter so that the - // electrocution continues - unless cancelled - // - // if the power is disabled however, just don't bother - if (timed && IsPowered(wire.Owner) && !allCut) + // if we were electrified, then return false + return !electrifiedAttempt; + + } + + private void UpdateElectrocution(Wire wire) + { + var allCut = AllWiresCut(wire.Owner); + + var activePulse = false; + + if (WiresSystem.TryGetData(wire.Owner, PowerWireActionKey.Pulsed, out bool pulsed)) + { + activePulse = pulsed; + } + + // if this is actively pulsed, + // and there's not already an electrification cancel occurring, + // we need to start that timer immediately + if (!WiresSystem.HasData(wire.Owner, PowerWireActionKey.ElectrifiedCancel) + && activePulse + && IsPowered(wire.Owner) + && !allCut) { WiresSystem.StartWireAction(wire.Owner, _pulseTimeout, PowerWireActionKey.ElectrifiedCancel, new TimedWireEvent(AwaitElectrifiedCancel, wire)); } else { - if (allCut) + if (!activePulse && allCut || AllWiresMended(wire.Owner)) { - SetElectrified(wire.Owner, false, electrified); + SetElectrified(wire.Owner, false); } } - - return !electrifiedAttempt; } public override void Initialize() @@ -213,10 +230,8 @@ public sealed class PowerWireAction : BaseWireAction { WiresSystem.TryCancelWireAction(wire.Owner, PowerWireActionKey.ElectrifiedCancel); - if (!TrySetElectrocution(user, wire, true)) - return false; + var electrocuted = !TrySetElectrocution(user, wire, true); - // disrupted power shouldn't re-disrupt if (WiresSystem.TryGetData(wire.Owner, PowerWireActionKey.Pulsed, out bool pulsedKey) && pulsedKey) { @@ -224,16 +239,21 @@ public sealed class PowerWireAction : BaseWireAction } WiresSystem.SetData(wire.Owner, PowerWireActionKey.Pulsed, true); - WiresSystem.StartWireAction(wire.Owner, _pulseTimeout, PowerWireActionKey.PulseCancel, new TimedWireEvent(AwaitPulseCancel, wire)); - SetPower(wire.Owner, true); + if (electrocuted) + { + return false; + } + SetPower(wire.Owner, true); return true; } public override void Update(Wire wire) { + UpdateElectrocution(wire); + if (!IsPowered(wire.Owner)) { if (!WiresSystem.TryGetData(wire.Owner, PowerWireActionKey.Pulsed, out bool pulsed) diff --git a/Content.Server/Wires/WiresSystem.cs b/Content.Server/Wires/WiresSystem.cs index 89b5a123c0..3bf987dd6d 100644 --- a/Content.Server/Wires/WiresSystem.cs +++ b/Content.Server/Wires/WiresSystem.cs @@ -231,6 +231,7 @@ public sealed class WiresSystem : EntitySystem false, color, letter, + position, action); } @@ -557,14 +558,23 @@ public sealed class WiresSystem : EntitySystem var statusData = entry.Action.GetStatusLightData(entry); if (statusData != null && entry.Action.StatusKey != null) { - wires.Statuses[entry.Action.StatusKey] = statusData; + wires.Statuses[entry.Action.StatusKey] = (entry.OriginalPosition, statusData); } } + var statuses = new List<(int position, object key, object value)>(); + foreach (var (key, value) in wires.Statuses) + { + var valueCast = ((int position, StatusLightData? value)) value; + statuses.Add((valueCast.position, key, valueCast.value!)); + } + + statuses.Sort((a, b) => a.position.CompareTo(b.position)); + _uiSystem.GetUiOrNull(uid, WiresUiKey.Key)?.SetState( new WiresBoundUserInterfaceState( clientList.ToArray(), - wires.Statuses.Select(p => new StatusEntry(p.Key, p.Value)).ToArray(), + statuses.Select(p => new StatusEntry(p.key, p.value)).ToArray(), wires.BoardName, wires.SerialNumber, wires.WireSeed)); @@ -630,6 +640,12 @@ public sealed class WiresSystem : EntitySystem return; } + if (wire.IsCut) + { + _popupSystem.PopupCursor(Loc.GetString("wires-component-ui-on-receive-message-cannot-cut-cut-wire"), Filter.Entities(user)); + return; + } + break; case WiresAction.Mend: if (!_toolSystem.HasQuality(toolEntity, "Cutting", tool)) @@ -638,6 +654,12 @@ public sealed class WiresSystem : EntitySystem return; } + if (!wire.IsCut) + { + _popupSystem.PopupCursor(Loc.GetString("wires-component-ui-on-receive-message-cannot-mend-uncut-wire"), Filter.Entities(user)); + return; + } + break; case WiresAction.Pulse: if (!_toolSystem.HasQuality(toolEntity, "Pulsing", tool)) @@ -646,9 +668,17 @@ public sealed class WiresSystem : EntitySystem return; } + if (wire.IsCut) + { + _popupSystem.PopupCursor(Loc.GetString("wires-component-ui-on-receive-message-cannot-pulse-cut-wire"), Filter.Entities(user)); + return; + } + break; } + wires.WiresQueue.Add(id); + if (_toolTime > 0f) { var args = new DoAfterEventArgs(user, _toolTime, default, used) @@ -672,8 +702,6 @@ public sealed class WiresSystem : EntitySystem }; _doAfter.DoAfter(args); - - wires.WiresQueue.Add(id); } else { @@ -688,6 +716,9 @@ public sealed class WiresSystem : EntitySystem if (!Resolve(used, ref wires)) return; + if (!wires.WiresQueue.Contains(id)) + return; + if (!Resolve(toolEntity, ref tool)) { wires.WiresQueue.Remove(id); @@ -711,6 +742,12 @@ public sealed class WiresSystem : EntitySystem break; } + if (wire.IsCut) + { + _popupSystem.PopupCursor(Loc.GetString("wires-component-ui-on-receive-message-cannot-cut-cut-wire"), Filter.Entities(user)); + break; + } + _toolSystem.PlayToolSound(toolEntity, tool); if (wire.Action.Cut(user, wire)) { @@ -726,6 +763,12 @@ public sealed class WiresSystem : EntitySystem break; } + if (!wire.IsCut) + { + _popupSystem.PopupCursor(Loc.GetString("wires-component-ui-on-receive-message-cannot-mend-uncut-wire"), Filter.Entities(user)); + break; + } + _toolSystem.PlayToolSound(toolEntity, tool); if (wire.Action.Mend(user, wire)) { @@ -754,6 +797,7 @@ public sealed class WiresSystem : EntitySystem break; } + wire.Action.Update(wire); wires.WiresQueue.Remove(id); } @@ -888,6 +932,12 @@ public sealed class Wire [ViewVariables] public int Id { get; set; } + /// + /// The original position of this wire in the prototype. + /// + [ViewVariables] + public int OriginalPosition { get; set; } + /// /// The color of the wire. /// @@ -903,11 +953,12 @@ public sealed class Wire // The action that this wire performs upon activation. public IWireAction Action { get; set; } - public Wire(EntityUid owner, bool isCut, WireColor color, WireLetter letter, IWireAction action) + public Wire(EntityUid owner, bool isCut, WireColor color, WireLetter letter, int position, IWireAction action) { Owner = owner; IsCut = isCut; Color = color; + OriginalPosition = position; Letter = letter; Action = action; } diff --git a/Resources/Locale/en-US/wires/components/wires-component.ftl b/Resources/Locale/en-US/wires/components/wires-component.ftl index d4d173501d..496a0d0f6a 100644 --- a/Resources/Locale/en-US/wires/components/wires-component.ftl +++ b/Resources/Locale/en-US/wires/components/wires-component.ftl @@ -3,6 +3,8 @@ wires-component-ui-on-receive-message-cannot-reach = You can't reach there! wires-component-ui-on-receive-message-need-wirecutters = You need to hold a wirecutter in your hand! wires-component-ui-on-receive-message-need-multitool = You need to hold a multitool in your hand! 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].