namespace ReactorMaintenance.Simulation; public sealed class SimulationEngine { public LevelState MoveRobot(LevelState level, GridPosition destination) { return PlayerActionSystem.MoveRobot(level, destination); } public LevelState InteractProp(LevelState level) { return PlayerActionSystem.InteractProp(level, ResolveStep); } public LevelState InteractLeak(LevelState level, ECarrierType carrier, bool useRemedy) { return PlayerActionSystem.InteractLeak(level, carrier, useRemedy, ResolveStep); } public LevelState ApplyHeatShield(LevelState level) { return PlayerActionSystem.ApplyHeatShield(level, ResolveStep); } private LevelState ResolveStep(LevelState level) { return ResolveStep(level, true); } public LevelState ActivateReactor(LevelState level) { return ReactorSystem.Activate(level); } public LevelState EndTurn(LevelState level) { return ResolveStep(level); } public LevelState AdvanceTurn(LevelState level) { return ResolveStep(level); } public IReadOnlyList Forecast(LevelState level) { return ForecastSystem.Forecast(level, simulated => ResolveStep(simulated, false)); } private LevelState ResolveStep(LevelState level, bool refreshForecasts) { var report = m_Validator.Validate(level); if (!report.IsValid) return level with { Global = level.Global with { LevelState = ELevelState.Lost, Status = report.Errors[0].Message } }; var next = level; next = NetworkPropagationSystem.Propagate(next); next = ConsumerSystem.Resolve(next); next = StructuralIntegritySystem.Resolve(next); next = LeakSystem.Inject(next); next = SurfaceInteractionSystem.Resolve(next); next = RobotSafetySystem.Resolve(next); next = ReactorSystem.DeriveState(next); next = SurfaceInteractionSystem.AdvanceDurations(next); next = next with { Global = next.Global with { Turn = next.Global.Turn + 1 } }; return refreshForecasts ? next with { Forecasts = Forecast(next) } : next; } private readonly LevelValidator m_Validator = new(); }