Make doors event-based rather than EntityQuery based (#2195)
* Event-based door updates Slight perf increase * Optimise CheckCrush too Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
This commit is contained in:
@@ -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,17 +298,10 @@ 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
|
||||
bool hitSomeone = false;
|
||||
foreach (var e in collidesWith)
|
||||
foreach (var e in body.GetCollidingEntities(Vector2.Zero, false))
|
||||
{
|
||||
if (!e.TryGetComponent(out StunnableComponent? stun)
|
||||
|| !e.TryGetComponent(out IDamageableComponent? damage)
|
||||
@@ -315,14 +315,10 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
|
||||
damage.ChangeDamage(DamageType.Blunt, DoorCrushDamage, false, Owner);
|
||||
stun.Paralyze(DoorStunTime);
|
||||
hitSomeone = true;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -32,18 +35,43 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
AllowAll
|
||||
}
|
||||
|
||||
private List<ServerDoorComponent> _activeDoors = new List<ServerDoorComponent>();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
AccessType = AccessTypes.Id;
|
||||
SubscribeLocalEvent<DoorStateMessage>(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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
foreach (var comp in ComponentManager.EntityQuery<ServerDoorComponent>())
|
||||
for (var i = _activeDoors.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var comp = _activeDoors[i];
|
||||
if (comp.Deleted)
|
||||
_activeDoors.RemoveAt(i);
|
||||
|
||||
comp.OnUpdate(frameTime);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user