diff --git a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs index e9597ace7e..6852509d44 100644 --- a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs +++ b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs @@ -43,7 +43,14 @@ namespace Content.Server.GameObjects.Components.Doors public virtual DoorState State { get => _state; - protected set => _state = value; + protected set + { + if (_state == value) + return; + + _state = value; + Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, new DoorStateMessage(this, State)); + } } [ViewVariables] @@ -291,38 +298,27 @@ namespace Content.Server.GameObjects.Components.Doors private void CheckCrush() { if (!Owner.TryGetComponent(out ICollidableComponent? body)) - { return; - } - // Check if collides with something - var collidesWith = body.GetCollidingEntities(Vector2.Zero, false); - if (collidesWith.Count() != 0) + // Crush + foreach (var e in body.GetCollidingEntities(Vector2.Zero, false)) { - // Crush - bool hitSomeone = false; - foreach (var e in collidesWith) - { - if (!e.TryGetComponent(out StunnableComponent? stun) - || !e.TryGetComponent(out IDamageableComponent? damage) - || !e.TryGetComponent(out ICollidableComponent? otherBody)) - continue; + if (!e.TryGetComponent(out StunnableComponent? stun) + || !e.TryGetComponent(out IDamageableComponent? damage) + || !e.TryGetComponent(out ICollidableComponent? otherBody)) + continue; - var percentage = otherBody.WorldAABB.IntersectPercentage(body.WorldAABB); + var percentage = otherBody.WorldAABB.IntersectPercentage(body.WorldAABB); - if (percentage < 0.1f) - continue; - - damage.ChangeDamage(DamageType.Blunt, DoorCrushDamage, false, Owner); - stun.Paralyze(DoorStunTime); - hitSomeone = true; - } + if (percentage < 0.1f) + continue; + damage.ChangeDamage(DamageType.Blunt, DoorCrushDamage, false, Owner); + stun.Paralyze(DoorStunTime); + // If we hit someone, open up after stun (opens right when stun ends) - if (hitSomeone) - { - Timer.Spawn(TimeSpan.FromSeconds(DoorStunTime) - OpenTimeOne - OpenTimeTwo, () => Open()); - } + Timer.Spawn(TimeSpan.FromSeconds(DoorStunTime) - OpenTimeOne - OpenTimeTwo, Open); + break; } } @@ -428,9 +424,7 @@ namespace Content.Server.GameObjects.Components.Doors public virtual void Deny() { if (State == DoorState.Open || _isWeldedShut) - { return; - } SetAppearance(DoorVisualState.Deny); Timer.Spawn(DenyTime, () => @@ -499,4 +493,16 @@ namespace Content.Server.GameObjects.Components.Doors return true; } } + + public sealed class DoorStateMessage : EntitySystemMessage + { + public ServerDoorComponent Component { get; } + public ServerDoorComponent.DoorState State { get; } + + public DoorStateMessage(ServerDoorComponent component, ServerDoorComponent.DoorState state) + { + Component = component; + State = state; + } + } } diff --git a/Content.Server/GameObjects/EntitySystems/DoorSystem.cs b/Content.Server/GameObjects/EntitySystems/DoorSystem.cs index 8feb00ca24..f5c257826b 100644 --- a/Content.Server/GameObjects/EntitySystems/DoorSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/DoorSystem.cs @@ -1,6 +1,9 @@ -using Content.Server.GameObjects.Components.Doors; +using System; +using System.Collections.Generic; +using Content.Server.GameObjects.Components.Doors; using JetBrains.Annotations; using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Interfaces.GameObjects; namespace Content.Server.GameObjects.EntitySystems { @@ -31,19 +34,44 @@ namespace Content.Server.GameObjects.EntitySystems /// Allows everyone to open all doors. AllowAll } + + private List _activeDoors = new List(); public override void Initialize() { base.Initialize(); AccessType = AccessTypes.Id; + SubscribeLocalEvent(HandleDoorState); + } + + private void HandleDoorState(DoorStateMessage message) + { + switch (message.State) + { + case ServerDoorComponent.DoorState.Closed: + _activeDoors.Remove(message.Component); + break; + case ServerDoorComponent.DoorState.Open: + _activeDoors.Add(message.Component); + break; + case ServerDoorComponent.DoorState.Closing: + case ServerDoorComponent.DoorState.Opening: + break; + default: + throw new ArgumentOutOfRangeException(); + } } /// public override void Update(float frameTime) { - foreach (var comp in ComponentManager.EntityQuery()) + for (var i = _activeDoors.Count - 1; i >= 0; i--) { + var comp = _activeDoors[i]; + if (comp.Deleted) + _activeDoors.RemoveAt(i); + comp.OnUpdate(frameTime); } }