Files
zfxaction26_2/src/ReactorMaintenance.Simulation/Balancing.cs

194 lines
7.8 KiB
C#

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<JunctionRatioPreset> JunctionRatios(int outflowCount)
{
return outflowCount switch {
2 => TwoOutflowJunctionRatios,
3 => ThreeOutflowJunctionRatios,
_ => Array.Empty<JunctionRatioPreset>()
};
}
public float[] JunctionWeights(int outflowCount, int mode)
{
var ratios = JunctionRatios(outflowCount);
if (ratios.Count == 0)
return Array.Empty<float>();
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 == ECarrierType.Water)
return Dilute(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.Water && colCarrier == ECarrierType.Electricity)
return Conduct(rowBand, colBand);
if (rowCarrier == ECarrierType.Water && 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.Water => WaterCritical,
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 Dilute(EBand rowBand, EBand colBand)
{
return new() {
Verb = ESurfaceInteractionVerb.Dilute,
Quantity = ESurfaceQuantity.Fuel,
Amount = Strongest(rowBand, colBand) == EBand.Critical ? DiluteCriticalAmount : DiluteCautionAmount
};
}
private SurfaceInteractionEffect Conduct(EBand rowBand, EBand colBand)
{
var critical = Strongest(rowBand, colBand) == EBand.Critical;
return new() {
Verb = ESurfaceInteractionVerb.Conduct,
Quantity = ESurfaceQuantity.Electricity,
Amount = critical ? ConductCriticalHeat : ConductCautionHeat,
SecondaryAmount = critical ? ConductCriticalDischarge : ConductCautionDischarge
};
}
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 int StepsPerPulse { 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 WaterSafe { get; }
public abstract float WaterCaution { get; }
public abstract float WaterCritical { 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 RobotWaterSafetyThreshold { 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<JunctionRatioPreset> TwoOutflowJunctionRatios { get; }
public abstract IReadOnlyList<JunctionRatioPreset> 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 SprinklerWaterPerStep { get; }
public abstract float SprinklerPressureDebt { get; }
public abstract float AmbientEvaporationPerStep { get; }
public abstract float HeatEvaporationScale { get; }
public abstract float EvaporationCoolingScale { get; }
public abstract float FlowTransferRatio { get; }
public abstract float WetElectricityFlowMultiplier { get; }
public abstract float WarmCautionAmount { get; }
public abstract float WarmCriticalAmount { get; }
public abstract float DiluteCautionAmount { get; }
public abstract float DiluteCriticalAmount { get; }
public abstract float QuenchCautionAmount { get; }
public abstract float QuenchCriticalAmount { get; }
public abstract float ConductCautionHeat { get; }
public abstract float ConductCautionDischarge { get; }
public abstract float ConductCriticalHeat { get; }
public abstract float ConductCriticalDischarge { 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; }
}