summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordP <dp@dpointer.org>2020-05-15 23:18:03 +0300
committerCharles Pigott <charlespigott@googlemail.com>2020-05-18 09:05:39 +0100
commit93d1d8773fab6eda973b19631a0473b11bba35e3 (patch)
tree09c6001a1d42b7e45b4bed1f67034f8daeba922e
parentd11bae58a0e00b8362d087e8aa54a867c668a986 (diff)
downloadopenttd-93d1d8773fab6eda973b19631a0473b11bba35e3.tar.xz
Fix: Desync after house replacement
-rw-r--r--src/town_cmd.cpp29
1 files changed, 17 insertions, 12 deletions
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
index 507cccd56..1d550fb02 100644
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -454,13 +454,22 @@ uint32 GetWorldPopulation()
/**
* Remove stations from nearby station list if a town is no longer in the catchment area of each.
+ * To improve performance only checks stations that cover the provided house area (doesn't need to contain an actual house).
* @param t Town to work on
+ * @param tile Location of house area (north part)
+ * @param flags BuildingFlags containing the size of house area
*/
-static void RemoveNearbyStations(Town *t)
+static void RemoveNearbyStations(Town *t, TileIndex tile, BuildingFlags flags)
{
for (StationList::iterator it = t->stations_near.begin(); it != t->stations_near.end(); /* incremented inside loop */) {
const Station *st = *it;
- if (!st->CatchmentCoversTown(t->index)) {
+
+ bool covers_area = st->TileIsInCatchment(tile);
+ if (flags & BUILDING_2_TILES_Y) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(0, 1));
+ if (flags & BUILDING_2_TILES_X) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 0));
+ if (flags & BUILDING_HAS_4_TILES) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 1));
+
+ if (covers_area && !st->CatchmentCoversTown(t->index)) {
it = t->stations_near.erase(it);
} else {
++it;
@@ -621,11 +630,7 @@ static void TileLoop_Town(TileIndex tile)
ClearTownHouse(t, tile);
/* Rebuild with another house? */
- if (GB(r, 24, 8) < 12 || !BuildTownHouse(t, tile))
- {
- /* House wasn't replaced, so remove it */
- if (!_generating_world) RemoveNearbyStations(t);
- }
+ if (GB(r, 24, 8) >= 12) BuildTownHouse(t, tile);
}
cur_company.Restore();
@@ -654,7 +659,6 @@ static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlag flags)
ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM, flags);
if (flags & DC_EXEC) {
ClearTownHouse(t, tile);
- RemoveNearbyStations(t);
}
return cost;
@@ -2666,11 +2670,12 @@ void ClearTownHouse(Town *t, TileIndex tile)
}
/* Do the actual clearing of tiles */
- uint eflags = hs->building_flags;
DoClearTownHouseHelper(tile, t, house);
- if (eflags & BUILDING_2_TILES_Y) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
- if (eflags & BUILDING_2_TILES_X) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
- if (eflags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
+ if (hs->building_flags & BUILDING_2_TILES_Y) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
+ if (hs->building_flags & BUILDING_2_TILES_X) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
+ if (hs->building_flags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
+
+ RemoveNearbyStations(t, tile, hs->building_flags);
UpdateTownRadius(t);