Add branch-aware junction flow
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
namespace ReactorMaintenance.Simulation;
|
||||
namespace ReactorMaintenance.Simulation;
|
||||
|
||||
public sealed class SimulationEngine
|
||||
{
|
||||
@@ -156,9 +156,10 @@ public sealed class SimulationEngine
|
||||
{
|
||||
var layer = level.Layer(carrier).ToArray();
|
||||
var sources = AllPositions(level).Where(position => level.GetProp(position) is { Type: EPropType.Flow, SwitchState: EPropSwitchState.Enabled, Carrier: var sourceCarrier } && sourceCarrier == carrier && level.GetUnderground(position, carrier).CarriesFlow).ToArray();
|
||||
var junctions = JunctionFlowAnalyzer.Analyze(level).Where(junction => junction.IsValid && junction.Carrier == carrier).ToDictionary(junction => junction.Position);
|
||||
|
||||
foreach (var source in sources)
|
||||
ApplySourceFlow(level, layer, source, carrier);
|
||||
ApplySourceFlow(level, layer, source, carrier, junctions);
|
||||
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => level with { Fuel = layer },
|
||||
@@ -168,7 +169,7 @@ public sealed class SimulationEngine
|
||||
};
|
||||
}
|
||||
|
||||
private static void ApplySourceFlow(LevelState level, UndergroundCell[] layer, GridPosition source, ECarrierType carrier)
|
||||
private static void ApplySourceFlow(LevelState level, UndergroundCell[] layer, GridPosition source, ECarrierType carrier, IReadOnlyDictionary<GridPosition, JunctionFlow> junctions)
|
||||
{
|
||||
var open = new Queue<(GridPosition Position, int Distance, float AmountFactor, float IntensityFactor)>();
|
||||
var best = new Dictionary<GridPosition, float>();
|
||||
@@ -191,7 +192,7 @@ public sealed class SimulationEngine
|
||||
if (!level.GetUnderground(next, carrier).CarriesFlow)
|
||||
continue;
|
||||
|
||||
var weights = BranchWeights(level, current.Position, next);
|
||||
var weights = BranchWeights(current.Position, next, junctions);
|
||||
var amountFactor = current.AmountFactor * weights.Amount;
|
||||
var intensityFactor = current.IntensityFactor * weights.Intensity;
|
||||
if (amountFactor <= 0 || intensityFactor <= 0)
|
||||
@@ -206,38 +207,12 @@ public sealed class SimulationEngine
|
||||
}
|
||||
}
|
||||
|
||||
private static (float Amount, float Intensity) BranchWeights(LevelState level, GridPosition from, GridPosition to)
|
||||
private static (float Amount, float Intensity) BranchWeights(GridPosition from, GridPosition to, IReadOnlyDictionary<GridPosition, JunctionFlow> junctions)
|
||||
{
|
||||
var prop = level.GetProp(from);
|
||||
return prop.Type switch {
|
||||
EPropType.TJunction => TJunctionWeights(prop.TJunctionMode),
|
||||
EPropType.CrossJunction => CrossJunctionWeights(prop.CrossJunctionMode),
|
||||
_ => (1, 1)
|
||||
};
|
||||
}
|
||||
if (!junctions.TryGetValue(from, out var junction))
|
||||
return (1, 1);
|
||||
|
||||
private static (float Amount, float Intensity) TJunctionWeights(ETJunctionMode mode)
|
||||
{
|
||||
var weight = mode switch {
|
||||
ETJunctionMode.ZeroFour => 0,
|
||||
ETJunctionMode.OneThree => 0.25f,
|
||||
ETJunctionMode.TwoTwo => 0.5f,
|
||||
ETJunctionMode.ThreeOne => 0.75f,
|
||||
ETJunctionMode.FourZero => 1,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(mode), mode, "Unsupported T-junction mode.")
|
||||
};
|
||||
return (weight, weight);
|
||||
}
|
||||
|
||||
private static (float Amount, float Intensity) CrossJunctionWeights(ECrossJunctionMode mode)
|
||||
{
|
||||
var weight = mode switch {
|
||||
ECrossJunctionMode.ZeroThreeThree => 0,
|
||||
ECrossJunctionMode.ThreeZeroThree => 0.5f,
|
||||
ECrossJunctionMode.ThreeThreeZero => 0.5f,
|
||||
ECrossJunctionMode.TwoTwoTwo => 1f / 3f,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(mode), mode, "Unsupported cross-junction mode.")
|
||||
};
|
||||
var weight = junction.WeightFor(to);
|
||||
return (weight, weight);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user