59 lines
2.1 KiB
C#
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));
|
|
}
|
|
} |