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 <iaada@users.noreply.github.com>
This commit is contained in:
sleepyyapril
2025-12-08 00:20:42 -04:00
committed by GitHub
parent 25bb98c1a2
commit f1443f0cd7
6 changed files with 109 additions and 15 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View 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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
}
}