Refine editor inspector and drag painting
This commit is contained in:
@@ -93,22 +93,17 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<TextBlock Text="Global Systems" FontSize="16" FontWeight="SemiBold" Foreground="#F4F1E8" />
|
<TextBlock Text="Inventory And Objects" FontSize="16" FontWeight="SemiBold" Foreground="#F4F1E8" />
|
||||||
<ItemsControl x:Name="GlobalGrid">
|
<ItemsControl x:Name="GlobalGrid">
|
||||||
<ItemsControl.ItemsPanel>
|
|
||||||
<ItemsPanelTemplate>
|
|
||||||
<ItemsWrapGrid Orientation="Horizontal" MaximumRowsOrColumns="2" />
|
|
||||||
</ItemsPanelTemplate>
|
|
||||||
</ItemsControl.ItemsPanel>
|
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Border BorderBrush="#3C4650" BorderThickness="1" Padding="8" Margin="0,0,8,8"
|
<Border BorderBrush="#3C4650" BorderThickness="1" Padding="8" Margin="0,0,8,8"
|
||||||
Width="126" CornerRadius="3">
|
CornerRadius="3">
|
||||||
<StackPanel Spacing="2">
|
<StackPanel Spacing="2">
|
||||||
<TextBlock Text="{Binding Label}" Foreground="#9EA7AE" FontSize="11"
|
<TextBlock Text="{Binding Label}" Foreground="#9EA7AE" FontSize="11"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
<TextBlock Text="{Binding Value}" Foreground="#F4F1E8" FontSize="15"
|
<TextBlock Text="{Binding Value}" Foreground="#F4F1E8" FontSize="15"
|
||||||
TextWrapping="WrapWholeWords" />
|
TextWrapping="Wrap" />
|
||||||
<TextBlock Text="{Binding Description}" Foreground="#9EA7AE" FontSize="11"
|
<TextBlock Text="{Binding Description}" Foreground="#9EA7AE" FontSize="11"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@@ -117,17 +112,36 @@
|
|||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
|
|
||||||
<TextBlock Text="Selected Cell" FontSize="16" FontWeight="SemiBold" Foreground="#F4F1E8" />
|
<TextBlock Text="Required" FontSize="16" FontWeight="SemiBold" Foreground="#F4F1E8" />
|
||||||
<ItemsControl x:Name="CellGrid">
|
<ItemsControl x:Name="RequiredGrid">
|
||||||
<ItemsControl.ItemsPanel>
|
<ItemsControl.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<ItemsWrapGrid Orientation="Horizontal" MaximumRowsOrColumns="2" />
|
<StackPanel Orientation="Horizontal" />
|
||||||
</ItemsPanelTemplate>
|
</ItemsPanelTemplate>
|
||||||
</ItemsControl.ItemsPanel>
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid Width="84" Margin="0,0,4,0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TextBlock Text="{Binding Label}" Foreground="#9EA7AE" FontSize="11" />
|
||||||
|
<TextBlock Grid.Row="1" Text="{Binding Value}" Foreground="#F4F1E8"
|
||||||
|
FontSize="18" />
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
|
||||||
|
<TextBlock Text="Selected Cell" FontSize="16" FontWeight="SemiBold" Foreground="#F4F1E8" />
|
||||||
|
<TextBlock x:Name="SelectedCellTitleText" FontSize="19" FontWeight="SemiBold"
|
||||||
|
Foreground="#F4F1E8" TextWrapping="Wrap" />
|
||||||
|
<ItemsControl x:Name="CellGrid">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Border BorderBrush="#3C4650" BorderThickness="1" Padding="8" Margin="0,0,8,8"
|
<Border BorderBrush="#3C4650" BorderThickness="1" Padding="8" Margin="0,0,8,8"
|
||||||
Width="126" CornerRadius="3">
|
CornerRadius="3">
|
||||||
<StackPanel Spacing="2">
|
<StackPanel Spacing="2">
|
||||||
<TextBlock Text="{Binding Label}" Foreground="#9EA7AE" FontSize="11"
|
<TextBlock Text="{Binding Label}" Foreground="#9EA7AE" FontSize="11"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
@@ -141,6 +155,70 @@
|
|||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
|
|
||||||
|
<TextBlock Text="Surface" FontSize="16" FontWeight="SemiBold" Foreground="#F4F1E8" />
|
||||||
|
<ItemsControl x:Name="SurfaceGrid">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid Width="64" Margin="0,0,4,0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TextBlock Text="{Binding Label}" Foreground="#9EA7AE" FontSize="11"
|
||||||
|
TextWrapping="NoWrap" />
|
||||||
|
<TextBlock Grid.Row="1" Text="{Binding Value}" Foreground="#F4F1E8"
|
||||||
|
FontSize="16" />
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
|
||||||
|
<TextBlock Text="Network" FontSize="16" FontWeight="SemiBold" Foreground="#F4F1E8" />
|
||||||
|
<Grid ColumnSpacing="6">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="64" />
|
||||||
|
<ColumnDefinition Width="60" />
|
||||||
|
<ColumnDefinition Width="34" />
|
||||||
|
<ColumnDefinition Width="34" />
|
||||||
|
<ColumnDefinition Width="34" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock Text="Carrier" Foreground="#9EA7AE" FontSize="11" />
|
||||||
|
<TextBlock Grid.Column="1" Text="State" Foreground="#9EA7AE" FontSize="11" />
|
||||||
|
<TextBlock Grid.Column="2" Text="Amt" Foreground="#9EA7AE" FontSize="11" />
|
||||||
|
<TextBlock Grid.Column="3" Text="Int" Foreground="#9EA7AE" FontSize="11" />
|
||||||
|
<TextBlock Grid.Column="4" Text="HP" Foreground="#9EA7AE" FontSize="11" />
|
||||||
|
</Grid>
|
||||||
|
<ItemsControl x:Name="NetworkGrid">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid Margin="0,0,0,8" ColumnSpacing="6">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="64" />
|
||||||
|
<ColumnDefinition Width="60" />
|
||||||
|
<ColumnDefinition Width="34" />
|
||||||
|
<ColumnDefinition Width="34" />
|
||||||
|
<ColumnDefinition Width="34" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock Text="{Binding Carrier}" Foreground="#F4F1E8" FontSize="12"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<TextBlock Grid.Column="1" Text="{Binding State}" Foreground="#9EA7AE"
|
||||||
|
FontSize="12" TextWrapping="Wrap" />
|
||||||
|
<TextBlock Grid.Column="2" Text="{Binding Amount}" Foreground="#F4F1E8"
|
||||||
|
FontSize="12" />
|
||||||
|
<TextBlock Grid.Column="3" Text="{Binding Intensity}" Foreground="#F4F1E8"
|
||||||
|
FontSize="12" />
|
||||||
|
<TextBlock Grid.Column="4" Text="{Binding Integrity}" Foreground="#F4F1E8"
|
||||||
|
FontSize="12" />
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
|
||||||
<TextBlock Text="Forecasts" FontSize="16" FontWeight="SemiBold" Foreground="#F4F1E8" />
|
<TextBlock Text="Forecasts" FontSize="16" FontWeight="SemiBold" Foreground="#F4F1E8" />
|
||||||
<ItemsControl x:Name="ForecastList">
|
<ItemsControl x:Name="ForecastList">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ public sealed partial class MainWindow
|
|||||||
|
|
||||||
private sealed record ForecastViewModel(string Message);
|
private sealed record ForecastViewModel(string Message);
|
||||||
private sealed record InspectorItemViewModel(string Label, string Value, string Description);
|
private sealed record InspectorItemViewModel(string Label, string Value, string Description);
|
||||||
|
private sealed record NetworkInspectionViewModel(string Carrier, string State, string Amount, string Intensity, string Integrity);
|
||||||
|
|
||||||
private sealed class EditorToolViewModel(EditorToolCommand command, string label) : INotifyPropertyChanged
|
private sealed class EditorToolViewModel(EditorToolCommand command, string label) : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
@@ -260,12 +261,13 @@ public sealed partial class MainWindow
|
|||||||
m_DragExceededClickThreshold = false;
|
m_DragExceededClickThreshold = false;
|
||||||
m_IsPanning = e.KeyModifiers.HasFlag(VirtualKeyModifiers.Shift);
|
m_IsPanning = e.KeyModifiers.HasFlag(VirtualKeyModifiers.Shift);
|
||||||
m_CursorDragStartCell = null;
|
m_CursorDragStartCell = null;
|
||||||
|
m_CursorDragStartRejected = false;
|
||||||
m_DragPreviewDestination = null;
|
m_DragPreviewDestination = null;
|
||||||
m_InvalidDragCell = null;
|
m_InvalidDragCell = null;
|
||||||
m_EditorFeedback = string.Empty;
|
m_EditorFeedback = string.Empty;
|
||||||
m_LastPaintedCell = null;
|
m_LastPaintedCell = null;
|
||||||
if (!m_IsPanning && m_SelectedTool.Tool == EEditorTool.Cursor && TryGetGridPosition(point.Position, out var position))
|
if (!m_IsPanning && m_SelectedTool.Tool == EEditorTool.Cursor && TryGetGridPosition(point.Position, out var position))
|
||||||
m_CursorDragStartCell = position;
|
StartCursorDrag(position);
|
||||||
else if (!m_IsPanning && IsDragPaintTool(m_SelectedTool.Tool) && TryGetGridPosition(point.Position, out position))
|
else if (!m_IsPanning && IsDragPaintTool(m_SelectedTool.Tool) && TryGetGridPosition(point.Position, out position))
|
||||||
{
|
{
|
||||||
m_LastPaintedCell = position;
|
m_LastPaintedCell = position;
|
||||||
@@ -337,7 +339,7 @@ public sealed partial class MainWindow
|
|||||||
RefreshInspector();
|
RefreshInspector();
|
||||||
LevelCanvas.Invalidate();
|
LevelCanvas.Invalidate();
|
||||||
}
|
}
|
||||||
else if (!m_DragExceededClickThreshold && !IsDragPaintTool(m_SelectedTool.Tool))
|
else if (!m_DragExceededClickThreshold && !m_CursorDragStartRejected && !IsDragPaintTool(m_SelectedTool.Tool))
|
||||||
{
|
{
|
||||||
SelectOrPaintAt(point.Position);
|
SelectOrPaintAt(point.Position);
|
||||||
}
|
}
|
||||||
@@ -346,6 +348,7 @@ public sealed partial class MainWindow
|
|||||||
m_LeftPointerDown = false;
|
m_LeftPointerDown = false;
|
||||||
m_IsPanning = false;
|
m_IsPanning = false;
|
||||||
m_CursorDragStartCell = null;
|
m_CursorDragStartCell = null;
|
||||||
|
m_CursorDragStartRejected = false;
|
||||||
m_DragPreviewDestination = null;
|
m_DragPreviewDestination = null;
|
||||||
m_LastPaintedCell = null;
|
m_LastPaintedCell = null;
|
||||||
m_DragExceededClickThreshold = false;
|
m_DragExceededClickThreshold = false;
|
||||||
@@ -358,6 +361,7 @@ public sealed partial class MainWindow
|
|||||||
m_LeftPointerDown = false;
|
m_LeftPointerDown = false;
|
||||||
m_IsPanning = false;
|
m_IsPanning = false;
|
||||||
m_CursorDragStartCell = null;
|
m_CursorDragStartCell = null;
|
||||||
|
m_CursorDragStartRejected = false;
|
||||||
m_DragPreviewDestination = null;
|
m_DragPreviewDestination = null;
|
||||||
m_LastPaintedCell = null;
|
m_LastPaintedCell = null;
|
||||||
m_DragExceededClickThreshold = false;
|
m_DragExceededClickThreshold = false;
|
||||||
@@ -413,7 +417,25 @@ public sealed partial class MainWindow
|
|||||||
|
|
||||||
private static bool IsDragPaintTool(EEditorTool tool)
|
private static bool IsDragPaintTool(EEditorTool tool)
|
||||||
{
|
{
|
||||||
return tool is EEditorTool.Floor or EEditorTool.Wall;
|
return tool is EEditorTool.Floor or EEditorTool.Wall or EEditorTool.Underground;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartCursorDrag(GridPosition position)
|
||||||
|
{
|
||||||
|
m_SelectedCell = position;
|
||||||
|
if (HasMovableAt(position))
|
||||||
|
{
|
||||||
|
m_CursorDragStartCell = position;
|
||||||
|
RefreshInspector();
|
||||||
|
LevelCanvas.Invalidate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_CursorDragStartRejected = true;
|
||||||
|
m_InvalidDragCell = position;
|
||||||
|
m_EditorFeedback = "No movable robot, prop, source, or leak starts here.";
|
||||||
|
RefreshInspector();
|
||||||
|
LevelCanvas.Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearAt(Point point)
|
private void ClearAt(Point point)
|
||||||
@@ -788,13 +810,29 @@ public sealed partial class MainWindow
|
|||||||
GlobalGrid.ItemsSource = new[] {
|
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("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("Heat Shield", m_Level.Robot.HeatImmunitySteps.ToString(CultureInfo.InvariantCulture), "Remaining protected movement steps."),
|
||||||
new InspectorItemViewModel("Required F/C/E", $"{m_Level.RequiredFuelConsumers}/{m_Level.RequiredCoolantConsumers}/{m_Level.RequiredElectricityConsumers}", "Producing consumers needed for readiness."),
|
|
||||||
new InspectorItemViewModel("Objects", $"R {m_Level.Reactors.Count} / L {m_Level.Leaks.Count} / D {doorCount}", "Reactors, active leaks, and doors.")
|
new InspectorItemViewModel("Objects", $"R {m_Level.Reactors.Count} / L {m_Level.Leaks.Count} / D {doorCount}", "Reactors, active leaks, and doors.")
|
||||||
};
|
};
|
||||||
|
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.")
|
||||||
|
};
|
||||||
|
|
||||||
|
if (m_SelectedCell is { } position && m_Level.InBounds(position))
|
||||||
|
{
|
||||||
|
SelectedCellTitleText.Text = SelectedCellTitle(position);
|
||||||
|
CellGrid.ItemsSource = CellInspectionItems(position);
|
||||||
|
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<InspectorItemViewModel>();
|
||||||
|
NetworkGrid.ItemsSource = Array.Empty<NetworkInspectionViewModel>();
|
||||||
|
}
|
||||||
|
|
||||||
CellGrid.ItemsSource = m_SelectedCell is { } position && m_Level.InBounds(position)
|
|
||||||
? CellInspectionItems(position)
|
|
||||||
: new[] { new InspectorItemViewModel("Selection", "None", "Select a grid cell to inspect it.") };
|
|
||||||
ForecastList.ItemsSource = m_Level.Forecasts.Select(forecast => new ForecastViewModel($"{forecast.Turns}: {forecast.Message}")).ToArray();
|
ForecastList.ItemsSource = m_Level.Forecasts.Select(forecast => new ForecastViewModel($"{forecast.Turns}: {forecast.Message}")).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,25 +865,61 @@ public sealed partial class MainWindow
|
|||||||
{
|
{
|
||||||
var prop = m_Level.GetProp(position);
|
var prop = m_Level.GetProp(position);
|
||||||
var surface = m_Level.GetSurface(position);
|
var surface = m_Level.GetSurface(position);
|
||||||
var fuel = m_Level.GetUnderground(position, ECarrierType.Fuel);
|
|
||||||
var coolant = m_Level.GetUnderground(position, ECarrierType.Coolant);
|
|
||||||
var electricity = m_Level.GetUnderground(position, ECarrierType.Electricity);
|
|
||||||
return [
|
return [
|
||||||
new("Position", $"{position.X},{position.Y}", "Grid coordinate."),
|
new("Position", $"{position.X},{position.Y}", "Grid coordinate."),
|
||||||
new("Terrain", m_Level.GetTerrain(position).ToString(), "Static surface cell type."),
|
new("Terrain", m_Level.GetTerrain(position).ToString(), "Static surface cell type."),
|
||||||
new("Prop", $"{prop.Type} {prop.SwitchState}", "Placed surface object and switch state."),
|
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("Services F/C/E", $"{prop.FuelServiceState}/{prop.CoolantServiceState}/{prop.ElectricityServiceState}", "Consumer service status."),
|
||||||
new("Fuel Net", UndergroundText(fuel), "Amount, intensity, and integrity."),
|
|
||||||
new("Coolant Net", UndergroundText(coolant), "Amount, intensity, and integrity."),
|
|
||||||
new("Electric Net", UndergroundText(electricity), "Amount, intensity, and integrity."),
|
|
||||||
new("Surface F/C/E/H", $"{Format(surface.Fuel)} / {Format(surface.Coolant)} / {Format(surface.Electricity)} / {Format(surface.Heat)}", "Visible hazards and heat."),
|
|
||||||
new("Blocks F/C/E", $"{surface.FuelBlockTurns}/{surface.CoolantBlockTurns}/{surface.ElectricityBlockTurns}", "Temporary remedy entry blocks.")
|
new("Blocks F/C/E", $"{surface.FuelBlockTurns}/{surface.CoolantBlockTurns}/{surface.ElectricityBlockTurns}", "Temporary remedy entry blocks.")
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string UndergroundText(UndergroundCell cell)
|
private InspectorItemViewModel[] SurfaceInspectionItems(GridPosition position)
|
||||||
{
|
{
|
||||||
return $"{cell.State} amount {Format(cell.Amount)} intensity {Format(cell.Intensity)} integrity {cell.StructuralIntegrity}";
|
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.")
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetworkInspectionViewModel[] NetworkInspectionItems(GridPosition position)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
NetworkInspectionItem("Fuel", m_Level.GetUnderground(position, ECarrierType.Fuel)),
|
||||||
|
NetworkInspectionItem("Coolant", m_Level.GetUnderground(position, ECarrierType.Coolant)),
|
||||||
|
NetworkInspectionItem("Electric", m_Level.GetUnderground(position, ECarrierType.Electricity))
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NetworkInspectionViewModel NetworkInspectionItem(string carrier, UndergroundCell cell)
|
||||||
|
{
|
||||||
|
return new(carrier, cell.State.ToString(), Format(cell.Amount), Format(cell.Intensity), cell.StructuralIntegrity.ToString(CultureInfo.InvariantCulture));
|
||||||
|
}
|
||||||
|
|
||||||
|
private string SelectedCellTitle(GridPosition position)
|
||||||
|
{
|
||||||
|
var prop = m_Level.GetProp(position);
|
||||||
|
if (prop.Type != EPropType.None)
|
||||||
|
return $"{prop.Type} {prop.SwitchState}";
|
||||||
|
|
||||||
|
if (m_Level.Robot.Position == position)
|
||||||
|
return "Robot";
|
||||||
|
|
||||||
|
var leak = m_Level.Leaks.FirstOrDefault(leak => !leak.Repaired && (leak.AccessPosition == position || leak.UndergroundPosition == position));
|
||||||
|
if (leak is not null)
|
||||||
|
return $"{leak.Carrier} Leak";
|
||||||
|
|
||||||
|
var surface = m_Level.GetSurface(position);
|
||||||
|
if (surface.Fuel > 0 || surface.Coolant > 0 || surface.Electricity > 0)
|
||||||
|
return "Surface Hazard";
|
||||||
|
|
||||||
|
if (surface.Heat > 0)
|
||||||
|
return "Heat";
|
||||||
|
|
||||||
|
return m_Level.GetTerrain(position).ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string Format(float value)
|
private static string Format(float value)
|
||||||
@@ -957,6 +1031,11 @@ public sealed partial class MainWindow
|
|||||||
return m_Level.Robot.Position == source ? "robot" : null;
|
return m_Level.Robot.Position == source ? "robot" : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool HasMovableAt(GridPosition source)
|
||||||
|
{
|
||||||
|
return MovableImageKey(source) is not null;
|
||||||
|
}
|
||||||
|
|
||||||
private float SurfaceOpacity()
|
private float SurfaceOpacity()
|
||||||
{
|
{
|
||||||
return m_ActiveLayer == EEditorLayer.Surface ? 1.0f : 0.5f;
|
return m_ActiveLayer == EEditorLayer.Surface ? 1.0f : 0.5f;
|
||||||
@@ -1217,6 +1296,7 @@ public sealed partial class MainWindow
|
|||||||
private EEditorLayer m_ActiveLayer = EEditorLayer.Surface;
|
private EEditorLayer m_ActiveLayer = EEditorLayer.Surface;
|
||||||
private StorageFile? m_CurrentFile;
|
private StorageFile? m_CurrentFile;
|
||||||
private GridPosition? m_CursorDragStartCell;
|
private GridPosition? m_CursorDragStartCell;
|
||||||
|
private bool m_CursorDragStartRejected;
|
||||||
private bool m_DragExceededClickThreshold;
|
private bool m_DragExceededClickThreshold;
|
||||||
private GridPosition? m_DragPreviewDestination;
|
private GridPosition? m_DragPreviewDestination;
|
||||||
private string m_EditorFeedback = string.Empty;
|
private string m_EditorFeedback = string.Empty;
|
||||||
|
|||||||
@@ -42,6 +42,21 @@ public sealed class LevelEditorTests
|
|||||||
Assert.Equal(EUndergroundState.Intact, next.GetUnderground(position, ECarrierType.Electricity).State);
|
Assert.Equal(EUndergroundState.Intact, next.GetUnderground(position, ECarrierType.Electricity).State);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void UndergroundToolCanPaintAdjacentCellsRepeatedly()
|
||||||
|
{
|
||||||
|
var level = LevelState.Create("Network editor", 6, 6);
|
||||||
|
var command = new EditorToolCommand { Tool = EEditorTool.Underground, Carrier = ECarrierType.Fuel };
|
||||||
|
|
||||||
|
level = LevelEditor.Apply(level, new(1, 1), command);
|
||||||
|
level = LevelEditor.Apply(level, new(2, 1), command);
|
||||||
|
level = LevelEditor.Apply(level, new(3, 1), command);
|
||||||
|
|
||||||
|
Assert.Equal(EUndergroundState.Intact, level.GetUnderground(new(1, 1), ECarrierType.Fuel).State);
|
||||||
|
Assert.Equal(EUndergroundState.Intact, level.GetUnderground(new(2, 1), ECarrierType.Fuel).State);
|
||||||
|
Assert.Equal(EUndergroundState.Intact, level.GetUnderground(new(3, 1), ECarrierType.Fuel).State);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ConsumerToolPlacesCarrierAgnosticConsumer()
|
public void ConsumerToolPlacesCarrierAgnosticConsumer()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user