OpenTTD Source 20241224-master-gf74b0cf984
labelmaps_sl.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
6 */
7
10#include "../stdafx.h"
11
12#include "saveload.h"
14
15#include "saveload_internal.h"
16#include "../rail.h"
17#include "../road.h"
18#include "../station_map.h"
19#include "../tunnelbridge_map.h"
20
21#include "../safeguards.h"
22
24template <typename T>
26 T label = {};
27 uint8_t subtype = 0;
28};
29
30static std::vector<LabelObject<RailTypeLabel>> _railtype_list;
31static std::vector<LabelObject<RoadTypeLabel>> _roadtype_list;
32
37static void ConvertRailTypes()
38{
39 std::vector<RailType> railtype_conversion_map;
40 bool needs_conversion = false;
41
42 for (auto it = std::begin(_railtype_list); it != std::end(_railtype_list); ++it) {
43 RailType rt = GetRailTypeByLabel(it->label);
44 if (rt == INVALID_RAILTYPE) {
45 rt = RAILTYPE_RAIL;
46 }
47
48 railtype_conversion_map.push_back(rt);
49
50 /* Conversion is needed if the rail type is in a different position than the list. */
51 if (it->label != 0 && rt != std::distance(std::begin(_railtype_list), it)) needs_conversion = true;
52 }
53 if (!needs_conversion) return;
54
55 for (const auto t : Map::Iterate()) {
56 switch (GetTileType(t)) {
57 case MP_RAILWAY:
58 SetRailType(t, railtype_conversion_map[GetRailType(t)]);
59 break;
60
61 case MP_ROAD:
62 if (IsLevelCrossing(t)) {
63 SetRailType(t, railtype_conversion_map[GetRailType(t)]);
64 }
65 break;
66
67 case MP_STATION:
68 if (HasStationRail(t)) {
69 SetRailType(t, railtype_conversion_map[GetRailType(t)]);
70 }
71 break;
72
73 case MP_TUNNELBRIDGE:
75 SetRailType(t, railtype_conversion_map[GetRailType(t)]);
76 }
77 break;
78
79 default:
80 break;
81 }
82 }
83}
84
89static void ConvertRoadTypes()
90{
91 std::vector<RoadType> roadtype_conversion_map;
92 bool needs_conversion = false;
93 for (auto it = std::begin(_roadtype_list); it != std::end(_roadtype_list); ++it) {
94 RoadType rt = GetRoadTypeByLabel(it->label);
95 if (rt == INVALID_ROADTYPE || GetRoadTramType(rt) != it->subtype) {
96 rt = it->subtype ? ROADTYPE_TRAM : ROADTYPE_ROAD;
97 }
98
99 roadtype_conversion_map.push_back(rt);
100
101 /* Conversion is needed if the road type is in a different position than the list. */
102 if (it->label != 0 && rt != std::distance(std::begin(_roadtype_list), it)) needs_conversion = true;
103 }
104 if (!needs_conversion) return;
105
106 for (TileIndex t : Map::Iterate()) {
107 switch (GetTileType(t)) {
108 case MP_ROAD:
109 if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetRoadTypeRoad(t, roadtype_conversion_map[rt]);
110 if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetRoadTypeTram(t, roadtype_conversion_map[rt]);
111 break;
112
113 case MP_STATION:
114 if (IsStationRoadStop(t) || IsRoadWaypoint(t)) {
115 if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetRoadTypeRoad(t, roadtype_conversion_map[rt]);
116 if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetRoadTypeTram(t, roadtype_conversion_map[rt]);
117 }
118 break;
119
120 case MP_TUNNELBRIDGE:
122 if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetRoadTypeRoad(t, roadtype_conversion_map[rt]);
123 if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetRoadTypeTram(t, roadtype_conversion_map[rt]);
124 }
125 break;
126
127 default:
128 break;
129 }
130 }
131}
132
135{
136 _railtype_list.clear();
137 for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
138 _railtype_list.push_back({GetRailTypeInfo(rt)->label, 0});
139 }
140
141 _roadtype_list.clear();
142 for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
143 _roadtype_list.push_back({GetRoadTypeInfo(rt)->label, GetRoadTramType(rt)});
144 }
145}
146
155
156void ResetLabelMaps()
157{
158 _railtype_list.clear();
159 _roadtype_list.clear();
160}
161
163 RAILChunkHandler() : ChunkHandler('RAIL', CH_TABLE) {}
164
165 static inline const SaveLoad description[] = {
166 SLE_VAR(LabelObject<RailTypeLabel>, label, SLE_UINT32),
167 };
168
169 void Save() const override
170 {
171 SlTableHeader(description);
172
174 for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) {
175 lo.label = GetRailTypeInfo(r)->label;
176
177 SlSetArrayIndex(r);
178 SlObject(&lo, description);
179 }
180 }
181
182 void Load() const override
183 {
184 const std::vector<SaveLoad> slt = SlCompatTableHeader(description, _label_object_sl_compat);
185
186 _railtype_list.reserve(RAILTYPE_END);
187
189
190 while (SlIterateArray() != -1) {
191 SlObject(&lo, slt);
192 _railtype_list.push_back(lo);
193 }
194 }
195};
196
198 ROTTChunkHandler() : ChunkHandler('ROTT', CH_TABLE) {}
199
200 static inline const SaveLoad description[] = {
201 SLE_VAR(LabelObject<RoadTypeLabel>, label, SLE_UINT32),
202 SLE_VAR(LabelObject<RoadTypeLabel>, subtype, SLE_UINT8),
203 };
204
205 void Save() const override
206 {
207 SlTableHeader(description);
208
210 for (RoadType r = ROADTYPE_BEGIN; r != ROADTYPE_END; r++) {
211 const RoadTypeInfo *rti = GetRoadTypeInfo(r);
212 lo.label = rti->label;
213 lo.subtype = GetRoadTramType(r);
214
215 SlSetArrayIndex(r);
216 SlObject(&lo, description);
217 }
218 }
219
220 void Load() const override
221 {
222 const std::vector<SaveLoad> slt = SlCompatTableHeader(description, _label_object_sl_compat);
223
224 _roadtype_list.reserve(ROADTYPE_END);
225
227
228 while (SlIterateArray() != -1) {
229 SlObject(&lo, slt);
230 _roadtype_list.push_back(lo);
231 }
232 }
233};
234
235static const RAILChunkHandler RAIL;
236static const ROTTChunkHandler ROTT;
237
238static const ChunkHandlerRef labelmaps_chunk_handlers[] = {
239 RAIL,
240 ROTT,
241};
242
243extern const ChunkHandlerTable _labelmaps_chunk_handlers(labelmaps_chunk_handlers);
244
RailTypeLabel label
Unique 32 bit rail type identifier.
Definition rail.h:236
RoadTypeLabel label
Unique 32 bit road type identifier.
Definition road.h:147
static void SetCurrentLabelLists()
Populate label lists with current values.
static void ConvertRoadTypes()
Test if any saved road type labels are different to the currently loaded road types.
static void ConvertRailTypes()
Test if any saved rail type labels are different to the currently loaded rail types.
void AfterLoadLabelMaps()
Perform rail type and road type conversion if necessary.
Loading of labelmaps chunks before table headers were added.
const SaveLoadCompat _label_object_sl_compat[]
Original field order for _label_object_desc.
RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels)
Get the rail type for a given label.
Definition rail.cpp:311
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition rail.h:307
RailType GetRailType(Tile t)
Gets the rail type of the given tile.
Definition rail_map.h:115
void SetRailType(Tile t, RailType r)
Sets the rail type of the given tile.
Definition rail_map.h:125
RailType
Enumeration for all possible railtypes.
Definition rail_type.h:27
@ RAILTYPE_BEGIN
Used for iterations.
Definition rail_type.h:28
@ RAILTYPE_END
Used for iterations.
Definition rail_type.h:33
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition rail_type.h:34
@ RAILTYPE_RAIL
Standard non-electric rails.
Definition rail_type.h:29
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
Get the road type for a given label.
Definition road.cpp:254
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:227
void SetRoadTypeRoad(Tile t, RoadType rt)
Set the road road type of a tile.
Definition road_map.h:579
void SetRoadTypeTram(Tile t, RoadType rt)
Set the tram road type of a tile.
Definition road_map.h:591
bool IsLevelCrossing(Tile t)
Return whether a tile is a level crossing.
Definition road_map.h:85
RoadType
The different roadtypes we support.
Definition road_type.h:25
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:30
@ ROADTYPE_TRAM
Trams.
Definition road_type.h:28
@ ROADTYPE_ROAD
Basic road type.
Definition road_type.h:27
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:29
@ ROADTYPE_BEGIN
Used for iterations.
Definition road_type.h:26
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition saveload.cpp:659
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
Functions/types related to saving and loading games.
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition saveload.h:509
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:512
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition saveload.h:1002
Declaration of functions used in more save/load files.
bool IsRoadWaypoint(Tile t)
Is the station at t a road waypoint?
bool IsStationRoadStop(Tile t)
Is the station at t a road station?
bool HasStationRail(Tile t)
Has this station tile a rail? In other words, is this station tile a rail station or rail waypoint?
Handlers and description of chunk.
Definition saveload.h:463
Container for a label for rail or road type conversion.
uint8_t subtype
Subtype of type (road or tram).
T label
Label of rail or road type.
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:363
void Load() const override
Load the chunk.
void Save() const override
Save the chunk.
void Load() const override
Load the chunk.
void Save() const override
Save the chunk.
SaveLoad type struct.
Definition saveload.h:717
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
@ MP_ROAD
A tile with road (or tram tracks)
Definition tile_type.h:50
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
@ TRANSPORT_RAIL
Transport by train.
@ TRANSPORT_ROAD
Transport by road vehicle.
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...