diff --git a/docs/landscape.html b/docs/landscape.html index 07609d4a85..966c476bf8 100644 --- a/docs/landscape.html +++ b/docs/landscape.html @@ -1054,6 +1054,7 @@
  • m1 bits 6..5 : Water class (sea, canal or river)
  • m1 bits 4..0: owner (for sea, rivers, and coasts normally 11)
  • m2: Depot index (for depots only)
  • +
  • m3 bit 0: No flooding state, set if all neighbouring tiles are also water
  • m4: Random data for canal or river tiles
  • m5: tile type: diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html index 293b9780cc..02a4df7017 100644 --- a/docs/landscape_grid.html +++ b/docs/landscape_grid.html @@ -241,7 +241,7 @@ the array so you can quickly see what is used and what is not. - + diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 4d83529a3f..9ad1fce10b 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -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 }; diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index 2a0eb7221d..2b7e84be11 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -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 diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 5ec1f1db0c..3770048ae2 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -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; diff --git a/src/water_map.h b/src/water_map.h index 1ca39f3191..7a324e5a81 100644 --- a/src/water_map.h +++ b/src/water_map.h @@ -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 */
    sea, shore X XX XXXXX OOOO OOOO OOOO OOOOOOOO OOOOOOOO OOOP OOOO OOOO OOOO OOOX OOOO OOOO