using ReactorMaintenance.Simulation.Difficulties; namespace ReactorMaintenance.Simulation; public abstract class Balancing { public float ClampValue(float value) { return Math.Clamp(value, MinValue, MaxValue); } public EBand Band(float value, float caution, float critical) { if (value >= critical) return EBand.Critical; return value >= caution ? EBand.Caution : EBand.Safe; } public IReadOnlyList JunctionRatios(int outflowCount) { return outflowCount switch { 2 => TwoOutflowJunctionRatios, 3 => ThreeOutflowJunctionRatios, _ => Array.Empty() }; } public float[] JunctionWeights(int outflowCount, int mode) { var ratios = JunctionRatios(outflowCount); if (ratios.Count == 0) return Array.Empty(); return ratios[Math.Clamp(mode, 0, ratios.Count - 1)].Weights; } public SurfaceInteractionEffect SameCellInteraction(ECarrierType? rowCarrier, EBand rowBand, ECarrierType? colCarrier, EBand colBand) { if (rowBand == EBand.Safe && colBand == EBand.Safe) return SurfaceInteractionEffect.Hold; if (rowCarrier == ECarrierType.Fuel && colCarrier == ECarrierType.Electricity) return Ignite(rowBand, colBand); if (rowCarrier == ECarrierType.Fuel && colCarrier is null) return rowBand == EBand.Critical || colBand == EBand.Critical ? Ignite(rowBand, colBand) : Warm(rowBand, colBand); if (rowCarrier == ECarrierType.Coolant && colCarrier == ECarrierType.Electricity) return Short(rowBand, colBand); if (rowCarrier == ECarrierType.Coolant && colCarrier is null) return Quench(rowBand, colBand); return SurfaceInteractionEffect.Hold; } public SurfaceInteractionEffect FlowInteraction(ESurfaceQuantity quantity) { return new() { Verb = ESurfaceInteractionVerb.Flow, Quantity = quantity, Amount = FlowTransferRatio }; } public float StructuralPressureThreshold(ECarrierType carrier) { return carrier switch { ECarrierType.Fuel => FuelCritical, ECarrierType.Coolant => CoolantCritical, ECarrierType.Electricity => ElectricityCritical, _ => MaxValue }; } private SurfaceInteractionEffect Warm(EBand rowBand, EBand colBand) { return new() { Verb = ESurfaceInteractionVerb.Warm, Quantity = ESurfaceQuantity.Heat, Amount = Strongest(rowBand, colBand) == EBand.Critical ? WarmCriticalAmount : WarmCautionAmount }; } private SurfaceInteractionEffect Quench(EBand rowBand, EBand colBand) { return new() { Verb = ESurfaceInteractionVerb.Quench, Quantity = ESurfaceQuantity.Heat, Amount = Strongest(rowBand, colBand) == EBand.Critical ? QuenchCriticalAmount : QuenchCautionAmount }; } private SurfaceInteractionEffect Short(EBand rowBand, EBand colBand) { var critical = Strongest(rowBand, colBand) == EBand.Critical; return new() { Verb = ESurfaceInteractionVerb.Short, Quantity = ESurfaceQuantity.Electricity, Amount = critical ? ShortCriticalHeat : ShortCautionHeat, SecondaryAmount = critical ? ShortCriticalDischarge : ShortCautionDischarge }; } private SurfaceInteractionEffect Ignite(EBand rowBand, EBand colBand) { var critical = Strongest(rowBand, colBand) == EBand.Critical; return new() { Verb = ESurfaceInteractionVerb.Ignite, Quantity = ESurfaceQuantity.Fuel, Amount = critical ? IgniteCriticalHeat : IgniteCautionHeat, SecondaryAmount = critical ? IgniteCriticalFuelConsumption : IgniteCautionFuelConsumption }; } private static EBand Strongest(EBand a, EBand b) { return a > b ? a : b; } public static Balancing Current { get; set; } = new NormalBalancing(); public abstract int DefaultLevelWidth { get; } public abstract int DefaultLevelHeight { get; } public abstract int MinimumLevelSize { get; } public abstract int ForecastHorizon { get; } public abstract float MinValue { get; } public abstract float MaxValue { get; } public abstract float FuelSafe { get; } public abstract float FuelCaution { get; } public abstract float FuelCritical { get; } public abstract float CoolantSafe { get; } public abstract float CoolantCaution { get; } public abstract float CoolantCritical { get; } public abstract float ElectricitySafe { get; } public abstract float ElectricityCaution { get; } public abstract float ElectricityCritical { get; } public abstract float HeatSafe { get; } public abstract float HeatCaution { get; } public abstract float HeatCritical { get; } public abstract float TerminalHeat { get; } public abstract float RobotFuelSafetyThreshold { get; } public abstract float RobotCoolantSafetyThreshold { get; } public abstract float RobotElectricitySafetyThreshold { get; } public abstract float RobotHeatSafetyThreshold { get; } public abstract float SourceAmount { get; } public abstract float SourceIntensity { get; } public abstract float DistanceAmountFalloff { get; } public abstract float DistanceIntensityFalloff { get; } public abstract IReadOnlyList TwoOutflowJunctionRatios { get; } public abstract IReadOnlyList ThreeOutflowJunctionRatios { get; } public abstract float ConsumerRequiredAmount { get; } public abstract float ConsumerRequiredIntensity { get; } public abstract int MaxStructuralIntegrity { get; } public abstract int StructuralIntegrityLeakThreshold { get; } public abstract float StructuralIntegrityDamageScale { get; } public abstract float LeakBaseAmount { get; } public abstract float LeakAmountScale { get; } public abstract float LeakIntensityScale { get; } public abstract float FlowTransferRatio { get; } public abstract float WarmCautionAmount { get; } public abstract float WarmCriticalAmount { get; } public abstract float QuenchCautionAmount { get; } public abstract float QuenchCriticalAmount { get; } public abstract float ShortCautionHeat { get; } public abstract float ShortCautionDischarge { get; } public abstract float ShortCriticalHeat { get; } public abstract float ShortCriticalDischarge { get; } public abstract float IgniteCautionHeat { get; } public abstract float IgniteCautionFuelConsumption { get; } public abstract float IgniteCriticalHeat { get; } public abstract float IgniteCriticalFuelConsumption { get; } public abstract int RemedyBlockTurns { get; } public abstract int HeatShieldSteps { get; } public abstract int InventoryCapacityPerRemedy { get; } }