cleanup code
This commit is contained in:
@@ -20,9 +20,9 @@ insert_final_newline = false
|
|||||||
# Organize usings
|
# Organize usings
|
||||||
dotnet_separate_import_directive_groups = false
|
dotnet_separate_import_directive_groups = false
|
||||||
dotnet_sort_system_directives_first = false
|
dotnet_sort_system_directives_first = false
|
||||||
file_header_template =
|
file_header_template = # this. and Me. preferences
|
||||||
|
|
||||||
|
|
||||||
# this. and Me. preferences
|
|
||||||
dotnet_style_qualification_for_event = false:suggestion
|
dotnet_style_qualification_for_event = false:suggestion
|
||||||
dotnet_style_qualification_for_field = false:suggestion
|
dotnet_style_qualification_for_field = false:suggestion
|
||||||
dotnet_style_qualification_for_method = false:suggestion
|
dotnet_style_qualification_for_method = false:suggestion
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Windows-specific instructions
|
# Windows-specific instructions
|
||||||
|
|
||||||
- After the implementation is finished, run `python D:\Code\crlf.py $file1 $file2 ...` for changed files you recognize, in order to normalize all line endings of all touched files to CRLF.
|
- After the implementation is finished, run `python D:\Code\crlf.py $file1 $file2 ...` for changed files you recognize, in order to normalize all line endings of all touched files to CRLF.
|
||||||
- After every iteration, run `jb cleanupcode --build=False '$file1' '$file2' ...` for every C# file you touched.
|
- After every iteration, run `jb cleanupcode '$file1' '$file2' ...` for every C# file you touched.
|
||||||
@@ -4,8 +4,6 @@ namespace ReactorMaintenance.Simulation;
|
|||||||
|
|
||||||
public abstract class Balancing
|
public abstract class Balancing
|
||||||
{
|
{
|
||||||
public static Balancing Current { get; set; } = new NormalBalancing();
|
|
||||||
|
|
||||||
public float ClampValue(float value)
|
public float ClampValue(float value)
|
||||||
{
|
{
|
||||||
return Math.Clamp(value, MinValue, MaxValue);
|
return Math.Clamp(value, MinValue, MaxValue);
|
||||||
@@ -107,6 +105,8 @@ public abstract class Balancing
|
|||||||
return a > b ? a : b;
|
return a > b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Balancing Current { get; set; } = new NormalBalancing();
|
||||||
|
|
||||||
public abstract int DefaultLevelWidth { get; }
|
public abstract int DefaultLevelWidth { get; }
|
||||||
public abstract int DefaultLevelHeight { get; }
|
public abstract int DefaultLevelHeight { get; }
|
||||||
public abstract int MinimumLevelSize { get; }
|
public abstract int MinimumLevelSize { get; }
|
||||||
|
|||||||
@@ -2,15 +2,6 @@
|
|||||||
|
|
||||||
public sealed record JunctionFlow
|
public sealed record JunctionFlow
|
||||||
{
|
{
|
||||||
public GridPosition Position { get; init; } = new(0, 0);
|
|
||||||
public PropState Prop { get; init; } = new();
|
|
||||||
public ECarrierType Carrier { get; init; }
|
|
||||||
public IReadOnlyList<GridPosition> Branches { get; init; } = Array.Empty<GridPosition>();
|
|
||||||
public GridPosition? IncomingBranch { get; init; }
|
|
||||||
public IReadOnlyList<GridPosition> OutgoingBranches { get; init; } = Array.Empty<GridPosition>();
|
|
||||||
public IReadOnlyList<string> Errors { get; init; } = Array.Empty<string>();
|
|
||||||
public bool IsValid => Errors.Count == 0;
|
|
||||||
|
|
||||||
public float WeightFor(GridPosition outgoingBranch)
|
public float WeightFor(GridPosition outgoingBranch)
|
||||||
{
|
{
|
||||||
var index = IndexOfOutgoingBranch(outgoingBranch);
|
var index = IndexOfOutgoingBranch(outgoingBranch);
|
||||||
@@ -31,4 +22,13 @@ public sealed record JunctionFlow
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GridPosition Position { get; init; } = new(0, 0);
|
||||||
|
public PropState Prop { get; init; } = new();
|
||||||
|
public ECarrierType Carrier { get; init; }
|
||||||
|
public IReadOnlyList<GridPosition> Branches { get; init; } = Array.Empty<GridPosition>();
|
||||||
|
public GridPosition? IncomingBranch { get; init; }
|
||||||
|
public IReadOnlyList<GridPosition> OutgoingBranches { get; init; } = Array.Empty<GridPosition>();
|
||||||
|
public IReadOnlyList<string> Errors { get; init; } = Array.Empty<string>();
|
||||||
|
public bool IsValid => Errors.Count == 0;
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
public static class JunctionFlowAnalyzer
|
public static class JunctionFlowAnalyzer
|
||||||
{
|
{
|
||||||
|
private sealed record SourceBranch(GridPosition Position, int? Distance);
|
||||||
|
|
||||||
public static IReadOnlyList<JunctionFlow> Analyze(LevelState level)
|
public static IReadOnlyList<JunctionFlow> Analyze(LevelState level)
|
||||||
{
|
{
|
||||||
var flows = new List<JunctionFlow>();
|
var flows = new List<JunctionFlow>();
|
||||||
@@ -92,6 +94,4 @@ public static class JunctionFlowAnalyzer
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed record SourceBranch(GridPosition Position, int? Distance);
|
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,7 @@ public static class LevelEditor
|
|||||||
return SetFloorProp(level, position, new() { Type = EPropType.Door });
|
return SetFloorProp(level, position, new() { Type = EPropType.Door });
|
||||||
|
|
||||||
return SetFloorProp(level, position, new() { Type = EPropType.Door }) with {
|
return SetFloorProp(level, position, new() { Type = EPropType.Door }) with {
|
||||||
Doors = [.. level.Doors, new DoorState { A = position, B = neighbor }]
|
Doors = [.. level.Doors, new() { A = position, B = neighbor }]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ public static class LevelEditor
|
|||||||
return levelWithProp with {
|
return levelWithProp with {
|
||||||
Reactors = [
|
Reactors = [
|
||||||
.. level.Reactors,
|
.. level.Reactors,
|
||||||
new ReactorBinding {
|
new() {
|
||||||
ReactorId = id,
|
ReactorId = id,
|
||||||
ControlPosition = position,
|
ControlPosition = position,
|
||||||
FuelConsumerPosition = position,
|
FuelConsumerPosition = position,
|
||||||
@@ -152,7 +152,7 @@ public static class LevelEditor
|
|||||||
return next with {
|
return next with {
|
||||||
Leaks = [
|
Leaks = [
|
||||||
.. next.Leaks,
|
.. next.Leaks,
|
||||||
new LeakState {
|
new() {
|
||||||
Carrier = carrier,
|
Carrier = carrier,
|
||||||
UndergroundPosition = position,
|
UndergroundPosition = position,
|
||||||
AccessPosition = accessPosition
|
AccessPosition = accessPosition
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ namespace ReactorMaintenance.Simulation;
|
|||||||
|
|
||||||
public static class LevelSerializer
|
public static class LevelSerializer
|
||||||
{
|
{
|
||||||
private const int c_CurrentVersion = 2;
|
private sealed record LevelFile
|
||||||
|
{
|
||||||
|
public int Version { get; init; }
|
||||||
|
public LevelState? Level { get; init; }
|
||||||
|
}
|
||||||
|
|
||||||
public static string Serialize(LevelState level)
|
public static string Serialize(LevelState level)
|
||||||
{
|
{
|
||||||
@@ -29,14 +33,10 @@ public static class LevelSerializer
|
|||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const int c_CurrentVersion = 2;
|
||||||
|
|
||||||
private static readonly JsonSerializerOptions s_Options = new() {
|
private static readonly JsonSerializerOptions s_Options = new() {
|
||||||
WriteIndented = true,
|
WriteIndented = true,
|
||||||
Converters = { new JsonStringEnumConverter() }
|
Converters = { new JsonStringEnumConverter() }
|
||||||
};
|
};
|
||||||
|
|
||||||
private sealed record LevelFile
|
|
||||||
{
|
|
||||||
public int Version { get; init; }
|
|
||||||
public LevelState? Level { get; init; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ public static class LevelStateExtensions
|
|||||||
if (!level.InBounds(position))
|
if (!level.InBounds(position))
|
||||||
throw new ArgumentOutOfRangeException(nameof(position), $"Position {position.X},{position.Y} is outside {level.Width}x{level.Height}.");
|
throw new ArgumentOutOfRangeException(nameof(position), $"Position {position.X},{position.Y} is outside {level.Width}x{level.Height}.");
|
||||||
|
|
||||||
return position.Y * level.Width + position.X;
|
return (position.Y * level.Width) + position.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ECellTerrain GetTerrain(this LevelState level, GridPosition position)
|
public static ECellTerrain GetTerrain(this LevelState level, GridPosition position)
|
||||||
@@ -111,6 +111,6 @@ public static class LevelStateExtensions
|
|||||||
|
|
||||||
private static bool SameEdge(GridPosition edgeA, GridPosition edgeB, GridPosition a, GridPosition b)
|
private static bool SameEdge(GridPosition edgeA, GridPosition edgeB, GridPosition a, GridPosition b)
|
||||||
{
|
{
|
||||||
return edgeA == a && edgeB == b || edgeA == b && edgeB == a;
|
return (edgeA == a && edgeB == b) || (edgeA == b && edgeB == a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ public static class LevelStateFactory
|
|||||||
for (var x = 0; x < width; x++)
|
for (var x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
if (x == 0 || y == 0 || x == width - 1 || y == height - 1)
|
if (x == 0 || y == 0 || x == width - 1 || y == height - 1)
|
||||||
terrain[y * width + x] = ECellTerrain.Wall;
|
terrain[(y * width) + x] = ECellTerrain.Wall;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,24 @@
|
|||||||
|
|
||||||
internal sealed class SimulationCoreSystem
|
internal sealed class SimulationCoreSystem
|
||||||
{
|
{
|
||||||
|
private sealed class SurfaceDelta
|
||||||
|
{
|
||||||
|
public SurfaceState Apply(SurfaceState surface)
|
||||||
|
{
|
||||||
|
return surface with {
|
||||||
|
Fuel = surface.Fuel + Fuel,
|
||||||
|
Coolant = surface.Coolant + Coolant,
|
||||||
|
Electricity = surface.Electricity + Electricity,
|
||||||
|
Heat = surface.Heat + Heat
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Fuel { get; set; }
|
||||||
|
public float Coolant { get; set; }
|
||||||
|
public float Electricity { get; set; }
|
||||||
|
public float Heat { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public LevelState MoveRobot(LevelState level, GridPosition destination)
|
public LevelState MoveRobot(LevelState level, GridPosition destination)
|
||||||
{
|
{
|
||||||
if (!CanSpendAction(level) || !level.IsFloor(destination) || level.Robot.Position.ManhattanDistance(destination) != 1)
|
if (!CanSpendAction(level) || !level.IsFloor(destination) || level.Robot.Position.ManhattanDistance(destination) != 1)
|
||||||
@@ -252,7 +270,7 @@ internal sealed class SimulationCoreSystem
|
|||||||
if (surface[accessIndex].Blocks(leak.Carrier))
|
if (surface[accessIndex].Blocks(leak.Carrier))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var amount = Balancing.Current.LeakBaseAmount + underground.Amount * Balancing.Current.LeakAmountScale + underground.Intensity * Balancing.Current.LeakIntensityScale;
|
var amount = Balancing.Current.LeakBaseAmount + (underground.Amount * Balancing.Current.LeakAmountScale) + (underground.Intensity * Balancing.Current.LeakIntensityScale);
|
||||||
surface[accessIndex] = AddSurfaceCarrier(surface[accessIndex], leak.Carrier, amount);
|
surface[accessIndex] = AddSurfaceCarrier(surface[accessIndex], leak.Carrier, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -447,7 +465,7 @@ internal sealed class SimulationCoreSystem
|
|||||||
ERulePredicateKind.TurnAtLeast => level.Global.Turn >= predicate.Turn,
|
ERulePredicateKind.TurnAtLeast => level.Global.Turn >= predicate.Turn,
|
||||||
ERulePredicateKind.LevelStateIs => level.Global.LevelState == predicate.LevelState,
|
ERulePredicateKind.LevelStateIs => level.Global.LevelState == predicate.LevelState,
|
||||||
ERulePredicateKind.ReactorReadyIs => ReactorMatches(level, predicate, reactor => reactor.Ready),
|
ERulePredicateKind.ReactorReadyIs => ReactorMatches(level, predicate, reactor => reactor.Ready),
|
||||||
ERulePredicateKind.ReactorLostIs => (level.Global.LevelState == ELevelState.Lost) == predicate.BoolValue,
|
ERulePredicateKind.ReactorLostIs => level.Global.LevelState == ELevelState.Lost == predicate.BoolValue,
|
||||||
ERulePredicateKind.ReactorWonIs => ReactorWonMatches(level, predicate),
|
ERulePredicateKind.ReactorWonIs => ReactorWonMatches(level, predicate),
|
||||||
ERulePredicateKind.PropStateAt => level.InBounds(predicate.Position) && level.GetProp(predicate.Position).SwitchState == predicate.PropSwitchState,
|
ERulePredicateKind.PropStateAt => level.InBounds(predicate.Position) && level.GetProp(predicate.Position).SwitchState == predicate.PropSwitchState,
|
||||||
ERulePredicateKind.ConsumerStateAt => level.InBounds(predicate.Position) && level.GetProp(predicate.Position).ServiceState == predicate.ConsumerServiceState,
|
ERulePredicateKind.ConsumerStateAt => level.InBounds(predicate.Position) && level.GetProp(predicate.Position).ServiceState == predicate.ConsumerServiceState,
|
||||||
@@ -684,23 +702,5 @@ internal sealed class SimulationCoreSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class SurfaceDelta
|
|
||||||
{
|
|
||||||
public SurfaceState Apply(SurfaceState surface)
|
|
||||||
{
|
|
||||||
return surface with {
|
|
||||||
Fuel = surface.Fuel + Fuel,
|
|
||||||
Coolant = surface.Coolant + Coolant,
|
|
||||||
Electricity = surface.Electricity + Electricity,
|
|
||||||
Heat = surface.Heat + Heat
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public float Fuel { get; set; }
|
|
||||||
public float Coolant { get; set; }
|
|
||||||
public float Electricity { get; set; }
|
|
||||||
public float Heat { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly LevelValidator m_Validator = new();
|
private readonly LevelValidator m_Validator = new();
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,8 @@
|
|||||||
<ToggleButton IsChecked="{Binding IsSelected, Mode=TwoWay}"
|
<ToggleButton IsChecked="{Binding IsSelected, Mode=TwoWay}"
|
||||||
Checked="ToolToggle_Checked" ToolTipService.ToolTip="{Binding Label}"
|
Checked="ToolToggle_Checked" ToolTipService.ToolTip="{Binding Label}"
|
||||||
Width="112" MinHeight="46" Padding="6" Margin="0,0,8,8">
|
Width="112" MinHeight="46" Padding="6" Margin="0,0,8,8">
|
||||||
<TextBlock Text="{Binding Label}" TextWrapping="WrapWholeWords" TextAlignment="Center"
|
<TextBlock Text="{Binding Label}" TextWrapping="WrapWholeWords"
|
||||||
|
TextAlignment="Center"
|
||||||
FontSize="12" />
|
FontSize="12" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
@@ -50,7 +51,8 @@
|
|||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
<TextBlock Text="Left click selects or paints. Right click clears surface prop and hazards."
|
<TextBlock Text="Left click selects or paints. Right click clears surface prop and hazards."
|
||||||
Foreground="#9EA7AE" TextWrapping="Wrap" />
|
Foreground="#9EA7AE" TextWrapping="Wrap" />
|
||||||
<TextBlock Text="Door chooses the first adjacent floor edge. Reactor controls auto-bind to the first available consumers."
|
<TextBlock
|
||||||
|
Text="Door chooses the first adjacent floor edge. Reactor controls auto-bind to the first available consumers."
|
||||||
Foreground="#9EA7AE"
|
Foreground="#9EA7AE"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using Microsoft.Graphics.Canvas;
|
using Microsoft.Graphics.Canvas;
|
||||||
using Microsoft.Graphics.Canvas.Text;
|
using Microsoft.Graphics.Canvas.Text;
|
||||||
|
using Microsoft.Graphics.Canvas.UI;
|
||||||
using Microsoft.Graphics.Canvas.UI.Xaml;
|
using Microsoft.Graphics.Canvas.UI.Xaml;
|
||||||
using Microsoft.UI;
|
using Microsoft.UI;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Controls;
|
|
||||||
using Microsoft.UI.Xaml.Input;
|
using Microsoft.UI.Xaml.Input;
|
||||||
using ReactorMaintenance.Simulation;
|
using ReactorMaintenance.Simulation;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
@@ -22,7 +22,7 @@ public sealed partial class MainWindow
|
|||||||
{
|
{
|
||||||
public Rect CellRect(GridPosition position)
|
public Rect CellRect(GridPosition position)
|
||||||
{
|
{
|
||||||
return new(OriginX + position.X * CellSize, OriginY + position.Y * CellSize, CellSize, CellSize);
|
return new(OriginX + (position.X * CellSize), OriginY + (position.Y * CellSize), CellSize, CellSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +202,7 @@ public sealed partial class MainWindow
|
|||||||
|
|
||||||
var totalDeltaX = point.Position.X - m_LeftPointerDownPoint.X;
|
var totalDeltaX = point.Position.X - m_LeftPointerDownPoint.X;
|
||||||
var totalDeltaY = point.Position.Y - m_LeftPointerDownPoint.Y;
|
var totalDeltaY = point.Position.Y - m_LeftPointerDownPoint.Y;
|
||||||
if (Math.Sqrt(totalDeltaX * totalDeltaX + totalDeltaY * totalDeltaY) > c_ClickPixelThreshold)
|
if (Math.Sqrt((totalDeltaX * totalDeltaX) + (totalDeltaY * totalDeltaY)) > c_ClickPixelThreshold)
|
||||||
m_DragExceededClickThreshold = true;
|
m_DragExceededClickThreshold = true;
|
||||||
|
|
||||||
m_PanX += deltaX;
|
m_PanX += deltaX;
|
||||||
@@ -319,7 +319,7 @@ public sealed partial class MainWindow
|
|||||||
|
|
||||||
drawing.DrawRectangle(rect, color, cell.State == EUndergroundState.Leaking ? 4 : 2);
|
drawing.DrawRectangle(rect, color, cell.State == EUndergroundState.Leaking ? 4 : 2);
|
||||||
if (cell.Amount > 0 || cell.Intensity > 0)
|
if (cell.Amount > 0 || cell.Intensity > 0)
|
||||||
drawing.FillCircle((float)(rect.X + rect.Width / 2), (float)(rect.Y + rect.Height / 2), (float)Math.Max(2, rect.Width * 0.08), color);
|
drawing.FillCircle((float)(rect.X + (rect.Width / 2)), (float)(rect.Y + (rect.Height / 2)), (float)Math.Max(2, rect.Width * 0.08), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawSurface(CanvasDrawingSession drawing, CanvasLayout layout)
|
private void DrawSurface(CanvasDrawingSession drawing, CanvasLayout layout)
|
||||||
@@ -341,7 +341,7 @@ public sealed partial class MainWindow
|
|||||||
if (amount <= 0)
|
if (amount <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var alpha = (byte)Math.Clamp(40 + amount / Balancing.Current.MaxValue * 130, 40, 170);
|
var alpha = (byte)Math.Clamp(40 + (amount / Balancing.Current.MaxValue * 130), 40, 170);
|
||||||
drawing.FillRectangle(Inset(rect, inset), ColorHelper.FromArgb(alpha, color.R, color.G, color.B));
|
drawing.FillRectangle(Inset(rect, inset), ColorHelper.FromArgb(alpha, color.R, color.G, color.B));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +431,7 @@ public sealed partial class MainWindow
|
|||||||
{
|
{
|
||||||
var availableWidth = Math.Max(1, LevelCanvas.ActualWidth);
|
var availableWidth = Math.Max(1, LevelCanvas.ActualWidth);
|
||||||
var availableHeight = Math.Max(1, LevelCanvas.ActualHeight);
|
var availableHeight = Math.Max(1, LevelCanvas.ActualHeight);
|
||||||
return new((availableWidth - cellSize * m_Level.Width) / 2, (availableHeight - cellSize * m_Level.Height) / 2);
|
return new((availableWidth - (cellSize * m_Level.Width)) / 2, (availableHeight - (cellSize * m_Level.Height)) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClampPan()
|
private void ClampPan()
|
||||||
@@ -459,8 +459,8 @@ public sealed partial class MainWindow
|
|||||||
m_Zoom = Math.Clamp(m_Zoom * zoomFactor, c_MinZoom, c_MaxZoom);
|
m_Zoom = Math.Clamp(m_Zoom * zoomFactor, c_MinZoom, c_MaxZoom);
|
||||||
var newCellSize = GetBaseCellSize() * m_Zoom;
|
var newCellSize = GetBaseCellSize() * m_Zoom;
|
||||||
var originWithoutPan = GetCenteredOrigin(newCellSize);
|
var originWithoutPan = GetCenteredOrigin(newCellSize);
|
||||||
m_PanX = point.X - originWithoutPan.X - cellX * newCellSize;
|
m_PanX = point.X - originWithoutPan.X - (cellX * newCellSize);
|
||||||
m_PanY = point.Y - originWithoutPan.Y - cellY * newCellSize;
|
m_PanY = point.Y - originWithoutPan.Y - (cellY * newCellSize);
|
||||||
ClampPan();
|
ClampPan();
|
||||||
LevelCanvas.Invalidate();
|
LevelCanvas.Invalidate();
|
||||||
}
|
}
|
||||||
@@ -523,11 +523,11 @@ public sealed partial class MainWindow
|
|||||||
level = level.SetProp(new(11, 4), new() { Type = EPropType.AllSeeingEyeTerminal });
|
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.SetProp(new(11, 6), new() { Type = EPropType.RemedySupply, RemedyType = ERemedyType.HeatShield });
|
||||||
level = level.SetUnderground(new(4, 5), ECarrierType.Coolant, new() { State = EUndergroundState.Leaking }) with {
|
level = level.SetUnderground(new(4, 5), ECarrierType.Coolant, new() { State = EUndergroundState.Leaking }) with {
|
||||||
Leaks = [new LeakState { Carrier = ECarrierType.Coolant, UndergroundPosition = new(4, 5), AccessPosition = new(4, 5) }],
|
Leaks = [new() { Carrier = ECarrierType.Coolant, UndergroundPosition = new(4, 5), AccessPosition = new(4, 5) }],
|
||||||
Doors = [new DoorState { A = new(8, 5), B = new(9, 5), State = EDoorState.Closed }],
|
Doors = [new() { A = new(8, 5), B = new(9, 5), State = EDoorState.Closed }],
|
||||||
Robot = new() { Position = new(10, 5) },
|
Robot = new() { Position = new(10, 5) },
|
||||||
Reactors = [
|
Reactors = [
|
||||||
new ReactorBinding {
|
new() {
|
||||||
ReactorId = 1,
|
ReactorId = 1,
|
||||||
ControlPosition = new(10, 5),
|
ControlPosition = new(10, 5),
|
||||||
FuelConsumerPosition = new(5, 3),
|
FuelConsumerPosition = new(5, 3),
|
||||||
@@ -594,12 +594,12 @@ public sealed partial class MainWindow
|
|||||||
private static Rect Inset(Rect rect, double fraction)
|
private static Rect Inset(Rect rect, double fraction)
|
||||||
{
|
{
|
||||||
var inset = rect.Width * fraction;
|
var inset = rect.Width * fraction;
|
||||||
return new(rect.X + inset, rect.Y + inset, rect.Width - inset * 2, rect.Height - inset * 2);
|
return new(rect.X + inset, rect.Y + inset, rect.Width - (inset * 2), rect.Height - (inset * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Point Center(Rect rect)
|
private static Point Center(Rect rect)
|
||||||
{
|
{
|
||||||
return new(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
|
return new(rect.X + (rect.Width / 2), rect.Y + (rect.Height / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DrawImage(CanvasDrawingSession drawing, CanvasBitmap? image, Rect rect, float opacity = 1)
|
private static void DrawImage(CanvasDrawingSession drawing, CanvasBitmap? image, Rect rect, float opacity = 1)
|
||||||
@@ -699,22 +699,22 @@ public sealed partial class MainWindow
|
|||||||
private static readonly Color c_FuelColor = ColorHelper.FromArgb(255, 220, 170, 68);
|
private static readonly Color c_FuelColor = ColorHelper.FromArgb(255, 220, 170, 68);
|
||||||
private static readonly Color c_CoolantColor = ColorHelper.FromArgb(255, 57, 174, 196);
|
private static readonly Color c_CoolantColor = ColorHelper.FromArgb(255, 57, 174, 196);
|
||||||
private static readonly Color c_ElectricityColor = ColorHelper.FromArgb(255, 236, 226, 82);
|
private static readonly Color c_ElectricityColor = ColorHelper.FromArgb(255, 236, 226, 82);
|
||||||
|
private readonly IReadOnlyList<EditorToolViewModel> m_EditorTools = [];
|
||||||
|
|
||||||
private readonly SimulationEngine m_Simulation = new();
|
private readonly SimulationEngine m_Simulation = new();
|
||||||
private StorageFile? m_CurrentFile;
|
private StorageFile? m_CurrentFile;
|
||||||
private LevelState m_Level;
|
|
||||||
private IReadOnlyList<EditorToolViewModel> m_EditorTools = [];
|
|
||||||
private bool m_LeftPointerDown;
|
|
||||||
private bool m_DragExceededClickThreshold;
|
private bool m_DragExceededClickThreshold;
|
||||||
private Point m_LeftPointerDownPoint;
|
private CanvasBitmap? m_HeatSprite;
|
||||||
private Point m_LastPanPoint;
|
private Point m_LastPanPoint;
|
||||||
private GridPosition? m_SelectedCell;
|
private CanvasBitmap? m_LeakSprite;
|
||||||
private EEditorTool m_SelectedTool = EEditorTool.Cursor;
|
private bool m_LeftPointerDown;
|
||||||
private double m_Zoom = 1;
|
private Point m_LeftPointerDownPoint;
|
||||||
|
private LevelState m_Level;
|
||||||
private double m_PanX;
|
private double m_PanX;
|
||||||
private double m_PanY;
|
private double m_PanY;
|
||||||
private CanvasBitmap? m_TerrainTilemap;
|
|
||||||
private CanvasBitmap? m_RobotSprite;
|
private CanvasBitmap? m_RobotSprite;
|
||||||
private CanvasBitmap? m_LeakSprite;
|
private GridPosition? m_SelectedCell;
|
||||||
private CanvasBitmap? m_HeatSprite;
|
private EEditorTool m_SelectedTool = EEditorTool.Cursor;
|
||||||
|
private CanvasBitmap? m_TerrainTilemap;
|
||||||
|
private double m_Zoom = 1;
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ public sealed class SimulationEngineTests
|
|||||||
{
|
{
|
||||||
var level = LevelState.Create("Leak", 6, 6);
|
var level = LevelState.Create("Leak", 6, 6);
|
||||||
level = level.SetUnderground(new(2, 2), ECarrierType.Fuel, new() { State = EUndergroundState.Leaking, Amount = 5, Intensity = 5 }) with {
|
level = level.SetUnderground(new(2, 2), ECarrierType.Fuel, new() { State = EUndergroundState.Leaking, Amount = 5, Intensity = 5 }) with {
|
||||||
Leaks = [new LeakState { Carrier = ECarrierType.Fuel, UndergroundPosition = new(2, 2), AccessPosition = new(2, 2) }]
|
Leaks = [new() { Carrier = ECarrierType.Fuel, UndergroundPosition = new(2, 2), AccessPosition = new(2, 2) }]
|
||||||
};
|
};
|
||||||
level = level.SetProp(new(2, 2), new() { Type = EPropType.Flow, Carrier = ECarrierType.Fuel });
|
level = level.SetProp(new(2, 2), new() { Type = EPropType.Flow, Carrier = ECarrierType.Fuel });
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ public sealed class SimulationEngineTests
|
|||||||
level = level.SetUnderground(new(2, 2), ECarrierType.Fuel, new() { State = EUndergroundState.Leaking, Amount = 5, Intensity = 5 });
|
level = level.SetUnderground(new(2, 2), ECarrierType.Fuel, new() { State = EUndergroundState.Leaking, Amount = 5, Intensity = 5 });
|
||||||
level = level.SetSurface(new(2, 2), new() { Fuel = 5 }) with {
|
level = level.SetSurface(new(2, 2), new() { Fuel = 5 }) with {
|
||||||
Robot = new() { Position = new(2, 2), FuelNeutralizers = 1 },
|
Robot = new() { Position = new(2, 2), FuelNeutralizers = 1 },
|
||||||
Leaks = [new LeakState { Carrier = ECarrierType.Fuel, UndergroundPosition = new(2, 2), AccessPosition = new(2, 2) }]
|
Leaks = [new() { Carrier = ECarrierType.Fuel, UndergroundPosition = new(2, 2), AccessPosition = new(2, 2) }]
|
||||||
};
|
};
|
||||||
|
|
||||||
var next = m_Engine.InteractLeak(level, ECarrierType.Fuel, true);
|
var next = m_Engine.InteractLeak(level, ECarrierType.Fuel, true);
|
||||||
@@ -65,7 +65,7 @@ public sealed class SimulationEngineTests
|
|||||||
{
|
{
|
||||||
var level = LevelState.Create("Door", 6, 6);
|
var level = LevelState.Create("Door", 6, 6);
|
||||||
level = level.SetSurface(new(2, 2), new() { Heat = 8 }) with {
|
level = level.SetSurface(new(2, 2), new() { Heat = 8 }) with {
|
||||||
Doors = [new DoorState { A = new(2, 2), B = new(3, 2), State = EDoorState.Closed }]
|
Doors = [new() { A = new(2, 2), B = new(3, 2), State = EDoorState.Closed }]
|
||||||
};
|
};
|
||||||
|
|
||||||
var next = m_Engine.AdvanceTurn(level);
|
var next = m_Engine.AdvanceTurn(level);
|
||||||
@@ -155,11 +155,11 @@ public sealed class SimulationEngineTests
|
|||||||
{
|
{
|
||||||
var level = LevelState.Create("Rule", 6, 6) with {
|
var level = LevelState.Create("Rule", 6, 6) with {
|
||||||
RuleEvents = [
|
RuleEvents = [
|
||||||
new RuleEventState {
|
new() {
|
||||||
Phase = ERuleEventPhase.EndOfTurn,
|
Phase = ERuleEventPhase.EndOfTurn,
|
||||||
ForecastText = "containment failure",
|
ForecastText = "containment failure",
|
||||||
Predicates = [new RulePredicate { Kind = ERulePredicateKind.TurnAtLeast, Turn = 0 }],
|
Predicates = [new() { Kind = ERulePredicateKind.TurnAtLeast, Turn = 0 }],
|
||||||
Effects = [new RuleEffect { Kind = ERuleEffectKind.MarkTerminalLoss, Message = "CONTAINMENT FAILURE" }]
|
Effects = [new() { Kind = ERuleEffectKind.MarkTerminalLoss, Message = "CONTAINMENT FAILURE" }]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@@ -177,10 +177,10 @@ public sealed class SimulationEngineTests
|
|||||||
level = AddLine(level, ECarrierType.Fuel, new(2, 2), new(3, 2));
|
level = AddLine(level, ECarrierType.Fuel, new(2, 2), new(3, 2));
|
||||||
level = level.SetProp(new(2, 2), new() { Type = EPropType.Flow, Carrier = ECarrierType.Fuel }) with {
|
level = level.SetProp(new(2, 2), new() { Type = EPropType.Flow, Carrier = ECarrierType.Fuel }) with {
|
||||||
RuleEvents = [
|
RuleEvents = [
|
||||||
new RuleEventState {
|
new() {
|
||||||
Phase = ERuleEventPhase.EndOfTurn,
|
Phase = ERuleEventPhase.EndOfTurn,
|
||||||
Predicates = [new RulePredicate { Kind = ERulePredicateKind.NetworkBandAt, Position = new(3, 2), Carrier = ECarrierType.Fuel, NetworkValue = ENetworkValueKind.Amount, Band = EBand.Critical }],
|
Predicates = [new() { Kind = ERulePredicateKind.NetworkBandAt, Position = new(3, 2), Carrier = ECarrierType.Fuel, NetworkValue = ENetworkValueKind.Amount, Band = EBand.Critical }],
|
||||||
Effects = [new RuleEffect { Kind = ERuleEffectKind.EmitWarning, Message = "fuel pressure high" }]
|
Effects = [new() { Kind = ERuleEffectKind.EmitWarning, Message = "fuel pressure high" }]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@@ -195,10 +195,10 @@ public sealed class SimulationEngineTests
|
|||||||
{
|
{
|
||||||
var level = BuildReadyLevel() with {
|
var level = BuildReadyLevel() with {
|
||||||
RuleEvents = [
|
RuleEvents = [
|
||||||
new RuleEventState {
|
new() {
|
||||||
Phase = ERuleEventPhase.EndOfTurn,
|
Phase = ERuleEventPhase.EndOfTurn,
|
||||||
Predicates = [new RulePredicate { Kind = ERulePredicateKind.ReactorReadyIs, ReactorId = 1, BoolValue = true }],
|
Predicates = [new() { Kind = ERulePredicateKind.ReactorReadyIs, ReactorId = 1, BoolValue = true }],
|
||||||
Effects = [new RuleEffect { Kind = ERuleEffectKind.EmitWarning, Message = "reactor ready rule" }]
|
Effects = [new() { Kind = ERuleEffectKind.EmitWarning, Message = "reactor ready rule" }]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@@ -214,10 +214,10 @@ public sealed class SimulationEngineTests
|
|||||||
var level = LevelState.Create("Inventory rule", 6, 6) with {
|
var level = LevelState.Create("Inventory rule", 6, 6) with {
|
||||||
Robot = new() { Position = new(1, 1), FuelNeutralizers = 1 },
|
Robot = new() { Position = new(1, 1), FuelNeutralizers = 1 },
|
||||||
RuleEvents = [
|
RuleEvents = [
|
||||||
new RuleEventState {
|
new() {
|
||||||
Phase = ERuleEventPhase.StartOfSimulation,
|
Phase = ERuleEventPhase.StartOfSimulation,
|
||||||
Predicates = [new RulePredicate { Kind = ERulePredicateKind.RobotInventoryAtLeast, Remedy = ERemedyType.FuelNeutralizer, InventoryCount = 1 }],
|
Predicates = [new() { Kind = ERulePredicateKind.RobotInventoryAtLeast, Remedy = ERemedyType.FuelNeutralizer, InventoryCount = 1 }],
|
||||||
Effects = [new RuleEffect { Kind = ERuleEffectKind.EmitWarning, Message = "fuel kit detected" }]
|
Effects = [new() { Kind = ERuleEffectKind.EmitWarning, Message = "fuel kit detected" }]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@@ -234,19 +234,19 @@ public sealed class SimulationEngineTests
|
|||||||
level = level.SetSurface(new(2, 2), new() { Fuel = 5, Heat = 5 }) with {
|
level = level.SetSurface(new(2, 2), new() { Fuel = 5, Heat = 5 }) with {
|
||||||
Robot = new() { Position = new(1, 1), FuelNeutralizers = 2 },
|
Robot = new() { Position = new(1, 1), FuelNeutralizers = 2 },
|
||||||
Doors = [
|
Doors = [
|
||||||
new DoorState { A = new(2, 2), B = new(1, 2), State = EDoorState.Closed },
|
new() { A = new(2, 2), B = new(1, 2), State = EDoorState.Closed },
|
||||||
new DoorState { A = new(2, 2), B = new(3, 2), State = EDoorState.Closed },
|
new() { A = new(2, 2), B = new(3, 2), State = EDoorState.Closed },
|
||||||
new DoorState { A = new(2, 2), B = new(2, 1), State = EDoorState.Closed },
|
new() { A = new(2, 2), B = new(2, 1), State = EDoorState.Closed },
|
||||||
new DoorState { A = new(2, 2), B = new(2, 3), State = EDoorState.Closed }
|
new() { A = new(2, 2), B = new(2, 3), State = EDoorState.Closed }
|
||||||
],
|
],
|
||||||
RuleEvents = [
|
RuleEvents = [
|
||||||
new RuleEventState {
|
new() {
|
||||||
Phase = ERuleEventPhase.StartOfSimulation,
|
Phase = ERuleEventPhase.StartOfSimulation,
|
||||||
Predicates = [new RulePredicate { Kind = ERulePredicateKind.TurnAtLeast, Turn = 0 }],
|
Predicates = [new() { Kind = ERulePredicateKind.TurnAtLeast, Turn = 0 }],
|
||||||
Effects = [
|
Effects = [
|
||||||
new RuleEffect { Kind = ERuleEffectKind.RemoveSurfaceHazard, Position = new(2, 2), Carrier = ECarrierType.Fuel, Amount = 2 },
|
new() { Kind = ERuleEffectKind.RemoveSurfaceHazard, Position = new(2, 2), Carrier = ECarrierType.Fuel, Amount = 2 },
|
||||||
new RuleEffect { Kind = ERuleEffectKind.RemoveHeat, Position = new(2, 2), Amount = 3 },
|
new() { Kind = ERuleEffectKind.RemoveHeat, Position = new(2, 2), Amount = 3 },
|
||||||
new RuleEffect { Kind = ERuleEffectKind.RemoveInventory, Remedy = ERemedyType.FuelNeutralizer, Amount = 1 }
|
new() { Kind = ERuleEffectKind.RemoveInventory, Remedy = ERemedyType.FuelNeutralizer, Amount = 1 }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -266,10 +266,10 @@ public sealed class SimulationEngineTests
|
|||||||
level = level.SetTerrain(new(2, 2), ECellTerrain.Wall);
|
level = level.SetTerrain(new(2, 2), ECellTerrain.Wall);
|
||||||
level = level.SetUnderground(new(2, 2), ECarrierType.Electricity, new() { State = EUndergroundState.Intact }) with {
|
level = level.SetUnderground(new(2, 2), ECarrierType.Electricity, new() { State = EUndergroundState.Intact }) with {
|
||||||
RuleEvents = [
|
RuleEvents = [
|
||||||
new RuleEventState {
|
new() {
|
||||||
Phase = ERuleEventPhase.StartOfSimulation,
|
Phase = ERuleEventPhase.StartOfSimulation,
|
||||||
Predicates = [new RulePredicate { Kind = ERulePredicateKind.TurnAtLeast, Turn = 0 }],
|
Predicates = [new() { Kind = ERulePredicateKind.TurnAtLeast, Turn = 0 }],
|
||||||
Effects = [new RuleEffect { Kind = ERuleEffectKind.StartLeak, Position = new(2, 2), AccessPosition = new(2, 3), Carrier = ECarrierType.Electricity }]
|
Effects = [new() { Kind = ERuleEffectKind.StartLeak, Position = new(2, 2), AccessPosition = new(2, 3), Carrier = ECarrierType.Electricity }]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@@ -287,11 +287,11 @@ public sealed class SimulationEngineTests
|
|||||||
var level = LevelState.Create("Invalid rules", 6, 6);
|
var level = LevelState.Create("Invalid rules", 6, 6);
|
||||||
level = level.SetTerrain(new(2, 2), ECellTerrain.Wall) with {
|
level = level.SetTerrain(new(2, 2), ECellTerrain.Wall) with {
|
||||||
RuleEvents = [
|
RuleEvents = [
|
||||||
new RuleEventState {
|
new() {
|
||||||
Predicates = [new RulePredicate { Kind = ERulePredicateKind.PropStateAt, Position = new(1, 1) }],
|
Predicates = [new() { Kind = ERulePredicateKind.PropStateAt, Position = new(1, 1) }],
|
||||||
Effects = [
|
Effects = [
|
||||||
new RuleEffect { Kind = ERuleEffectKind.AddSurfaceHazard, Position = new(2, 2), Carrier = ECarrierType.Fuel, Amount = 1 },
|
new() { Kind = ERuleEffectKind.AddSurfaceHazard, Position = new(2, 2), Carrier = ECarrierType.Fuel, Amount = 1 },
|
||||||
new RuleEffect { Kind = ERuleEffectKind.RepairNetworkCell, Position = new(3, 3), Carrier = ECarrierType.Coolant }
|
new() { Kind = ERuleEffectKind.RepairNetworkCell, Position = new(3, 3), Carrier = ECarrierType.Coolant }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -312,7 +312,7 @@ public sealed class SimulationEngineTests
|
|||||||
level = level.SetTerrain(new(2, 2), ECellTerrain.Wall);
|
level = level.SetTerrain(new(2, 2), ECellTerrain.Wall);
|
||||||
level = level with {
|
level = level with {
|
||||||
Surface = level.Surface.ToArray(),
|
Surface = level.Surface.ToArray(),
|
||||||
Reactors = [new ReactorBinding { ControlPosition = new(3, 3), FuelConsumerPosition = new(1, 1), CoolantConsumerPosition = new(1, 1), ElectricityConsumerPosition = new(1, 1) }]
|
Reactors = [new() { ControlPosition = new(3, 3), FuelConsumerPosition = new(1, 1), CoolantConsumerPosition = new(1, 1), ElectricityConsumerPosition = new(1, 1) }]
|
||||||
};
|
};
|
||||||
level.Surface[level.Index(new(2, 2))] = new() { Heat = 1 };
|
level.Surface[level.Index(new(2, 2))] = new() { Heat = 1 };
|
||||||
|
|
||||||
@@ -367,7 +367,7 @@ public sealed class SimulationEngineTests
|
|||||||
return level with {
|
return level with {
|
||||||
Robot = new() { Position = new(5, 3) },
|
Robot = new() { Position = new(5, 3) },
|
||||||
Reactors = [
|
Reactors = [
|
||||||
new ReactorBinding {
|
new() {
|
||||||
ReactorId = 1,
|
ReactorId = 1,
|
||||||
ControlPosition = new(5, 3),
|
ControlPosition = new(5, 3),
|
||||||
FuelConsumerPosition = new(3, 2),
|
FuelConsumerPosition = new(3, 2),
|
||||||
|
|||||||
Reference in New Issue
Block a user