diff --git a/Content.Server/Access/AccessWireAction.cs b/Content.Server/Access/AccessWireAction.cs index 35f3efbf0d..8592febf23 100644 --- a/Content.Server/Access/AccessWireAction.cs +++ b/Content.Server/Access/AccessWireAction.cs @@ -1,6 +1,7 @@ using Content.Server.Wires; using Content.Shared.Access; using Content.Shared.Access.Components; +using Content.Shared.Emag.Components; using Content.Shared.Wires; namespace Content.Server.Access; @@ -14,26 +15,28 @@ public sealed class AccessWireAction : ComponentWireAction comp.Enabled ? StatusLightState.On : StatusLightState.Off; + { + return EntityManager.HasComponent(comp.Owner) ? StatusLightState.On : StatusLightState.Off; + } public override object StatusKey { get; } = AccessWireActionKey.Status; public override bool Cut(EntityUid user, Wire wire, AccessReaderComponent comp) { WiresSystem.TryCancelWireAction(wire.Owner, PulseTimeoutKey.Key); - comp.Enabled = false; + EntityManager.RemoveComponent(comp.Owner); return true; } public override bool Mend(EntityUid user, Wire wire, AccessReaderComponent comp) { - comp.Enabled = true; + EntityManager.AddComponent(comp.Owner); return true; } public override void Pulse(EntityUid user, Wire wire, AccessReaderComponent comp) { - comp.Enabled = false; + EntityManager.RemoveComponent(comp.Owner); WiresSystem.StartWireAction(wire.Owner, _pulseTimeout, PulseTimeoutKey.Key, new TimedWireEvent(AwaitPulseCancel, wire)); } @@ -49,9 +52,10 @@ public sealed class AccessWireAction : ComponentWireAction(wire.Owner, out var access)) { - access.Enabled = true; + EntityManager.RemoveComponent(wire.Owner); } } } diff --git a/Content.Server/Bed/BedSystem.cs b/Content.Server/Bed/BedSystem.cs index d39f24931c..01346fd19a 100644 --- a/Content.Server/Bed/BedSystem.cs +++ b/Content.Server/Bed/BedSystem.cs @@ -10,6 +10,7 @@ using Content.Shared.Bed.Sleep; using Content.Shared.Body.Components; using Content.Shared.Buckle.Components; using Content.Shared.Damage; +using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; using Content.Server.Construction; using Content.Shared.Mobs.Systems; @@ -114,7 +115,7 @@ namespace Content.Server.Bed private void OnEmagged(EntityUid uid, StasisBedComponent component, ref GotEmaggedEvent args) { - // Repeatable + args.Repeatable = true; // Reset any metabolisms first so they receive the multiplier correctly UpdateMetabolisms(uid, component, false); component.Multiplier = 1 / component.Multiplier; @@ -139,7 +140,7 @@ namespace Content.Server.Bed { var metabolismRating = args.PartRatings[component.MachinePartMetabolismModifier]; component.Multiplier = component.BaseMultiplier * metabolismRating; //linear scaling so it's not OP - if (component.Emagged) + if (HasComp(uid)) component.Multiplier = 1f / component.Multiplier; } diff --git a/Content.Server/Bed/Components/StasisBedComponent.cs b/Content.Server/Bed/Components/StasisBedComponent.cs index 4309ba48de..9a98c793ae 100644 --- a/Content.Server/Bed/Components/StasisBedComponent.cs +++ b/Content.Server/Bed/Components/StasisBedComponent.cs @@ -6,14 +6,6 @@ namespace Content.Server.Bed.Components [RegisterComponent] public sealed class StasisBedComponent : Component { - /// - /// Stores whether or not the stasis bed has been emagged, - /// which causes the multiplier to speed up rather than - /// slow down. Needs to be stored for machine upgrades. - /// - [ViewVariables(VVAccess.ReadWrite)] - public bool Emagged = false; - [DataField("baseMultiplier", required: true), ViewVariables(VVAccess.ReadWrite)] public float BaseMultiplier = 10f; diff --git a/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs b/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs index 3104a11d35..8592eda00e 100644 --- a/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs +++ b/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs @@ -22,9 +22,6 @@ namespace Content.Server.Chemistry.Components [ViewVariables(VVAccess.ReadWrite)] public string? EmagPackPrototypeId = default!; - [ViewVariables(VVAccess.ReadWrite)] - public bool IsEmagged = false; - [DataField("clickSound"), ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier ClickSound = new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg"); diff --git a/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs b/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs index 62f4fc0e7d..9a1d560f34 100644 --- a/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Chemistry; using Content.Shared.Chemistry.Dispenser; using Content.Shared.Containers.ItemSlots; using Content.Shared.Database; +using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; using Content.Shared.FixedPoint; using JetBrains.Annotations; @@ -79,7 +80,7 @@ namespace Content.Server.Chemistry.EntitySystems inventory.AddRange(packPrototype.Inventory); } - if (reagentDispenser.IsEmagged + if (HasComp(reagentDispenser.Owner) && reagentDispenser.EmagPackPrototypeId is not null && _prototypeManager.TryIndex(reagentDispenser.EmagPackPrototypeId, out ReagentDispenserInventoryPrototype? emagPackPrototype)) { @@ -91,12 +92,10 @@ namespace Content.Server.Chemistry.EntitySystems private void OnEmagged(EntityUid uid, ReagentDispenserComponent reagentDispenser, ref GotEmaggedEvent args) { - if (!reagentDispenser.IsEmagged) - { - reagentDispenser.IsEmagged = true; - args.Handled = true; - UpdateUiState(reagentDispenser); - } + // adding component manually to have correct state + EntityManager.AddComponent(uid); + UpdateUiState(reagentDispenser); + args.Handled = true; } private void OnSetDispenseAmountMessage(EntityUid uid, ReagentDispenserComponent reagentDispenser, ReagentDispenserSetDispenseAmountMessage message) diff --git a/Content.Server/Communications/CommunicationsConsoleSystem.cs b/Content.Server/Communications/CommunicationsConsoleSystem.cs index 23dc79b648..6e2844e271 100644 --- a/Content.Server/Communications/CommunicationsConsoleSystem.cs +++ b/Content.Server/Communications/CommunicationsConsoleSystem.cs @@ -15,6 +15,7 @@ using Content.Shared.Access.Systems; using Content.Shared.CCVar; using Content.Shared.Communications; using Content.Shared.Database; +using Content.Shared.Emag.Components; using Content.Shared.Examine; using Content.Shared.Popups; using Robust.Server.GameObjects; @@ -175,7 +176,7 @@ namespace Content.Server.Communications if (!_interaction.InRangeUnobstructed(console, user)) return false; - if (TryComp(console, out var accessReaderComponent) && accessReaderComponent.Enabled) + if (TryComp(console, out var accessReaderComponent) && !HasComp(console)) { return _accessReaderSystem.IsAllowed(user, accessReaderComponent); } diff --git a/Content.Server/Fax/FaxMachineComponent.cs b/Content.Server/Fax/FaxMachineComponent.cs index 07402aefc8..25ceaf179c 100644 --- a/Content.Server/Fax/FaxMachineComponent.cs +++ b/Content.Server/Fax/FaxMachineComponent.cs @@ -50,13 +50,6 @@ public sealed class FaxMachineComponent : Component [DataField("receiveNukeCodes")] public bool ReceiveNukeCodes { get; set; } = false; - /// - /// Is fax was emaaged - /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField("emagged")] - public bool Emagged { get; set; } = false; - /// /// Sound to play when fax has been emagged /// diff --git a/Content.Server/Fax/FaxSystem.cs b/Content.Server/Fax/FaxSystem.cs index b7126a192c..2881dae022 100644 --- a/Content.Server/Fax/FaxSystem.cs +++ b/Content.Server/Fax/FaxSystem.cs @@ -13,6 +13,7 @@ using Content.Server.UserInterface; using Content.Shared.Administration.Logs; using Content.Shared.Containers.ItemSlots; using Content.Shared.Database; +using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; using Content.Shared.Fax; using Content.Shared.Interaction; @@ -210,7 +211,7 @@ public sealed class FaxSystem : EntitySystem return; } - if (component.KnownFaxes.ContainsValue(newName) && !component.Emagged) // Allow exist names if emagged for fun + if (component.KnownFaxes.ContainsValue(newName) && !HasComp(uid)) // Allow existing names if emagged for fun { _popupSystem.PopupEntity(Loc.GetString("fax-machine-popup-name-exist"), uid); return; @@ -228,11 +229,7 @@ public sealed class FaxSystem : EntitySystem private void OnEmagged(EntityUid uid, FaxMachineComponent component, ref GotEmaggedEvent args) { - if (component.Emagged) - return; - _audioSystem.PlayPvs(component.EmagSound, uid); - component.Emagged = true; args.Handled = true; } @@ -246,7 +243,7 @@ public sealed class FaxSystem : EntitySystem switch (command) { case FaxConstants.FaxPingCommand: - var isForSyndie = component.Emagged && + var isForSyndie = HasComp(uid) && args.Data.ContainsKey(FaxConstants.FaxSyndicateData); if (!isForSyndie && !component.ResponsePings) return; @@ -362,7 +359,7 @@ public sealed class FaxSystem : EntitySystem { DeviceNetworkConstants.Command, FaxConstants.FaxPingCommand } }; - if (component.Emagged) + if (HasComp(uid)) payload.Add(FaxConstants.FaxSyndicateData, true); _deviceNetworkSystem.QueuePacket(uid, null, payload); diff --git a/Content.Server/Power/Components/ApcComponent.cs b/Content.Server/Power/Components/ApcComponent.cs index 3047d7a711..12a7f61921 100644 --- a/Content.Server/Power/Components/ApcComponent.cs +++ b/Content.Server/Power/Components/ApcComponent.cs @@ -27,8 +27,6 @@ public sealed class ApcComponent : BaseApcNetComponent [ViewVariables] public bool MainBreakerEnabled = true; - public bool Emagged = false; - public const float HighPowerThreshold = 0.9f; public static TimeSpan VisualsChangeDelay = TimeSpan.FromSeconds(1); diff --git a/Content.Server/Power/EntitySystems/ApcSystem.cs b/Content.Server/Power/EntitySystems/ApcSystem.cs index c602ee3ab6..d442a77c06 100644 --- a/Content.Server/Power/EntitySystems/ApcSystem.cs +++ b/Content.Server/Power/EntitySystems/ApcSystem.cs @@ -5,6 +5,7 @@ using Content.Server.Wires; using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.APC; +using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; using Content.Shared.Examine; using Content.Shared.Interaction; @@ -88,11 +89,8 @@ namespace Content.Server.Power.EntitySystems private void OnEmagged(EntityUid uid, ApcComponent comp, ref GotEmaggedEvent args) { - if(!comp.Emagged) - { - comp.Emagged = true; - args.Handled = true; - } + // no fancy conditions + args.Handled = true; } public void UpdateApcState(EntityUid uid, @@ -147,7 +145,7 @@ namespace Content.Server.Power.EntitySystems ApcComponent? apc=null, BatteryComponent? battery=null) { - if (apc != null && apc.Emagged) + if (apc != null && HasComp(uid)) return ApcChargeState.Emag; if (!Resolve(uid, ref apc, ref battery)) diff --git a/Content.Server/Recycling/Components/RecyclerComponent.cs b/Content.Server/Recycling/Components/RecyclerComponent.cs index 37225b5721..017c9881c1 100644 --- a/Content.Server/Recycling/Components/RecyclerComponent.cs +++ b/Content.Server/Recycling/Components/RecyclerComponent.cs @@ -13,13 +13,6 @@ namespace Content.Server.Recycling.Components [DataField("enabled")] public bool Enabled; - /// - /// Whether or not sentient beings will be recycled - /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField("safe")] - internal bool Safe = true; - /// /// The percentage of material that will be recovered /// diff --git a/Content.Server/Recycling/RecyclerSystem.cs b/Content.Server/Recycling/RecyclerSystem.cs index 43d274bcf4..de7c558b4c 100644 --- a/Content.Server/Recycling/RecyclerSystem.cs +++ b/Content.Server/Recycling/RecyclerSystem.cs @@ -8,6 +8,7 @@ using Content.Server.Power.EntitySystems; using Content.Server.Recycling.Components; using Content.Shared.Audio; using Content.Shared.Body.Components; +using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; using Content.Shared.Examine; using Content.Shared.IdentityManagement; @@ -131,7 +132,7 @@ namespace Content.Server.Recycling // Can only recycle things that are tagged trash or recyclable... And also check the safety of the thing to recycle. if (!_tags.HasAnyTag(entity, "Trash", "Recyclable") && - (!TryComp(entity, out recyclable) || !recyclable.Safe && component.Safe)) + (!TryComp(entity, out recyclable) || !recyclable.Safe && !HasComp(component.Owner))) { return; } @@ -162,7 +163,7 @@ namespace Content.Server.Recycling private bool CanGib(RecyclerComponent component, EntityUid entity) { - return HasComp(entity) && !component.Safe && + return HasComp(entity) && HasComp(component.Owner) && this.IsPowered(component.Owner, EntityManager); } @@ -191,8 +192,7 @@ namespace Content.Server.Recycling private void OnEmagged(EntityUid uid, RecyclerComponent component, ref GotEmaggedEvent args) { - if (!component.Safe) return; - component.Safe = false; + // no fancy conditions args.Handled = true; } } diff --git a/Content.Server/VendingMachines/VendingMachineSystem.cs b/Content.Server/VendingMachines/VendingMachineSystem.cs index 7949b56ec4..ccef2b1b4c 100644 --- a/Content.Server/VendingMachines/VendingMachineSystem.cs +++ b/Content.Server/VendingMachines/VendingMachineSystem.cs @@ -10,6 +10,7 @@ using Content.Shared.Actions; using Content.Shared.Actions.ActionTypes; using Content.Shared.Damage; using Content.Shared.Destructible; +using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; using Content.Shared.Popups; using Content.Shared.Throwing; @@ -133,11 +134,8 @@ namespace Content.Server.VendingMachines private void OnEmagged(EntityUid uid, VendingMachineComponent component, ref GotEmaggedEvent args) { - if (component.Emagged || component.EmaggedInventory.Count == 0 ) - return; - - component.Emagged = true; - args.Handled = true; + // only emag if there are emag-only items + args.Handled = component.EmaggedInventory.Count > 0; } private void OnDamage(EntityUid uid, VendingMachineComponent component, DamageChangedEvent args) @@ -224,7 +222,7 @@ namespace Content.Server.VendingMachines if (TryComp(vendComponent.Owner, out var accessReader)) { - if (!_accessReader.IsAllowed(sender.Value, accessReader) && !vendComponent.Emagged) + if (!_accessReader.IsAllowed(sender.Value, accessReader) && !HasComp(uid)) { _popupSystem.PopupEntity(Loc.GetString("vending-machine-component-try-eject-access-denied"), uid); Deny(uid, vendComponent); @@ -391,7 +389,7 @@ namespace Content.Server.VendingMachines private VendingMachineInventoryEntry? GetEntry(string entryId, InventoryType type, VendingMachineComponent component) { - if (type == InventoryType.Emagged && component.Emagged) + if (type == InventoryType.Emagged && HasComp(component.Owner)) return component.EmaggedInventory.GetValueOrDefault(entryId); if (type == InventoryType.Contraband && component.Contraband) diff --git a/Content.Shared/Access/Components/AccessReaderComponent.cs b/Content.Shared/Access/Components/AccessReaderComponent.cs index db5f9218e8..97fe78f7e6 100644 --- a/Content.Shared/Access/Components/AccessReaderComponent.cs +++ b/Content.Shared/Access/Components/AccessReaderComponent.cs @@ -7,13 +7,6 @@ namespace Content.Shared.Access.Components [RegisterComponent] public sealed class AccessReaderComponent : Component { - /// - /// Whether this reader is enabled or not. If disabled, all access - /// checks will pass. - /// - [ViewVariables(VVAccess.ReadWrite)] - public bool Enabled = true; - /// /// The set of tags that will automatically deny an allowed check, if any of them are present. /// diff --git a/Content.Shared/Access/Systems/AccessReaderSystem.cs b/Content.Shared/Access/Systems/AccessReaderSystem.cs index e19db766ab..4562d05858 100644 --- a/Content.Shared/Access/Systems/AccessReaderSystem.cs +++ b/Content.Shared/Access/Systems/AccessReaderSystem.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Shared.Inventory; +using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; using Content.Shared.PDA; using Content.Shared.Access.Components; @@ -28,7 +29,7 @@ namespace Content.Shared.Access.Systems { if (args.User == null) // AutoLink (and presumably future external linkers) have no user. return; - if (component.Enabled && !IsAllowed(args.User.Value, component)) + if (!HasComp(uid) && !IsAllowed(args.User.Value, component)) args.Cancel(); } @@ -46,12 +47,10 @@ namespace Content.Shared.Access.Systems private void OnEmagged(EntityUid uid, AccessReaderComponent reader, ref GotEmaggedEvent args) { - if (reader.Enabled) - { - reader.Enabled = false; - args.Handled = true; - } + // no fancy conditions + args.Handled = true; } + /// /// Searches the source for access tags /// then compares it with the targets readers access list to see if it is allowed. @@ -86,7 +85,7 @@ namespace Content.Shared.Access.Systems /// An access reader to check against public bool IsAllowed(ICollection accessTags, AccessReaderComponent reader) { - if (!reader.Enabled) + if (HasComp(reader.Owner)) { // Access reader is totally disabled, so access is always allowed. return true; diff --git a/Content.Shared/Emag/Components/EmaggedComponent.cs b/Content.Shared/Emag/Components/EmaggedComponent.cs new file mode 100644 index 0000000000..1b66357f3e --- /dev/null +++ b/Content.Shared/Emag/Components/EmaggedComponent.cs @@ -0,0 +1,11 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Emag.Components; + +/// +/// Marker component for emagged entities +/// +[RegisterComponent, NetworkedComponent] +public sealed class EmaggedComponent : Component +{ +} diff --git a/Content.Shared/Emag/Systems/EmagSystem.cs b/Content.Shared/Emag/Systems/EmagSystem.cs index 8d68131e42..d5db09e1e2 100644 --- a/Content.Shared/Emag/Systems/EmagSystem.cs +++ b/Content.Shared/Emag/Systems/EmagSystem.cs @@ -156,12 +156,19 @@ namespace Content.Shared.Emag.Systems /// public bool DoEmagEffect(EntityUid user, EntityUid target) { + // prevent emagging twice + if (HasComp(target)) + return false; + var emaggedEvent = new GotEmaggedEvent(user); RaiseLocalEvent(target, ref emaggedEvent); + + if (!emaggedEvent.Repeatable) + EnsureComp(target); return emaggedEvent.Handled; } } [ByRefEvent] - public record struct GotEmaggedEvent(EntityUid UserUid, bool Handled = false); + public record struct GotEmaggedEvent(EntityUid UserUid, bool Handled = false, bool Repeatable = false); } diff --git a/Content.Shared/VendingMachines/SharedVendingMachineSystem.cs b/Content.Shared/VendingMachines/SharedVendingMachineSystem.cs index 96b1f0a1d1..dfd129a9da 100644 --- a/Content.Shared/VendingMachines/SharedVendingMachineSystem.cs +++ b/Content.Shared/VendingMachines/SharedVendingMachineSystem.cs @@ -1,3 +1,4 @@ +using Content.Shared.Emag.Components; using Robust.Shared.Prototypes; using System.Linq; @@ -36,7 +37,7 @@ public abstract class SharedVendingMachineSystem : EntitySystem /// /// Returns all of the vending machine's inventory. Only includes emagged and contraband inventories if - /// and + /// exists and is true /// are true respectively. /// /// @@ -49,7 +50,7 @@ public abstract class SharedVendingMachineSystem : EntitySystem var inventory = new List(component.Inventory.Values); - if (component.Emagged) + if (HasComp(uid)) inventory.AddRange(component.EmaggedInventory.Values); if (component.Contraband) diff --git a/Content.Shared/VendingMachines/VendingMachineComponent.cs b/Content.Shared/VendingMachines/VendingMachineComponent.cs index 1ae9562f7b..52264aa4f3 100644 --- a/Content.Shared/VendingMachines/VendingMachineComponent.cs +++ b/Content.Shared/VendingMachines/VendingMachineComponent.cs @@ -40,7 +40,6 @@ namespace Content.Shared.VendingMachines [ViewVariables] public Dictionary ContrabandInventory = new(); - public bool Emagged; public bool Contraband; public bool Ejecting;