+++ /dev/null
-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;
-}
--- /dev/null
+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;
+}
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);
Dirty(uid, projectile);
}
+ var ev = new EmbedDetachEvent(user, embeddedInto.Value);
+ RaiseLocalEvent(uid, ref ev);
+
if (user != null)
{
// Land it just coz uhhh yeah
--- /dev/null
+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;
+}
--- /dev/null
+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;
+}
--- /dev/null
+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);
+ }
+}