Hand pickup and drop triggers (#39663)

This commit is contained in:
slarticodefast
2025-08-18 01:47:26 +02:00
committed by GitHub
parent 9d32e7db4e
commit e16bca5b18
6 changed files with 114 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Trigger.Components.Triggers;
/// <summary>
/// Triggers an entity when it is equips an item into one of its hand slots.
/// The user is the entity that was equipped.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class TriggerOnDidEquipHandComponent : BaseTriggerOnXComponent;

View File

@@ -0,0 +1,10 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Trigger.Components.Triggers;
/// <summary>
/// Triggers an entity when it is drops an item from one of its hand slots.
/// The user is the entity that was dropped.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class TriggerOnDidUnequipHandComponent : BaseTriggerOnXComponent;

View File

@@ -0,0 +1,10 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Trigger.Components.Triggers;
/// <summary>
/// Triggers an entity when it is dropped from a users hands, or directly removed from a users inventory, but not when moved between hands & inventory.
/// The user is the player that was holding or wearing the item.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class TriggerOnDroppedComponent : BaseTriggerOnXComponent;

View File

@@ -0,0 +1,10 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Trigger.Components.Triggers;
/// <summary>
/// Triggers an item when it is equipped into a hand slot.
/// The user is the entity that picked the item up.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class TriggerOnGotEquippedHandComponent : BaseTriggerOnXComponent;

View File

@@ -0,0 +1,10 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Trigger.Components.Triggers;
/// <summary>
/// Triggers an item when it is dropped from a hand slot.
/// The user is the entity that dropped the item.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class TriggerOnGotUnequippedHandComponent : BaseTriggerOnXComponent;

View File

@@ -0,0 +1,64 @@
using Content.Shared.Hands;
using Content.Shared.Interaction.Events;
using Content.Shared.Trigger.Components.Triggers;
using Robust.Shared.Timing;
namespace Content.Shared.Trigger.Systems;
public sealed partial class HandTriggerSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly TriggerSystem _trigger = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<TriggerOnGotEquippedHandComponent, GotEquippedHandEvent>(OnGotEquipped);
SubscribeLocalEvent<TriggerOnGotUnequippedHandComponent, GotUnequippedHandEvent>(OnGotUnequipped);
SubscribeLocalEvent<TriggerOnDidEquipHandComponent, DidEquipHandEvent>(OnDidEquip);
SubscribeLocalEvent<TriggerOnDidUnequipHandComponent, DidUnequipHandEvent>(OnDidUnequip);
SubscribeLocalEvent<TriggerOnDroppedComponent, DroppedEvent>(OnDropped);
}
private void OnGotEquipped(Entity<TriggerOnGotEquippedHandComponent> ent, ref GotEquippedHandEvent args)
{
// If the entity was equipped on the server (without prediction) then the container change is networked to the client
// which will raise the same event, but the effect of the trigger is already networked on its own. So this guard statement
// prevents triggering twice on the client.
if (_timing.ApplyingState)
return;
_trigger.Trigger(ent.Owner, args.User, ent.Comp.KeyOut);
}
private void OnGotUnequipped(Entity<TriggerOnGotUnequippedHandComponent> ent, ref GotUnequippedHandEvent args)
{
if (_timing.ApplyingState)
return;
_trigger.Trigger(ent.Owner, args.User, ent.Comp.KeyOut);
}
private void OnDidEquip(Entity<TriggerOnDidEquipHandComponent> ent, ref DidEquipHandEvent args)
{
if (_timing.ApplyingState)
return;
_trigger.Trigger(ent.Owner, args.Equipped, ent.Comp.KeyOut);
}
private void OnDidUnequip(Entity<TriggerOnDidUnequipHandComponent> ent, ref DidUnequipHandEvent args)
{
if (_timing.ApplyingState)
return;
_trigger.Trigger(ent.Owner, args.Unequipped, ent.Comp.KeyOut);
}
private void OnDropped(Entity<TriggerOnDroppedComponent> ent, ref DroppedEvent args)
{
// We don't need the guard statement here because this one is not a container event, but raised directly when interacting.
_trigger.Trigger(ent.Owner, args.User, ent.Comp.KeyOut);
}
}