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);
}
}