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:
@@ -146,6 +146,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||
{ XSLFI_INDUSTRY_CARGO_ADJ, XSCF_IGNORABLE_UNKNOWN, 1, 1, "industry_cargo_adj", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_REALISTIC_TRAIN_BRAKING,XSCF_NULL, 1, 1, "realistic_train_braking", nullptr, nullptr, "VLKA" },
|
||||
{ XSLFI_INFLATION_FIXED_DATES, XSCF_IGNORABLE_ALL, 1, 1, "inflation_fixed_dates", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_WATER_FLOODING, XSCF_NULL, 1, 1, "water_flooding", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
|
||||
};
|
||||
|
||||
|
@@ -100,6 +100,7 @@ enum SlXvFeatureIndex {
|
||||
XSLFI_INDUSTRY_CARGO_ADJ, ///< Industry cargo adjustment patch
|
||||
XSLFI_REALISTIC_TRAIN_BRAKING, ///< Realistic train braking
|
||||
XSLFI_INFLATION_FIXED_DATES, ///< Inflation is applied between fixed dates
|
||||
XSLFI_WATER_FLOODING, ///< Water flooding map bit
|
||||
|
||||
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
|
||||
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk
|
||||
|
@@ -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;
|
||||
|
@@ -504,4 +504,24 @@ static inline void MakeLock(TileIndex t, Owner o, DiagDirection d, WaterClass wc
|
||||
MakeLockTile(t + delta, IsWaterTile(t + delta) ? GetTileOwner(t + delta) : o, LOCK_PART_UPPER, d, wc_upper);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the non-flooding water tile state of a tile.
|
||||
* @param t the tile
|
||||
* @param b the non-flooding water tile state
|
||||
*/
|
||||
static inline void SetNonFloodingWaterTile(TileIndex t, bool b)
|
||||
{
|
||||
assert(IsTileType(t, MP_WATER));
|
||||
SB(_m[t].m3, 0, 1, b ? 1 : 0);
|
||||
}
|
||||
/**
|
||||
* Checks whether the tile is marked as a non-flooding water tile.
|
||||
* @return true iff the tile is marked as a non-flooding water tile.
|
||||
*/
|
||||
static inline bool IsNonFloodingWaterTile(TileIndex t)
|
||||
{
|
||||
return IsTileType(t, MP_WATER) && HasBit(_m[t].m3, 0);
|
||||
}
|
||||
|
||||
#endif /* WATER_MAP_H */
|
||||
|
Reference in New Issue
Block a user