Files
brick-framework/GameCore/Interaction/DoorSystem.cs

59 lines
2.1 KiB
C#

using GameCore.ECS;
using GameCore.ECS.Interfaces;
using GameCore.Events;
namespace GameCore.Interaction;
public class DoorSystem : ISystem
{
public void Update(World world, float deltaTime)
{
var doors = world.GetEntitiesWith<DoorComponent>();
foreach (var entity in doors)
{
var door = world.GetComponent<DoorComponent>(entity);
if (door == null) continue;
switch (door.CurrentState)
{
case DoorComponent.DoorState.Opening:
ApplyMovement(entity, door, world, deltaTime, DoorComponent.DoorState.Open,
System.Math.Max(door.OpenSpeed, 0f));
break;
case DoorComponent.DoorState.Closing:
ApplyMovement(entity, door, world, -deltaTime, DoorComponent.DoorState.Closed, 0f);
break;
case DoorComponent.DoorState.Open:
door.Timer = System.Math.Max(door.OpenSpeed, 0f);
door.OpenProgress = 1f;
break;
case DoorComponent.DoorState.Closed:
case DoorComponent.DoorState.Locked:
door.Timer = 0f;
door.OpenProgress = 0f;
break;
}
}
}
private void ApplyMovement(Entity entity, DoorComponent door, World world, float delta,
DoorComponent.DoorState targetState, float targetBoundary)
{
var effectiveSpeed = System.Math.Max(door.OpenSpeed, 0f);
door.Timer = System.Math.Clamp(door.Timer + delta, 0f, effectiveSpeed);
if (effectiveSpeed > 0f)
door.OpenProgress = System.Math.Clamp(door.Timer / effectiveSpeed, 0f, 1f);
else
door.OpenProgress = door.Timer > 0f ? 1f : 0f;
if ((!(delta > 0f) || !(door.Timer >= targetBoundary)) &&
(!(delta < 0f) || !(door.Timer <= targetBoundary))) return;
door.CurrentState = targetState;
world.PublishEvent(new DoorStateChangedEvent(entity, door.CurrentState));
}
}