diff options
Diffstat (limited to 'src/saveload')
-rw-r--r-- | src/saveload/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/saveload/afterload.cpp | 48 | ||||
-rw-r--r-- | src/saveload/saveload.cpp | 2 | ||||
-rw-r--r-- | src/saveload/tunnel_sl.cpp | 48 |
4 files changed, 98 insertions, 1 deletions
diff --git a/src/saveload/CMakeLists.txt b/src/saveload/CMakeLists.txt index 32bcc57ac..f1fce31c2 100644 --- a/src/saveload/CMakeLists.txt +++ b/src/saveload/CMakeLists.txt @@ -41,6 +41,7 @@ add_files( story_sl.cpp subsidy_sl.cpp town_sl.cpp + tunnel_sl.cpp vehicle_sl.cpp waypoint_sl.cpp ) diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index df1b4e44f..9696e390d 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -11,6 +11,7 @@ #include "../void_map.h" #include "../signs_base.h" #include "../depot_base.h" +#include "../tunnel_base.h" #include "../fios.h" #include "../gamelog_internal.h" #include "../network/network.h" @@ -537,6 +538,25 @@ static inline bool MayHaveBridgeAbove(TileIndex t) IsTileType(t, MP_WATER) || IsTileType(t, MP_TUNNELBRIDGE) || IsTileType(t, MP_OBJECT); } +TileIndex GetOtherTunnelBridgeEndOld(TileIndex tile) +{ + DiagDirection dir = GetTunnelBridgeDirection(tile); + TileIndexDiff delta = TileOffsByDiagDir(dir); + int z = GetTileZ(tile); + + dir = ReverseDiagDir(dir); + do { + tile += delta; + } while ( + !IsTunnelTile(tile) || + GetTunnelBridgeDirection(tile) != dir || + GetTileZ(tile) != z + ); + + return tile; +} + + /** * Perform a (large) amount of savegame conversion *magic* in order to * load older savegames and to fill the caches for various purposes. @@ -1942,6 +1962,32 @@ bool AfterLoadGame() } } + /* Tunnel pool has to be initiated before reservations. */ + if (IsSavegameVersionBefore(SLV_196)) { + for (TileIndex t = 0; t < map_size; t++) { + if (IsTunnelTile(t)) { + DiagDirection dir = GetTunnelBridgeDirection(t); + if (dir == DIAGDIR_SE || dir == DIAGDIR_SW) { + TileIndex start_tile = t; + TileIndex end_tile = GetOtherTunnelBridgeEndOld(start_tile); + + if (!Tunnel::CanAllocateItem()) { + SetSaveLoadError(STR_ERROR_TUNNEL_TOO_MANY); + /* Restore the signals */ + ResetSignalHandlers(); + return false; + } + + const Tunnel *t = new Tunnel(start_tile, end_tile, false); + + _m[start_tile].m2 = t->index; + _m[end_tile].m2 = t->index; + } + } + } + } + + /* Move the signal variant back up one bit for PBS. We don't convert the old PBS * format here, as an old layout wouldn't work properly anyway. To be safe, we * clear any possible PBS reservations as well. */ @@ -2545,7 +2591,7 @@ bool AfterLoadGame() } else if (dir == ReverseDiagDir(vdir)) { // Leaving tunnel hidden = frame < TILE_SIZE - _tunnel_visibility_frame[dir]; /* v->tile changes at the moment when the vehicle leaves the tunnel. */ - v->tile = hidden ? GetOtherTunnelBridgeEnd(vtile) : vtile; + v->tile = hidden ? GetOtherTunnelBridgeEndOld(vtile) : vtile; } else { /* We could get here in two cases: * - for road vehicles, it is reversing at the end of the tunnel diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index c8a1a0d29..6ce5493b7 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -252,6 +252,7 @@ static const std::vector<ChunkHandlerRef> &ChunkHandlers() extern const ChunkHandlerTable _airport_chunk_handlers; extern const ChunkHandlerTable _object_chunk_handlers; extern const ChunkHandlerTable _persistent_storage_chunk_handlers; + extern const ChunkHandlerTable _tunnel_chunk_handlers[]; /** List of all chunks in a savegame. */ static const ChunkHandlerTable _chunk_handler_tables[] = { @@ -288,6 +289,7 @@ static const std::vector<ChunkHandlerRef> &ChunkHandlers() _airport_chunk_handlers, _object_chunk_handlers, _persistent_storage_chunk_handlers, + _tunnel_chunk_handlers, }; static std::vector<ChunkHandlerRef> _chunk_handlers; diff --git a/src/saveload/tunnel_sl.cpp b/src/saveload/tunnel_sl.cpp new file mode 100644 index 000000000..7ad37b12b --- /dev/null +++ b/src/saveload/tunnel_sl.cpp @@ -0,0 +1,48 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>. + */ + +/** @file tunnel_sl.cpp Code handling saving and loading of tunnels */ + +#include "../stdafx.h" +#include "../tunnel_base.h" + +#include "saveload.h" + +#include "../safeguards.h" + + +static const SaveLoad _tunnel_desc[] = { + SLE_CONDVAR(Tunnel, tile_n, SLE_UINT32, SLV_196, SL_MAX_VERSION), + SLE_CONDVAR(Tunnel, tile_s, SLE_UINT32, SLV_196, SL_MAX_VERSION), + SLE_CONDVAR(Tunnel, is_chunnel, SLE_BOOL, SLV_196, SL_MAX_VERSION), + SLE_END() +}; + +static void Save_TUNN() +{ + for(Tunnel *tunnel : Tunnel::Iterate()) { + SlSetArrayIndex(tunnel->index); + SlObject(tunnel, _tunnel_desc); + } +} + +static void Load_TUNN() +{ + int index; + + while ((index = SlIterateArray()) != -1) { + Tunnel *tunnel = new (index) Tunnel(); + SlObject(tunnel, _tunnel_desc); + } +} + + +extern const ChunkHandler _tunnel_chunk_handlers[] = { + { 'TUNN', Save_TUNN, Load_TUNN, nullptr, nullptr, CH_ARRAY | CH_LAST}, +}; |