From 297276dcc3e3f17f1e84f47502753a537dceb744 Mon Sep 17 00:00:00 2001
From: alexalexmax <149889301+alexalexmax@users.noreply.github.com>
Date: Tue, 13 Jan 2026 08:30:53 -0500
Subject: [PATCH] Adds EMP Resistance component, gives it to ninja suit and
headset (#42334)
* add comp and apply to ninja gear
* cleanup
* requested changes
---------
Co-authored-by: seanpimble <149889301+seanpimble@users.noreply.github.com>
---
Content.Shared/Emp/EmpResistanceComponent.cs | 18 ++++++++++++++++
Content.Shared/Emp/SharedEmpSystem.cs | 21 +++++++++++++++++++
.../Ninja/Systems/SharedNinjaSuitSystem.cs | 8 -------
.../Entities/Clothing/Ears/headsets.yml | 2 ++
.../Entities/Clothing/OuterClothing/suits.yml | 2 ++
5 files changed, 43 insertions(+), 8 deletions(-)
create mode 100644 Content.Shared/Emp/EmpResistanceComponent.cs
diff --git a/Content.Shared/Emp/EmpResistanceComponent.cs b/Content.Shared/Emp/EmpResistanceComponent.cs
new file mode 100644
index 0000000000..0768ad744f
--- /dev/null
+++ b/Content.Shared/Emp/EmpResistanceComponent.cs
@@ -0,0 +1,18 @@
+using Content.Shared.FixedPoint;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Emp;
+
+///
+/// An entity with this component resists or is fully immune to EMPs.
+///
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(SharedEmpSystem))]
+public sealed partial class EmpResistanceComponent : Component
+{
+ ///
+ /// The proportion of the EMP effect that is resisted. 1.00 indicates full immunity while 0.00 indicates no resistance.
+ ///
+ [DataField, AutoNetworkedField]
+ public FixedPoint2 Resistance = FixedPoint2.Zero;
+}
diff --git a/Content.Shared/Emp/SharedEmpSystem.cs b/Content.Shared/Emp/SharedEmpSystem.cs
index 4b806ab153..22457e2d6e 100644
--- a/Content.Shared/Emp/SharedEmpSystem.cs
+++ b/Content.Shared/Emp/SharedEmpSystem.cs
@@ -11,6 +11,7 @@ using Robust.Shared.GameStates;
using Robust.Shared.Configuration; // Frontier
using Robust.Shared;
using Content.Shared.Damage; // Frontier
+using Robust.Shared.Utility;
namespace Content.Shared.Emp;
@@ -39,6 +40,9 @@ public abstract class SharedEmpSystem : EntitySystem
SubscribeLocalEvent(OnExamine);
SubscribeLocalEvent(OnRemove);
SubscribeLocalEvent(OnRejuvenate);
+
+ SubscribeLocalEvent(OnResistEmpAttempt);
+ SubscribeLocalEvent(OnResistEmpPulse);
}
public static readonly EntProtoId EmpPulseEffectPrototype = "EffectEmpBlast"; // Frontier - was EffectEmpPulse
@@ -192,6 +196,23 @@ public abstract class SharedEmpSystem : EntitySystem
{
RemCompDeferred(ent);
}
+
+ private void OnResistEmpAttempt(Entity ent, ref EmpAttemptEvent args)
+ {
+ if (ent.Comp.Resistance >= 1)
+ args.Cancelled = true;
+ }
+
+ private void OnResistEmpPulse(Entity ent, ref EmpPulseEvent args)
+ {
+ var empStrengthMultiplier = 1 - ent.Comp.Resistance;
+
+ if (empStrengthMultiplier <= 0)
+ return;
+
+ args.Duration *= (float) empStrengthMultiplier;
+ args.EnergyConsumption *= (float) empStrengthMultiplier;
+ }
}
///
diff --git a/Content.Shared/Ninja/Systems/SharedNinjaSuitSystem.cs b/Content.Shared/Ninja/Systems/SharedNinjaSuitSystem.cs
index 69627badd1..a5455c6158 100644
--- a/Content.Shared/Ninja/Systems/SharedNinjaSuitSystem.cs
+++ b/Content.Shared/Ninja/Systems/SharedNinjaSuitSystem.cs
@@ -36,7 +36,6 @@ public abstract class SharedNinjaSuitSystem : EntitySystem
SubscribeLocalEvent(OnCreateStarAttempt);
SubscribeLocalEvent(OnActivateAttempt);
SubscribeLocalEvent(OnUnequipped);
- SubscribeLocalEvent(OnEmpAttempt);
}
private void OnEquipped(Entity ent, ref ClothingGotEquippedEvent args)
@@ -178,11 +177,4 @@ public abstract class SharedNinjaSuitSystem : EntitySystem
if (user.Comp.Gloves is { } uid)
_toggle.TryDeactivate(uid, user: user);
}
-
- private void OnEmpAttempt(Entity ent, ref EmpAttemptEvent args)
- {
- // ninja suit (battery) is immune to emp
- // powercell relays the event to suit
- args.Cancelled = true;
- }
}
diff --git a/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml b/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
index 2b7e039955..1de824388e 100644
--- a/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
+++ b/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
@@ -315,3 +315,5 @@
sprite: Clothing/Ears/Headsets/ninja.rsi
- type: Clothing
sprite: Clothing/Ears/Headsets/ninja.rsi
+ - type: EmpResistance
+ resistance: 1
diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml
index 7c827ec010..1d2100ee2e 100644
--- a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml
+++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml
@@ -249,6 +249,8 @@
noPowerPopup: ninja-no-power
# core ninja suit stuff
- type: NinjaSuit
+ - type: EmpResistance
+ resistance: 1
- type: UseDelay
delay: 5 # disable time
- type: PowerCellSlot