diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 333aeaffa9..9921589829 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -243,6 +243,8 @@ namespace OpenRA public CellRegion AllCells { get; private set; } public List AllEdgeCells { get; private set; } + public event Action CellProjectionChanged; + // Internal data readonly ModData modData; CellLayer cachedTerrainIndexes; @@ -336,11 +338,12 @@ namespace OpenRA Height = new CellLayer(Grid.Type, size); Ramp = new CellLayer(Grid.Type, size); Tiles.Clear(terrainInfo.DefaultTerrainTile); + if (Grid.MaximumTerrainHeight > 0) { - Height.CellEntryChanged += UpdateProjection; - Tiles.CellEntryChanged += UpdateProjection; Tiles.CellEntryChanged += UpdateRamp; + Tiles.CellEntryChanged += UpdateProjection; + Height.CellEntryChanged += UpdateProjection; } PostInit(); @@ -530,6 +533,7 @@ namespace OpenRA var inverse = inverseCellProjection[uv]; inverse.Clear(); inverse.Add(uv); + CellProjectionChanged?.Invoke(cell); return; } @@ -567,6 +571,8 @@ namespace OpenRA projectedHeight[temp] = height; } } + + CellProjectionChanged?.Invoke(cell); } byte ProjectedCellHeightInner(PPos puv) diff --git a/OpenRA.Mods.Common/Pathfinder/HierarchicalPathFinder.cs b/OpenRA.Mods.Common/Pathfinder/HierarchicalPathFinder.cs index 7ba38b5692..885faed296 100644 --- a/OpenRA.Mods.Common/Pathfinder/HierarchicalPathFinder.cs +++ b/OpenRA.Mods.Common/Pathfinder/HierarchicalPathFinder.cs @@ -281,6 +281,10 @@ namespace OpenRA.Mods.Common.Pathfinder // When we build the cost table, it depends on the movement costs of the cells at that time. // When this changes, we must update the cost table. locomotor.CellCostChanged += RequireCostRefreshInCell; + + // If the map projection changes, the result of Map.Contains(CPos) may change. + // We need to rebuild grids to account for this possibility. + this.world.Map.CellProjectionChanged += RequireProjectionRefreshInCell; } public ( @@ -619,6 +623,14 @@ namespace OpenRA.Mods.Common.Pathfinder } } + /// + /// When map projection changes for a cell, marks the grid it belongs to as out of date. + /// + void RequireProjectionRefreshInCell(CPos cell) + { + dirtyGridIndexes.Add(GridIndex(cell)); + } + /// /// defines immovability based on the mobile trait. The blocking rules /// in allow units to