Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<Version>0.7.0</Version>
<Version>0.7.1</Version>
<Authors>Anton Makarevich</Authors>
<Company>Anton Makarevich</Company>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
Expand Down
11 changes: 7 additions & 4 deletions src/MakaMek.MapEditor/ViewModels/EditMapViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -422,14 +422,15 @@ private void LoadTools()
}

private static bool IsGroundTerrain(MakaMekTerrains id) =>
id is MakaMekTerrains.LightWoods
or MakaMekTerrains.HeavyWoods or MakaMekTerrains.Rough
or MakaMekTerrains.Pavement or MakaMekTerrains.Rubble;
id is MakaMekTerrains.Clear
or MakaMekTerrains.LightWoods or MakaMekTerrains.HeavyWoods
or MakaMekTerrains.Rough or MakaMekTerrains.Pavement
or MakaMekTerrains.Rubble;

/// <summary>
/// Applies a terrain to a hex with correct layering:
/// - Ground terrains (Clear/Woods/Rough/Pavement/Rubble) are mutually exclusive with each other
/// - Water coexists with ground and road layers; adding Water over Road converts Road to Bridge
/// - Water replaces any ground terrain and coexists with road layers; adding Water over Road converts Road to Bridge
/// - Road/Bridge sits on top and coexists with ground + water layers
/// </summary>
private static Hex ApplyTerrainToHex(Hex hex, Terrain terrain)
Expand Down Expand Up @@ -457,6 +458,8 @@ private static Hex ApplyTerrainToHex(Hex hex, Terrain terrain)
if (newId == MakaMekTerrains.Water)
{
hex.RemoveTerrain(MakaMekTerrains.Water);
foreach (var t in hex.GetTerrains().Where(t => IsGroundTerrain(t.Id)).ToList())
hex.RemoveTerrain(t.Id);
if (hex.HasTerrain(MakaMekTerrains.Road))
{
hex.RemoveTerrain(MakaMekTerrains.Road);
Expand Down
101 changes: 101 additions & 0 deletions tests/MakaMek.MapEditor.Test/ViewModels/EditMapViewModelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1715,6 +1715,107 @@ public void HandleHexSelection_TerrainMode_WaterOnBridge_ShouldPreserveBridge()
result.HasTerrain(MakaMekTerrains.Bridge).ShouldBeTrue();
}

[Fact]
public void HandleHexSelection_TerrainMode_WaterOnClear_ShouldRemoveClear()
{
var hex = new Hex(new HexCoordinates(0, 0));
hex.AddTerrain(new ClearTerrain());
_sut.SelectedTerrain = new WaterTerrain(-1);

var result = _sut.HandleHexSelection(hex);

result.ShouldNotBeNull();
result.HasTerrain(MakaMekTerrains.Water).ShouldBeTrue();
result.HasTerrain(MakaMekTerrains.Clear).ShouldBeFalse();
}

[Fact]
public void HandleHexSelection_TerrainMode_WaterOnLightWoods_ShouldRemoveLightWoods()
{
var hex = new Hex(new HexCoordinates(0, 0));
hex.AddTerrain(new LightWoodsTerrain());
_sut.SelectedTerrain = new WaterTerrain(-1);

var result = _sut.HandleHexSelection(hex);

result.ShouldNotBeNull();
result.HasTerrain(MakaMekTerrains.Water).ShouldBeTrue();
result.HasTerrain(MakaMekTerrains.LightWoods).ShouldBeFalse();
}

[Fact]
public void HandleHexSelection_TerrainMode_WaterOnHeavyWoods_ShouldRemoveHeavyWoods()
{
var hex = new Hex(new HexCoordinates(0, 0));
hex.AddTerrain(new HeavyWoodsTerrain());
_sut.SelectedTerrain = new WaterTerrain(-1);

var result = _sut.HandleHexSelection(hex);

result.ShouldNotBeNull();
result.HasTerrain(MakaMekTerrains.Water).ShouldBeTrue();
result.HasTerrain(MakaMekTerrains.HeavyWoods).ShouldBeFalse();
}

[Fact]
public void HandleHexSelection_TerrainMode_WaterOnRough_ShouldRemoveRough()
{
var hex = new Hex(new HexCoordinates(0, 0));
hex.AddTerrain(new RoughTerrain());
_sut.SelectedTerrain = new WaterTerrain(-1);

var result = _sut.HandleHexSelection(hex);

result.ShouldNotBeNull();
result.HasTerrain(MakaMekTerrains.Water).ShouldBeTrue();
result.HasTerrain(MakaMekTerrains.Rough).ShouldBeFalse();
}

[Fact]
public void HandleHexSelection_TerrainMode_WaterOnGroundWithRoad_ShouldRemoveGroundAndConvertRoadToBridge()
{
var hex = new Hex(new HexCoordinates(0, 0));
hex.AddTerrain(new LightWoodsTerrain());
hex.AddTerrain(new RoadTerrain());
_sut.SelectedTerrain = new WaterTerrain(-1);

var result = _sut.HandleHexSelection(hex);

result.ShouldNotBeNull();
result.HasTerrain(MakaMekTerrains.Water).ShouldBeTrue();
result.HasTerrain(MakaMekTerrains.LightWoods).ShouldBeFalse();
result.HasTerrain(MakaMekTerrains.Bridge).ShouldBeTrue();
result.HasTerrain(MakaMekTerrains.Road).ShouldBeFalse();
}

[Fact]
public void HandleHexSelection_TerrainMode_LightWoodsOnClear_ShouldRemoveClear()
{
var hex = new Hex(new HexCoordinates(0, 0));
hex.AddTerrain(new ClearTerrain());
_sut.SelectedTerrain = new LightWoodsTerrain();

var result = _sut.HandleHexSelection(hex);

result.ShouldNotBeNull();
result.HasTerrain(MakaMekTerrains.LightWoods).ShouldBeTrue();
result.HasTerrain(MakaMekTerrains.Clear).ShouldBeFalse();
}

[Fact]
public void HandleHexSelection_TerrainMode_RoughOnClear_ShouldRemoveClear()
{
var hex = new Hex(new HexCoordinates(0, 0));
hex.AddTerrain(new ClearTerrain());
_sut.SelectedTerrain = new RoughTerrain();

var result = _sut.HandleHexSelection(hex);

result.ShouldNotBeNull();
result.HasTerrain(MakaMekTerrains.Rough).ShouldBeTrue();
result.HasTerrain(MakaMekTerrains.Clear).ShouldBeFalse();
}

// --- Bridge Command Tests ---
[Fact]
public async Task RaiseBridgeLevelCommand_ConvertsRoadToBridge()
Expand Down
Loading