if (args.Handled)
return;
- // TODO: this pattern is super uncommon, but it might be worth changing GetUsedEntityEvent to be recursive.
- if (TryComp<VirtualItemComponent>(component.ActiveHandEntity, out var virtualItem))
- args.Used = virtualItem.BlockingEntity;
- else
- args.Used = component.ActiveHandEntity;
+ if (component.ActiveHandEntity.HasValue)
+ {
+ // allow for the item to return a different entity, e.g. virtual items
+ RaiseLocalEvent(component.ActiveHandEntity.Value, ref args);
+ }
+
+ args.Used ??= component.ActiveHandEntity;
}
//TODO: Actually shows all items/clothing/etc.
/// <returns>If there is an entity being used.</returns>
public bool TryGetUsedEntity(EntityUid user, [NotNullWhen(true)] out EntityUid? used, bool checkCanUse = true)
{
- var ev = new GetUsedEntityEvent();
+ var ev = new GetUsedEntityEvent(user);
RaiseLocalEvent(user, ref ev);
used = ev.Used;
/// Raised directed by-ref on an entity to determine what item will be used in interactions.
/// </summary>
[ByRefEvent]
- public record struct GetUsedEntityEvent()
+ public record struct GetUsedEntityEvent(EntityUid User)
{
+ public EntityUid User = User;
public EntityUid? Used = null;
public bool Handled => Used != null;
SubscribeLocalEvent<VirtualItemComponent, BeforeRangedInteractEvent>(OnBeforeRangedInteract);
SubscribeLocalEvent<VirtualItemComponent, GettingInteractedWithAttemptEvent>(OnGettingInteractedWithAttemptEvent);
+
+ SubscribeLocalEvent<VirtualItemComponent, GetUsedEntityEvent>(OnGetUsedEntity);
}
/// <summary>
args.Cancelled = true;
}
+ private void OnGetUsedEntity(Entity<VirtualItemComponent> ent, ref GetUsedEntityEvent args)
+ {
+ if (args.Handled)
+ return;
+
+ // if the user is holding the real item the virtual item points to,
+ // we allow them to use it in the interaction
+ foreach (var hand in _handsSystem.EnumerateHands(args.User))
+ {
+ if (hand.HeldEntity == ent.Comp.BlockingEntity)
+ {
+ args.Used = ent.Comp.BlockingEntity;
+ return;
+ }
+ }
+ }
+
#region Hands
/// <summary>