Throwing triggers (#39650)

throw triggers
This commit is contained in:
slarticodefast
2025-08-15 07:33:37 +02:00
committed by GitHub
parent 7a31e3c1f8
commit 7a3026b4f8
8 changed files with 68 additions and 52 deletions

View File

@@ -3,7 +3,7 @@ using Robust.Shared.GameStates;
namespace Content.Shared.Sound.Components; namespace Content.Shared.Sound.Components;
/// <summary> /// <summary>
/// Simple sound emitter that emits sound on ThrowEvent /// Simple sound emitter that emits sound on ThrownEvent
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class EmitSoundOnThrowComponent : BaseEmitSoundComponent; public sealed partial class EmitSoundOnThrowComponent : BaseEmitSoundComponent;

View File

@@ -1,39 +1,25 @@
namespace Content.Shared.Throwing namespace Content.Shared.Throwing;
{
/// <summary>
/// Base class for all throw events.
/// </summary>
public abstract class ThrowEvent : HandledEntityEventArgs
{
public readonly EntityUid Thrown;
public readonly EntityUid Target;
public ThrownItemComponent Component;
public ThrowEvent(EntityUid thrown, EntityUid target, ThrownItemComponent component) /// <summary>
{ /// Raised on an entity after it has thrown something.
Thrown = thrown; /// </summary>
Target = target; [ByRefEvent]
Component = component; public readonly record struct ThrowEvent(EntityUid? User, EntityUid Thrown);
}
}
/// <summary> /// <summary>
/// Raised directed on the target entity being hit by the thrown entity. /// Raised on an entity after it has been thrown.
/// </summary> /// </summary>
public sealed class ThrowHitByEvent : ThrowEvent [ByRefEvent]
{ public readonly record struct ThrownEvent(EntityUid? User, EntityUid Thrown);
public ThrowHitByEvent(EntityUid thrown, EntityUid target, ThrownItemComponent component) : base(thrown, target, component)
{
}
}
/// <summary> /// <summary>
/// Raised directed on the thrown entity that hits another. /// Raised directed on the target entity being hit by the thrown entity.
/// </summary> /// </summary>
public sealed class ThrowDoHitEvent : ThrowEvent [ByRefEvent]
{ public readonly record struct ThrowHitByEvent(EntityUid Thrown, EntityUid Target, ThrownItemComponent Component);
public ThrowDoHitEvent(EntityUid thrown, EntityUid target, ThrownItemComponent component) : base(thrown, target, component)
{ /// <summary>
} /// Raised directed on the thrown entity that hits another.
} /// </summary>
} [ByRefEvent]
public readonly record struct ThrowDoHitEvent(EntityUid Thrown, EntityUid Target, ThrownItemComponent Component);

View File

@@ -192,8 +192,6 @@ public sealed class ThrowingSystem : EntitySystem
} }
} }
var throwEvent = new ThrownEvent(user, uid);
RaiseLocalEvent(uid, ref throwEvent, true);
if (user != null) if (user != null)
_adminLogger.Add(LogType.Throw, LogImpact.Low, $"{ToPrettyString(user.Value):user} threw {ToPrettyString(uid):entity}"); _adminLogger.Add(LogType.Throw, LogImpact.Low, $"{ToPrettyString(user.Value):user} threw {ToPrettyString(uid):entity}");
@@ -206,6 +204,14 @@ public sealed class ThrowingSystem : EntitySystem
var impulseVector = direction.Normalized() * throwSpeed * physics.Mass; var impulseVector = direction.Normalized() * throwSpeed * physics.Mass;
_physics.ApplyLinearImpulse(uid, impulseVector, body: physics); _physics.ApplyLinearImpulse(uid, impulseVector, body: physics);
var thrownEvent = new ThrownEvent(user, uid);
RaiseLocalEvent(uid, ref thrownEvent, true);
if (user != null)
{
var throwEvent = new ThrowEvent(user, uid);
RaiseLocalEvent(user.Value, ref throwEvent, true);
}
if (comp.LandTime == null || comp.LandTime <= TimeSpan.Zero) if (comp.LandTime == null || comp.LandTime <= TimeSpan.Zero)
{ {
_thrownSystem.LandComponent(uid, comp, physics, playSound); _thrownSystem.LandComponent(uid, comp, physics, playSound);

View File

@@ -1,10 +0,0 @@
using JetBrains.Annotations;
namespace Content.Shared.Throwing;
/// <summary>
/// Raised on thrown entity.
/// </summary>
[PublicAPI]
[ByRefEvent]
public readonly record struct ThrownEvent(EntityUid? User, EntityUid Thrown);

View File

@@ -140,8 +140,10 @@ namespace Content.Shared.Throwing
_adminLogger.Add(LogType.ThrowHit, LogImpact.Low, _adminLogger.Add(LogType.ThrowHit, LogImpact.Low,
$"{ToPrettyString(thrown):thrown} thrown by {ToPrettyString(component.Thrower.Value):thrower} hit {ToPrettyString(target):target}."); $"{ToPrettyString(thrown):thrown} thrown by {ToPrettyString(component.Thrower.Value):thrower} hit {ToPrettyString(target):target}.");
RaiseLocalEvent(target, new ThrowHitByEvent(thrown, target, component), true); var hitByEv = new ThrowHitByEvent(thrown, target, component);
RaiseLocalEvent(thrown, new ThrowDoHitEvent(thrown, target, component), true); var doHitEv = new ThrowDoHitEvent(thrown, target, component);
RaiseLocalEvent(target, ref hitByEv, true);
RaiseLocalEvent(thrown, ref doHitEv, true);
} }
public override void Update(float frameTime) public override void Update(float frameTime)

View File

@@ -0,0 +1,10 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Trigger.Components.Triggers;
/// <summary>
/// Triggers when after an entity has thrown something.
/// The user is the thrown item.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class TriggerOnThrowComponent : BaseTriggerOnXComponent;

View File

@@ -0,0 +1,10 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Trigger.Components.Triggers;
/// <summary>
/// Triggers when an entity was thrown.
/// The user is the thrower.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class TriggerOnThrownComponent : BaseTriggerOnXComponent;

View File

@@ -2,6 +2,7 @@
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Interaction.Events; using Content.Shared.Interaction.Events;
using Content.Shared.Item.ItemToggle.Components; using Content.Shared.Item.ItemToggle.Components;
using Content.Shared.Throwing;
using Content.Shared.Trigger.Components.Triggers; using Content.Shared.Trigger.Components.Triggers;
using Content.Shared.Trigger.Components.Effects; using Content.Shared.Trigger.Components.Effects;
@@ -12,10 +13,11 @@ public sealed partial class TriggerSystem
private void InitializeInteraction() private void InitializeInteraction()
{ {
SubscribeLocalEvent<TriggerOnExaminedComponent, ExaminedEvent>(OnExamined); SubscribeLocalEvent<TriggerOnExaminedComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<TriggerOnActivateComponent, ActivateInWorldEvent>(OnActivate); SubscribeLocalEvent<TriggerOnActivateComponent, ActivateInWorldEvent>(OnActivate);
SubscribeLocalEvent<TriggerOnUseComponent, UseInHandEvent>(OnUse); SubscribeLocalEvent<TriggerOnUseComponent, UseInHandEvent>(OnUse);
SubscribeLocalEvent<TriggerOnInteractHandComponent, InteractHandEvent>(OnInteractHand); SubscribeLocalEvent<TriggerOnInteractHandComponent, InteractHandEvent>(OnInteractHand);
SubscribeLocalEvent<TriggerOnThrowComponent, ThrowEvent>(OnThrow);
SubscribeLocalEvent<TriggerOnThrownComponent, ThrownEvent>(OnThrown);
SubscribeLocalEvent<ItemToggleOnTriggerComponent, TriggerEvent>(HandleItemToggleOnTrigger); SubscribeLocalEvent<ItemToggleOnTriggerComponent, TriggerEvent>(HandleItemToggleOnTrigger);
SubscribeLocalEvent<AnchorOnTriggerComponent, TriggerEvent>(HandleAnchorOnTrigger); SubscribeLocalEvent<AnchorOnTriggerComponent, TriggerEvent>(HandleAnchorOnTrigger);
@@ -57,6 +59,16 @@ public sealed partial class TriggerSystem
args.Handled = true; args.Handled = true;
} }
private void OnThrow(Entity<TriggerOnThrowComponent> ent, ref ThrowEvent args)
{
Trigger(ent.Owner, args.Thrown, ent.Comp.KeyOut);
}
private void OnThrown(Entity<TriggerOnThrownComponent> ent, ref ThrownEvent args)
{
Trigger(ent.Owner, args.User, ent.Comp.KeyOut);
}
private void HandleItemToggleOnTrigger(Entity<ItemToggleOnTriggerComponent> ent, ref TriggerEvent args) private void HandleItemToggleOnTrigger(Entity<ItemToggleOnTriggerComponent> ent, ref TriggerEvent args)
{ {
if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key)) if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))