diff options
author | smatz <smatz@openttd.org> | 2011-01-14 16:20:25 +0000 |
---|---|---|
committer | smatz <smatz@openttd.org> | 2011-01-14 16:20:25 +0000 |
commit | c53c869556a13f2cb777a287a8074ce4060695e5 (patch) | |
tree | 3a917252b7e05bb2c6b91d3106960e4cd0c7807c | |
parent | d811238dd0050fc9cc443eae7d0a60742fa02fa2 (diff) | |
download | openttd-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.cpp | 31 |
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); } } |