summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsmatz <smatz@openttd.org>2011-01-14 16:20:25 +0000
committersmatz <smatz@openttd.org>2011-01-14 16:20:25 +0000
commitc53c869556a13f2cb777a287a8074ce4060695e5 (patch)
tree3a917252b7e05bb2c6b91d3106960e4cd0c7807c
parentd811238dd0050fc9cc443eae7d0a60742fa02fa2 (diff)
downloadopenttd-c53c869556a13f2cb777a287a8074ce4060695e5.tar.xz
(svn r21786) -Fix [FS#4398]: don't trust rail station width and height data stored by TTDPatch, it is invalid for stations wider or higher than 7
-rw-r--r--src/saveload/afterload.cpp31
1 files changed, 18 insertions, 13 deletions
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
index 82e360b9c..ef2143fa1 100644
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -469,22 +469,27 @@ bool AfterLoadGame()
_pause_mode &= ~PMB_PAUSED_NETWORK;
}
- /* in very old versions, size of train stations was stored differently */
+ /* In very old versions, size of train stations was stored differently.
+ * They had swapped width and height if station was built along the Y axis.
+ * TTO and TTD used 3 bits for width/height, while OpenTTD used 4.
+ * Because the data stored by TTDPatch are unusable for rail stations > 7x7,
+ * recompute the width and height. Doing this unconditionally for all old
+ * savegames simplifies the code. */
if (IsSavegameVersionBefore(2)) {
Station *st;
FOR_ALL_STATIONS(st) {
- if (st->train_station.tile != 0 && st->train_station.h == 0) {
- uint n = _savegame_type == SGT_OTTD ? 4 : 3; // OTTD uses 4 bits per dimensions, TTD 3 bits
- uint w = GB(st->train_station.w, n, n);
- uint h = GB(st->train_station.w, 0, n);
-
- if (GetRailStationAxis(st->train_station.tile) != AXIS_X) Swap(w, h);
-
- st->train_station.w = w;
- st->train_station.h = h;
-
- assert(GetStationIndex(st->train_station.tile + TileDiffXY(w - 1, h - 1)) == st->index);
- }
+ st->train_station.w = st->train_station.h = 0;
+ }
+ for (TileIndex t = 0; t < map_size; t++) {
+ if (!IsTileType(t, MP_STATION)) continue;
+ if (_m[t].m5 > 7) continue; // is it a rail station tile?
+ st = Station::Get(_m[t].m2);
+ assert(st->train_station.tile != 0);
+ int dx = TileX(t) - TileX(st->train_station.tile);
+ int dy = TileY(t) - TileY(st->train_station.tile);
+ assert(dx >= 0 && dy >= 0);
+ st->train_station.w = max<uint>(st->train_station.w, dx + 1);
+ st->train_station.h = max<uint>(st->train_station.h, dy + 1);
}
}