]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
TriggerOn(Un)Embed (#41720)
authorsleepyyapril <123355664+sleepyyapril@users.noreply.github.com>
Mon, 8 Dec 2025 04:20:42 +0000 (00:20 -0400)
committerGitHub <noreply@github.com>
Mon, 8 Dec 2025 04:20:42 +0000 (04:20 +0000)
* feat: TriggerOn(Un)Embed

* feat: StopEmbedEvent

* fix: forgot initialize

* chore: better naming

* chore: oops

* Update Content.Shared/Trigger/Components/Triggers/TriggerOnUnembedComponent.cs

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Update Content.Shared/Projectiles/EmbedEvents.cs

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* review

im lazy

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Update Content.Shared/Trigger/Components/Triggers/TriggerOnEmbedComponent.cs

* chore: docs

* comment change

---------

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
Co-authored-by: iaada <iaada@users.noreply.github.com>
Content.Shared/Projectiles/EmbedEvent.cs [deleted file]
Content.Shared/Projectiles/EmbedEvents.cs [new file with mode: 0644]
Content.Shared/Projectiles/SharedProjectileSystem.cs
Content.Shared/Trigger/Components/Triggers/TriggerOnEmbedComponent.cs [new file with mode: 0644]
Content.Shared/Trigger/Components/Triggers/TriggerOnUnembedComponent.cs [new file with mode: 0644]
Content.Shared/Trigger/Systems/TriggerOnEmbedSystem.cs [new file with mode: 0644]

diff --git a/Content.Shared/Projectiles/EmbedEvent.cs b/Content.Shared/Projectiles/EmbedEvent.cs
deleted file mode 100644 (file)
index 521a691..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace Content.Shared.Projectiles;
-
-/// <summary>
-/// Raised directed on an entity when it embeds in another entity.
-/// </summary>
-[ByRefEvent]
-public readonly record struct EmbedEvent(EntityUid? Shooter, EntityUid Embedded)
-{
-    public readonly EntityUid? Shooter = Shooter;
-
-    /// <summary>
-    /// Entity that is embedded in.
-    /// </summary>
-    public readonly EntityUid Embedded = Embedded;
-}
diff --git a/Content.Shared/Projectiles/EmbedEvents.cs b/Content.Shared/Projectiles/EmbedEvents.cs
new file mode 100644 (file)
index 0000000..6f357a3
--- /dev/null
@@ -0,0 +1,35 @@
+namespace Content.Shared.Projectiles;
+
+/// <summary>
+/// Raised directed on an entity when it embeds in another entity.
+/// </summary>
+[ByRefEvent]
+public readonly record struct EmbedEvent(EntityUid? Shooter, EntityUid Embedded)
+{
+    /// <summary>
+    /// The entity that threw/shot the embed, if any.
+    /// </summary>
+    public readonly EntityUid? Shooter = Shooter;
+
+    /// <summary>
+    /// Entity that is embedded in.
+    /// </summary>
+    public readonly EntityUid Embedded = Embedded;
+}
+
+/// <summary>
+/// Raised directed on an entity when it stops being embedded in another entity.
+/// </summary>
+[ByRefEvent]
+public readonly record struct EmbedDetachEvent(EntityUid? Detacher, EntityUid Embedded)
+{
+    /// <summary>
+    /// The entity that detached the embed, if any.
+    /// </summary>
+    public readonly EntityUid? Detacher = Detacher;
+
+    /// <summary>
+    /// Entity that it is embedded in.
+    /// </summary>
+    public readonly EntityUid Embedded = Embedded;
+}
index 9a44ca545d00903a961eeb543a04ecec7da516d7..c5aaf3135dc9f2dafc93c338fb65b02d00c72eb1 100644 (file)
@@ -135,6 +135,8 @@ public abstract partial class SharedProjectileSystem : EntitySystem
         if (component.EmbeddedIntoUid == null)
             return; // the entity is not embedded, so do nothing
 
+        var embeddedInto = component.EmbeddedIntoUid;
+
         if (TryComp<EmbeddedContainerComponent>(component.EmbeddedIntoUid.Value, out var embeddedContainer))
         {
             embeddedContainer.EmbeddedObjects.Remove(uid);
@@ -168,6 +170,9 @@ public abstract partial class SharedProjectileSystem : EntitySystem
             Dirty(uid, projectile);
         }
 
+        var ev = new EmbedDetachEvent(user, embeddedInto.Value);
+        RaiseLocalEvent(uid, ref ev);
+
         if (user != null)
         {
             // Land it just coz uhhh yeah
diff --git a/Content.Shared/Trigger/Components/Triggers/TriggerOnEmbedComponent.cs b/Content.Shared/Trigger/Components/Triggers/TriggerOnEmbedComponent.cs
new file mode 100644 (file)
index 0000000..e298d3e
--- /dev/null
@@ -0,0 +1,18 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Trigger.Components.Triggers;
+
+/// <summary>
+/// Triggers when this entity first embeds into something.
+/// User is the item that was embedded or the actual embed depending on <see cref="UserIsEmbed"/>
+/// </summary>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class TriggerOnEmbedComponent : BaseTriggerOnXComponent
+{
+    /// <summary>
+    /// If false the trigger user will be the mob that shot the embeddable projectile.
+    /// If true, the trigger user will be the entity the projectile was embedded into.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public bool UserIsEmbeddedInto;
+}
diff --git a/Content.Shared/Trigger/Components/Triggers/TriggerOnUnembedComponent.cs b/Content.Shared/Trigger/Components/Triggers/TriggerOnUnembedComponent.cs
new file mode 100644 (file)
index 0000000..ba0dd80
--- /dev/null
@@ -0,0 +1,20 @@
+using Content.Shared.Trigger.Systems;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Trigger.Components.Triggers;
+
+/// <summary>
+/// Triggers when this entity gets un-embedded from something.
+/// User is the item that was embedded or the actual embed depending on <see cref="UserIsEmbed"/>
+/// Handled by <seealso cref="TriggerOnEmbedSystem"/>
+/// </summary>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class TriggerOnUnembedComponent : BaseTriggerOnXComponent
+{
+    /// <summary>
+    /// If false the trigger user will be the one that detaches the embedded entity.
+    /// If true, the trigger user will be the entity the projectile was embedded into.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public bool UserIsEmbeddedInto;
+}
diff --git a/Content.Shared/Trigger/Systems/TriggerOnEmbedSystem.cs b/Content.Shared/Trigger/Systems/TriggerOnEmbedSystem.cs
new file mode 100644 (file)
index 0000000..ade48c9
--- /dev/null
@@ -0,0 +1,31 @@
+using Content.Shared.Projectiles;
+using Content.Shared.Trigger.Components.Triggers;
+
+namespace Content.Shared.Trigger.Systems;
+
+/// <summary>
+/// This handles <see cref="TriggerOnEmbedComponent"/> subscriptions.
+/// </summary>
+public sealed class TriggerOnEmbedSystem : TriggerOnXSystem
+{
+    /// <inheritdoc/>
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<TriggerOnEmbedComponent, EmbedEvent>(OnEmbed);
+        SubscribeLocalEvent<TriggerOnUnembedComponent, EmbedDetachEvent>(OnStopEmbed);
+    }
+
+    private void OnEmbed(Entity<TriggerOnEmbedComponent> ent, ref EmbedEvent args)
+    {
+        var user = ent.Comp.UserIsEmbeddedInto ? args.Embedded : args.Shooter;
+        Trigger.Trigger(ent, user, ent.Comp.KeyOut);
+    }
+
+    private void OnStopEmbed(Entity<TriggerOnUnembedComponent> ent, ref EmbedDetachEvent args)
+    {
+        var user = ent.Comp.UserIsEmbeddedInto ? args.Embedded : args.Detacher;
+        Trigger.Trigger(ent, user, ent.Comp.KeyOut);
+    }
+}