diff --git a/Content.Client/CardboardBox/CardboardBoxSystem.cs b/Content.Client/CardboardBox/CardboardBoxSystem.cs index f527caf678..2ba237fc8b 100644 --- a/Content.Client/CardboardBox/CardboardBoxSystem.cs +++ b/Content.Client/CardboardBox/CardboardBoxSystem.cs @@ -11,10 +11,11 @@ namespace Content.Client.CardboardBox; public sealed partial class CardboardBoxSystem : SharedCardboardBoxSystem { [Dependency] private EntityLookupSystem _entityLookup = default!; - [Dependency] private TransformSystem _transform = default!; [Dependency] private ExamineSystemShared _examine = default!; [Dependency] private SpriteSystem _sprite = default!; - [Dependency] private EntityQuery _mobStateQuery = default!; + [Dependency] private TransformSystem _transform = default!; + + [Dependency] private EntityQuery _mobStateQuery; public override void Initialize() { @@ -33,13 +34,13 @@ public sealed partial class CardboardBoxSystem : SharedCardboardBoxSystem var xform = Transform(source); var sourcePos = _transform.GetMapCoordinates(source, xform); - //Any mob that can move should be surprised? - //God mind rework needs to come faster so it can just check for mind - //TODO: Replace with Mind Query when mind rework is in. + // Any mob that can move should be surprised? + // God mind rework needs to come faster so it can just check for mind + // TODO: Replace with Mind Query when mind rework is in. var mobMoverEntities = new List(); var mover = GetEntity(msg.Mover); - //Filter out entities in range to see that they're a mob and add them to the mobMoverEntities hash for faster lookup + // Filter out entities in range to see that they're a mob and add them to the mobMoverEntities hash for faster lookup var movers = new HashSet>(); _entityLookup.GetEntitiesInRange(xform.Coordinates, box.Distance, movers); @@ -52,7 +53,7 @@ public sealed partial class CardboardBoxSystem : SharedCardboardBoxSystem mobMoverEntities.Add(uid); } - //Play the effect for the mobs as long as they can see the box and are in range. + // Play the effect for the mobs as long as they can see the box and are in range. foreach (var mob in mobMoverEntities) { var mapPos = _transform.GetMapCoordinates(mob); @@ -64,13 +65,11 @@ public sealed partial class CardboardBoxSystem : SharedCardboardBoxSystem continue; var ent = Spawn(box.Effect, mapPos); - if (!TryComp(ent, out TransformComponent? entTransform) || !TryComp(ent, out var sprite)) continue; _sprite.SetOffset((ent, sprite), new Vector2(0, 1)); _transform.SetParent(ent, entTransform, mob); } - } } diff --git a/Content.Server/CardboardBox/CardboardBoxSystem.cs b/Content.Server/CardboardBox/CardboardBoxSystem.cs index 05501915d0..f1ea4538db 100644 --- a/Content.Server/CardboardBox/CardboardBoxSystem.cs +++ b/Content.Server/CardboardBox/CardboardBoxSystem.cs @@ -1,138 +1,5 @@ -using Content.Server.Storage.EntitySystems; -using Content.Shared.Access.Components; using Content.Shared.CardboardBox; -using Content.Shared.CardboardBox.Components; -using Content.Shared.Damage.Systems; -using Content.Shared.Interaction; -using Content.Shared.Movement.Components; -using Content.Shared.Movement.Systems; -using Content.Shared.Stealth; -using Content.Shared.Stealth.Components; -using Content.Shared.Storage.Components; -using Robust.Shared.Audio.Systems; -using Robust.Shared.Containers; -using Robust.Shared.Timing; namespace Content.Server.CardboardBox; -public sealed partial class CardboardBoxSystem : SharedCardboardBoxSystem -{ - [Dependency] private SharedAudioSystem _audio = default!; - [Dependency] private SharedMoverController _mover = default!; - [Dependency] private IGameTiming _timing = default!; - [Dependency] private SharedStealthSystem _stealth = default!; - [Dependency] private DamageableSystem _damageable = default!; - [Dependency] private EntityStorageSystem _storage = default!; - - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(AfterStorageOpen); - SubscribeLocalEvent(BeforeStorageOpen); - SubscribeLocalEvent(AfterStorageClosed); - SubscribeLocalEvent(OnGetAdditionalAccess); - SubscribeLocalEvent(OnInteracted); - SubscribeLocalEvent(OnEntInserted); - SubscribeLocalEvent(OnEntRemoved); - - SubscribeLocalEvent(OnDamage); - } - - private void OnInteracted(EntityUid uid, CardboardBoxComponent component, ActivateInWorldEvent args) - { - if (args.Handled) - return; - - if (!TryComp(uid, out var box)) - return; - - if (!args.Complex) - { - if (box.Open || !box.Contents.Contains(args.User)) - return; - } - - args.Handled = true; - _storage.ToggleOpen(args.User, uid, box); - - if (box.Contents.Contains(args.User) && !box.Open) - { - _mover.SetRelay(args.User, uid); - component.Mover = args.User; - } - } - - private void OnGetAdditionalAccess(EntityUid uid, CardboardBoxComponent component, ref GetAdditionalAccessEvent args) - { - if (component.Mover == null) - return; - args.Entities.Add(component.Mover.Value); - } - - private void BeforeStorageOpen(EntityUid uid, CardboardBoxComponent component, ref StorageBeforeOpenEvent args) - { - if (component.Quiet) - return; - - //Play effect & sound - if (component.Mover != null) - { - if (_timing.CurTime > component.EffectCooldown) - { - RaiseNetworkEvent(new PlayBoxEffectMessage(GetNetEntity(uid), GetNetEntity(component.Mover.Value))); - _audio.PlayPvs(component.EffectSound, uid); - component.EffectCooldown = _timing.CurTime + component.CooldownDuration; - } - } - } - - private void AfterStorageOpen(EntityUid uid, CardboardBoxComponent component, ref StorageAfterOpenEvent args) - { - // If this box has a stealth/chameleon effect, disable the stealth effect while the box is open. - _stealth.SetEnabled(uid, false); - } - - private void AfterStorageClosed(EntityUid uid, CardboardBoxComponent component, ref StorageAfterCloseEvent args) - { - // If this box has a stealth/chameleon effect, enable the stealth effect. - if (TryComp(uid, out StealthComponent? stealth)) - { - _stealth.SetVisibility(uid, stealth.MaxVisibility, stealth); - _stealth.SetEnabled(uid, true, stealth); - } - } - - //Relay damage to the mover - private void OnDamage(EntityUid uid, CardboardBoxComponent component, DamageChangedEvent args) - { - if (args.DamageDelta == null || !args.DamageIncreased || component.Mover is not { } mover) - return; - - _damageable.ChangeDamage(mover, args.DamageDelta, origin: args.Origin); - } - - private void OnEntInserted(EntityUid uid, CardboardBoxComponent component, EntInsertedIntoContainerMessage args) - { - if (!TryComp(args.Entity, out MobMoverComponent? mover)) - return; - - if (component.Mover == null) - { - _mover.SetRelay(args.Entity, uid); - component.Mover = args.Entity; - } - } - - /// - /// Through e.g. teleporting, it's possible for the mover to exit the box without opening it. - /// Handle those situations but don't play the sound. - /// - private void OnEntRemoved(EntityUid uid, CardboardBoxComponent component, EntRemovedFromContainerMessage args) - { - if (args.Entity != component.Mover) - return; - - RemComp(component.Mover.Value); - component.Mover = null; - } -} +public sealed partial class CardboardBoxSystem : SharedCardboardBoxSystem; diff --git a/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs b/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs index b63505d6b5..007518fc12 100644 --- a/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs +++ b/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs @@ -48,7 +48,6 @@ public sealed partial class RevenantSystem [Dependency] private SharedMapSystem _mapSystem = default!; [Dependency] private EntityQuery _tagQuery = default!; - [Dependency] private EntityQuery _entityStorageQuery = default!; [Dependency] private EntityQuery _itemQuery = default!; [Dependency] private EntityQuery _poweredLightQuery = default!; [Dependency] private EntityQuery _mobStateQuery = default!; @@ -281,8 +280,7 @@ public sealed partial class RevenantSystem continue; //randomly opens some lockers and such. - if (_entityStorageQuery.TryGetComponent(ent, out var entstorecomp)) - _entityStorage.OpenStorage(ent, entstorecomp); + _entityStorage.OpenStorage(ent, args.Performer); //chucks shit if (_itemQuery.HasComponent(ent) && diff --git a/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs b/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs index bea9155e40..14954f497f 100644 --- a/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs +++ b/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs @@ -86,7 +86,7 @@ public sealed partial class BluespaceLockerSystem : EntitySystem // Close target if it is open if (target.Value.storageComponent.Open) - _entityStorage.CloseStorage(target.Value.uid, target.Value.storageComponent); + _entityStorage.CloseStorage((target.Value.uid, target.Value.storageComponent)); // Apply bluespace effects if target is not a bluespace locker, otherwise let it handle it if (target.Value.bluespaceLockerComponent == null) @@ -352,7 +352,7 @@ public sealed partial class BluespaceLockerSystem : EntitySystem if (Resolve(target.Value.uid, ref lockComponent, false) && lockComponent.Locked) _lockSystem.Unlock(target.Value.uid, target.Value.uid, lockComponent); - _entityStorage.OpenStorage(target.Value.uid, target.Value.storageComponent); + _entityStorage.OpenStorage((target.Value.uid, target.Value.storageComponent)); } // Bluespace effects diff --git a/Content.Shared/CardboardBox/Components/CardboardBoxComponent.cs b/Content.Shared/CardboardBox/Components/CardboardBoxComponent.cs index 0e607f5076..4bb2c99558 100644 --- a/Content.Shared/CardboardBox/Components/CardboardBoxComponent.cs +++ b/Content.Shared/CardboardBox/Components/CardboardBoxComponent.cs @@ -1,72 +1,67 @@ using Robust.Shared.Audio; using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Shared.CardboardBox.Components; + /// /// Allows a user to control an EntityStorage entity while inside of it. /// Used for big cardboard box entities. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause] public sealed partial class CardboardBoxComponent : Component { /// /// The person in control of this box /// - [DataField("mover")] + [DataField, AutoNetworkedField] public EntityUid? Mover; /// /// The entity used for the box opening effect /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField("effect")] - public string Effect = "Exclamation"; + [DataField] + public EntProtoId Effect = "Exclamation"; /// /// Sound played upon effect creation /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField("effectSound")] + [DataField] public SoundSpecifier? EffectSound; /// /// Whether to prevent the box from making the sound and effect /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField("quiet")] - public bool Quiet = false; + [DataField] + public bool Quiet; /// /// How far should the box opening effect go? /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField("distance")] + [DataField] public float Distance = 6f; /// /// Time at which the sound effect can next be played. /// - [DataField("effectCooldown", customTypeSerializer: typeof(TimeOffsetSerializer))] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField, AutoPausedField] public TimeSpan EffectCooldown; /// /// Time between sound effects. Prevents effect spam /// - [DataField("cooldownDuration")] + [DataField] public TimeSpan CooldownDuration = TimeSpan.FromSeconds(5f); } +/// +/// Message to play the box effect. +/// [Serializable, NetSerializable] -public sealed class PlayBoxEffectMessage : EntityEventArgs +public sealed class PlayBoxEffectMessage(NetEntity source, NetEntity mover) : EntityEventArgs { - public NetEntity Source; - public NetEntity Mover; - - public PlayBoxEffectMessage(NetEntity source, NetEntity mover) - { - Source = source; - Mover = mover; - } + public NetEntity Source = source; + public NetEntity Mover = mover; } diff --git a/Content.Shared/CardboardBox/SharedCardboardBoxSystem.cs b/Content.Shared/CardboardBox/SharedCardboardBoxSystem.cs index 856bb94ae0..d028515e89 100644 --- a/Content.Shared/CardboardBox/SharedCardboardBoxSystem.cs +++ b/Content.Shared/CardboardBox/SharedCardboardBoxSystem.cs @@ -1,6 +1,156 @@ -namespace Content.Shared.CardboardBox; +using System.Numerics; +using Content.Shared.Access.Components; +using Content.Shared.CardboardBox.Components; +using Content.Shared.Damage.Systems; +using Content.Shared.Interaction; +using Content.Shared.Movement.Components; +using Content.Shared.Movement.Systems; +using Content.Shared.Stealth; +using Content.Shared.Stealth.Components; +using Content.Shared.Storage.Components; +using Content.Shared.Storage.EntitySystems; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Containers; +using Robust.Shared.Network; +using Robust.Shared.Physics.Systems; +using Robust.Shared.Timing; -public abstract class SharedCardboardBoxSystem : EntitySystem +namespace Content.Shared.CardboardBox; + +public abstract partial class SharedCardboardBoxSystem : EntitySystem { + [Dependency] private IGameTiming _timing = default!; + [Dependency] private INetManager _net = default!; + [Dependency] private DamageableSystem _damageable = default!; + [Dependency] private SharedAudioSystem _audio = default!; + [Dependency] private SharedEntityStorageSystem _storage = default!; + [Dependency] private SharedMoverController _mover = default!; + [Dependency] private SharedPhysicsSystem _physics = default!; + [Dependency] private SharedStealthSystem _stealth = default!; + [SubscribeLocalEvent] + private void OnInteracted(Entity ent, ref ActivateInWorldEvent args) + { + if (args.Handled) + return; + + if (!TryComp(ent, out var box)) + return; + + if (!args.Complex) + { + if (box.Open || !box.Contents.Contains(args.User)) + return; + } + + args.Handled = true; + _storage.ToggleOpen(args.User, ent, box); + + if (!box.Contents.Contains(args.User) || box.Open) + return; + + _mover.SetRelay(args.User, ent); + ent.Comp.Mover = args.User; + Dirty(ent); + } + + [SubscribeLocalEvent] + private void OnGetAdditionalAccess(Entity ent, ref GetAdditionalAccessEvent args) + { + if (ent.Comp.Mover == null) + return; + + args.Entities.Add(ent.Comp.Mover.Value); + } + + [SubscribeLocalEvent] + private void BeforeStorageOpen(Entity ent, ref StorageBeforeOpenEvent args) + { + if (ent.Comp.Quiet) + return; + + // Play effect & sound. + if (ent.Comp.Mover == null) + return; + + if (_timing.CurTime <= ent.Comp.EffectCooldown) + return; + + if (_net.IsServer) + RaiseNetworkEvent(new PlayBoxEffectMessage(GetNetEntity(ent), GetNetEntity(ent.Comp.Mover.Value))); + + _audio.PlayPredicted(ent.Comp.EffectSound, ent, args.User); + ent.Comp.EffectCooldown = _timing.CurTime + ent.Comp.CooldownDuration; + Dirty(ent); + } + + [SubscribeLocalEvent] + private void AfterStorageOpen(Entity ent, ref StorageAfterOpenEvent args) + { + // If this box has a stealth/chameleon effect, disable the stealth effect while the box is open. + if (!TryComp(ent, out var stealth)) + return; + + _stealth.SetEnabled(ent, false, stealth); + } + + [SubscribeLocalEvent] + private void AfterStorageClosed(Entity ent, ref StorageAfterCloseEvent args) + { + // If this box has a stealth/chameleon effect, enable the stealth effect. + if (!TryComp(ent, out var stealth)) + return; + + _stealth.SetVisibility(ent, stealth.MaxVisibility, stealth); + _stealth.SetEnabled(ent, true, stealth); + } + + /// + /// Relay damage to the mover. + /// + [SubscribeLocalEvent] + private void OnDamage(Entity ent, ref DamageDealtEvent args) + { + if (ent.Comp.Mover is not { } mover) + return; + + _damageable.ChangeDamage(mover, args.Damage, origin: args.Origin); + } + + [SubscribeLocalEvent] + private void OnEntInserted(Entity ent, ref EntInsertedIntoContainerMessage args) + { + if (_timing.ApplyingState) + return; + + if (!HasComp(args.Entity)) + return; + + if (ent.Comp.Mover != null) + return; + + _mover.SetRelay(args.Entity, ent); + ent.Comp.Mover = args.Entity; + Dirty(ent); + } + + /// + /// Through e.g. teleporting, it's possible for the mover to exit the box without opening it. + /// Handle those situations but don't play the sound. + /// + [SubscribeLocalEvent] + private void OnEntRemoved(Entity ent, ref EntRemovedFromContainerMessage args) + { + if (_timing.ApplyingState) + return; + + if (args.Entity != ent.Comp.Mover) + return; + + // Stops movement after exit. + _physics.SetLinearVelocity(ent, Vector2.Zero); + RemComp(ent.Comp.Mover.Value); + ent.Comp.Mover = null; + Dirty(ent); + } } diff --git a/Content.Shared/Morgue/SharedCrematoriumSystem.cs b/Content.Shared/Morgue/SharedCrematoriumSystem.cs index 0a0f9d20b2..1b60785554 100644 --- a/Content.Shared/Morgue/SharedCrematoriumSystem.cs +++ b/Content.Shared/Morgue/SharedCrematoriumSystem.cs @@ -147,7 +147,7 @@ public abstract partial class SharedCrematoriumSystem : EntitySystem PredictedTrySpawnInContainer(ent.Comp1.LeftOverProtoId, ent.Owner, ent.Comp2.Contents.ID, out _); } - EntityStorage.OpenStorage(ent.Owner, ent.Comp2); + EntityStorage.OpenStorage((ent.Owner, ent.Comp2)); if (_net.IsServer) // can't predict without the user _audio.PlayPvs(ent.Comp1.CremateFinishSound, ent.Owner); diff --git a/Content.Shared/Security/Systems/SharedGenpopSystem.cs b/Content.Shared/Security/Systems/SharedGenpopSystem.cs index 2956e96d8a..1d4d0bb8dc 100644 --- a/Content.Shared/Security/Systems/SharedGenpopSystem.cs +++ b/Content.Shared/Security/Systems/SharedGenpopSystem.cs @@ -60,7 +60,7 @@ public abstract partial class SharedGenpopSystem : EntitySystem ent.Comp.LinkedId = EntityUid.Invalid; _lock.Lock(ent.Owner, args.Actor); - _entityStorage.CloseStorage(ent); + _entityStorage.CloseStorage(ent.Owner, args.Actor); CreateId(ent, args.Name, args.Sentence, args.Crime); } @@ -200,7 +200,7 @@ public abstract partial class SharedGenpopSystem : EntitySystem ent.Comp.LinkedId = null; _lock.Unlock(ent.Owner, user); - _entityStorage.OpenStorage(ent.Owner); + _entityStorage.OpenStorage(ent.Owner, user); if (TryComp(ent.Comp.LinkedId, out var expire)) IdCard.ExpireId((ent.Comp.LinkedId.Value, expire)); diff --git a/Content.Shared/Storage/Components/EntityStorageComponent.cs b/Content.Shared/Storage/Components/EntityStorageComponent.cs index ba267aa5bf..30c46e5b3b 100644 --- a/Content.Shared/Storage/Components/EntityStorageComponent.cs +++ b/Content.Shared/Storage/Components/EntityStorageComponent.cs @@ -184,16 +184,16 @@ public record struct EntityStorageIntoContainerAttemptEvent(BaseContainer Contai public record struct StorageOpenAttemptEvent(EntityUid User, bool Silent, bool Cancelled = false); [ByRefEvent] -public readonly record struct StorageBeforeOpenEvent; +public readonly record struct StorageBeforeOpenEvent(EntityUid? User); [ByRefEvent] -public readonly record struct StorageAfterOpenEvent; +public readonly record struct StorageAfterOpenEvent(EntityUid? User); [ByRefEvent] public record struct StorageCloseAttemptEvent(EntityUid? User, bool Cancelled = false); [ByRefEvent] -public readonly record struct StorageBeforeCloseEvent(HashSet Contents, HashSet BypassChecks); +public readonly record struct StorageBeforeCloseEvent(EntityUid? User, HashSet Contents, HashSet BypassChecks); [ByRefEvent] -public readonly record struct StorageAfterCloseEvent; +public readonly record struct StorageAfterCloseEvent(EntityUid? User); diff --git a/Content.Shared/Storage/EntitySystems/SharedEntityStorageSystem.cs b/Content.Shared/Storage/EntitySystems/SharedEntityStorageSystem.cs index 6ffc743908..fd95be7473 100644 --- a/Content.Shared/Storage/EntitySystems/SharedEntityStorageSystem.cs +++ b/Content.Shared/Storage/EntitySystems/SharedEntityStorageSystem.cs @@ -225,77 +225,76 @@ public abstract partial class SharedEntityStorageSystem : EntitySystem } } - public void OpenStorage(EntityUid uid, EntityStorageComponent? component = null) + public void OpenStorage(Entity target, EntityUid? user = null) { - if (!Resolve(uid, ref component)) + if (!Resolve(target, ref target.Comp)) return; - if (component.Open) + if (target.Comp.Open) return; - var beforeev = new StorageBeforeOpenEvent(); - RaiseLocalEvent(uid, ref beforeev); - component.Open = true; - Dirty(uid, component); - EmptyContents(uid, component); - ModifyComponents(uid, component); - if (_net.IsClient && _timing.IsFirstTimePredicted) - _audio.PlayPvs(component.OpenSound, uid); - ReleaseGas(uid, component); - var afterev = new StorageAfterOpenEvent(); - RaiseLocalEvent(uid, ref afterev); + var beforeev = new StorageBeforeOpenEvent(user); + RaiseLocalEvent(target, ref beforeev); + target.Comp.Open = true; + Dirty(target); + EmptyContents(target, target.Comp); + ModifyComponents(target, target.Comp); + _audio.PlayLocal(target.Comp.OpenSound, target, user); + ReleaseGas(target, target.Comp); + var afterev = new StorageAfterOpenEvent(user); + RaiseLocalEvent(target, ref afterev); } - public void CloseStorage(EntityUid uid, EntityStorageComponent? component = null) + public void CloseStorage(Entity target, EntityUid? user = null) { - if (!Resolve(uid, ref component)) + if (!Resolve(target, ref target.Comp)) return; - if (!component.Open) + if (!target.Comp.Open) return; // Prevent the container from closing if it is queued for deletion. This is so that the container-emptying // behaviour of DestructionEventArgs is respected. This exists because malicious players were using // destructible boxes to delete entities by having two players simultaneously destroy and close the box in // the same tick. - if (EntityManager.IsQueuedForDeletion(uid)) + if (EntityManager.IsQueuedForDeletion(target)) return; - component.Open = false; - Dirty(uid, component); + target.Comp.Open = false; + Dirty(target); var entities = _lookup.GetEntitiesInRange( - new EntityCoordinates(uid, component.EnteringOffset), - component.EnteringRange, + new EntityCoordinates(target, target.Comp.EnteringOffset), + target.Comp.EnteringRange, LookupFlags.Approximate | LookupFlags.Dynamic | LookupFlags.Sundries ); // Don't insert the container into itself. - entities.Remove(uid); + entities.Remove(target); - var ev = new StorageBeforeCloseEvent(entities, []); - RaiseLocalEvent(uid, ref ev); + var ev = new StorageBeforeCloseEvent(user, entities, []); + RaiseLocalEvent(target, ref ev); foreach (var entity in ev.Contents) { - if (!ev.BypassChecks.Contains(entity) && !CanInsert(entity, uid, component)) + if (!ev.BypassChecks.Contains(entity) && !CanInsert(entity, target, target.Comp)) continue; - if (!AddToContents(entity, uid, component)) + if (!AddToContents(entity, target, target.Comp)) continue; - if (component.Contents.ContainedEntities.Count >= component.Capacity) + if (target.Comp.Contents.ContainedEntities.Count >= target.Comp.Capacity) break; } - if (LifeStage(uid) >= EntityLifeStage.MapInitialized) // stop mappers from serializing air in locker - TakeGas(uid, component); - ModifyComponents(uid, component); - if (_net.IsClient && _timing.IsFirstTimePredicted) - _audio.PlayPvs(component.CloseSound, uid); + if (LifeStage(target) >= EntityLifeStage.MapInitialized) // stop mappers from serializing air in locker + TakeGas(target, target.Comp); - var afterev = new StorageAfterCloseEvent(); - RaiseLocalEvent(uid, ref afterev); + ModifyComponents(target, target.Comp); + _audio.PlayLocal(target.Comp.CloseSound, target, user); + + var afterev = new StorageAfterCloseEvent(user); + RaiseLocalEvent(target, ref afterev); } public bool Insert(EntityUid toInsert, EntityUid container, EntityStorageComponent? component = null) @@ -388,7 +387,7 @@ public abstract partial class SharedEntityStorageSystem : EntitySystem if (!CanOpen(user, target, silent)) return false; - OpenStorage(target); + OpenStorage(target, user); return true; } @@ -399,7 +398,7 @@ public abstract partial class SharedEntityStorageSystem : EntitySystem return false; } - CloseStorage(target); + CloseStorage(target, user); return true; }