]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
feat: add a component for rejuvenateable status effects (#39025)
authorPerry Fraser <perryprog@users.noreply.github.com>
Thu, 24 Jul 2025 15:13:29 +0000 (11:13 -0400)
committerGitHub <noreply@github.com>
Thu, 24 Jul 2025 15:13:29 +0000 (17:13 +0200)
* feat: add a component for rejuvenateable effects

* feat: let god mode'd entities get buffs

* fix: handle old status effect system

Didn't realize BeforeStatusEffectAddedEvent was called by both systems,
oops.

* refactor: rename to RejuvenateRemovedStatusEffect

* fix: make forced sleeping a debuff again

Missed in rebase.

* refactor: make BeforeStatusEffectAdded two events

Content.Shared/Damage/Systems/SharedGodmodeSystem.cs
Content.Shared/StatusEffect/StatusEffectsSystem.cs
Content.Shared/StatusEffectNew/Components/RejuvenateRemovedStatusEffectComponent.cs [new file with mode: 0644]
Content.Shared/StatusEffectNew/StatusEffectSystem.Relay.cs
Content.Shared/StatusEffectNew/StatusEffectsSystem.cs
Resources/Prototypes/Entities/StatusEffects/misc.yml
Resources/Prototypes/Entities/StatusEffects/movement.yml

index d10600ab563109e3e45ff94f76d7ead52bbf9d2a..feb5dd4140b8aeff127198601080b472875e36f2 100644 (file)
@@ -1,14 +1,19 @@
 using Content.Shared.Damage.Components;
 using Content.Shared.Damage.Events;
 using Content.Shared.Destructible;
+using Content.Shared.Prototypes;
 using Content.Shared.Rejuvenate;
 using Content.Shared.Slippery;
+using Content.Shared.StatusEffect;
 using Content.Shared.StatusEffectNew;
+using Content.Shared.StatusEffectNew.Components;
+using Robust.Shared.Prototypes;
 
 namespace Content.Shared.Damage.Systems;
 
 public abstract class SharedGodmodeSystem : EntitySystem
 {
+    [Dependency] private readonly IPrototypeManager _protoMan = default!;
     [Dependency] private readonly DamageableSystem _damageable = default!;
 
     public override void Initialize()
@@ -17,6 +22,7 @@ public abstract class SharedGodmodeSystem : EntitySystem
 
         SubscribeLocalEvent<GodmodeComponent, BeforeDamageChangedEvent>(OnBeforeDamageChanged);
         SubscribeLocalEvent<GodmodeComponent, BeforeStatusEffectAddedEvent>(OnBeforeStatusEffect);
+        SubscribeLocalEvent<GodmodeComponent, BeforeOldStatusEffectAddedEvent>(OnBeforeOldStatusEffect);
         SubscribeLocalEvent<GodmodeComponent, BeforeStaminaDamageEvent>(OnBeforeStaminaDamage);
         SubscribeLocalEvent<GodmodeComponent, SlipAttemptEvent>(OnSlipAttempt);
         SubscribeLocalEvent<GodmodeComponent, DestructionAttemptEvent>(OnDestruction);
@@ -34,6 +40,13 @@ public abstract class SharedGodmodeSystem : EntitySystem
 
     private void OnBeforeStatusEffect(EntityUid uid, GodmodeComponent component, ref BeforeStatusEffectAddedEvent args)
     {
+        if (_protoMan.Index(args.Effect).HasComponent<RejuvenateRemovedStatusEffectComponent>(Factory))
+            args.Cancelled = true;
+    }
+
+    private void OnBeforeOldStatusEffect(Entity<GodmodeComponent> ent, ref BeforeOldStatusEffectAddedEvent args)
+    {
+        // Old status effect system doesn't distinguish between good and bad status effects
         args.Cancelled = true;
     }
 
index b56acd3cc5d56749252cc4118bdbb70a15609996..c0c409d168befac1f8fef37882b209d3915ade9b 100644 (file)
@@ -353,7 +353,7 @@ namespace Content.Shared.StatusEffect
             if (!Resolve(uid, ref status, false))
                 return false;
 
-            var ev = new BeforeStatusEffectAddedEvent(key);
+            var ev = new BeforeOldStatusEffectAddedEvent(key);
             RaiseLocalEvent(uid, ref ev);
             if (ev.Cancelled)
                 return false;
@@ -481,6 +481,13 @@ namespace Content.Shared.StatusEffect
         }
     }
 
+    /// <summary>
+    /// Raised on an entity before a status effect is added to determine if adding it should be cancelled.
+    /// Obsolete version of <see cref="BeforeStatusEffectAddedEvent" />
+    /// </summary>
+    [ByRefEvent, Obsolete("Migration to StatusEffectNew.StatusEffectsSystem is required")]
+    public record struct BeforeOldStatusEffectAddedEvent(string EffectKey, bool Cancelled = false);
+
     public readonly struct StatusEffectAddedEvent
     {
         public readonly EntityUid Uid;
diff --git a/Content.Shared/StatusEffectNew/Components/RejuvenateRemovedStatusEffectComponent.cs b/Content.Shared/StatusEffectNew/Components/RejuvenateRemovedStatusEffectComponent.cs
new file mode 100644 (file)
index 0000000..808830f
--- /dev/null
@@ -0,0 +1,14 @@
+using Content.Shared.Damage.Components;
+using Content.Shared.Rejuvenate;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.StatusEffectNew.Components;
+
+/// <summary>
+/// Marker component for a status effect that should be removed on rejuvenation
+/// and should not be applied on targets with <see cref="GodmodeComponent" />.
+/// Only applies to effects using the new <see cref="StatusEffectsSystem" />.
+/// </summary>
+/// <seealso cref="RejuvenateEvent"/>
+[RegisterComponent, NetworkedComponent]
+public sealed partial class RejuvenateRemovedStatusEffectComponent : Component;
index 96ef0121689d28b4fe46487c00959b8526150070..0c4c5cf1f7f23effca56973556dc181db5b6eeb5 100644 (file)
@@ -1,5 +1,6 @@
 using Content.Shared.Movement.Events;
 using Content.Shared.Movement.Systems;
+using Content.Shared.Rejuvenate;
 using Content.Shared.StatusEffectNew.Components;
 using Content.Shared.Stunnable;
 using Robust.Shared.Player;
@@ -12,6 +13,7 @@ public sealed partial class StatusEffectsSystem
     {
         SubscribeLocalEvent<StatusEffectContainerComponent, LocalPlayerAttachedEvent>(RelayStatusEffectEvent);
         SubscribeLocalEvent<StatusEffectContainerComponent, LocalPlayerDetachedEvent>(RelayStatusEffectEvent);
+        SubscribeLocalEvent<StatusEffectContainerComponent, RejuvenateEvent>(RelayStatusEffectEvent);
 
         SubscribeLocalEvent<StatusEffectContainerComponent, RefreshMovementSpeedModifiersEvent>(RelayStatusEffectEvent);
         SubscribeLocalEvent<StatusEffectContainerComponent, UpdateCanMoveEvent>(RelayStatusEffectEvent);
index ce595109b3cb2d561f0707648e35dfdb202d6261..7f8eef5102f5c4c49446af54e241ecd5b2f3742c 100644 (file)
@@ -1,4 +1,5 @@
 using System.Diagnostics.CodeAnalysis;
+using Content.Shared.Rejuvenate;
 using Content.Shared.StatusEffectNew.Components;
 using Content.Shared.Whitelist;
 using Robust.Shared.Containers;
@@ -32,6 +33,8 @@ public sealed partial class StatusEffectsSystem : EntitySystem
         SubscribeLocalEvent<StatusEffectContainerComponent, EntInsertedIntoContainerMessage>(OnEntityInserted);
         SubscribeLocalEvent<StatusEffectContainerComponent, EntRemovedFromContainerMessage>(OnEntityRemoved);
 
+        SubscribeLocalEvent<RejuvenateRemovedStatusEffectComponent, StatusEffectRelayedEvent<RejuvenateEvent>>(OnRejuvenate);
+
         _containerQuery = GetEntityQuery<StatusEffectContainerComponent>();
         _effectQuery = GetEntityQuery<StatusEffectComponent>();
     }
@@ -115,6 +118,12 @@ public sealed partial class StatusEffectsSystem : EntitySystem
         Dirty(args.Entity, statusComp);
     }
 
+    private void OnRejuvenate(Entity<RejuvenateRemovedStatusEffectComponent> ent,
+        ref StatusEffectRelayedEvent<RejuvenateEvent> args)
+    {
+        PredictedQueueDel(ent.Owner);
+    }
+
     private void SetStatusEffectTime(EntityUid effect, TimeSpan? duration)
     {
         if (!_effectQuery.TryComp(effect, out var effectComp))
index 273a52c0a8ece9f72675cfd527e47625af1030f3..3ce81081c0ebd32c48e30f537cfdd48772c07100 100644 (file)
       components:
       - MobState
 
+# Things that should be removed by rejuvenation should parent to this
+# Also blocks the status effect being added to godmode-ed entities.
 - type: entity
-  parent: StatusEffectBase
+  parent: MobStatusEffectBase
+  id: MobStatusEffectDebuff
+  abstract: true
+  components:
+  - type: RejuvenateRemovedStatusEffect
+
+- type: entity
+  parent: MobStatusEffectDebuff
   id: MobStandStatusEffectBase
   abstract: true
   components:
@@ -36,7 +45,7 @@
 
 # The creature sleeps so heavily that nothing can wake him up. Not even its own death.
 - type: entity
-  parent: MobStatusEffectBase
+  parent: MobStatusEffectDebuff
   id: StatusEffectForcedSleeping
   name: forced sleep
   components:
@@ -46,7 +55,7 @@
 
 # This creature is asleep because it's disconnected from the game.
 - type: entity
-  parent: MobStatusEffectBase
+  parent: MobStatusEffectBase # Not even rejuvenate can cure SSD...
   id: StatusEffectSSDSleeping
   name: forced sleep
   components:
@@ -56,7 +65,7 @@
 
 # Blurs your vision and makes you randomly fall asleep
 - type: entity
-  parent: MobStatusEffectBase
+  parent: MobStatusEffectDebuff
   id: StatusEffectDrowsiness
   name: drowsiness
   components:
@@ -64,7 +73,7 @@
 
 # Adds drugs overlay
 - type: entity
-  parent: MobStatusEffectBase
+  parent: MobStatusEffectDebuff
   id: StatusEffectSeeingRainbow
   name: hallucinations
   components:
index b6fa426f72d256632d647f8b0b89b495dac3a906..a6cbd207246e2e1c852e7c725e84e5aff3475e46 100644 (file)
@@ -1,5 +1,5 @@
 - type: entity
-  parent: MobStatusEffectBase
+  parent: MobStatusEffectDebuff
   id: StatusEffectSlowdown
   abstract: true
   name: slowdown
@@ -35,7 +35,7 @@
 
 # Makes you more slippery, or perhaps less slippery.
 - type: entity
-  parent: MobStatusEffectBase
+  parent: MobStatusEffectDebuff # Debatable if this should be MobStatusEffectBase or not
   id: StatusEffectFriction
   name: friction
   components:
@@ -44,7 +44,7 @@
 # Stunnable Status Effect
 
 - type: entity
-  parent: MobStatusEffectBase
+  parent: MobStatusEffectDebuff
   id: StatusEffectStunned
   name: stunned
   components: