summaryrefslogtreecommitdiff
path: root/src/saveload
diff options
context:
space:
mode:
Diffstat (limited to 'src/saveload')
-rw-r--r--src/saveload/CMakeLists.txt1
-rw-r--r--src/saveload/afterload.cpp48
-rw-r--r--src/saveload/saveload.cpp2
-rw-r--r--src/saveload/tunnel_sl.cpp48
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},
+};