From d939b4dec795ccdc5d94578153d14716ed86f753 Mon Sep 17 00:00:00 2001
From: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
Date: Thu, 14 Aug 2025 16:18:56 +0200
Subject: [PATCH] RemoveComponentsOnTrigger, ToggleComponentsOnTrigger (#39639)
---
.../RemoveComponentsOnTriggerComponent.cs | 35 +++++++++
.../ToggleComponentsOnTriggerComponent.cs | 31 ++++++++
.../Systems/AddComponentsOnTriggerSystem.cs | 33 --------
.../Systems/ComponentsOnTriggerSystem.cs | 76 +++++++++++++++++++
4 files changed, 142 insertions(+), 33 deletions(-)
create mode 100644 Content.Shared/Trigger/Components/Effects/RemoveComponentsOnTriggerComponent.cs
create mode 100644 Content.Shared/Trigger/Components/Effects/ToggleComponentsOnTriggerComponent.cs
delete mode 100644 Content.Shared/Trigger/Systems/AddComponentsOnTriggerSystem.cs
create mode 100644 Content.Shared/Trigger/Systems/ComponentsOnTriggerSystem.cs
diff --git a/Content.Shared/Trigger/Components/Effects/RemoveComponentsOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/RemoveComponentsOnTriggerComponent.cs
new file mode 100644
index 0000000000..e69bf42a15
--- /dev/null
+++ b/Content.Shared/Trigger/Components/Effects/RemoveComponentsOnTriggerComponent.cs
@@ -0,0 +1,35 @@
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.Trigger.Components.Effects;
+
+///
+/// Removes the specified components when triggered.
+/// If TargetUser is true they will be from the user instead.
+///
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class RemoveComponentsOnTriggerComponent : BaseXOnTriggerComponent
+{
+ ///
+ /// The list of components that will be removed.
+ ///
+ ///
+ /// TODO: Using a ComponentRegistry for this is cursed because it stores all the datafields along with it,
+ /// but ComponentNameSerializer will complain if you have components that are not in shared.
+ ///
+ [DataField(required: true)]
+ public ComponentRegistry Components = new();
+
+ ///
+ /// If this component has been triggered at least once already.
+ /// If this is true the components have been removed.
+ ///
+ [DataField, AutoNetworkedField]
+ public bool Triggered = false;
+
+ ///
+ /// If this effect can only be triggered once.
+ ///
+ [DataField, AutoNetworkedField]
+ public bool TriggerOnce = false;
+}
diff --git a/Content.Shared/Trigger/Components/Effects/ToggleComponentsOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/ToggleComponentsOnTriggerComponent.cs
new file mode 100644
index 0000000000..4ce5652318
--- /dev/null
+++ b/Content.Shared/Trigger/Components/Effects/ToggleComponentsOnTriggerComponent.cs
@@ -0,0 +1,31 @@
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.Trigger.Components.Effects;
+
+///
+/// Adds or removes the specified components when triggered.
+/// If TargetUser is true they will be added to or removed from the user instead.
+///
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class ToggleComponentsOnTriggerComponent : BaseXOnTriggerComponent
+{
+ ///
+ /// The list of components that will be added/removed.
+ ///
+ [DataField(required: true)]
+ public ComponentRegistry Components = new();
+
+ ///
+ /// Are the components currently added?
+ ///
+ [DataField, AutoNetworkedField]
+ public bool ComponentsAdded;
+
+ ///
+ /// Should components that already exist on the entity be overwritten?
+ /// (They will still be removed when toggling again).
+ ///
+ [DataField, AutoNetworkedField]
+ public bool RemoveExisting = false;
+}
diff --git a/Content.Shared/Trigger/Systems/AddComponentsOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/AddComponentsOnTriggerSystem.cs
deleted file mode 100644
index 908307dad0..0000000000
--- a/Content.Shared/Trigger/Systems/AddComponentsOnTriggerSystem.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using Content.Shared.Trigger.Components.Effects;
-
-namespace Content.Shared.Trigger.Systems;
-
-public sealed partial class AddComponentsOnTriggerSystem : EntitySystem
-{
- public override void Initialize()
- {
- base.Initialize();
-
- SubscribeLocalEvent(OnTrigger);
- }
-
- private void OnTrigger(Entity ent, ref TriggerEvent args)
- {
- if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))
- return;
-
- var target = ent.Comp.TargetUser ? args.User : ent.Owner;
-
- if (target == null)
- return;
-
- if (ent.Comp.TriggerOnce && ent.Comp.Triggered)
- return;
-
- EntityManager.AddComponents(target.Value, ent.Comp.Components, ent.Comp.RemoveExisting);
- ent.Comp.Triggered = true;
- Dirty(ent);
-
- args.Handled = true;
- }
-}
diff --git a/Content.Shared/Trigger/Systems/ComponentsOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/ComponentsOnTriggerSystem.cs
new file mode 100644
index 0000000000..f4e144b7ce
--- /dev/null
+++ b/Content.Shared/Trigger/Systems/ComponentsOnTriggerSystem.cs
@@ -0,0 +1,76 @@
+using Content.Shared.Trigger.Components.Effects;
+
+namespace Content.Shared.Trigger.Systems;
+
+public sealed partial class ComponentsOnTriggerSystem : EntitySystem
+{
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(HandleAddTrigger);
+ SubscribeLocalEvent(HandleRemoveTrigger);
+ SubscribeLocalEvent(HandleToggleTrigger);
+ }
+
+ private void HandleAddTrigger(Entity ent, ref TriggerEvent args)
+ {
+ if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))
+ return;
+
+ var target = ent.Comp.TargetUser ? args.User : ent.Owner;
+
+ if (target == null)
+ return;
+
+ if (ent.Comp.TriggerOnce && ent.Comp.Triggered)
+ return;
+
+ EntityManager.AddComponents(target.Value, ent.Comp.Components, ent.Comp.RemoveExisting);
+ ent.Comp.Triggered = true;
+ Dirty(ent);
+
+ args.Handled = true;
+ }
+
+ private void HandleRemoveTrigger(Entity ent, ref TriggerEvent args)
+ {
+ if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))
+ return;
+
+ var target = ent.Comp.TargetUser ? args.User : ent.Owner;
+
+ if (target == null)
+ return;
+
+ if (ent.Comp.TriggerOnce && ent.Comp.Triggered)
+ return;
+
+ EntityManager.RemoveComponents(target.Value, ent.Comp.Components);
+ ent.Comp.Triggered = true;
+ Dirty(ent);
+
+ args.Handled = true;
+ }
+
+ private void HandleToggleTrigger(Entity ent, ref TriggerEvent args)
+ {
+ if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))
+ return;
+
+ var target = ent.Comp.TargetUser ? args.User : ent.Owner;
+
+ if (target == null)
+ return;
+
+ if (!ent.Comp.ComponentsAdded)
+ EntityManager.AddComponents(target.Value, ent.Comp.Components, ent.Comp.RemoveExisting);
+ else
+ EntityManager.RemoveComponents(target.Value, ent.Comp.Components);
+
+ ent.Comp.ComponentsAdded = !ent.Comp.ComponentsAdded;
+ Dirty(ent);
+
+ args.Handled = true;
+ }
+}
--
2.51.2