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(); foreach (var entity in doors) { var door = world.GetComponent(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)); } }