diff --git a/Content.Server/Atmos/PressureEvent.cs b/Content.Server/Atmos/PressureEvent.cs index 57cf060df1..72df9a01f4 100644 --- a/Content.Server/Atmos/PressureEvent.cs +++ b/Content.Server/Atmos/PressureEvent.cs @@ -1,8 +1,9 @@ -using Robust.Shared.GameObjects; +using Content.Shared.Inventory; +using Robust.Shared.GameObjects; namespace Content.Server.Atmos { - public abstract class PressureEvent : EntityEventArgs + public abstract class PressureEvent : EntityEventArgs, IInventoryRelayEvent { /// /// The environment pressure. @@ -28,6 +29,11 @@ namespace Content.Server.Atmos /// public float Multiplier { get; set; } = 1f; + /// + /// The inventory slots that should be checked for pressure protecting equipment. + /// + public SlotFlags TargetSlots { get; } = ~SlotFlags.POCKET; + protected PressureEvent(float pressure) { Pressure = pressure; diff --git a/Content.Server/Temperature/Systems/TemperatureSystem.cs b/Content.Server/Temperature/Systems/TemperatureSystem.cs index eee2476d7e..8c044ef3dc 100644 --- a/Content.Server/Temperature/Systems/TemperatureSystem.cs +++ b/Content.Server/Temperature/Systems/TemperatureSystem.cs @@ -8,6 +8,7 @@ using Content.Server.Temperature.Components; using Content.Shared.Alert; using Content.Shared.Damage; using Content.Shared.Database; +using Content.Shared.Inventory; using Robust.Shared.GameObjects; using Robust.Shared.IoC; @@ -212,8 +213,10 @@ namespace Content.Server.Temperature.Systems } } - public class ModifyChangedTemperatureEvent : EntityEventArgs + public class ModifyChangedTemperatureEvent : EntityEventArgs, IInventoryRelayEvent { + public SlotFlags TargetSlots { get; } = ~SlotFlags.POCKET; + public float TemperatureDelta; public ModifyChangedTemperatureEvent(float temperature) diff --git a/Content.Shared/Damage/Systems/DamageableSystem.cs b/Content.Shared/Damage/Systems/DamageableSystem.cs index 16b409df8d..6a84fe4cfc 100644 --- a/Content.Shared/Damage/Systems/DamageableSystem.cs +++ b/Content.Shared/Damage/Systems/DamageableSystem.cs @@ -1,6 +1,7 @@ using System.Linq; using Content.Shared.Damage.Prototypes; using Content.Shared.FixedPoint; +using Content.Shared.Inventory; using Robust.Shared.GameObjects; using Robust.Shared.GameStates; using Robust.Shared.IoC; @@ -216,8 +217,11 @@ namespace Content.Shared.Damage /// /// For example, armor. /// - public class DamageModifyEvent : EntityEventArgs + public class DamageModifyEvent : EntityEventArgs, IInventoryRelayEvent { + // Whenever locational damage is a thing, this should just check only that bit of armour. + public SlotFlags TargetSlots { get; } = ~SlotFlags.POCKET; + public DamageSpecifier Damage; public DamageModifyEvent(DamageSpecifier damage) diff --git a/Content.Shared/Electrocution/ElectrocutionEvents.cs b/Content.Shared/Electrocution/ElectrocutionEvents.cs index 7d9d48320c..d057c7c8b1 100644 --- a/Content.Shared/Electrocution/ElectrocutionEvents.cs +++ b/Content.Shared/Electrocution/ElectrocutionEvents.cs @@ -1,9 +1,12 @@ +using Content.Shared.Inventory; using Robust.Shared.GameObjects; namespace Content.Shared.Electrocution { - public class ElectrocutionAttemptEvent : CancellableEntityEventArgs + public class ElectrocutionAttemptEvent : CancellableEntityEventArgs, IInventoryRelayEvent { + public SlotFlags TargetSlots { get; } = ~SlotFlags.POCKET; + public readonly EntityUid TargetUid; public readonly EntityUid? SourceUid; public float SiemensCoefficient = 1f; diff --git a/Content.Shared/Inventory/InventorySystem.Relay.cs b/Content.Shared/Inventory/InventorySystem.Relay.cs index 5be3240681..7b473f3b07 100644 --- a/Content.Shared/Inventory/InventorySystem.Relay.cs +++ b/Content.Shared/Inventory/InventorySystem.Relay.cs @@ -16,9 +16,9 @@ public partial class InventorySystem SubscribeLocalEvent(RelayInventoryEvent); } - protected void RelayInventoryEvent(EntityUid uid, InventoryComponent component, T args) where T : EntityEventArgs + protected void RelayInventoryEvent(EntityUid uid, InventoryComponent component, T args) where T : EntityEventArgs, IInventoryRelayEvent { - var containerEnumerator = new ContainerSlotEnumerator(uid, component.TemplateId, _prototypeManager, this); + var containerEnumerator = new ContainerSlotEnumerator(uid, component.TemplateId, _prototypeManager, this, args.TargetSlots); while(containerEnumerator.MoveNext(out var container)) { if(!container.ContainedEntity.HasValue) continue; @@ -26,3 +26,18 @@ public partial class InventorySystem } } } + +/// +/// Events that should be relayed to inventory slots should implement this interface. +/// +public interface IInventoryRelayEvent +{ + /// + /// What inventory slots should this event be relayed to, if any? + /// + /// + /// In general you may want to exclude , given that those items are not truly + /// "equipped" by the user. + /// + public SlotFlags TargetSlots { get; } +} diff --git a/Content.Shared/Inventory/InventorySystem.Slots.cs b/Content.Shared/Inventory/InventorySystem.Slots.cs index fa15414aa9..772e8da2ba 100644 --- a/Content.Shared/Inventory/InventorySystem.Slots.cs +++ b/Content.Shared/Inventory/InventorySystem.Slots.cs @@ -86,32 +86,38 @@ public partial class InventorySystem : EntitySystem private readonly InventorySystem _inventorySystem; private readonly EntityUid _uid; private readonly SlotDefinition[] _slots; - private int _nextIdx = int.MaxValue; + private readonly SlotFlags _flags; + private int _nextIdx = 0; - public ContainerSlotEnumerator(EntityUid uid, string prototypeId, IPrototypeManager prototypeManager, InventorySystem inventorySystem) + public ContainerSlotEnumerator(EntityUid uid, string prototypeId, IPrototypeManager prototypeManager, InventorySystem inventorySystem, SlotFlags flags = SlotFlags.All) { _uid = uid; _inventorySystem = inventorySystem; + _flags = flags; + if (prototypeManager.TryIndex(prototypeId, out var prototype)) - { _slots = prototype.Slots; - if(_slots.Length > 0) - _nextIdx = 0; - } else - { _slots = Array.Empty(); - } } public bool MoveNext([NotNullWhen(true)] out ContainerSlot? container) { container = null; - if (_nextIdx >= _slots.Length) return false; - while (_nextIdx < _slots.Length && !_inventorySystem.TryGetSlotContainer(_uid, _slots[_nextIdx++].Name, out container, out _)) { } + while (_nextIdx < _slots.Length) + { + var slot = _slots[_nextIdx]; + _nextIdx++; - return container != null; + if ((slot.SlotFlags & _flags) == 0) + continue; + + if (_inventorySystem.TryGetSlotContainer(_uid, slot.Name, out container, out _)) + return true; + } + + return false; } } } diff --git a/Content.Shared/Inventory/SlotFlags.cs b/Content.Shared/Inventory/SlotFlags.cs index 9031edda93..27f3f3258a 100644 --- a/Content.Shared/Inventory/SlotFlags.cs +++ b/Content.Shared/Inventory/SlotFlags.cs @@ -26,4 +26,5 @@ public enum SlotFlags POCKET = 1 << 12, LEGS = 1 << 13, FEET = 1 << 14, + All = ~NONE, } diff --git a/Content.Shared/Movement/EntitySystems/MovementSpeedModifierSystem.cs b/Content.Shared/Movement/EntitySystems/MovementSpeedModifierSystem.cs index d781f1a625..88993c4aa6 100644 --- a/Content.Shared/Movement/EntitySystems/MovementSpeedModifierSystem.cs +++ b/Content.Shared/Movement/EntitySystems/MovementSpeedModifierSystem.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Content.Shared.Inventory; using Content.Shared.Movement.Components; using Robust.Shared.GameObjects; using Robust.Shared.GameStates; @@ -84,8 +85,10 @@ namespace Content.Shared.Movement.EntitySystems /// should hook into this event and set it then. If you want this event to be raised, /// call . /// - public class RefreshMovementSpeedModifiersEvent : EntityEventArgs + public class RefreshMovementSpeedModifiersEvent : EntityEventArgs, IInventoryRelayEvent { + public SlotFlags TargetSlots { get; } = ~SlotFlags.POCKET; + public float WalkSpeedModifier { get; private set; } = 1.0f; public float SprintSpeedModifier { get; private set; } = 1.0f; diff --git a/Content.Shared/Slippery/SharedSlipperySystem.cs b/Content.Shared/Slippery/SharedSlipperySystem.cs index 7d8046e5fe..7a3204c848 100644 --- a/Content.Shared/Slippery/SharedSlipperySystem.cs +++ b/Content.Shared/Slippery/SharedSlipperySystem.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using Content.Shared.Administration.Logs; using Content.Shared.Database; +using Content.Shared.Inventory; using Content.Shared.StatusEffect; using Content.Shared.Stunnable; using JetBrains.Annotations; @@ -158,7 +159,8 @@ namespace Content.Shared.Slippery /// /// Raised on an entity to determine if it can slip or not. /// - public class SlipAttemptEvent : CancellableEntityEventArgs + public class SlipAttemptEvent : CancellableEntityEventArgs, IInventoryRelayEvent { + public SlotFlags TargetSlots { get; } = SlotFlags.FEET; } }