Add map bit to suppress water flooding checks

Set if all neighbour tiles are also water
This reduces the overhead of flood checks on large maps
This commit is contained in:
Jonathan G Rennison
2021-02-21 21:11:35 +00:00
parent 0df3e785cb
commit f595696e97
6 changed files with 42 additions and 2 deletions

View File

@@ -88,6 +88,13 @@ static void MarkCanalsAndRiversAroundDirty(TileIndex tile)
}
}
static void ClearNeighbourNonFloodingStates(TileIndex tile)
{
for (Direction dir = DIR_BEGIN; dir < DIR_END; dir++) {
TileIndex dest = tile + TileOffsByDir(dir);
if (IsValidTile(dest) && IsTileType(dest, MP_WATER)) SetNonFloodingWaterTile(dest, false);
}
}
/**
* Build a ship depot.
@@ -400,6 +407,7 @@ static CommandCost RemoveLock(TileIndex tile, DoCommandFlag flags)
MakeRiver(tile, Random());
} else {
DoClearSquare(tile);
ClearNeighbourNonFloodingStates(tile);
}
MakeWaterKeepingClass(tile + delta, GetTileOwner(tile + delta));
MakeWaterKeepingClass(tile - delta, GetTileOwner(tile - delta));
@@ -570,6 +578,7 @@ static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags)
DoClearSquare(tile);
MarkCanalsAndRiversAroundDirty(tile);
if (remove) RemoveDockingTile(tile);
ClearNeighbourNonFloodingStates(tile);
}
return CommandCost(EXPENSES_CONSTRUCTION, base_cost);
@@ -593,6 +602,7 @@ static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags)
DoClearSquare(tile);
MarkCanalsAndRiversAroundDirty(tile);
if (remove) RemoveDockingTile(tile);
ClearNeighbourNonFloodingStates(tile);
}
return ret;
}
@@ -1248,14 +1258,19 @@ void TileLoop_Water(TileIndex tile)
{
if (IsTileType(tile, MP_WATER)) AmbientSoundEffect(tile);
if (IsNonFloodingWaterTile(tile)) return;
switch (GetFloodingBehaviour(tile)) {
case FLOOD_ACTIVE:
case FLOOD_ACTIVE: {
int non_water_neighbours = 0;
for (Direction dir = DIR_BEGIN; dir < DIR_END; dir++) {
TileIndex dest = tile + TileOffsByDir(dir);
if (!IsValidTile(dest)) continue;
/* do not try to flood water tiles - increases performance a lot */
if (IsTileType(dest, MP_WATER)) continue;
non_water_neighbours++;
/* TREE_GROUND_SHORE is the sign of a previous flood. */
if (IsTileType(dest, MP_TREES) && GetTreeGround(dest) == TREE_GROUND_SHORE) continue;
@@ -1267,7 +1282,9 @@ void TileLoop_Water(TileIndex tile)
DoFloodTile(dest);
}
if (non_water_neighbours == 0 && IsTileType(tile, MP_WATER)) SetNonFloodingWaterTile(tile, true);
break;
}
case FLOOD_DRYUP: {
Slope slope_here = GetFoundationSlope(tile) & ~SLOPE_HALFTILE_MASK & ~SLOPE_STEEP;