using System.Collections.Generic; using Content.Server.GameObjects.Components.Items.Storage; using Content.Server.GameObjects.EntitySystems.Click; using JetBrains.Annotations; using Robust.Server.GameObjects.EntitySystemMessages; using Robust.Server.Interfaces.Player; using Robust.Shared.GameObjects.Systems; namespace Content.Server.GameObjects.EntitySystems { [UsedImplicitly] internal sealed class StorageSystem : EntitySystem { private readonly List _sessionCache = new(); /// public override void Initialize() { SubscribeLocalEvent(HandleEntityRemovedFromContainer); SubscribeLocalEvent(HandleEntityInsertedIntoContainer); } /// public override void Update(float frameTime) { foreach (var component in ComponentManager.EntityQuery(true)) { CheckSubscribedEntities(component); } } private static void HandleEntityRemovedFromContainer(EntRemovedFromContainerMessage message) { var oldParentEntity = message.Container.Owner; if (oldParentEntity.TryGetComponent(out ServerStorageComponent storageComp)) { storageComp.HandleEntityMaybeRemoved(message); } } private static void HandleEntityInsertedIntoContainer(EntInsertedIntoContainerMessage message) { var oldParentEntity = message.Container.Owner; if (oldParentEntity.TryGetComponent(out ServerStorageComponent storageComp)) { storageComp.HandleEntityMaybeInserted(message); } } private void CheckSubscribedEntities(ServerStorageComponent storageComp) { // We have to cache the set of sessions because Unsubscribe modifies the original. _sessionCache.Clear(); _sessionCache.AddRange(storageComp.SubscribedSessions); if (_sessionCache.Count == 0) return; var storagePos = storageComp.Owner.Transform.WorldPosition; var storageMap = storageComp.Owner.Transform.MapID; foreach (var session in _sessionCache) { var attachedEntity = session.AttachedEntity; // The component manages the set of sessions, so this invalid session should be removed soon. if (attachedEntity == null || !attachedEntity.IsValid()) continue; if (storageMap != attachedEntity.Transform.MapID) continue; var distanceSquared = (storagePos - attachedEntity.Transform.WorldPosition).LengthSquared; if (distanceSquared > InteractionSystem.InteractionRangeSquared) { storageComp.UnsubscribeSession(session); } } } } }