summaryrefslogtreecommitdiff
path: root/src/town_cmd.cpp
diff options
context:
space:
mode:
authorsmatz <smatz@openttd.org>2008-11-18 22:43:59 +0000
committersmatz <smatz@openttd.org>2008-11-18 22:43:59 +0000
commit07e3c096b3b744ef1d094c9481faa31ec8d2034a (patch)
treefb5982346d711d936b8aa9f87eab53f416ab29d4 /src/town_cmd.cpp
parente1a36e90a44cf50ebcfa52ec8685e76230a22910 (diff)
downloadopenttd-07e3c096b3b744ef1d094c9481faa31ec8d2034a.tar.xz
(svn r14591) -Fix [FS#2388](r14528): cached nearest town could be invalid after importing older savegame and during town generation
-Codechange: rewrite parts of code responsible for caching index of nearest town
Diffstat (limited to 'src/town_cmd.cpp')
-rw-r--r--src/town_cmd.cpp59
1 files changed, 34 insertions, 25 deletions
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
index daa8a298b..58f9a5e32 100644
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -94,12 +94,12 @@ Town::~Town()
break;
case MP_ROAD:
- if (!IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN) && GetTownIndex(tile) == this->index) {
- /* Town-owned roads get cleared soon, anyway */
- SetTownIndex(tile, (TownID)INVALID_TOWN);
- break;
+ /* Cached nearest town is updated later (after this town has been deleted) */
+ if (HasTownOwnedRoad(tile) && GetTownIndex(tile) == this->index) {
+ DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
}
- /* Fall-through */
+ break;
+
case MP_TUNNELBRIDGE:
if (IsTileOwner(tile, OWNER_TOWN) &&
ClosestTownFromTile(tile, UINT_MAX) == this)
@@ -116,6 +116,8 @@ Town::~Town()
MarkWholeScreenDirty();
this->xy = 0;
+
+ UpdateNearestTownForRoadTiles(false);
}
/**
@@ -1564,8 +1566,9 @@ CommandCost CmdBuildTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (flags & DC_EXEC) {
Town *t = new Town(tile);
_generating_world = true;
+ UpdateNearestTownForRoadTiles(true);
DoCreateTown(t, tile, townnameparts, (TownSizeMode)p2, p1);
- InvalidateTownForRoadTile();
+ UpdateNearestTownForRoadTiles(false);
_generating_world = false;
}
return CommandCost();
@@ -2471,26 +2474,32 @@ Town *CalcClosestTownFromTile(TileIndex tile, uint threshold)
Town *ClosestTownFromTile(TileIndex tile, uint threshold)
{
- if (IsTileType(tile, MP_HOUSE) || (
- IsTileType(tile, MP_ROAD) && HasTileRoadType(tile, ROADTYPE_ROAD) &&
- IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN)
- )) {
- return GetTownByTile(tile);
- } else if (IsTileType(tile, MP_ROAD)) {
- TownID town_id = GetTownIndex(tile);
- Town *town;
-
- if (town_id == INVALID_TOWN) {
- town = CalcClosestTownFromTile(tile, UINT_MAX);
- if (town != NULL) SetTownIndex(tile, town->index);
- } else {
- town = GetTown(town_id);
- }
+ switch (GetTileType(tile)) {
+ case MP_ROAD:
+ if (!HasTownOwnedRoad(tile)) {
+ TownID tid = GetTownIndex(tile);
+ if (tid == (TownID)INVALID_TOWN) {
+ /* in the case we are generating "many random towns", this value may be INVALID_TOWN */
+ if (_generating_world) CalcClosestTownFromTile(tile, threshold);
+ assert(GetNumTowns() == 0);
+ return NULL;
+ }
- if (town != NULL && town->IsValid() && DistanceManhattan(tile, town->xy) < threshold) return town;
- return NULL;
- } else {
- return CalcClosestTownFromTile(tile, threshold);
+ Town *town = GetTown(tid);
+ assert(town->IsValid());
+ assert(town == CalcClosestTownFromTile(tile, UINT_MAX));
+
+ if (DistanceManhattan(tile, town->xy) >= threshold) town = NULL;
+
+ return town;
+ }
+ /* FALL THROUGH */
+
+ case MP_HOUSE:
+ return GetTownByTile(tile);
+
+ default:
+ return CalcClosestTownFromTile(tile, threshold);
}
}