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:
@@ -1054,6 +1054,7 @@
|
||||
<li>m1 bits 6..5 : Water class (sea, canal or river)
|
||||
<li>m1 bits 4..0: <a href="#OwnershipInfo">owner</a> (for sea, rivers, and coasts normally <tt>11</tt>)</li>
|
||||
<li>m2: Depot index (for depots only)</li>
|
||||
<li style="color: blue">m3 bit 0: No flooding state, set if all neighbouring tiles are also water</li>
|
||||
<li>m4: Random data for canal or river tiles</li>
|
||||
<li>m5: tile type:
|
||||
<table>
|
||||
|
@@ -241,7 +241,7 @@ the array so you can quickly see what is used and what is not.
|
||||
<td class="caption">sea, shore</td>
|
||||
<td class="bits" rowspan=4><span class="used" title="Ship docking tile status">X</span> <span class="used" title="Water class">XX</span> <span class="used" title="Owner">XXXXX</span></td>
|
||||
<td class="bits" rowspan=3><span class="free">OOOO OOOO OOOO OOOO</span></td>
|
||||
<td class="bits" rowspan=4><span class="free">OOOO OOOO</span></td>
|
||||
<td class="bits" rowspan=4><span class="free">OOOO OOO</span><span class="patch" title="No flooding state">P</span></td>
|
||||
<td class="bits"><span class="free">OOOO OOOO</span></td>
|
||||
<td class="bits"><span class="used" title="Water tile type: coast, clear, lock, depot">O<span class="usable">OO</span>O</span> <span class="free">OOO</span><span class="used" title="Sea shore flag">X</span></td>
|
||||
<td class="bits" rowspan=4><span class="free">OOOO OOOO</span></td>
|
||||
|
@@ -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