diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj
index 2a68c0974b..57aecf0c30 100644
--- a/projects/openttd_vs80.vcproj
+++ b/projects/openttd_vs80.vcproj
@@ -2079,6 +2079,10 @@
RelativePath=".\..\src\saveload\industry_sl.cpp"
>
+
+
diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj
index 1724d95a50..c724e0e54c 100644
--- a/projects/openttd_vs90.vcproj
+++ b/projects/openttd_vs90.vcproj
@@ -2076,6 +2076,10 @@
RelativePath=".\..\src\saveload\industry_sl.cpp"
>
+
+
diff --git a/source.list b/source.list
index acfee02e17..8dde15af01 100644
--- a/source.list
+++ b/source.list
@@ -469,6 +469,7 @@ saveload/engine_sl.cpp
saveload/gamelog_sl.cpp
saveload/group_sl.cpp
saveload/industry_sl.cpp
+saveload/labelmaps_sl.cpp
saveload/map_sl.cpp
saveload/misc_sl.cpp
saveload/newgrf_sl.cpp
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
index 44fd9f01cd..5f7cc18484 100644
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -1797,6 +1797,8 @@ bool AfterLoadGame()
}
}
+ AfterLoadLabelMaps();
+
GamelogPrintDebug(1);
bool ret = InitializeWindowsAndCaches();
diff --git a/src/saveload/labelmaps_sl.cpp b/src/saveload/labelmaps_sl.cpp
new file mode 100644
index 0000000000..e39e4d9b6c
--- /dev/null
+++ b/src/saveload/labelmaps_sl.cpp
@@ -0,0 +1,125 @@
+/* $Id$ */
+
+/** @file labelmaps_sl.cpp Code handling saving and loading of rail type label mappings */
+
+#include "../stdafx.h"
+#include "../strings_type.h"
+#include "../rail.h"
+#include "../map_func.h"
+#include "../tile_map.h"
+#include "../rail_map.h"
+#include "../road_map.h"
+#include "../station_map.h"
+#include "../tunnelbridge_map.h"
+#include "../core/alloc_func.hpp"
+#include "../core/smallvec_type.hpp"
+#include "../settings_type.h"
+
+#include "saveload.h"
+
+static SmallVector _railtype_list;
+
+/**
+ * Test if any saved rail type labels are different to the currently loaded
+ * rail types, which therefore requires conversion.
+ * @return true if (and only if) conversion due to rail type changes is needed.
+ */
+static bool NeedRailTypeConversion()
+{
+ for (uint i = 0; i < _railtype_list.Length(); i++) {
+ if ((RailType)i < RAILTYPE_END) {
+ const RailtypeInfo *rti = GetRailTypeInfo((RailType)i);
+ if (rti->label != _railtype_list[i]) return true;
+ } else {
+ if (_railtype_list[i] != 0) return true;
+ }
+ }
+
+ /* No rail type conversion is necessary */
+ return false;
+}
+
+void AfterLoadLabelMaps()
+{
+ if (NeedRailTypeConversion()) {
+ SmallVector railtype_conversion_map;
+
+ for (uint i = 0; i < _railtype_list.Length(); i++) {
+ RailType r = GetRailTypeByLabel(_railtype_list[i]);
+ if (r == INVALID_RAILTYPE) r = RAILTYPE_BEGIN;
+
+ *railtype_conversion_map.Append() = r;
+ }
+
+ for (TileIndex t = 0; t < MapSize(); t++) {
+ switch (GetTileType(t)) {
+ case MP_RAILWAY:
+ SetRailType(t, railtype_conversion_map[GetRailType(t)]);
+ break;
+
+ case MP_ROAD:
+ if (IsLevelCrossing(t)) {
+ SetRailType(t, railtype_conversion_map[GetRailType(t)]);
+ }
+ break;
+
+ case MP_STATION:
+ if (IsRailwayStation(t)) {
+ SetRailType(t, railtype_conversion_map[GetRailType(t)]);
+ }
+ break;
+
+ case MP_TUNNELBRIDGE:
+ if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) {
+ SetRailType(t, railtype_conversion_map[GetRailType(t)]);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ _railtype_list.Clear();
+}
+
+/** Container for a label for SaveLoad system */
+struct LabelObject {
+ uint32 label;
+};
+
+static const SaveLoad _label_object_desc[] = {
+ SLE_VAR(LabelObject, label, SLE_UINT32),
+ SLE_END(),
+};
+
+static void Save_RAIL()
+{
+ LabelObject lo;
+
+ for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) {
+ lo.label = GetRailTypeInfo(r)->label;
+
+ SlSetArrayIndex(r);
+ SlObject(&lo, _label_object_desc);
+ }
+}
+
+static void Load_RAIL()
+{
+ _railtype_list.Clear();
+
+ LabelObject lo;
+ int index;
+
+ while ((index = SlIterateArray()) != -1) {
+ SlObject(&lo, _label_object_desc);
+ *_railtype_list.Append() = (RailTypeLabel)lo.label;
+ }
+}
+
+extern const ChunkHandler _labelmaps_chunk_handlers[] = {
+ { 'RAIL', Save_RAIL, Load_RAIL, CH_ARRAY | CH_LAST},
+};
+
diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp
index 04b6499e70..c9480f884c 100644
--- a/src/saveload/saveload.cpp
+++ b/src/saveload/saveload.cpp
@@ -1332,6 +1332,7 @@ extern const ChunkHandler _newgrf_chunk_handlers[];
extern const ChunkHandler _group_chunk_handlers[];
extern const ChunkHandler _cargopacket_chunk_handlers[];
extern const ChunkHandler _autoreplace_chunk_handlers[];
+extern const ChunkHandler _labelmaps_chunk_handlers[];
static const ChunkHandler * const _chunk_handlers[] = {
_gamelog_chunk_handlers,
@@ -1358,6 +1359,7 @@ static const ChunkHandler * const _chunk_handlers[] = {
_group_chunk_handlers,
_cargopacket_chunk_handlers,
_autoreplace_chunk_handlers,
+ _labelmaps_chunk_handlers,
NULL,
};
diff --git a/src/saveload/saveload_internal.h b/src/saveload/saveload_internal.h
index 19a5b5cbff..0486a796f7 100644
--- a/src/saveload/saveload_internal.h
+++ b/src/saveload/saveload_internal.h
@@ -21,6 +21,7 @@ void FixOldWaypoints();
void AfterLoadWaypoints();
void AfterLoadVehicles(bool part_of_load);
void AfterLoadStations();
+void AfterLoadLabelMaps();
void UpdateHousesAndTowns();
void UpdateOldAircraft();