diff --git a/src/ReactorMaintenance.Win2D/MainWindow.xaml b/src/ReactorMaintenance.Win2D/MainWindow.xaml
index aa76577..20c4533 100644
--- a/src/ReactorMaintenance.Win2D/MainWindow.xaml
+++ b/src/ReactorMaintenance.Win2D/MainWindow.xaml
@@ -93,21 +93,23 @@
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
@@ -134,23 +136,77 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -169,10 +225,8 @@
-
-
+
+
diff --git a/src/ReactorMaintenance.Win2D/MainWindow.xaml.cs b/src/ReactorMaintenance.Win2D/MainWindow.xaml.cs
index 9194d57..0295d4e 100644
--- a/src/ReactorMaintenance.Win2D/MainWindow.xaml.cs
+++ b/src/ReactorMaintenance.Win2D/MainWindow.xaml.cs
@@ -44,7 +44,7 @@ public sealed partial class MainWindow
}
private sealed record ForecastViewModel(string Message);
- private sealed record InspectorItemViewModel(string Label, string Value, string Description);
+ private sealed record InspectorItemViewModel(string Label, string Value);
private sealed record NetworkInspectionViewModel(string Carrier, string State, string Amount, string Intensity, string Integrity);
private sealed class EditorToolViewModel(EditorToolCommand command, string label) : INotifyPropertyChanged
@@ -171,7 +171,6 @@ public sealed partial class MainWindow
m_Level = loaded with { Forecasts = m_Simulation.Forecast(loaded) };
m_CurrentFile = file;
m_SelectedCell = null;
- m_SelectedReactorId = m_Level.Reactors.FirstOrDefault()?.ReactorId;
RefreshInspector();
LevelCanvas.Invalidate();
}
@@ -332,7 +331,6 @@ public sealed partial class MainWindow
m_EditorFeedback = result.Reason;
if (result.Success)
{
- SelectReactorFromCell(destination);
RefreshForecasts();
}
@@ -388,10 +386,6 @@ public sealed partial class MainWindow
{
ApplySelectedTool(position);
}
- else
- {
- SelectReactorFromCell(position);
- }
RefreshInspector();
LevelCanvas.Invalidate();
@@ -408,11 +402,12 @@ public sealed partial class MainWindow
private void UpdateHoverCell(Point point)
{
var nextHover = TryGetGridPosition(point, out var position) ? position : null;
- if (nextHover == m_HoverCell)
+ if (nextHover == HoverCell)
return;
- m_HoverCell = nextHover;
+ HoverCell = nextHover;
LevelCanvas.Invalidate();
+ RefreshInspector();
}
private static bool IsDragPaintTool(EEditorTool tool)
@@ -695,7 +690,7 @@ public sealed partial class MainWindow
DrawStatusBadge(drawing, rect, m_EditorFeedback);
}
- if (m_HoverCell is { } hover && m_SelectedTool.Tool != EEditorTool.Cursor)
+ if (HoverCell is { } hover && m_SelectedTool.Tool != EEditorTool.Cursor)
{
var rect = layout.CellRect(hover);
var size = Math.Max(26, rect.Width * 0.42);
@@ -806,31 +801,49 @@ public sealed partial class MainWindow
StatusText.Text = string.IsNullOrWhiteSpace(m_EditorFeedback)
? $"{m_Level.Global.LevelState}: {m_Level.Global.Status}"
: $"{m_Level.Global.LevelState}: {m_EditorFeedback}";
- var doorCount = m_Level.Props.Count(prop => prop.Type == EPropType.Door);
- GlobalGrid.ItemsSource = new[] {
- new InspectorItemViewModel("Inventory", $"F {m_Level.Robot.FuelNeutralizers} / C {m_Level.Robot.CoolantNeutralizers} / E {m_Level.Robot.ElectricityNeutralizers} / H {m_Level.Robot.HeatShields}", "Remedies carried by the robot."),
- new InspectorItemViewModel("Heat Shield", m_Level.Robot.HeatImmunitySteps.ToString(CultureInfo.InvariantCulture), "Remaining protected movement steps."),
- new InspectorItemViewModel("Objects", $"R {m_Level.Reactors.Count} / L {m_Level.Leaks.Count} / D {doorCount}", "Reactors, active leaks, and doors.")
+ InventoryGrid.ItemsSource = new[] {
+ new InspectorItemViewModel("Fuel", $"{m_Level.Robot.FuelNeutralizers}"),
+ new InspectorItemViewModel("Coolant", $"{m_Level.Robot.CoolantNeutralizers}"),
+ 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), "Producing consumers needed for readiness."),
- new InspectorItemViewModel("Coolant", m_Level.RequiredCoolantConsumers.ToString(CultureInfo.InvariantCulture), "Producing consumers needed for readiness."),
- new InspectorItemViewModel("Electric", m_Level.RequiredElectricityConsumers.ToString(CultureInfo.InvariantCulture), "Producing consumers needed for readiness.")
+ new InspectorItemViewModel("Fuel", m_Level.RequiredFuelConsumers.ToString(CultureInfo.InvariantCulture)),
+ new InspectorItemViewModel("Coolant", m_Level.RequiredCoolantConsumers.ToString(CultureInfo.InvariantCulture)),
+ new InspectorItemViewModel("Electric", m_Level.RequiredElectricityConsumers.ToString(CultureInfo.InvariantCulture))
};
if (m_SelectedCell is { } position && m_Level.InBounds(position))
{
- SelectedCellTitleText.Text = SelectedCellTitle(position);
- CellGrid.ItemsSource = CellInspectionItems(position);
+ SelectedCellText.Text = $"Selected cell: {position.X}, {position.Y}";
+ TerrainText.Text = m_Level.GetTerrain(position).ToString();
+ var prop = m_Level.GetProp(position);
+ 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("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("Electricity", surface.ElectricityBlockTurns.ToString()),
+ };
+ LeaksGrid.ItemsSource = m_Level.Leaks.Select(leak => new InspectorItemViewModel(leak.Carrier.ToString(), $"{leak.UndergroundPosition.X}, {leak.UndergroundPosition.Y}"));
SurfaceGrid.ItemsSource = SurfaceInspectionItems(position);
NetworkGrid.ItemsSource = NetworkInspectionItems(position);
}
else
{
- SelectedCellTitleText.Text = "None";
- CellGrid.ItemsSource = new[] { new InspectorItemViewModel("Selection", "None", "Select a grid cell to inspect it.") };
- SurfaceGrid.ItemsSource = Array.Empty();
- NetworkGrid.ItemsSource = Array.Empty();
+ SelectedCellText.Text = "Selected cell: (none)";
+ TerrainText.Text = string.Empty;
+ PropText.Text = string.Empty;
+ ServicesGrid.ItemsSource = null;
+ ConsumersGrid.ItemsSource = null;
+ LeaksGrid.ItemsSource = null;
+ SurfaceGrid.ItemsSource = null;
+ NetworkGrid.ItemsSource = null;
}
ForecastList.ItemsSource = m_Level.Forecasts.Select(forecast => new ForecastViewModel($"{forecast.Turns}: {forecast.Message}")).ToArray();
@@ -849,7 +862,6 @@ public sealed partial class MainWindow
break;
default:
m_Level = LevelEditor.Apply(m_Level, position, m_SelectedTool);
- SelectReactorFromCell(position);
RefreshForecasts();
break;
}
@@ -861,27 +873,14 @@ public sealed partial class MainWindow
RefreshForecasts();
}
- private InspectorItemViewModel[] CellInspectionItems(GridPosition position)
- {
- var prop = m_Level.GetProp(position);
- var surface = m_Level.GetSurface(position);
- return [
- new("Position", $"{position.X},{position.Y}", "Grid coordinate."),
- new("Terrain", m_Level.GetTerrain(position).ToString(), "Static surface cell type."),
- new("Prop", $"{prop.Type} {prop.SwitchState}", "Placed surface object and switch state."),
- new("Services F/C/E", $"{prop.FuelServiceState}/{prop.CoolantServiceState}/{prop.ElectricityServiceState}", "Consumer service status."),
- new("Blocks F/C/E", $"{surface.FuelBlockTurns}/{surface.CoolantBlockTurns}/{surface.ElectricityBlockTurns}", "Temporary remedy entry blocks.")
- ];
- }
-
private InspectorItemViewModel[] SurfaceInspectionItems(GridPosition position)
{
var surface = m_Level.GetSurface(position);
return [
- new("Fuel", Format(surface.Fuel), "Visible fuel hazard."),
- new("Coolant", Format(surface.Coolant), "Visible coolant hazard."),
- new("Electric", Format(surface.Electricity), "Visible electricity hazard."),
- new("Heat", Format(surface.Heat), "Visible heat.")
+ new("Fuel", Format(surface.Fuel)),
+ new("Coolant", Format(surface.Coolant)),
+ new("Electric", Format(surface.Electricity)),
+ new("Heat", Format(surface.Heat))
];
}
@@ -1264,17 +1263,12 @@ public sealed partial class MainWindow
return command.Carrier == activeCarrier && command.Tool is EEditorTool.Underground or EEditorTool.Flow or EEditorTool.Leak;
}
- private void SelectReactorFromCell(GridPosition position)
- {
- var prop = m_Level.GetProp(position);
- if (prop is { Type: EPropType.ReactorControl, ReactorId: > 0 })
- m_SelectedReactorId = prop.ReactorId;
- }
-
private void RefreshForecasts()
{
m_Level = m_Level with { Forecasts = m_Simulation.Forecast(m_Level) };
}
+
+ public GridPosition? HoverCell { get; private set; }
private const double c_MinZoom = 0.5;
private const double c_MaxZoom = 4;
@@ -1301,7 +1295,6 @@ public sealed partial class MainWindow
private GridPosition? m_DragPreviewDestination;
private string m_EditorFeedback = string.Empty;
private CanvasBitmap? m_HeatSprite;
- private GridPosition? m_HoverCell;
private GridPosition? m_InvalidDragCell;
private bool m_IsPanning;
private GridPosition? m_LastPaintedCell;
@@ -1313,7 +1306,6 @@ public sealed partial class MainWindow
private double m_PanX;
private double m_PanY;
private GridPosition? m_SelectedCell;
- private int? m_SelectedReactorId = 1;
private EditorToolCommand m_SelectedTool = new() { Tool = EEditorTool.Cursor };
private CanvasBitmap? m_TerrainTilemap;
private double m_Zoom = 1;