119 lines
3.7 KiB
C#
119 lines
3.7 KiB
C#
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, ResolvePulse);
|
|
}
|
|
|
|
public LevelState InteractLeak(LevelState level, ECarrierType carrier, bool useRemedy)
|
|
{
|
|
return PlayerActionSystem.InteractLeak(level, carrier, useRemedy, ResolvePulse);
|
|
}
|
|
|
|
public LevelState ApplyHeatShield(LevelState level)
|
|
{
|
|
return PlayerActionSystem.ApplyHeatShield(level, ResolvePulse);
|
|
}
|
|
|
|
public LevelState ActivateReactor(LevelState level)
|
|
{
|
|
return ReactorSystem.Activate(level);
|
|
}
|
|
|
|
public LevelState AdvancePulseForDebug(LevelState level)
|
|
{
|
|
return ResolvePulse(level);
|
|
}
|
|
|
|
public LevelState AdvanceStepForDebug(LevelState level)
|
|
{
|
|
return ResolveStep(level);
|
|
}
|
|
|
|
[Obsolete("Use AdvancePulseForDebug. Player-facing wait/turn advancement is not part of normal gameplay.")]
|
|
public LevelState EndTurn(LevelState level)
|
|
{
|
|
return AdvancePulseForDebug(level);
|
|
}
|
|
|
|
[Obsolete("Use AdvancePulseForDebug. Player-facing wait/turn advancement is not part of normal gameplay.")]
|
|
public LevelState AdvanceTurn(LevelState level)
|
|
{
|
|
return AdvancePulseForDebug(level);
|
|
}
|
|
|
|
public IReadOnlyList<Forecast> Forecast(LevelState level)
|
|
{
|
|
if (!level.HasActivePoweredTerminalAccess())
|
|
return Array.Empty<Forecast>();
|
|
|
|
return ForecastSystem.Forecast(level, simulated => ResolveStep(simulated, false));
|
|
}
|
|
|
|
private LevelState ResolvePulse(LevelState level)
|
|
{
|
|
var next = ValidateAndPropagate(level);
|
|
if (next.Global.LevelState == ELevelState.Lost)
|
|
return next;
|
|
|
|
for (var i = 0; i < Balancing.Current.StepsPerPulse; i++)
|
|
next = ResolveStepContent(next);
|
|
|
|
next = ReactorSystem.DeriveState(next);
|
|
next = SurfaceInteractionSystem.AdvanceDurations(next);
|
|
next = next with {
|
|
Global = next.Global with {
|
|
Turn = next.Global.Pulse + 1,
|
|
Pulse = next.Global.Pulse + 1
|
|
}
|
|
};
|
|
|
|
return next with { Forecasts = Forecast(next) };
|
|
}
|
|
|
|
private LevelState ResolveStep(LevelState level, bool refreshForecasts = true)
|
|
{
|
|
var next = ValidateAndPropagate(level);
|
|
if (next.Global.LevelState == ELevelState.Lost)
|
|
return next;
|
|
|
|
next = ResolveStepContent(next);
|
|
next = ReactorSystem.DeriveState(next);
|
|
next = SurfaceInteractionSystem.AdvanceDurations(next);
|
|
|
|
return refreshForecasts ? next with { Forecasts = Forecast(next) } : next;
|
|
}
|
|
|
|
private LevelState ValidateAndPropagate(LevelState level)
|
|
{
|
|
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 = SprinklerSystem.ApplyPressureDebt(next);
|
|
next = ConsumerSystem.Resolve(next);
|
|
next = StructuralIntegritySystem.Resolve(next);
|
|
return next;
|
|
}
|
|
|
|
private static LevelState ResolveStepContent(LevelState level)
|
|
{
|
|
var next = level;
|
|
next = SprinklerSystem.Discharge(next);
|
|
next = LeakSystem.Inject(next);
|
|
next = SurfaceInteractionSystem.Resolve(next);
|
|
next = next with { Global = next.Global with { Step = next.Global.Step + 1 } };
|
|
return next;
|
|
}
|
|
|
|
private readonly LevelValidator m_Validator = new();
|
|
} |