Fix inventory relay by-ref events (#20816)

* Fix inventory relay ref events

* this works too (avoid duplication)

---------

Co-authored-by: Slava0135 <super.novalskiy_0135@inbox.ru>
This commit is contained in:
Leon Friedrich
2023-10-12 03:31:10 +11:00
committed by GitHub
parent 6d34f19030
commit 1f21826c21
3 changed files with 20 additions and 15 deletions

View File

@@ -116,8 +116,7 @@ public sealed partial class ExplosionSystem : EntitySystem
private void RelayedResistance(EntityUid uid, ExplosionResistanceComponent component, private void RelayedResistance(EntityUid uid, ExplosionResistanceComponent component,
InventoryRelayedEvent<GetExplosionResistanceEvent> args) InventoryRelayedEvent<GetExplosionResistanceEvent> args)
{ {
var a = args.Args; OnGetResistance(uid, component, ref args.Args);
OnGetResistance(uid, component, ref a);
} }
private void OnGetResistance(EntityUid uid, ExplosionResistanceComponent component, ref GetExplosionResistanceEvent args) private void OnGetResistance(EntityUid uid, ExplosionResistanceComponent component, ref GetExplosionResistanceEvent args)

View File

@@ -24,12 +24,14 @@ public partial class InventorySystem
SubscribeLocalEvent<InventoryComponent, ElectrocutionAttemptEvent>(RelayInventoryEvent); SubscribeLocalEvent<InventoryComponent, ElectrocutionAttemptEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, SlipAttemptEvent>(RelayInventoryEvent); SubscribeLocalEvent<InventoryComponent, SlipAttemptEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, RefreshMovementSpeedModifiersEvent>(RelayInventoryEvent); SubscribeLocalEvent<InventoryComponent, RefreshMovementSpeedModifiersEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, GetExplosionResistanceEvent>(RefRelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, BeforeStripEvent>(RelayInventoryEvent); SubscribeLocalEvent<InventoryComponent, BeforeStripEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, SeeIdentityAttemptEvent>(RelayInventoryEvent); SubscribeLocalEvent<InventoryComponent, SeeIdentityAttemptEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, ModifyChangedTemperatureEvent>(RelayInventoryEvent); SubscribeLocalEvent<InventoryComponent, ModifyChangedTemperatureEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, GetDefaultRadioChannelEvent>(RelayInventoryEvent); SubscribeLocalEvent<InventoryComponent, GetDefaultRadioChannelEvent>(RelayInventoryEvent);
// by-ref events
SubscribeLocalEvent<InventoryComponent, GetExplosionResistanceEvent>(RefRelayInventoryEvent);
// Eye/vision events // Eye/vision events
SubscribeLocalEvent<InventoryComponent, CanSeeAttemptEvent>(RelayInventoryEvent); SubscribeLocalEvent<InventoryComponent, CanSeeAttemptEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, GetEyeProtectionEvent>(RelayInventoryEvent); SubscribeLocalEvent<InventoryComponent, GetEyeProtectionEvent>(RelayInventoryEvent);
@@ -41,22 +43,24 @@ public partial class InventorySystem
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowHungerIconsComponent>>(RelayInventoryEvent); SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowHungerIconsComponent>>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowThirstIconsComponent>>(RelayInventoryEvent); SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowThirstIconsComponent>>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, GetVerbsEvent<EquipmentVerb>>(OnGetStrippingVerbs); SubscribeLocalEvent<InventoryComponent, GetVerbsEvent<EquipmentVerb>>(OnGetEquipmentVerbs);
} }
protected void RefRelayInventoryEvent<T>(EntityUid uid, InventoryComponent component, ref T args) where T : IInventoryRelayEvent protected void RefRelayInventoryEvent<T>(EntityUid uid, InventoryComponent component, ref T args) where T : IInventoryRelayEvent
{ {
// Just so I don't have to update 20 morbillion events at once.
if (args.TargetSlots == SlotFlags.NONE)
return;
var containerEnumerator = new ContainerSlotEnumerator(uid, component.TemplateId, _prototypeManager, this, args.TargetSlots); var containerEnumerator = new ContainerSlotEnumerator(uid, component.TemplateId, _prototypeManager, this, args.TargetSlots);
// this copies the by-ref event
var ev = new InventoryRelayedEvent<T>(args); var ev = new InventoryRelayedEvent<T>(args);
while (containerEnumerator.MoveNext(out var container)) while (containerEnumerator.MoveNext(out var container))
{ {
if (!container.ContainedEntity.HasValue) continue; if (!container.ContainedEntity.HasValue) continue;
RaiseLocalEvent(container.ContainedEntity.Value, ev, broadcast: false); RaiseLocalEvent(container.ContainedEntity.Value, ev);
} }
// and now we copy it back
args = ev.Args;
} }
protected void RelayInventoryEvent<T>(EntityUid uid, InventoryComponent component, T args) where T : IInventoryRelayEvent protected void RelayInventoryEvent<T>(EntityUid uid, InventoryComponent component, T args) where T : IInventoryRelayEvent
@@ -69,11 +73,11 @@ public partial class InventorySystem
while (containerEnumerator.MoveNext(out var container)) while (containerEnumerator.MoveNext(out var container))
{ {
if (!container.ContainedEntity.HasValue) continue; if (!container.ContainedEntity.HasValue) continue;
RaiseLocalEvent(container.ContainedEntity.Value, ev, broadcast: false); RaiseLocalEvent(container.ContainedEntity.Value, ev);
} }
} }
private void OnGetStrippingVerbs(EntityUid uid, InventoryComponent component, GetVerbsEvent<EquipmentVerb> args) private void OnGetEquipmentVerbs(EntityUid uid, InventoryComponent component, GetVerbsEvent<EquipmentVerb> args)
{ {
// Automatically relay stripping related verbs to all equipped clothing. // Automatically relay stripping related verbs to all equipped clothing.
@@ -112,7 +116,7 @@ public partial class InventorySystem
/// </remarks> /// </remarks>
public sealed class InventoryRelayedEvent<TEvent> : EntityEventArgs public sealed class InventoryRelayedEvent<TEvent> : EntityEventArgs
{ {
public readonly TEvent Args; public TEvent Args;
public InventoryRelayedEvent(TEvent args) public InventoryRelayedEvent(TEvent args)
{ {

View File

@@ -1,5 +1,6 @@
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Interaction.Events; using Content.Shared.Interaction.Events;
using Content.Shared.Inventory;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -349,9 +350,10 @@ namespace Content.Shared.Verbs
} }
/// <summary> /// <summary>
/// Verbs specifically for interactions that occur with equipped entities. These verbs should be accessible via /// Verbs specifically for interactions that occur with equipped entities. These verbs are unique in that they
/// the stripping UI, and may optionally also be accessible via a verb on the equipee if the via inventory relay /// can be used via the stripping UI. Additionally, when getting verbs on an entity with an inventory it will
/// events.get-verbs event. /// these automatically relay the <see cref="GetVerbsEvent{EquipmentVerb}"/> event to all equipped items via a
/// <see cref="InventoryRelayedEvent{T}"/>.
/// </summary> /// </summary>
[Serializable, NetSerializable] [Serializable, NetSerializable]
public sealed class EquipmentVerb : Verb public sealed class EquipmentVerb : Verb