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:
metalgearsloth
2020-10-10 22:33:56 +11:00
committed by GitHub
parent fe39b5fb71
commit 7bf28ff3d5
2 changed files with 64 additions and 30 deletions

View File

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