make emagged marker component (fixed version of #13867) (#14096)

* The all-in-one hacking solution
The thinking man's lockpick
The iconic EMAG

* emagged medbay's stasis bed

* left med, emagged sec' apc

* went back to chem, emagged the dispenser

* emagged the fax while i was there

* had a donut while waiting for emag to charge

* i broke into the bridge then announced 'mandatory johnson inspection in medical'

* get system instead of dependency

* feedback

* net suggestion

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>

* use EnsureComp and import NetworkedComponent

---------

Co-authored-by: deltanedas <user@zenith>
Co-authored-by: deltanedas <deltanedas@laptop>
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
deltanedas
2023-02-19 01:03:06 +00:00
committed by GitHub
parent 04a0faf478
commit 98b02b3d97
19 changed files with 65 additions and 84 deletions

View File

@@ -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<AccessReaderComponent
private int _pulseTimeout = 30;
public override StatusLightState? GetLightState(Wire wire, AccessReaderComponent comp)
=> comp.Enabled ? StatusLightState.On : StatusLightState.Off;
{
return EntityManager.HasComponent<EmaggedComponent>(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<EmaggedComponent>(comp.Owner);
return true;
}
public override bool Mend(EntityUid user, Wire wire, AccessReaderComponent comp)
{
comp.Enabled = true;
EntityManager.AddComponent<EmaggedComponent>(comp.Owner);
return true;
}
public override void Pulse(EntityUid user, Wire wire, AccessReaderComponent comp)
{
comp.Enabled = false;
EntityManager.RemoveComponent<EmaggedComponent>(comp.Owner);
WiresSystem.StartWireAction(wire.Owner, _pulseTimeout, PulseTimeoutKey.Key, new TimedWireEvent(AwaitPulseCancel, wire));
}
@@ -49,9 +52,10 @@ public sealed class AccessWireAction : ComponentWireAction<AccessReaderComponent
{
if (!wire.IsCut)
{
// check is still here incase you somehow TOCTOU it into unemagging something it shouldn't
if (EntityManager.TryGetComponent<AccessReaderComponent>(wire.Owner, out var access))
{
access.Enabled = true;
EntityManager.RemoveComponent<EmaggedComponent>(wire.Owner);
}
}
}

View File

@@ -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<EmaggedComponent>(uid))
component.Multiplier = 1f / component.Multiplier;
}

View File

@@ -6,14 +6,6 @@ namespace Content.Server.Bed.Components
[RegisterComponent]
public sealed class StasisBedComponent : Component
{
/// <summary>
/// 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.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public bool Emagged = false;
[DataField("baseMultiplier", required: true), ViewVariables(VVAccess.ReadWrite)]
public float BaseMultiplier = 10f;

View File

@@ -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");

View File

@@ -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<EmaggedComponent>(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;
// adding component manually to have correct state
EntityManager.AddComponent<EmaggedComponent>(uid);
UpdateUiState(reagentDispenser);
}
args.Handled = true;
}
private void OnSetDispenseAmountMessage(EntityUid uid, ReagentDispenserComponent reagentDispenser, ReagentDispenserSetDispenseAmountMessage message)

View File

@@ -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<AccessReaderComponent>(console, out var accessReaderComponent) && accessReaderComponent.Enabled)
if (TryComp<AccessReaderComponent>(console, out var accessReaderComponent) && !HasComp<EmaggedComponent>(console))
{
return _accessReaderSystem.IsAllowed(user, accessReaderComponent);
}

View File

@@ -50,13 +50,6 @@ public sealed class FaxMachineComponent : Component
[DataField("receiveNukeCodes")]
public bool ReceiveNukeCodes { get; set; } = false;
/// <summary>
/// Is fax was emaaged
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("emagged")]
public bool Emagged { get; set; } = false;
/// <summary>
/// Sound to play when fax has been emagged
/// </summary>

View File

@@ -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<EmaggedComponent>(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<EmaggedComponent>(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<EmaggedComponent>(uid))
payload.Add(FaxConstants.FaxSyndicateData, true);
_deviceNetworkSystem.QueuePacket(uid, null, payload);

View File

@@ -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);

View File

@@ -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,12 +89,9 @@ namespace Content.Server.Power.EntitySystems
private void OnEmagged(EntityUid uid, ApcComponent comp, ref GotEmaggedEvent args)
{
if(!comp.Emagged)
{
comp.Emagged = true;
// no fancy conditions
args.Handled = true;
}
}
public void UpdateApcState(EntityUid uid,
ApcComponent? apc=null,
@@ -147,7 +145,7 @@ namespace Content.Server.Power.EntitySystems
ApcComponent? apc=null,
BatteryComponent? battery=null)
{
if (apc != null && apc.Emagged)
if (apc != null && HasComp<EmaggedComponent>(uid))
return ApcChargeState.Emag;
if (!Resolve(uid, ref apc, ref battery))

View File

@@ -13,13 +13,6 @@ namespace Content.Server.Recycling.Components
[DataField("enabled")]
public bool Enabled;
/// <summary>
/// Whether or not sentient beings will be recycled
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("safe")]
internal bool Safe = true;
/// <summary>
/// The percentage of material that will be recovered
/// </summary>

View File

@@ -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<EmaggedComponent>(component.Owner)))
{
return;
}
@@ -162,7 +163,7 @@ namespace Content.Server.Recycling
private bool CanGib(RecyclerComponent component, EntityUid entity)
{
return HasComp<BodyComponent>(entity) && !component.Safe &&
return HasComp<BodyComponent>(entity) && HasComp<EmaggedComponent>(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;
}
}

View File

@@ -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<AccessReaderComponent?>(vendComponent.Owner, out var accessReader))
{
if (!_accessReader.IsAllowed(sender.Value, accessReader) && !vendComponent.Emagged)
if (!_accessReader.IsAllowed(sender.Value, accessReader) && !HasComp<EmaggedComponent>(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<EmaggedComponent>(component.Owner))
return component.EmaggedInventory.GetValueOrDefault(entryId);
if (type == InventoryType.Contraband && component.Contraband)

View File

@@ -7,13 +7,6 @@ namespace Content.Shared.Access.Components
[RegisterComponent]
public sealed class AccessReaderComponent : Component
{
/// <summary>
/// Whether this reader is enabled or not. If disabled, all access
/// checks will pass.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public bool Enabled = true;
/// <summary>
/// The set of tags that will automatically deny an allowed check, if any of them are present.
/// </summary>

View File

@@ -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<EmaggedComponent>(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;
// no fancy conditions
args.Handled = true;
}
}
/// <summary>
/// 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
/// <param name="reader">An access reader to check against</param>
public bool IsAllowed(ICollection<string> accessTags, AccessReaderComponent reader)
{
if (!reader.Enabled)
if (HasComp<EmaggedComponent>(reader.Owner))
{
// Access reader is totally disabled, so access is always allowed.
return true;

View File

@@ -0,0 +1,11 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Emag.Components;
/// <summary>
/// Marker component for emagged entities
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed class EmaggedComponent : Component
{
}

View File

@@ -156,12 +156,19 @@ namespace Content.Shared.Emag.Systems
/// </summary>
public bool DoEmagEffect(EntityUid user, EntityUid target)
{
// prevent emagging twice
if (HasComp<EmaggedComponent>(target))
return false;
var emaggedEvent = new GotEmaggedEvent(user);
RaiseLocalEvent(target, ref emaggedEvent);
if (!emaggedEvent.Repeatable)
EnsureComp<EmaggedComponent>(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);
}

View File

@@ -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
/// <summary>
/// Returns all of the vending machine's inventory. Only includes emagged and contraband inventories if
/// <see cref="VendingMachineComponent.Emagged"/> and <see cref="VendingMachineComponent.Contraband"/>
/// <see cref="EmaggedComponent"/> exists and <see cref="VendingMachineComponent.Contraband"/> is true
/// are <c>true</c> respectively.
/// </summary>
/// <param name="uid"></param>
@@ -49,7 +50,7 @@ public abstract class SharedVendingMachineSystem : EntitySystem
var inventory = new List<VendingMachineInventoryEntry>(component.Inventory.Values);
if (component.Emagged)
if (HasComp<EmaggedComponent>(uid))
inventory.AddRange(component.EmaggedInventory.Values);
if (component.Contraband)

View File

@@ -40,7 +40,6 @@ namespace Content.Shared.VendingMachines
[ViewVariables]
public Dictionary<string, VendingMachineInventoryEntry> ContrabandInventory = new();
public bool Emagged;
public bool Contraband;
public bool Ejecting;