Rename coolant to water
This commit is contained in:
46
TASKS.md
46
TASKS.md
@@ -8,7 +8,7 @@ This backlog tracks what must change so the implementation matches `docs/design.
|
||||
- Existing tests cover older behavior. They are useful regression scaffolding, but they do not prove the latest design rules.
|
||||
- The simulation has a working `SimulationEngine`, network propagation, consumers, structural integrity, leaks, reactor readiness, forecasts, serialization, editor helpers, and Godot session bridge.
|
||||
- Godot currently has a usable UX scaffold and grid renderer, but it still exposes older interaction concepts such as a player-facing `EndTurn` action and always-available underground layer controls.
|
||||
- Existing campaign data is the older three-level placeholder set: `coolant_restart.json`, `fuel_bleed.json`, and `black_start.json`. These levels and manifest entries must be replaced by the tutorial plus six-group campaign from `docs/CAMPAIGN.md`.
|
||||
- Existing campaign data is the older three-level placeholder set: `water_restart.json`, `fuel_bleed.json`, and `black_start.json`. These levels and manifest entries must be replaced by the tutorial plus six-group campaign from `docs/CAMPAIGN.md`.
|
||||
- Unrelated Godot metadata or generated `.uid` files are not part of this backlog unless a later implementation task intentionally touches them.
|
||||
|
||||
## P0 Simulation Contract
|
||||
@@ -27,34 +27,34 @@ This backlog tracks what must change so the implementation matches `docs/design.
|
||||
- Block intentional underground propagation across the authored branch boundary.
|
||||
- Preserve downstream starvation/readiness consequences for consumers and reactor feed.
|
||||
- Add editor placement, validation, serialization, and rendering support.
|
||||
- [ ] Add `SprinklerControlProp` and wall-mounted `CoolantSprinklerValve`.
|
||||
- A `SprinklerControlProp` links to exactly one `CoolantSprinklerValve`.
|
||||
- [ ] Add `SprinklerControlProp` and wall-mounted `SprinklerValve`.
|
||||
- A `SprinklerControlProp` links to exactly one `SprinklerValve`.
|
||||
- The valve is wall-mounted, not directly interactive, and has exactly one outlet/access floor face.
|
||||
- Discharge creates `SprinklerWater` only while linked control is `Enabled` and the coolant branch is fed.
|
||||
- Discharge applies deterministic local coolant pressure debt.
|
||||
- Discharge creates `Water` only while linked control is `Enabled` and the water branch is fed.
|
||||
- Discharge applies deterministic local water pressure debt.
|
||||
- Add editor placement/linking, validation, serialization, and rendering support.
|
||||
- [ ] Rework surface coolant into `SprinklerWater`.
|
||||
- Rename code-facing concepts where practical; otherwise make names and UI text consistently mean sprinkler water, not a generic coolant hazard.
|
||||
- `Coolant` pipe failures should inject `SprinklerWater`, not a second damaging liquid.
|
||||
- `SprinklerWater` alone must not cause `UnsafeEntryLoss`.
|
||||
- [ ] Rework surface water into `Water`.
|
||||
- Rename code-facing concepts where practical; otherwise make names and UI text consistently mean water, not a generic hazard.
|
||||
- `water` pipe failures should inject `Water`, not a damaging liquid.
|
||||
- `Water` alone must not cause `UnsafeEntryLoss`.
|
||||
- [ ] Update leak injection.
|
||||
- Leaks inject only when the underground leak cell has positive amount and positive pressure/voltage after propagation.
|
||||
- Isolating a leak stops fresh injection without repairing the underlying fault.
|
||||
- Repair restores structural integrity and stops future injection but does not clean existing surface values.
|
||||
- [ ] Implement the approved surface interaction order.
|
||||
- Resolve leak/sprinkler injection per `Step`.
|
||||
- Resolve coolant mitigation before ignition and electrical spread.
|
||||
- Resolve water mitigation before ignition and electrical spread.
|
||||
- Implement `Dilute`, `Quench`, value-based `Evaporate`, wet-electric `Conduct`, and `Ignite`.
|
||||
- Preserve deterministic same-cell and adjacent-cell delta accumulation.
|
||||
- Closed powered doors and remedy blocks must gate only the interactions they explicitly block.
|
||||
- [ ] Implement value-based evaporation.
|
||||
- Add balance values for ambient evaporation, heat-driven evaporation, and evaporation cooling.
|
||||
- Hot cells should evaporate `SprinklerWater` faster than cold cells.
|
||||
- Hot cells should evaporate `Water` faster than cold cells.
|
||||
- Evaporation happens during useful action pulses; there is no campaign wait command.
|
||||
- [ ] Implement `Unsafe` as derived movement safety.
|
||||
- `Unsafe` is recalculated after authored setup and after each `Pulse`.
|
||||
- `Unsafe` is caused by unsafe `Heat`, unsafe `LeakedElectricity`, or the wet-electric unsafe rule.
|
||||
- `LeakedFuel` alone and `SprinklerWater` alone are not `Unsafe`.
|
||||
- `LeakedFuel` alone and `Water` alone are not `Unsafe`.
|
||||
- `UnsafeEntryLoss` happens only when `MoveRobot` enters an `Unsafe` destination without applicable protection.
|
||||
- A `Pulse` must not kill a stationary robot just because the current cell becomes `Unsafe`.
|
||||
- [ ] Implement powered prop behavior.
|
||||
@@ -72,7 +72,7 @@ This backlog tracks what must change so the implementation matches `docs/design.
|
||||
|
||||
## P0 Simulation Tests
|
||||
|
||||
- [ ] Update existing tests so their names and assertions use `Pulse`, `Step`, `SprinklerWater`, `Unsafe`, and `ReactorReadiness` terminology.
|
||||
- [ ] Update existing tests so their names and assertions use `Pulse`, `Step`, `Water`, `Unsafe`, and `ReactorReadiness` terminology.
|
||||
- [ ] Add tests for fixed pulse length.
|
||||
- Every accepted `LengthyAction` advances one `Pulse`.
|
||||
- Each pulse resolves the configured number of `Step`s.
|
||||
@@ -84,18 +84,18 @@ This backlog tracks what must change so the implementation matches `docs/design.
|
||||
- Open valve allows branch propagation.
|
||||
- Closed valve isolates damaged branches and can starve downstream consumers/reactor feed.
|
||||
- Toggling a valve triggers exactly one `Pulse`.
|
||||
- [ ] Add tests for `SprinklerControlProp` and `CoolantSprinklerValve`.
|
||||
- Valve discharge requires a linked enabled control and fed coolant branch.
|
||||
- [ ] Add tests for `SprinklerControlProp` and `SprinklerValve`.
|
||||
- Valve discharge requires a linked enabled control and fed water branch.
|
||||
- Direct valve interaction is invalid or unavailable.
|
||||
- Discharge creates `SprinklerWater` at the authored outlet and applies pressure debt.
|
||||
- Discharge creates `Water` at the authored outlet and applies pressure debt.
|
||||
- Disabling the linked control or isolating the sprinkler branch stops fresh discharge.
|
||||
- [ ] Add tests for updated leak injection.
|
||||
- Fed fuel, coolant, and electricity leaks inject to the correct access face.
|
||||
- Fed fuel, water, and electricity leaks inject to the correct access face.
|
||||
- Isolated leaks stop new surface injection.
|
||||
- Repairs restore structural integrity without cleaning existing surface values.
|
||||
- [ ] Add tests for surface interactions.
|
||||
- `SprinklerWater` dilutes `LeakedFuel`.
|
||||
- `SprinklerWater` quenches `Heat`.
|
||||
- `Water` dilutes `LeakedFuel`.
|
||||
- `Water` quenches `Heat`.
|
||||
- Evaporation removes water and cools heat according to balance values.
|
||||
- Wet cells conduct electricity faster than dry cells.
|
||||
- Fuel plus electricity or heat can ignite and create heat while consuming fuel.
|
||||
@@ -126,7 +126,7 @@ This backlog tracks what must change so the implementation matches `docs/design.
|
||||
- [ ] Update serialization round trips for new fields.
|
||||
- `IsolationValveProp` carrier and open/closed state.
|
||||
- `SprinklerControlProp` enabled/disabled state and linked valve id or position.
|
||||
- `CoolantSprinklerValve` wall position, outlet/access face, linked control, and coolant connection.
|
||||
- `SprinklerValve` wall position, outlet/access face, linked control, and water connection.
|
||||
- Powered terminal active state if it becomes serialized runtime state.
|
||||
- [ ] Update `LevelEditor` tools.
|
||||
- Add isolation valve placement.
|
||||
@@ -137,7 +137,7 @@ This backlog tracks what must change so the implementation matches `docs/design.
|
||||
- [ ] Update `LevelValidator`.
|
||||
- Validate powered doors have valid geometry and local electricity.
|
||||
- Validate terminal power requirements where needed.
|
||||
- Validate wall-mounted sprinkler valve geometry, outlet/access face, coolant connection, and exactly one linked control.
|
||||
- Validate wall-mounted sprinkler valve geometry, outlet/access face, water connection, and exactly one linked control.
|
||||
- Validate isolation valves sit on exactly one matching underground carrier.
|
||||
- Warn on initially unready reactors, initially starved required consumers, unused supplies, and sprinkler valves with no useful suppression or pressure tradeoff.
|
||||
- [ ] Replace placeholder campaign files.
|
||||
@@ -167,7 +167,7 @@ This backlog tracks what must change so the implementation matches `docs/design.
|
||||
- Show why terminal access is unavailable when unpowered or away from the terminal.
|
||||
- Use `Pulse +N` wording in forecast UI.
|
||||
- [ ] Update grid rendering and inspector text.
|
||||
- Render `SprinklerWater` separately from underground `Coolant`.
|
||||
- Render `Water` separately from underground `water`.
|
||||
- Render `Unsafe` cells with a distinct movement warning treatment.
|
||||
- Render isolation valve state, sprinkler control state, wall-mounted sprinkler outlet, powered door state, and powered terminal state.
|
||||
- Inspector should display visible surface values, prop state, consumer per-carrier state, and underground values only when terminal access allows it.
|
||||
@@ -182,7 +182,7 @@ This backlog tracks what must change so the implementation matches `docs/design.
|
||||
- [ ] Add campaign completion flow for the final Group 6 level.
|
||||
- [ ] Add loading and malformed-level error states for campaign level loading.
|
||||
- [ ] Verify Win2D editor export and Godot loader compatibility for the new schema.
|
||||
- [ ] Revisit art labels/icons for `SprinklerWater`, `Unsafe`, powered props, and sprinkler controls after mechanics are implemented.
|
||||
- [ ] Revisit art labels/icons for `Water`, `Unsafe`, powered props, and sprinkler controls after mechanics are implemented.
|
||||
|
||||
## Verification Rules
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public partial class CellInspector : PanelContainer
|
||||
m_Text.AutowrapMode = TextServer.AutowrapMode.WordSmart;
|
||||
}
|
||||
|
||||
public void SetCellInfo(GridPosition? position, ECellTerrain terrain, EPropType prop, EConsumerServiceState serviceState, float fuelHazard, float coolantHazard, float electricityHazard, float heatHazard)
|
||||
public void SetCellInfo(GridPosition? position, ECellTerrain terrain, EPropType prop, EConsumerServiceState serviceState, float fuelHazard, float waterHazard, float electricityHazard, float heatHazard)
|
||||
{
|
||||
var pos = position ?? new(-1, -1);
|
||||
var sb = new StringBuilder();
|
||||
@@ -32,15 +32,15 @@ public partial class CellInspector : PanelContainer
|
||||
sb.AppendLine($"Prop: {prop}");
|
||||
if (prop != EPropType.None)
|
||||
sb.AppendLine($"Service: {serviceState}");
|
||||
sb.AppendLine($"Hazards: {FormatHazards(fuelHazard, coolantHazard, electricityHazard, heatHazard)}");
|
||||
sb.AppendLine($"Hazards: {FormatHazards(fuelHazard, waterHazard, electricityHazard, heatHazard)}");
|
||||
m_Text.Text = sb.ToString();
|
||||
}
|
||||
|
||||
private static string FormatHazards(float fuel, float coolant, float electricity, float heat)
|
||||
private static string FormatHazards(float fuel, float water, float electricity, float heat)
|
||||
{
|
||||
var parts = new List<string>();
|
||||
if (fuel > 0) parts.Add($"fuel {fuel:F1}");
|
||||
if (coolant > 0) parts.Add($"coolant {coolant:F1}");
|
||||
if (water > 0) parts.Add($"water {water:F1}");
|
||||
if (electricity > 0) parts.Add($"electricity {electricity:F1}");
|
||||
if (heat > 0) parts.Add($"heat {heat:F1}");
|
||||
return parts.Count > 0 ? string.Join(", ", parts) : "none";
|
||||
|
||||
@@ -20,7 +20,7 @@ internal static class FrontendAssets
|
||||
return ResourceLoader.Exists(path) ? ResourceLoader.Load<Texture2D>(path) : null;
|
||||
}
|
||||
|
||||
public const string CoolantIcon = "res://Assets/Ui/coolant_icon.png";
|
||||
public const string WaterIcon = "res://Assets/Ui/water_icon.png";
|
||||
public const string ElectricIcon = "res://Assets/Ui/electric_icon.png";
|
||||
public const string FuelIcon = "res://Assets/Ui/fuel_icon.png";
|
||||
public const string HeatShieldIcon = "res://Assets/Ui/heat_shield_icon.png";
|
||||
|
||||
@@ -147,7 +147,7 @@ public partial class GridViewport : Control
|
||||
|
||||
private IEnumerable<ECarrierType> OrderedUndergroundLayers()
|
||||
{
|
||||
var carriers = new[] { ECarrierType.Fuel, ECarrierType.Coolant, ECarrierType.Electricity }.Where(IsLayerVisible).ToArray();
|
||||
var carriers = new[] { ECarrierType.Fuel, ECarrierType.Water, ECarrierType.Electricity }.Where(IsLayerVisible).ToArray();
|
||||
return ActiveUndergroundLayer is { } activeCarrier && carriers.Contains(activeCarrier)
|
||||
? carriers.Where(carrier => carrier != activeCarrier).Append(activeCarrier)
|
||||
: carriers;
|
||||
@@ -200,7 +200,7 @@ public partial class GridViewport : Control
|
||||
var surface = m_LevelState.GetSurface(position);
|
||||
var rect = layout.CellRect(position);
|
||||
FillHazard(rect, surface.Fuel, c_FuelColor, 0.08f, opacity, Balancing.Current.FuelCaution, Balancing.Current.FuelCritical);
|
||||
FillHazard(rect, surface.Coolant, c_CoolantColor, 0.18f, opacity, Balancing.Current.CoolantCaution, Balancing.Current.CoolantCritical);
|
||||
FillHazard(rect, surface.Water, c_WaterColor, 0.18f, opacity, Balancing.Current.WaterCaution, Balancing.Current.WaterCritical);
|
||||
FillHazard(rect, surface.Electricity, c_ElectricityColor, 0.28f, opacity, Balancing.Current.ElectricityCaution, Balancing.Current.ElectricityCritical);
|
||||
FillHazard(rect, surface.Heat, c_HeatColor, 0.34f, opacity, Balancing.Current.HeatCaution, Balancing.Current.HeatCritical);
|
||||
}
|
||||
@@ -427,7 +427,7 @@ public partial class GridViewport : Control
|
||||
{
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => ShowFuelLayer,
|
||||
ECarrierType.Coolant => ShowCoolantLayer,
|
||||
ECarrierType.Water => ShowWaterLayer,
|
||||
ECarrierType.Electricity => ShowElectricityLayer,
|
||||
_ => false
|
||||
};
|
||||
@@ -501,7 +501,7 @@ public partial class GridViewport : Control
|
||||
{
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => c_FuelColor,
|
||||
ECarrierType.Coolant => c_CoolantColor,
|
||||
ECarrierType.Water => c_WaterColor,
|
||||
ECarrierType.Electricity => c_ElectricityColor,
|
||||
_ => Colors.White
|
||||
};
|
||||
@@ -537,7 +537,7 @@ public partial class GridViewport : Control
|
||||
{
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => "F",
|
||||
ECarrierType.Coolant => "C",
|
||||
ECarrierType.Water => "C",
|
||||
ECarrierType.Electricity => "E",
|
||||
_ => "?"
|
||||
};
|
||||
@@ -547,7 +547,7 @@ public partial class GridViewport : Control
|
||||
{
|
||||
return remedy switch {
|
||||
ERemedyType.FuelNeutralizer => "F REM",
|
||||
ERemedyType.CoolantNeutralizer => "C REM",
|
||||
ERemedyType.WaterNeutralizer => "C REM",
|
||||
ERemedyType.ElectricityNeutralizer => "E REM",
|
||||
ERemedyType.HeatShield => "H SHD",
|
||||
_ => "REM"
|
||||
@@ -588,7 +588,7 @@ public partial class GridViewport : Control
|
||||
public Vector2I HoveredCell { get; private set; } = c_InvalidCell;
|
||||
public Vector2I RobotPosition { get; private set; } = c_InvalidCell;
|
||||
public bool ShowFuelLayer { get; set; } = true;
|
||||
public bool ShowCoolantLayer { get; set; } = true;
|
||||
public bool ShowWaterLayer { get; set; } = true;
|
||||
public bool ShowElectricityLayer { get; set; } = true;
|
||||
public ECarrierType? ActiveUndergroundLayer { get; set; }
|
||||
|
||||
@@ -611,7 +611,7 @@ public partial class GridViewport : Control
|
||||
private const int c_AllCorners = c_TopLeftCorner | c_TopRightCorner | c_BottomLeftCorner | c_BottomRightCorner;
|
||||
private static readonly Vector2I c_InvalidCell = new(-1, -1);
|
||||
private static readonly Color c_BackgroundColor = new(0.06f, 0.07f, 0.08f);
|
||||
private static readonly Color c_CoolantColor = new(0.20f, 0.78f, 0.92f);
|
||||
private static readonly Color c_WaterColor = new(0.20f, 0.78f, 0.92f);
|
||||
private static readonly Color c_DisabledColor = new(0.32f, 0.34f, 0.35f);
|
||||
private static readonly Color c_ElectricityColor = new(0.96f, 0.78f, 0.20f);
|
||||
private static readonly Color c_FuelColor = new(0.86f, 0.20f, 0.18f);
|
||||
|
||||
@@ -7,19 +7,19 @@ public partial class InventoryStrip : HBoxContainer
|
||||
public override void _Ready()
|
||||
{
|
||||
AddChild(CreateItem("Fuel Neutralizer", 2, FrontendAssets.FuelIcon, out var fuelLabel));
|
||||
AddChild(CreateItem("Coolant Neutralizer", 2, FrontendAssets.CoolantIcon, out var coolantLabel));
|
||||
AddChild(CreateItem("Water Neutralizer", 2, FrontendAssets.WaterIcon, out var waterLabel));
|
||||
AddChild(CreateItem("Electric Neutralizer", 1, FrontendAssets.ElectricIcon, out var electricLabel));
|
||||
AddChild(CreateItem("Heat Shield", 1, FrontendAssets.HeatShieldIcon, out var heatLabel));
|
||||
m_FuelLabel = fuelLabel;
|
||||
m_CoolantLabel = coolantLabel;
|
||||
m_WaterLabel = waterLabel;
|
||||
m_ElectricLabel = electricLabel;
|
||||
m_HeatLabel = heatLabel;
|
||||
}
|
||||
|
||||
public void SetInventory(int fuelNeutralizers, int coolantNeutralizers, int electricNeutralizers, int heatShields)
|
||||
public void SetInventory(int fuelNeutralizers, int waterNeutralizers, int electricNeutralizers, int heatShields)
|
||||
{
|
||||
m_FuelLabel.Text = $"{fuelNeutralizers}";
|
||||
m_CoolantLabel.Text = $"{coolantNeutralizers}";
|
||||
m_WaterLabel.Text = $"{waterNeutralizers}";
|
||||
m_ElectricLabel.Text = $"{electricNeutralizers}";
|
||||
m_HeatLabel.Text = $"{heatShields}";
|
||||
}
|
||||
@@ -40,7 +40,7 @@ public partial class InventoryStrip : HBoxContainer
|
||||
return item;
|
||||
}
|
||||
|
||||
private Label m_CoolantLabel = null!;
|
||||
private Label m_WaterLabel = null!;
|
||||
private Label m_ElectricLabel = null!;
|
||||
|
||||
private Label m_FuelLabel = null!;
|
||||
|
||||
@@ -113,7 +113,7 @@ public sealed class GameSession
|
||||
public ECellTerrain[] Terrain => LevelState.Terrain;
|
||||
public SurfaceState[] Surface => LevelState.Surface;
|
||||
public UndergroundCell[] UndergroundFuel => LevelState.Fuel;
|
||||
public UndergroundCell[] UndergroundCoolant => LevelState.Coolant;
|
||||
public UndergroundCell[] UndergroundWater => LevelState.Water;
|
||||
public UndergroundCell[] UndergroundElectricity => LevelState.Electricity;
|
||||
public delegate void StateChangedHandler(GameSession sender);
|
||||
|
||||
|
||||
@@ -82,10 +82,10 @@ public partial class LevelScreen : ScreenBase
|
||||
m_GridViewport.ShowFuelLayer = pressed;
|
||||
m_GridViewport.QueueRedraw();
|
||||
}));
|
||||
controls.AddChild(CreateLayerToggle("Coolant", true, pressed => {
|
||||
controls.AddChild(CreateLayerToggle("Water", true, pressed => {
|
||||
if (m_GridViewport is null) return;
|
||||
|
||||
m_GridViewport.ShowCoolantLayer = pressed;
|
||||
m_GridViewport.ShowWaterLayer = pressed;
|
||||
m_GridViewport.QueueRedraw();
|
||||
}));
|
||||
controls.AddChild(CreateLayerToggle("Electricity", true, pressed => {
|
||||
@@ -98,14 +98,14 @@ public partial class LevelScreen : ScreenBase
|
||||
var activeLayer = new OptionButton();
|
||||
activeLayer.AddItem("Surface", 0);
|
||||
activeLayer.AddItem("Fuel", 1);
|
||||
activeLayer.AddItem("Coolant", 2);
|
||||
activeLayer.AddItem("Water", 2);
|
||||
activeLayer.AddItem("Electricity", 3);
|
||||
activeLayer.ItemSelected += index => {
|
||||
if (m_GridViewport is null) return;
|
||||
|
||||
m_GridViewport.ActiveUndergroundLayer = index switch {
|
||||
1 => ECarrierType.Fuel,
|
||||
2 => ECarrierType.Coolant,
|
||||
2 => ECarrierType.Water,
|
||||
3 => ECarrierType.Electricity,
|
||||
_ => null
|
||||
};
|
||||
@@ -187,7 +187,7 @@ public partial class LevelScreen : ScreenBase
|
||||
|
||||
m_InventoryStrip.SetInventory(
|
||||
m_Session.LevelState.Robot.FuelNeutralizers,
|
||||
m_Session.LevelState.Robot.CoolantNeutralizers,
|
||||
m_Session.LevelState.Robot.WaterNeutralizers,
|
||||
m_Session.LevelState.Robot.ElectricityNeutralizers,
|
||||
m_Session.LevelState.Robot.HeatShields);
|
||||
}
|
||||
@@ -213,7 +213,7 @@ public partial class LevelScreen : ScreenBase
|
||||
prop.Type,
|
||||
prop.ServiceState,
|
||||
surface.Fuel,
|
||||
surface.Coolant,
|
||||
surface.Water,
|
||||
surface.Electricity,
|
||||
surface.Heat);
|
||||
}
|
||||
|
||||
@@ -46,10 +46,10 @@ public abstract class Balancing
|
||||
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)
|
||||
if (rowCarrier == ECarrierType.Water && colCarrier == ECarrierType.Electricity)
|
||||
return Short(rowBand, colBand);
|
||||
|
||||
if (rowCarrier == ECarrierType.Coolant && colCarrier is null)
|
||||
if (rowCarrier == ECarrierType.Water && colCarrier is null)
|
||||
return Quench(rowBand, colBand);
|
||||
|
||||
return SurfaceInteractionEffect.Hold;
|
||||
@@ -64,7 +64,7 @@ public abstract class Balancing
|
||||
{
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => FuelCritical,
|
||||
ECarrierType.Coolant => CoolantCritical,
|
||||
ECarrierType.Water => WaterCritical,
|
||||
ECarrierType.Electricity => ElectricityCritical,
|
||||
_ => MaxValue
|
||||
};
|
||||
@@ -126,9 +126,9 @@ public abstract class Balancing
|
||||
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 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; }
|
||||
@@ -137,7 +137,7 @@ public abstract class Balancing
|
||||
public abstract float HeatCritical { get; }
|
||||
public abstract float TerminalHeat { get; }
|
||||
public abstract float RobotFuelSafetyThreshold { get; }
|
||||
public abstract float RobotCoolantSafetyThreshold { get; }
|
||||
public abstract float RobotWaterSafetyThreshold { get; }
|
||||
public abstract float RobotElectricitySafetyThreshold { get; }
|
||||
public abstract float RobotHeatSafetyThreshold { get; }
|
||||
public abstract float SourceAmount { get; }
|
||||
|
||||
@@ -11,9 +11,9 @@ public class NormalBalancing : Balancing
|
||||
public override float FuelSafe => 1.5f;
|
||||
public override float FuelCaution => 3.5f;
|
||||
public override float FuelCritical => 6.5f;
|
||||
public override float CoolantSafe => 1.5f;
|
||||
public override float CoolantCaution => 3.5f;
|
||||
public override float CoolantCritical => 6.5f;
|
||||
public override float WaterSafe => 1.5f;
|
||||
public override float WaterCaution => 3.5f;
|
||||
public override float WaterCritical => 6.5f;
|
||||
public override float ElectricitySafe => 1.5f;
|
||||
public override float ElectricityCaution => 3.5f;
|
||||
public override float ElectricityCritical => 6.5f;
|
||||
@@ -22,7 +22,7 @@ public class NormalBalancing : Balancing
|
||||
public override float HeatCritical => 8;
|
||||
public override float TerminalHeat => 10;
|
||||
public override float RobotFuelSafetyThreshold => 6.5f;
|
||||
public override float RobotCoolantSafetyThreshold => 8;
|
||||
public override float RobotWaterSafetyThreshold => 8;
|
||||
public override float RobotElectricitySafetyThreshold => 6.5f;
|
||||
public override float RobotHeatSafetyThreshold => 8;
|
||||
public override float SourceAmount => 8;
|
||||
|
||||
@@ -73,10 +73,10 @@ public static class LevelEditor
|
||||
|
||||
private static MoveOccupantResult TryMoveLeak(LevelState level, LeakState leak, GridPosition destination)
|
||||
{
|
||||
if (leak.Carrier is ECarrierType.Fuel or ECarrierType.Coolant)
|
||||
if (leak.Carrier is ECarrierType.Fuel or ECarrierType.Water)
|
||||
{
|
||||
if (!level.IsFloor(destination))
|
||||
return MoveOccupantResult.Failed(level, "Fuel and coolant leaks must move to a floor cell.");
|
||||
return MoveOccupantResult.Failed(level, "Fuel and water leaks must move to a floor cell.");
|
||||
|
||||
var next = ClearLeak(level, leak)
|
||||
.SetUnderground(leak.UndergroundPosition, leak.Carrier, new());
|
||||
@@ -158,7 +158,7 @@ public static class LevelEditor
|
||||
if (!level.InBounds(undergroundPosition) || !level.IsFloor(accessPosition))
|
||||
return level;
|
||||
|
||||
if (carrier is ECarrierType.Fuel or ECarrierType.Coolant && undergroundPosition != accessPosition)
|
||||
if (carrier is ECarrierType.Fuel or ECarrierType.Water && undergroundPosition != accessPosition)
|
||||
return level;
|
||||
|
||||
if (carrier == ECarrierType.Electricity && undergroundPosition.ManhattanDistance(accessPosition) != 1)
|
||||
@@ -198,7 +198,7 @@ public static class LevelEditor
|
||||
var surface = level.GetSurface(position);
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => level.SetSurface(position, surface with { Fuel = surface.Fuel + 1 }),
|
||||
ECarrierType.Coolant => level.SetSurface(position, surface with { Coolant = surface.Coolant + 1 }),
|
||||
ECarrierType.Water => level.SetSurface(position, surface with { Water = surface.Water + 1 }),
|
||||
ECarrierType.Electricity => level.SetSurface(position, surface with { Electricity = surface.Electricity + 1 }),
|
||||
_ => level
|
||||
};
|
||||
|
||||
@@ -59,7 +59,7 @@ public static class LevelStateExtensions
|
||||
next[level.Index(position)] = cell;
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => level with { Fuel = next },
|
||||
ECarrierType.Coolant => level with { Coolant = next },
|
||||
ECarrierType.Water => level with { Water = next },
|
||||
ECarrierType.Electricity => level with { Electricity = next },
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(carrier), carrier, "Unsupported carrier.")
|
||||
};
|
||||
@@ -79,11 +79,11 @@ public static class LevelStateExtensions
|
||||
return level with { Props = next };
|
||||
}
|
||||
|
||||
public static LevelState WithRuntimeArrays(this LevelState level, UndergroundCell[] fuel, UndergroundCell[] coolant, UndergroundCell[] electricity, SurfaceState[] surface, PropState[] props)
|
||||
public static LevelState WithRuntimeArrays(this LevelState level, UndergroundCell[] fuel, UndergroundCell[] water, UndergroundCell[] electricity, SurfaceState[] surface, PropState[] props)
|
||||
{
|
||||
return level with {
|
||||
Fuel = fuel,
|
||||
Coolant = coolant,
|
||||
Water = water,
|
||||
Electricity = electricity,
|
||||
Surface = surface,
|
||||
Props = props
|
||||
@@ -94,7 +94,7 @@ public static class LevelStateExtensions
|
||||
{
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => level.Fuel,
|
||||
ECarrierType.Coolant => level.Coolant,
|
||||
ECarrierType.Water => level.Water,
|
||||
ECarrierType.Electricity => level.Electricity,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(carrier), carrier, "Unsupported carrier.")
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ public static class LevelStateFactory
|
||||
Height = height,
|
||||
Terrain = CreateTerrain(width, height),
|
||||
Fuel = CreateUnderground(width, height),
|
||||
Coolant = CreateUnderground(width, height),
|
||||
Water = CreateUnderground(width, height),
|
||||
Electricity = CreateUnderground(width, height),
|
||||
Surface = CreateSurface(width, height),
|
||||
Props = CreateProps(width, height),
|
||||
|
||||
@@ -25,7 +25,7 @@ public sealed class LevelValidator
|
||||
errors.Add(new("Invalid level dimensions."));
|
||||
|
||||
var expected = level.Width * level.Height;
|
||||
if (level.Terrain.Length != expected || level.Fuel.Length != expected || level.Coolant.Length != expected || level.Electricity.Length != expected || level.Surface.Length != expected || level.Props.Length != expected)
|
||||
if (level.Terrain.Length != expected || level.Fuel.Length != expected || level.Water.Length != expected || level.Electricity.Length != expected || level.Surface.Length != expected || level.Props.Length != expected)
|
||||
errors.Add(new("Cell array counts do not match level dimensions."));
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public sealed class LevelValidator
|
||||
|
||||
if (level.GetTerrain(position) == ECellTerrain.Wall)
|
||||
{
|
||||
if (surface.Fuel > 0 || surface.Coolant > 0 || surface.Electricity > 0 || surface.Heat > 0)
|
||||
if (surface.Fuel > 0 || surface.Water > 0 || surface.Electricity > 0 || surface.Heat > 0)
|
||||
errors.Add(new("Wall cell cannot store surface hazards.", position));
|
||||
|
||||
if (prop.Type != EPropType.None)
|
||||
@@ -91,8 +91,8 @@ public sealed class LevelValidator
|
||||
if (!underground.IsPresent)
|
||||
errors.Add(new("Leak target must point to an underground cell.", leak.UndergroundPosition));
|
||||
|
||||
if (leak.Carrier is ECarrierType.Fuel or ECarrierType.Coolant && leak.UndergroundPosition != leak.AccessPosition)
|
||||
errors.Add(new("Fuel and coolant leaks must use their underground coordinate as access.", leak.AccessPosition));
|
||||
if (leak.Carrier is ECarrierType.Fuel or ECarrierType.Water && leak.UndergroundPosition != leak.AccessPosition)
|
||||
errors.Add(new("Fuel and water leaks must use their underground coordinate as access.", leak.AccessPosition));
|
||||
|
||||
if (leak.Carrier == ECarrierType.Electricity && leak.UndergroundPosition.ManhattanDistance(leak.AccessPosition) != 1)
|
||||
errors.Add(new("Electricity leak access must be an adjacent floor face.", leak.AccessPosition));
|
||||
@@ -110,7 +110,7 @@ public sealed class LevelValidator
|
||||
warnings.Add(new("Reactor is initially unready.", reactor.ControlPosition));
|
||||
}
|
||||
|
||||
if (level.RequiredFuelConsumers < 0 || level.RequiredCoolantConsumers < 0 || level.RequiredElectricityConsumers < 0)
|
||||
if (level.RequiredFuelConsumers < 0 || level.RequiredWaterConsumers < 0 || level.RequiredElectricityConsumers < 0)
|
||||
errors.Add(new("Required consumer counts cannot be negative."));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
public enum ECarrierType
|
||||
{
|
||||
Fuel,
|
||||
Coolant,
|
||||
Water,
|
||||
Electricity
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
public enum ERemedyType
|
||||
{
|
||||
FuelNeutralizer,
|
||||
CoolantNeutralizer,
|
||||
WaterNeutralizer,
|
||||
ElectricityNeutralizer,
|
||||
HeatShield
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
public enum ESurfaceQuantity
|
||||
{
|
||||
Fuel,
|
||||
Coolant,
|
||||
Water,
|
||||
Electricity,
|
||||
Heat
|
||||
}
|
||||
@@ -12,14 +12,14 @@ public sealed record LevelState
|
||||
public int Height { get; init; } = Balancing.Current.DefaultLevelHeight;
|
||||
public ECellTerrain[] Terrain { get; init; } = LevelStateFactory.CreateTerrain(Balancing.Current.DefaultLevelWidth, Balancing.Current.DefaultLevelHeight);
|
||||
public UndergroundCell[] Fuel { get; init; } = LevelStateFactory.CreateUnderground(Balancing.Current.DefaultLevelWidth, Balancing.Current.DefaultLevelHeight);
|
||||
public UndergroundCell[] Coolant { get; init; } = LevelStateFactory.CreateUnderground(Balancing.Current.DefaultLevelWidth, Balancing.Current.DefaultLevelHeight);
|
||||
public UndergroundCell[] Water { get; init; } = LevelStateFactory.CreateUnderground(Balancing.Current.DefaultLevelWidth, Balancing.Current.DefaultLevelHeight);
|
||||
public UndergroundCell[] Electricity { get; init; } = LevelStateFactory.CreateUnderground(Balancing.Current.DefaultLevelWidth, Balancing.Current.DefaultLevelHeight);
|
||||
public SurfaceState[] Surface { get; init; } = LevelStateFactory.CreateSurface(Balancing.Current.DefaultLevelWidth, Balancing.Current.DefaultLevelHeight);
|
||||
public PropState[] Props { get; init; } = LevelStateFactory.CreateProps(Balancing.Current.DefaultLevelWidth, Balancing.Current.DefaultLevelHeight);
|
||||
public IReadOnlyList<LeakState> Leaks { get; init; } = Array.Empty<LeakState>();
|
||||
public IReadOnlyList<ReactorState> Reactors { get; init; } = Array.Empty<ReactorState>();
|
||||
public int RequiredFuelConsumers { get; init; } = 1;
|
||||
public int RequiredCoolantConsumers { get; init; } = 1;
|
||||
public int RequiredWaterConsumers { get; init; } = 1;
|
||||
public int RequiredElectricityConsumers { get; init; } = 1;
|
||||
public RobotState Robot { get; init; } = new();
|
||||
public GlobalState Global { get; init; } = new();
|
||||
|
||||
@@ -6,7 +6,7 @@ public sealed record PropState
|
||||
{
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => FuelServiceState,
|
||||
ECarrierType.Coolant => CoolantServiceState,
|
||||
ECarrierType.Water => WaterServiceState,
|
||||
ECarrierType.Electricity => ElectricityServiceState,
|
||||
_ => EConsumerServiceState.Unknown
|
||||
};
|
||||
@@ -17,7 +17,7 @@ public sealed record PropState
|
||||
public EPropSwitchState SwitchState { get; init; } = EPropSwitchState.Enabled;
|
||||
public EConsumerServiceState ServiceState { get; init; } = EConsumerServiceState.Unknown;
|
||||
public EConsumerServiceState FuelServiceState { get; init; } = EConsumerServiceState.Unknown;
|
||||
public EConsumerServiceState CoolantServiceState { get; init; } = EConsumerServiceState.Unknown;
|
||||
public EConsumerServiceState WaterServiceState { get; init; } = EConsumerServiceState.Unknown;
|
||||
public EConsumerServiceState ElectricityServiceState { get; init; } = EConsumerServiceState.Unknown;
|
||||
public int JunctionMode { get; init; }
|
||||
public ERemedyType RemedyType { get; init; }
|
||||
|
||||
@@ -4,7 +4,7 @@ public sealed record RobotState
|
||||
{
|
||||
public GridPosition Position { get; init; } = new(1, 1);
|
||||
public int FuelNeutralizers { get; init; }
|
||||
public int CoolantNeutralizers { get; init; }
|
||||
public int WaterNeutralizers { get; init; }
|
||||
public int ElectricityNeutralizers { get; init; }
|
||||
public int HeatShields { get; init; }
|
||||
public int HeatImmunitySteps { get; init; }
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
public sealed record SurfaceState
|
||||
{
|
||||
public float Fuel { get; init; }
|
||||
public float Coolant { get; init; }
|
||||
public float Water { get; init; }
|
||||
public float Electricity { get; init; }
|
||||
public float Heat { get; init; }
|
||||
public int FuelBlockTurns { get; init; }
|
||||
public int CoolantBlockTurns { get; init; }
|
||||
public int WaterBlockTurns { get; init; }
|
||||
public int ElectricityBlockTurns { get; init; }
|
||||
}
|
||||
@@ -6,7 +6,7 @@ public static class RobotStateExtensions
|
||||
{
|
||||
return remedy switch {
|
||||
ERemedyType.FuelNeutralizer => robot.FuelNeutralizers,
|
||||
ERemedyType.CoolantNeutralizer => robot.CoolantNeutralizers,
|
||||
ERemedyType.WaterNeutralizer => robot.WaterNeutralizers,
|
||||
ERemedyType.ElectricityNeutralizer => robot.ElectricityNeutralizers,
|
||||
ERemedyType.HeatShield => robot.HeatShields,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(remedy), remedy, "Unsupported remedy.")
|
||||
@@ -17,7 +17,7 @@ public static class RobotStateExtensions
|
||||
{
|
||||
return remedy switch {
|
||||
ERemedyType.FuelNeutralizer => robot with { FuelNeutralizers = ClampInventory(robot.FuelNeutralizers + amount) },
|
||||
ERemedyType.CoolantNeutralizer => robot with { CoolantNeutralizers = ClampInventory(robot.CoolantNeutralizers + amount) },
|
||||
ERemedyType.WaterNeutralizer => robot with { WaterNeutralizers = ClampInventory(robot.WaterNeutralizers + amount) },
|
||||
ERemedyType.ElectricityNeutralizer => robot with { ElectricityNeutralizers = ClampInventory(robot.ElectricityNeutralizers + amount) },
|
||||
ERemedyType.HeatShield => robot with { HeatShields = ClampInventory(robot.HeatShields + amount) },
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(remedy), remedy, "Unsupported remedy.")
|
||||
|
||||
@@ -6,7 +6,7 @@ internal static class SimulationBands
|
||||
{
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => Fuel(surface.Fuel),
|
||||
ECarrierType.Coolant => Coolant(surface.Coolant),
|
||||
ECarrierType.Water => Water(surface.Water),
|
||||
ECarrierType.Electricity => Electricity(surface.Electricity),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(carrier), carrier, "Unsupported carrier.")
|
||||
};
|
||||
@@ -17,7 +17,7 @@ internal static class SimulationBands
|
||||
var value = valueKind == ENetworkValueKind.Amount ? underground.Amount : underground.Intensity;
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => Fuel(value),
|
||||
ECarrierType.Coolant => Coolant(value),
|
||||
ECarrierType.Water => Water(value),
|
||||
ECarrierType.Electricity => Electricity(value),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(carrier), carrier, "Unsupported carrier.")
|
||||
};
|
||||
@@ -28,9 +28,9 @@ internal static class SimulationBands
|
||||
return Balancing.Current.Band(value, Balancing.Current.FuelCaution, Balancing.Current.FuelCritical);
|
||||
}
|
||||
|
||||
public static EBand Coolant(float value)
|
||||
public static EBand Water(float value)
|
||||
{
|
||||
return Balancing.Current.Band(value, Balancing.Current.CoolantCaution, Balancing.Current.CoolantCritical);
|
||||
return Balancing.Current.Band(value, Balancing.Current.WaterCaution, Balancing.Current.WaterCritical);
|
||||
}
|
||||
|
||||
public static EBand Electricity(float value)
|
||||
|
||||
@@ -6,7 +6,7 @@ internal static class SurfaceCarrierMath
|
||||
{
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => surface with { Fuel = surface.Fuel + amount },
|
||||
ECarrierType.Coolant => surface with { Coolant = surface.Coolant + amount },
|
||||
ECarrierType.Water => surface with { Water = surface.Water + amount },
|
||||
ECarrierType.Electricity => surface with { Electricity = surface.Electricity + amount },
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(carrier), carrier, "Unsupported carrier.")
|
||||
};
|
||||
@@ -16,7 +16,7 @@ internal static class SurfaceCarrierMath
|
||||
{
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => surface with { Fuel = 0, FuelBlockTurns = Balancing.Current.RemedyBlockTurns },
|
||||
ECarrierType.Coolant => surface with { Coolant = 0, CoolantBlockTurns = Balancing.Current.RemedyBlockTurns },
|
||||
ECarrierType.Water => surface with { Water = 0, WaterBlockTurns = Balancing.Current.RemedyBlockTurns },
|
||||
ECarrierType.Electricity => surface with { Electricity = 0, ElectricityBlockTurns = Balancing.Current.RemedyBlockTurns },
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(carrier), carrier, "Unsupported carrier.")
|
||||
};
|
||||
|
||||
@@ -7,11 +7,11 @@ public static class SurfaceStateExtensions
|
||||
var balancing = Balancing.Current;
|
||||
return surface with {
|
||||
Fuel = balancing.ClampValue(surface.Fuel),
|
||||
Coolant = balancing.ClampValue(surface.Coolant),
|
||||
Water = balancing.ClampValue(surface.Water),
|
||||
Electricity = balancing.ClampValue(surface.Electricity),
|
||||
Heat = balancing.ClampValue(surface.Heat),
|
||||
FuelBlockTurns = Math.Max(0, surface.FuelBlockTurns),
|
||||
CoolantBlockTurns = Math.Max(0, surface.CoolantBlockTurns),
|
||||
WaterBlockTurns = Math.Max(0, surface.WaterBlockTurns),
|
||||
ElectricityBlockTurns = Math.Max(0, surface.ElectricityBlockTurns)
|
||||
};
|
||||
}
|
||||
@@ -20,7 +20,7 @@ public static class SurfaceStateExtensions
|
||||
{
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => surface.FuelBlockTurns > 0,
|
||||
ECarrierType.Coolant => surface.CoolantBlockTurns > 0,
|
||||
ECarrierType.Water => surface.WaterBlockTurns > 0,
|
||||
ECarrierType.Electricity => surface.ElectricityBlockTurns > 0,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(carrier), carrier, "Unsupported carrier.")
|
||||
};
|
||||
|
||||
@@ -15,24 +15,24 @@ internal static class ConsumerSystem
|
||||
if (prop.SwitchState == EPropSwitchState.Disabled)
|
||||
{
|
||||
var disabledFuel = DisabledServiceStateFor(level, position, ECarrierType.Fuel);
|
||||
var disabledCoolant = DisabledServiceStateFor(level, position, ECarrierType.Coolant);
|
||||
var disabledWater = DisabledServiceStateFor(level, position, ECarrierType.Water);
|
||||
var disabledElectricity = DisabledServiceStateFor(level, position, ECarrierType.Electricity);
|
||||
props[index] = prop with {
|
||||
ServiceState = Aggregate(disabledFuel, disabledCoolant, disabledElectricity),
|
||||
ServiceState = Aggregate(disabledFuel, disabledWater, disabledElectricity),
|
||||
FuelServiceState = disabledFuel,
|
||||
CoolantServiceState = disabledCoolant,
|
||||
WaterServiceState = disabledWater,
|
||||
ElectricityServiceState = disabledElectricity
|
||||
};
|
||||
continue;
|
||||
}
|
||||
|
||||
var fuel = ServiceStateFor(level, position, ECarrierType.Fuel);
|
||||
var coolant = ServiceStateFor(level, position, ECarrierType.Coolant);
|
||||
var water = ServiceStateFor(level, position, ECarrierType.Water);
|
||||
var electricity = ServiceStateFor(level, position, ECarrierType.Electricity);
|
||||
props[index] = prop with {
|
||||
ServiceState = Aggregate(fuel, coolant, electricity),
|
||||
ServiceState = Aggregate(fuel, water, electricity),
|
||||
FuelServiceState = fuel,
|
||||
CoolantServiceState = coolant,
|
||||
WaterServiceState = water,
|
||||
ElectricityServiceState = electricity
|
||||
};
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ internal static class ForecastSystem
|
||||
return level with {
|
||||
Terrain = level.Terrain.ToArray(),
|
||||
Fuel = level.Fuel.ToArray(),
|
||||
Coolant = level.Coolant.ToArray(),
|
||||
Water = level.Water.ToArray(),
|
||||
Electricity = level.Electricity.ToArray(),
|
||||
Surface = level.Surface.ToArray(),
|
||||
Props = level.Props.ToArray(),
|
||||
@@ -61,7 +61,7 @@ internal static class ForecastSystem
|
||||
}
|
||||
|
||||
var surface = level.GetSurface(position);
|
||||
if (SimulationBands.Fuel(surface.Fuel) == EBand.Critical || SimulationBands.Coolant(surface.Coolant) == EBand.Critical || SimulationBands.Electricity(surface.Electricity) == EBand.Critical || SimulationBands.Heat(surface.Heat) == EBand.Critical)
|
||||
if (SimulationBands.Fuel(surface.Fuel) == EBand.Critical || SimulationBands.Water(surface.Water) == EBand.Critical || SimulationBands.Electricity(surface.Electricity) == EBand.Critical || SimulationBands.Heat(surface.Heat) == EBand.Critical)
|
||||
forecasts.Add(new(EForecastKind.HazardGrowth, position, turn, "Critical hazard"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ internal static class NetworkPropagationSystem
|
||||
public static LevelState Propagate(LevelState level)
|
||||
{
|
||||
var fuel = ClearTransient(level.Fuel);
|
||||
var coolant = ClearTransient(level.Coolant);
|
||||
var water = ClearTransient(level.Water);
|
||||
var electricity = ClearTransient(level.Electricity);
|
||||
var next = level.WithRuntimeArrays(fuel, coolant, electricity, level.Surface.ToArray(), level.Props.ToArray());
|
||||
var next = level.WithRuntimeArrays(fuel, water, electricity, level.Surface.ToArray(), level.Props.ToArray());
|
||||
|
||||
foreach (var carrier in Enum.GetValues<ECarrierType>())
|
||||
next = PropagateCarrier(next, carrier);
|
||||
@@ -31,7 +31,7 @@ internal static class NetworkPropagationSystem
|
||||
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => level with { Fuel = layer },
|
||||
ECarrierType.Coolant => level with { Coolant = layer },
|
||||
ECarrierType.Water => level with { Water = layer },
|
||||
ECarrierType.Electricity => level with { Electricity = layer },
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(carrier), carrier, "Unsupported carrier.")
|
||||
};
|
||||
|
||||
@@ -98,7 +98,7 @@ internal static class PlayerActionSystem
|
||||
{
|
||||
var remedy = leak.Carrier switch {
|
||||
ECarrierType.Fuel => ERemedyType.FuelNeutralizer,
|
||||
ECarrierType.Coolant => ERemedyType.CoolantNeutralizer,
|
||||
ECarrierType.Water => ERemedyType.WaterNeutralizer,
|
||||
ECarrierType.Electricity => ERemedyType.ElectricityNeutralizer,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(leak), leak.Carrier, "Unsupported leak carrier.")
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@ internal static class ReactorSystem
|
||||
if (maxHeat >= Balancing.Current.TerminalHeat)
|
||||
return level with { Reactors = reactors, Global = level.Global with { LevelState = ELevelState.Lost, TerminalLoss = true, Status = "REACTOR HEAT TERMINAL" } };
|
||||
|
||||
var hasCritical = level.Surface.Any(surface => SimulationBands.Fuel(surface.Fuel) == EBand.Critical || SimulationBands.Coolant(surface.Coolant) == EBand.Critical || SimulationBands.Electricity(surface.Electricity) == EBand.Critical || SimulationBands.Heat(surface.Heat) == EBand.Critical);
|
||||
var hasCritical = level.Surface.Any(surface => SimulationBands.Fuel(surface.Fuel) == EBand.Critical || SimulationBands.Water(surface.Water) == EBand.Critical || SimulationBands.Electricity(surface.Electricity) == EBand.Critical || SimulationBands.Heat(surface.Heat) == EBand.Critical);
|
||||
var hasCaution = hasCritical
|
||||
|| !HasRequiredConsumers(level)
|
||||
|| level.Props.Any(prop => prop.Type == EPropType.Consumer && HasConsumerTrouble(prop))
|
||||
@@ -47,7 +47,7 @@ internal static class ReactorSystem
|
||||
{
|
||||
return ReactorFeedsPresentAndProducing(level, reactor.ControlPosition)
|
||||
&& ProducingConsumerCount(level, ECarrierType.Fuel) >= level.RequiredFuelConsumers
|
||||
&& ProducingConsumerCount(level, ECarrierType.Coolant) >= level.RequiredCoolantConsumers
|
||||
&& ProducingConsumerCount(level, ECarrierType.Water) >= level.RequiredWaterConsumers
|
||||
&& ProducingConsumerCount(level, ECarrierType.Electricity) >= level.RequiredElectricityConsumers
|
||||
&& level.GetSurface(reactor.ControlPosition).Heat < Balancing.Current.TerminalHeat;
|
||||
}
|
||||
@@ -73,14 +73,14 @@ internal static class ReactorSystem
|
||||
private static bool HasRequiredConsumers(LevelState level)
|
||||
{
|
||||
return ProducingConsumerCount(level, ECarrierType.Fuel) >= level.RequiredFuelConsumers
|
||||
&& ProducingConsumerCount(level, ECarrierType.Coolant) >= level.RequiredCoolantConsumers
|
||||
&& ProducingConsumerCount(level, ECarrierType.Water) >= level.RequiredWaterConsumers
|
||||
&& ProducingConsumerCount(level, ECarrierType.Electricity) >= level.RequiredElectricityConsumers;
|
||||
}
|
||||
|
||||
private static bool HasConsumerTrouble(PropState prop)
|
||||
{
|
||||
return prop.FuelServiceState is EConsumerServiceState.Starved or EConsumerServiceState.Disabled
|
||||
|| prop.CoolantServiceState is EConsumerServiceState.Starved or EConsumerServiceState.Disabled
|
||||
|| prop.WaterServiceState is EConsumerServiceState.Starved or EConsumerServiceState.Disabled
|
||||
|| prop.ElectricityServiceState is EConsumerServiceState.Starved or EConsumerServiceState.Disabled;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ internal static class RobotSafetySystem
|
||||
public static LevelState Resolve(LevelState level)
|
||||
{
|
||||
var surface = level.GetSurface(level.Robot.Position);
|
||||
var unsafeElement = surface.Fuel >= Balancing.Current.RobotFuelSafetyThreshold || surface.Coolant >= Balancing.Current.RobotCoolantSafetyThreshold || surface.Electricity >= Balancing.Current.RobotElectricitySafetyThreshold;
|
||||
var unsafeElement = surface.Fuel >= Balancing.Current.RobotFuelSafetyThreshold || surface.Water >= Balancing.Current.RobotWaterSafetyThreshold || surface.Electricity >= Balancing.Current.RobotElectricitySafetyThreshold;
|
||||
var unsafeHeat = surface.Heat >= Balancing.Current.RobotHeatSafetyThreshold && level.Robot.HeatImmunitySteps <= 0;
|
||||
return unsafeElement || unsafeHeat
|
||||
? level with { Global = level.Global with { LevelState = ELevelState.Lost, TerminalLoss = true, Status = "ROBOT LOST" } }
|
||||
|
||||
@@ -35,7 +35,7 @@ internal static class StructuralIntegritySystem
|
||||
|
||||
var next = carrier switch {
|
||||
ECarrierType.Fuel => level with { Fuel = layer },
|
||||
ECarrierType.Coolant => level with { Coolant = layer },
|
||||
ECarrierType.Water => level with { Water = layer },
|
||||
ECarrierType.Electricity => level with { Electricity = layer },
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(carrier), carrier, "Unsupported carrier.")
|
||||
};
|
||||
|
||||
@@ -8,14 +8,14 @@ internal static class SurfaceInteractionSystem
|
||||
{
|
||||
return surface with {
|
||||
Fuel = surface.Fuel + Fuel,
|
||||
Coolant = surface.Coolant + Coolant,
|
||||
Water = surface.Water + Water,
|
||||
Electricity = surface.Electricity + Electricity,
|
||||
Heat = surface.Heat + Heat
|
||||
};
|
||||
}
|
||||
|
||||
public float Fuel { get; set; }
|
||||
public float Coolant { get; set; }
|
||||
public float Water { get; set; }
|
||||
public float Electricity { get; set; }
|
||||
public float Heat { get; set; }
|
||||
}
|
||||
@@ -48,7 +48,7 @@ internal static class SurfaceInteractionSystem
|
||||
{
|
||||
var surface = level.Surface.Select(cell => cell with {
|
||||
FuelBlockTurns = Math.Max(0, cell.FuelBlockTurns - 1),
|
||||
CoolantBlockTurns = Math.Max(0, cell.CoolantBlockTurns - 1),
|
||||
WaterBlockTurns = Math.Max(0, cell.WaterBlockTurns - 1),
|
||||
ElectricityBlockTurns = Math.Max(0, cell.ElectricityBlockTurns - 1)
|
||||
})
|
||||
.ToArray();
|
||||
@@ -61,8 +61,8 @@ internal static class SurfaceInteractionSystem
|
||||
var surface = level.GetSurface(position);
|
||||
ApplyPair(level, position, ECarrierType.Fuel, SimulationBands.Fuel(surface.Fuel), ECarrierType.Electricity, SimulationBands.Electricity(surface.Electricity), deltas);
|
||||
ApplyPair(level, position, ECarrierType.Fuel, SimulationBands.Fuel(surface.Fuel), null, SimulationBands.Heat(surface.Heat), deltas);
|
||||
ApplyPair(level, position, ECarrierType.Coolant, SimulationBands.Coolant(surface.Coolant), ECarrierType.Electricity, SimulationBands.Electricity(surface.Electricity), deltas);
|
||||
ApplyPair(level, position, ECarrierType.Coolant, SimulationBands.Coolant(surface.Coolant), null, SimulationBands.Heat(surface.Heat), deltas);
|
||||
ApplyPair(level, position, ECarrierType.Water, SimulationBands.Water(surface.Water), ECarrierType.Electricity, SimulationBands.Electricity(surface.Electricity), deltas);
|
||||
ApplyPair(level, position, ECarrierType.Water, SimulationBands.Water(surface.Water), null, SimulationBands.Heat(surface.Heat), deltas);
|
||||
}
|
||||
|
||||
private static void ApplyAdjacentInteractions(LevelState level, GridPosition a, GridPosition b, SurfaceDelta[] deltas)
|
||||
@@ -70,7 +70,7 @@ internal static class SurfaceInteractionSystem
|
||||
var surfaceA = level.GetSurface(a);
|
||||
var surfaceB = level.GetSurface(b);
|
||||
FlowBetween(level, a, b, surfaceA.Fuel, surfaceB.Fuel, Balancing.Current.FlowInteraction(ESurfaceQuantity.Fuel), deltas);
|
||||
FlowBetween(level, a, b, surfaceA.Coolant, surfaceB.Coolant, Balancing.Current.FlowInteraction(ESurfaceQuantity.Coolant), deltas);
|
||||
FlowBetween(level, a, b, surfaceA.Water, surfaceB.Water, Balancing.Current.FlowInteraction(ESurfaceQuantity.Water), deltas);
|
||||
FlowBetween(level, a, b, surfaceA.Electricity, surfaceB.Electricity, Balancing.Current.FlowInteraction(ESurfaceQuantity.Electricity), deltas);
|
||||
FlowBetween(level, a, b, surfaceA.Heat, surfaceB.Heat, Balancing.Current.FlowInteraction(ESurfaceQuantity.Heat), deltas);
|
||||
}
|
||||
@@ -118,9 +118,9 @@ internal static class SurfaceInteractionSystem
|
||||
deltas[indexA].Fuel -= amount;
|
||||
deltas[indexB].Fuel += amount;
|
||||
break;
|
||||
case ESurfaceQuantity.Coolant:
|
||||
deltas[indexA].Coolant -= amount;
|
||||
deltas[indexB].Coolant += amount;
|
||||
case ESurfaceQuantity.Water:
|
||||
deltas[indexA].Water -= amount;
|
||||
deltas[indexB].Water += amount;
|
||||
break;
|
||||
case ESurfaceQuantity.Electricity:
|
||||
deltas[indexA].Electricity -= amount;
|
||||
|
||||
@@ -21,18 +21,18 @@ public sealed class EditorImageRegistry
|
||||
AddAlias("prop-consumer", "generator");
|
||||
AddAlias("prop-flow", "generator");
|
||||
AddAlias("carrier-fuel-source", "generator");
|
||||
AddAlias("carrier-coolant-source", "cooling-pump");
|
||||
AddAlias("carrier-water-source", "cooling-pump");
|
||||
AddAlias("carrier-electricity-source", "generator");
|
||||
AddAlias("prop-junction", "pressure-regulator");
|
||||
AddAlias("prop-door", "wall");
|
||||
AddAlias("prop-eye-terminal", "diagnostic-terminal");
|
||||
AddAlias("prop-remedy", "repair");
|
||||
AddAlias("leak-fuel", "leak");
|
||||
AddAlias("leak-coolant", "leak");
|
||||
AddAlias("leak-water", "leak");
|
||||
AddAlias("leak-electricity", "leak");
|
||||
AddAlias("hazard-heat", "heat");
|
||||
AddAlias("hazard-fuel", "fire");
|
||||
AddAlias("hazard-coolant", "leak");
|
||||
AddAlias("hazard-water", "leak");
|
||||
AddAlias("hazard-electricity", "heat");
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ public sealed partial class MainWindow
|
||||
Surface,
|
||||
Electricity,
|
||||
Fuel,
|
||||
Coolant
|
||||
Water
|
||||
}
|
||||
|
||||
private sealed record CanvasLayout(double CellSize, double OriginX, double OriginY)
|
||||
@@ -624,7 +624,7 @@ public sealed partial class MainWindow
|
||||
|
||||
private IEnumerable<ECarrierType> OrderedUndergroundLayers()
|
||||
{
|
||||
var carriers = new[] { ECarrierType.Fuel, ECarrierType.Coolant, ECarrierType.Electricity };
|
||||
var carriers = new[] { ECarrierType.Fuel, ECarrierType.Water, ECarrierType.Electricity };
|
||||
var activeCarrier = LayerCarrier(m_ActiveLayer);
|
||||
return activeCarrier is null ? carriers : carriers.Where(carrier => carrier != activeCarrier).Append(activeCarrier.Value);
|
||||
}
|
||||
@@ -679,7 +679,7 @@ public sealed partial class MainWindow
|
||||
var surface = m_Level.GetSurface(position);
|
||||
var rect = layout.CellRect(position);
|
||||
FillHazard(drawing, rect, surface.Fuel, c_FuelColor, 0.08, opacity, Balancing.Current.FuelCaution, Balancing.Current.FuelCritical);
|
||||
FillHazard(drawing, rect, surface.Coolant, c_CoolantColor, 0.18, opacity, Balancing.Current.CoolantCaution, Balancing.Current.CoolantCritical);
|
||||
FillHazard(drawing, rect, surface.Water, c_WaterColor, 0.18, opacity, Balancing.Current.WaterCaution, Balancing.Current.WaterCritical);
|
||||
FillHazard(drawing, rect, surface.Electricity, c_ElectricityColor, 0.28, opacity, Balancing.Current.ElectricityCaution, Balancing.Current.ElectricityCritical);
|
||||
|
||||
var heatOpacity = SurfaceOverlayOpacity(surface.Heat, Balancing.Current.HeatCaution, Balancing.Current.HeatCritical);
|
||||
@@ -884,13 +884,13 @@ public sealed partial class MainWindow
|
||||
: $"{m_Level.Global.LevelState}: {m_EditorFeedback}";
|
||||
InventoryGrid.ItemsSource = new[] {
|
||||
new InspectorItemViewModel("Fuel", $"{m_Level.Robot.FuelNeutralizers}"),
|
||||
new InspectorItemViewModel("Coolant", $"{m_Level.Robot.CoolantNeutralizers}"),
|
||||
new InspectorItemViewModel("Water", $"{m_Level.Robot.WaterNeutralizers}"),
|
||||
new InspectorItemViewModel("Electricity", $"{m_Level.Robot.ElectricityNeutralizers}"),
|
||||
new InspectorItemViewModel("Heat", $"{m_Level.Robot.HeatShields} ({m_Level.Robot.HeatImmunitySteps.ToString(CultureInfo.InvariantCulture)} steps)")
|
||||
};
|
||||
RequiredGrid.ItemsSource = new[] {
|
||||
new InspectorItemViewModel("Fuel", m_Level.RequiredFuelConsumers.ToString(CultureInfo.InvariantCulture)),
|
||||
new InspectorItemViewModel("Coolant", m_Level.RequiredCoolantConsumers.ToString(CultureInfo.InvariantCulture)),
|
||||
new InspectorItemViewModel("Water", m_Level.RequiredWaterConsumers.ToString(CultureInfo.InvariantCulture)),
|
||||
new InspectorItemViewModel("Electric", m_Level.RequiredElectricityConsumers.ToString(CultureInfo.InvariantCulture))
|
||||
};
|
||||
|
||||
@@ -902,13 +902,13 @@ public sealed partial class MainWindow
|
||||
PropText.Text = prop.Type != EPropType.None ? $"{prop.Type} {prop.SwitchState}" : "(none)";
|
||||
ServicesGrid.ItemsSource = new[] {
|
||||
new InspectorItemViewModel("Fuel", prop.FuelServiceState.ToString()),
|
||||
new InspectorItemViewModel("Coolant", prop.CoolantServiceState.ToString()),
|
||||
new InspectorItemViewModel("Water", prop.WaterServiceState.ToString()),
|
||||
new InspectorItemViewModel("Electricity", prop.ElectricityServiceState.ToString())
|
||||
};
|
||||
var surface = m_Level.GetSurface(position);
|
||||
ConsumersGrid.ItemsSource = new[] {
|
||||
new InspectorItemViewModel("Fuel", surface.FuelBlockTurns.ToString()),
|
||||
new InspectorItemViewModel("Coolant", surface.CoolantBlockTurns.ToString()),
|
||||
new InspectorItemViewModel("Water", surface.WaterBlockTurns.ToString()),
|
||||
new InspectorItemViewModel("Electricity", surface.ElectricityBlockTurns.ToString())
|
||||
};
|
||||
LeaksGrid.ItemsSource = m_Level.Leaks.Select(leak => new InspectorItemViewModel(leak.Carrier.ToString(), $"{leak.UndergroundPosition.X}, {leak.UndergroundPosition.Y}"));
|
||||
@@ -959,7 +959,7 @@ public sealed partial class MainWindow
|
||||
var surface = m_Level.GetSurface(position);
|
||||
return [
|
||||
new("Fuel", Format(surface.Fuel)),
|
||||
new("Coolant", Format(surface.Coolant)),
|
||||
new("Water", Format(surface.Water)),
|
||||
new("Electric", Format(surface.Electricity)),
|
||||
new("Heat", Format(surface.Heat))
|
||||
];
|
||||
@@ -969,7 +969,7 @@ public sealed partial class MainWindow
|
||||
{
|
||||
return [
|
||||
NetworkInspectionItem("Fuel", m_Level.GetUnderground(position, ECarrierType.Fuel)),
|
||||
NetworkInspectionItem("Coolant", m_Level.GetUnderground(position, ECarrierType.Coolant)),
|
||||
NetworkInspectionItem("Water", m_Level.GetUnderground(position, ECarrierType.Water)),
|
||||
NetworkInspectionItem("Electric", m_Level.GetUnderground(position, ECarrierType.Electricity))
|
||||
];
|
||||
}
|
||||
@@ -993,7 +993,7 @@ public sealed partial class MainWindow
|
||||
return $"{leak.Carrier} Leak";
|
||||
|
||||
var surface = m_Level.GetSurface(position);
|
||||
if (surface.Fuel > 0 || surface.Coolant > 0 || surface.Electricity > 0)
|
||||
if (surface.Fuel > 0 || surface.Water > 0 || surface.Electricity > 0)
|
||||
return "Surface Hazard";
|
||||
|
||||
if (surface.Heat > 0)
|
||||
@@ -1011,10 +1011,10 @@ public sealed partial class MainWindow
|
||||
{
|
||||
var level = LevelState.Create("Cooling Sector B", 16, 12);
|
||||
level = AddNetwork(level, ECarrierType.Fuel, new(2, 3), new(5, 3));
|
||||
level = AddNetwork(level, ECarrierType.Coolant, new(2, 5), new(5, 5));
|
||||
level = AddNetwork(level, ECarrierType.Water, new(2, 5), new(5, 5));
|
||||
level = AddNetwork(level, ECarrierType.Electricity, new(2, 7), new(5, 7));
|
||||
level = level.SetProp(new(2, 3), new() { Type = EPropType.Flow, Carrier = ECarrierType.Fuel });
|
||||
level = level.SetProp(new(2, 5), new() { Type = EPropType.Flow, Carrier = ECarrierType.Coolant });
|
||||
level = level.SetProp(new(2, 5), new() { Type = EPropType.Flow, Carrier = ECarrierType.Water });
|
||||
level = level.SetProp(new(2, 7), new() { Type = EPropType.Flow, Carrier = ECarrierType.Electricity });
|
||||
level = level.SetProp(new(5, 3), new() { Type = EPropType.Consumer });
|
||||
level = level.SetProp(new(5, 5), new() { Type = EPropType.Consumer });
|
||||
@@ -1022,8 +1022,8 @@ public sealed partial class MainWindow
|
||||
level = level.SetProp(new(10, 5), new() { Type = EPropType.ReactorControl, ReactorId = 1 });
|
||||
level = level.SetProp(new(11, 4), new() { Type = EPropType.AllSeeingEyeTerminal });
|
||||
level = level.SetProp(new(11, 6), new() { Type = EPropType.RemedySupply, RemedyType = ERemedyType.HeatShield });
|
||||
level = level.SetUnderground(new(4, 5), ECarrierType.Coolant, new() { State = EUndergroundState.Leaking }) with {
|
||||
Leaks = [new() { Carrier = ECarrierType.Coolant, UndergroundPosition = new(4, 5), AccessPosition = new(4, 5) }],
|
||||
level = level.SetUnderground(new(4, 5), ECarrierType.Water, new() { State = EUndergroundState.Leaking }) with {
|
||||
Leaks = [new() { Carrier = ECarrierType.Water, UndergroundPosition = new(4, 5), AccessPosition = new(4, 5) }],
|
||||
Robot = new() { Position = new(10, 5) },
|
||||
Reactors = [
|
||||
new() {
|
||||
@@ -1134,7 +1134,7 @@ public sealed partial class MainWindow
|
||||
return layer switch {
|
||||
EEditorLayer.Electricity => ECarrierType.Electricity,
|
||||
EEditorLayer.Fuel => ECarrierType.Fuel,
|
||||
EEditorLayer.Coolant => ECarrierType.Coolant,
|
||||
EEditorLayer.Water => ECarrierType.Water,
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
@@ -1217,7 +1217,7 @@ public sealed partial class MainWindow
|
||||
{
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => c_FuelColor,
|
||||
ECarrierType.Coolant => c_CoolantColor,
|
||||
ECarrierType.Water => c_WaterColor,
|
||||
ECarrierType.Electricity => c_ElectricityColor,
|
||||
_ => Colors.White
|
||||
};
|
||||
@@ -1256,7 +1256,7 @@ public sealed partial class MainWindow
|
||||
{
|
||||
return carrier switch {
|
||||
ECarrierType.Fuel => "F",
|
||||
ECarrierType.Coolant => "C",
|
||||
ECarrierType.Water => "C",
|
||||
ECarrierType.Electricity => "E",
|
||||
_ => "?"
|
||||
};
|
||||
@@ -1266,7 +1266,7 @@ public sealed partial class MainWindow
|
||||
{
|
||||
return remedy switch {
|
||||
ERemedyType.FuelNeutralizer => "F REM",
|
||||
ERemedyType.CoolantNeutralizer => "C REM",
|
||||
ERemedyType.WaterNeutralizer => "C REM",
|
||||
ERemedyType.ElectricityNeutralizer => "E REM",
|
||||
ERemedyType.HeatShield => "H SHD",
|
||||
_ => "REM"
|
||||
@@ -1295,25 +1295,25 @@ public sealed partial class MainWindow
|
||||
Tool(EEditorTool.Floor, "Floor"),
|
||||
Tool(EEditorTool.Wall, "Wall"),
|
||||
CarrierTool(EEditorTool.Underground, ECarrierType.Fuel, "Fuel Net"),
|
||||
CarrierTool(EEditorTool.Underground, ECarrierType.Coolant, "Coolant Net"),
|
||||
CarrierTool(EEditorTool.Underground, ECarrierType.Water, "Water Net"),
|
||||
CarrierTool(EEditorTool.Underground, ECarrierType.Electricity, "Electric Net"),
|
||||
CarrierTool(EEditorTool.Flow, ECarrierType.Fuel, "Fuel Source"),
|
||||
CarrierTool(EEditorTool.Flow, ECarrierType.Coolant, "Coolant Source"),
|
||||
CarrierTool(EEditorTool.Flow, ECarrierType.Water, "Water Source"),
|
||||
CarrierTool(EEditorTool.Flow, ECarrierType.Electricity, "Electric Source"),
|
||||
Tool(EEditorTool.Consumer, "Consumer"),
|
||||
Tool(EEditorTool.Junction, "Junction"),
|
||||
Tool(EEditorTool.Door, "Door"),
|
||||
Tool(EEditorTool.AllSeeingEyeTerminal, "Eye Terminal"),
|
||||
RemedyTool(ERemedyType.FuelNeutralizer, "Fuel Remedy"),
|
||||
RemedyTool(ERemedyType.CoolantNeutralizer, "Coolant Remedy"),
|
||||
RemedyTool(ERemedyType.WaterNeutralizer, "Water Remedy"),
|
||||
RemedyTool(ERemedyType.ElectricityNeutralizer, "Electric Remedy"),
|
||||
RemedyTool(ERemedyType.HeatShield, "Heat Shield"),
|
||||
Tool(EEditorTool.ReactorControl, "Reactor"),
|
||||
CarrierTool(EEditorTool.Leak, ECarrierType.Fuel, "Fuel Leak"),
|
||||
CarrierTool(EEditorTool.Leak, ECarrierType.Coolant, "Coolant Leak"),
|
||||
CarrierTool(EEditorTool.Leak, ECarrierType.Water, "Water Leak"),
|
||||
CarrierTool(EEditorTool.Leak, ECarrierType.Electricity, "Electric Leak"),
|
||||
CarrierTool(EEditorTool.SurfaceHazard, ECarrierType.Fuel, "Fuel Hazard"),
|
||||
CarrierTool(EEditorTool.SurfaceHazard, ECarrierType.Coolant, "Coolant Hazard"),
|
||||
CarrierTool(EEditorTool.SurfaceHazard, ECarrierType.Water, "Water Hazard"),
|
||||
CarrierTool(EEditorTool.SurfaceHazard, ECarrierType.Electricity, "Electric Hazard"),
|
||||
Tool(EEditorTool.Heat, "Heat"),
|
||||
Tool(EEditorTool.Robot, "Robot")
|
||||
@@ -1363,7 +1363,7 @@ public sealed partial class MainWindow
|
||||
private const int c_BottomRightCorner = 8;
|
||||
private const int c_AllCorners = c_TopLeftCorner | c_TopRightCorner | c_BottomLeftCorner | c_BottomRightCorner;
|
||||
private static readonly Color c_FuelColor = ColorHelper.FromArgb(255, 220, 65, 65);
|
||||
private static readonly Color c_CoolantColor = ColorHelper.FromArgb(255, 57, 174, 196);
|
||||
private static readonly Color c_WaterColor = ColorHelper.FromArgb(255, 57, 174, 196);
|
||||
private static readonly Color c_ElectricityColor = ColorHelper.FromArgb(255, 236, 226, 82);
|
||||
private readonly IReadOnlyList<EditorToolViewModel> m_EditorTools = [];
|
||||
private readonly EditorImageRegistry m_Images = new();
|
||||
|
||||
@@ -32,13 +32,13 @@ public sealed class LevelEditorTests
|
||||
var level = LevelState.Create("Wall editor", 6, 6);
|
||||
var position = new GridPosition(2, 2);
|
||||
level = LevelEditor.Apply(level, position, new() { Tool = EEditorTool.Underground, Carrier = ECarrierType.Fuel });
|
||||
level = LevelEditor.Apply(level, position, new() { Tool = EEditorTool.Underground, Carrier = ECarrierType.Coolant });
|
||||
level = LevelEditor.Apply(level, position, new() { Tool = EEditorTool.Underground, Carrier = ECarrierType.Water });
|
||||
level = LevelEditor.Apply(level, position, new() { Tool = EEditorTool.Underground, Carrier = ECarrierType.Electricity });
|
||||
|
||||
var next = LevelEditor.Apply(level, position, new() { Tool = EEditorTool.Wall });
|
||||
|
||||
Assert.Equal(EUndergroundState.Intact, next.GetUnderground(position, ECarrierType.Fuel).State);
|
||||
Assert.Equal(EUndergroundState.Intact, next.GetUnderground(position, ECarrierType.Coolant).State);
|
||||
Assert.Equal(EUndergroundState.Intact, next.GetUnderground(position, ECarrierType.Water).State);
|
||||
Assert.Equal(EUndergroundState.Intact, next.GetUnderground(position, ECarrierType.Electricity).State);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public sealed class LevelEditorTests
|
||||
|
||||
Assert.Equal(EPropType.Consumer, next.GetProp(new(2, 2)).Type);
|
||||
Assert.Equal(EConsumerServiceState.Unknown, next.GetProp(new(2, 2)).FuelServiceState);
|
||||
Assert.Equal(EConsumerServiceState.Unknown, next.GetProp(new(2, 2)).CoolantServiceState);
|
||||
Assert.Equal(EConsumerServiceState.Unknown, next.GetProp(new(2, 2)).WaterServiceState);
|
||||
Assert.Equal(EConsumerServiceState.Unknown, next.GetProp(new(2, 2)).ElectricityServiceState);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ public sealed class SimulationEngineTests
|
||||
var consumer = next.GetProp(new(3, 3));
|
||||
|
||||
Assert.Equal(EConsumerServiceState.Producing, consumer.FuelServiceState);
|
||||
Assert.Equal(EConsumerServiceState.Producing, consumer.CoolantServiceState);
|
||||
Assert.Equal(EConsumerServiceState.Producing, consumer.WaterServiceState);
|
||||
Assert.Equal(EConsumerServiceState.Producing, consumer.ElectricityServiceState);
|
||||
Assert.Equal(ELevelState.Ready, next.Global.LevelState);
|
||||
Assert.Contains(next.Forecasts, forecast => forecast.Kind == EForecastKind.ReactorReady);
|
||||
@@ -52,7 +52,7 @@ public sealed class SimulationEngineTests
|
||||
var consumer = next.GetProp(new(2, 2));
|
||||
|
||||
Assert.Equal(EConsumerServiceState.Disabled, consumer.FuelServiceState);
|
||||
Assert.Equal(EConsumerServiceState.Unknown, consumer.CoolantServiceState);
|
||||
Assert.Equal(EConsumerServiceState.Unknown, consumer.WaterServiceState);
|
||||
Assert.Equal(EConsumerServiceState.Unknown, consumer.ElectricityServiceState);
|
||||
Assert.Equal(EConsumerServiceState.Disabled, consumer.ServiceState);
|
||||
}
|
||||
@@ -277,12 +277,12 @@ public sealed class SimulationEngineTests
|
||||
{
|
||||
var level = LevelState.Create("Ready", 8, 7);
|
||||
level = AddLine(level, ECarrierType.Fuel, new(2, 3), new(3, 3));
|
||||
level = AddLine(level, ECarrierType.Coolant, new(2, 3), new(3, 3));
|
||||
level = AddLine(level, ECarrierType.Water, new(2, 3), new(3, 3));
|
||||
level = AddLine(level, ECarrierType.Electricity, new(2, 3), new(3, 3));
|
||||
level = level.SetProp(new(2, 3), new() { Type = EPropType.Flow, Carrier = ECarrierType.Fuel });
|
||||
level = level.SetProp(new(2, 2), new() { Type = EPropType.Flow, Carrier = ECarrierType.Coolant });
|
||||
level = level.SetUnderground(new(2, 2), ECarrierType.Coolant, new() { State = EUndergroundState.Intact });
|
||||
level = level.SetUnderground(new(2, 3), ECarrierType.Coolant, new() { State = EUndergroundState.Intact });
|
||||
level = level.SetProp(new(2, 2), new() { Type = EPropType.Flow, Carrier = ECarrierType.Water });
|
||||
level = level.SetUnderground(new(2, 2), ECarrierType.Water, new() { State = EUndergroundState.Intact });
|
||||
level = level.SetUnderground(new(2, 3), ECarrierType.Water, new() { State = EUndergroundState.Intact });
|
||||
level = level.SetProp(new(2, 4), new() { Type = EPropType.Flow, Carrier = ECarrierType.Electricity });
|
||||
level = level.SetUnderground(new(2, 4), ECarrierType.Electricity, new() { State = EUndergroundState.Intact });
|
||||
level = level.SetUnderground(new(2, 3), ECarrierType.Electricity, new() { State = EUndergroundState.Intact });
|
||||
|
||||
Reference in New Issue
Block a user