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
|
public virtual DoorState State
|
||||||
{
|
{
|
||||||
get => _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]
|
[ViewVariables]
|
||||||
@@ -291,17 +298,10 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
private void CheckCrush()
|
private void CheckCrush()
|
||||||
{
|
{
|
||||||
if (!Owner.TryGetComponent(out ICollidableComponent? body))
|
if (!Owner.TryGetComponent(out ICollidableComponent? body))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Check if collides with something
|
|
||||||
var collidesWith = body.GetCollidingEntities(Vector2.Zero, false);
|
|
||||||
if (collidesWith.Count() != 0)
|
|
||||||
{
|
|
||||||
// Crush
|
// Crush
|
||||||
bool hitSomeone = false;
|
foreach (var e in body.GetCollidingEntities(Vector2.Zero, false))
|
||||||
foreach (var e in collidesWith)
|
|
||||||
{
|
{
|
||||||
if (!e.TryGetComponent(out StunnableComponent? stun)
|
if (!e.TryGetComponent(out StunnableComponent? stun)
|
||||||
|| !e.TryGetComponent(out IDamageableComponent? damage)
|
|| !e.TryGetComponent(out IDamageableComponent? damage)
|
||||||
@@ -315,14 +315,10 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
|
|
||||||
damage.ChangeDamage(DamageType.Blunt, DoorCrushDamage, false, Owner);
|
damage.ChangeDamage(DamageType.Blunt, DoorCrushDamage, false, Owner);
|
||||||
stun.Paralyze(DoorStunTime);
|
stun.Paralyze(DoorStunTime);
|
||||||
hitSomeone = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we hit someone, open up after stun (opens right when stun ends)
|
// If we hit someone, open up after stun (opens right when stun ends)
|
||||||
if (hitSomeone)
|
Timer.Spawn(TimeSpan.FromSeconds(DoorStunTime) - OpenTimeOne - OpenTimeTwo, Open);
|
||||||
{
|
break;
|
||||||
Timer.Spawn(TimeSpan.FromSeconds(DoorStunTime) - OpenTimeOne - OpenTimeTwo, () => Open());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,9 +424,7 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
public virtual void Deny()
|
public virtual void Deny()
|
||||||
{
|
{
|
||||||
if (State == DoorState.Open || _isWeldedShut)
|
if (State == DoorState.Open || _isWeldedShut)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
SetAppearance(DoorVisualState.Deny);
|
SetAppearance(DoorVisualState.Deny);
|
||||||
Timer.Spawn(DenyTime, () =>
|
Timer.Spawn(DenyTime, () =>
|
||||||
@@ -499,4 +493,16 @@ namespace Content.Server.GameObjects.Components.Doors
|
|||||||
return true;
|
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 JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects.Systems;
|
using Robust.Shared.GameObjects.Systems;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.EntitySystems
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
@@ -32,18 +35,43 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
AllowAll
|
AllowAll
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ServerDoorComponent> _activeDoors = new List<ServerDoorComponent>();
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
AccessType = AccessTypes.Id;
|
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 />
|
/// <inheritdoc />
|
||||||
public override void Update(float frameTime)
|
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);
|
comp.OnUpdate(frameTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user