From: sleepyyapril <123355664+sleepyyapril@users.noreply.github.com> Date: Mon, 8 Dec 2025 04:20:42 +0000 (-0400) Subject: TriggerOn(Un)Embed (#41720) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=f1443f0cd7a26747582e2f204309b02b17138827;p=space-station-14.git TriggerOn(Un)Embed (#41720) * 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 --- diff --git a/Content.Shared/Projectiles/EmbedEvent.cs b/Content.Shared/Projectiles/EmbedEvent.cs deleted file mode 100644 index 521a691f45..0000000000 --- a/Content.Shared/Projectiles/EmbedEvent.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Content.Shared.Projectiles; - -/// -/// Raised directed on an entity when it embeds in another entity. -/// -[ByRefEvent] -public readonly record struct EmbedEvent(EntityUid? Shooter, EntityUid Embedded) -{ - public readonly EntityUid? Shooter = Shooter; - - /// - /// Entity that is embedded in. - /// - public readonly EntityUid Embedded = Embedded; -} diff --git a/Content.Shared/Projectiles/EmbedEvents.cs b/Content.Shared/Projectiles/EmbedEvents.cs new file mode 100644 index 0000000000..6f357a33a1 --- /dev/null +++ b/Content.Shared/Projectiles/EmbedEvents.cs @@ -0,0 +1,35 @@ +namespace Content.Shared.Projectiles; + +/// +/// Raised directed on an entity when it embeds in another entity. +/// +[ByRefEvent] +public readonly record struct EmbedEvent(EntityUid? Shooter, EntityUid Embedded) +{ + /// + /// The entity that threw/shot the embed, if any. + /// + public readonly EntityUid? Shooter = Shooter; + + /// + /// Entity that is embedded in. + /// + public readonly EntityUid Embedded = Embedded; +} + +/// +/// Raised directed on an entity when it stops being embedded in another entity. +/// +[ByRefEvent] +public readonly record struct EmbedDetachEvent(EntityUid? Detacher, EntityUid Embedded) +{ + /// + /// The entity that detached the embed, if any. + /// + public readonly EntityUid? Detacher = Detacher; + + /// + /// Entity that it is embedded in. + /// + public readonly EntityUid Embedded = Embedded; +} diff --git a/Content.Shared/Projectiles/SharedProjectileSystem.cs b/Content.Shared/Projectiles/SharedProjectileSystem.cs index 9a44ca545d..c5aaf3135d 100644 --- a/Content.Shared/Projectiles/SharedProjectileSystem.cs +++ b/Content.Shared/Projectiles/SharedProjectileSystem.cs @@ -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(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 index 0000000000..e298d3e378 --- /dev/null +++ b/Content.Shared/Trigger/Components/Triggers/TriggerOnEmbedComponent.cs @@ -0,0 +1,18 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Triggers; + +/// +/// Triggers when this entity first embeds into something. +/// User is the item that was embedded or the actual embed depending on +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class TriggerOnEmbedComponent : BaseTriggerOnXComponent +{ + /// + /// 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. + /// + [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 index 0000000000..ba0dd801f5 --- /dev/null +++ b/Content.Shared/Trigger/Components/Triggers/TriggerOnUnembedComponent.cs @@ -0,0 +1,20 @@ +using Content.Shared.Trigger.Systems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Triggers; + +/// +/// Triggers when this entity gets un-embedded from something. +/// User is the item that was embedded or the actual embed depending on +/// Handled by +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class TriggerOnUnembedComponent : BaseTriggerOnXComponent +{ + /// + /// 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. + /// + [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 index 0000000000..ade48c94a7 --- /dev/null +++ b/Content.Shared/Trigger/Systems/TriggerOnEmbedSystem.cs @@ -0,0 +1,31 @@ +using Content.Shared.Projectiles; +using Content.Shared.Trigger.Components.Triggers; + +namespace Content.Shared.Trigger.Systems; + +/// +/// This handles subscriptions. +/// +public sealed class TriggerOnEmbedSystem : TriggerOnXSystem +{ + /// + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnEmbed); + SubscribeLocalEvent(OnStopEmbed); + } + + private void OnEmbed(Entity ent, ref EmbedEvent args) + { + var user = ent.Comp.UserIsEmbeddedInto ? args.Embedded : args.Shooter; + Trigger.Trigger(ent, user, ent.Comp.KeyOut); + } + + private void OnStopEmbed(Entity ent, ref EmbedDetachEvent args) + { + var user = ent.Comp.UserIsEmbeddedInto ? args.Embedded : args.Detacher; + Trigger.Trigger(ent, user, ent.Comp.KeyOut); + } +}