OpenTTD Source: src/saveload/labelmaps_sl.cpp Source File

OpenTTD Source 15.0-beta1

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"
13#include "compat/labelmaps_sl_compat.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>
25 struct LabelObject {
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
37 static 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:
74 if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) {
75 SetRailType(t, railtype_conversion_map[GetRailType(t)]);
76 }
77 break;
78
79 default:
80 break;
81 }
82 }
83}
84
89 static 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:
121 if (GetTunnelBridgeTransportType(t) == TRANSPORT_ROAD) {
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
134 static void SetCurrentLabelLists()
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
148 void AfterLoadLabelMaps()
149{
150 ConvertRailTypes();
151 ConvertRoadTypes();
152
153 SetCurrentLabelLists();
154}
155
156void ResetLabelMaps()
157{
158 _railtype_list.clear();
159 _roadtype_list.clear();
160}
161
162 struct RAILChunkHandler : ChunkHandler {
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
173 LabelObject<RailTypeLabel> lo;
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
188 LabelObject<RailTypeLabel> lo;
189
190 while (SlIterateArray() != -1) {
191 SlObject(&lo, slt);
192 _railtype_list.push_back(lo);
193 }
194 }
195};
196
197 struct ROTTChunkHandler : ChunkHandler {
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
209 LabelObject<RoadTypeLabel> lo;
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
226 LabelObject<RoadTypeLabel> lo;
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
RailTypeInfo::label
RailTypeLabel label
Unique 32 bit rail type identifier.
Definition rail.h:236
RoadTypeInfo
Definition road.h:78
RoadTypeInfo::label
RoadTypeLabel label
Unique 32 bit road type identifier.
Definition road.h:147
SetCurrentLabelLists
static void SetCurrentLabelLists()
Populate label lists with current values.
Definition labelmaps_sl.cpp:134
ConvertRoadTypes
static void ConvertRoadTypes()
Test if any saved road type labels are different to the currently loaded road types.
Definition labelmaps_sl.cpp:89
ConvertRailTypes
static void ConvertRailTypes()
Test if any saved rail type labels are different to the currently loaded rail types.
Definition labelmaps_sl.cpp:37
AfterLoadLabelMaps
void AfterLoadLabelMaps()
Perform rail type and road type conversion if necessary.
Definition labelmaps_sl.cpp:148
labelmaps_sl_compat.h
Loading of labelmaps chunks before table headers were added.
_label_object_sl_compat
const SaveLoadCompat _label_object_sl_compat[]
Original field order for _label_object_desc.
Definition labelmaps_sl_compat.h:16
GetRailTypeByLabel
RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels)
Get the rail type for a given label.
Definition rail.cpp:311
GetRailTypeInfo
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition rail.h:307
GetRailType
RailType GetRailType(Tile t)
Gets the rail type of the given tile.
Definition rail_map.h:115
SetRailType
void SetRailType(Tile t, RailType r)
Sets the rail type of the given tile.
Definition rail_map.h:125
RailType
RailType
Enumeration for all possible railtypes.
Definition rail_type.h:27
RAILTYPE_BEGIN
@ RAILTYPE_BEGIN
Used for iterations.
Definition rail_type.h:28
RAILTYPE_END
@ RAILTYPE_END
Used for iterations.
Definition rail_type.h:33
INVALID_RAILTYPE
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition rail_type.h:34
RAILTYPE_RAIL
@ RAILTYPE_RAIL
Standard non-electric rails.
Definition rail_type.h:29
GetRoadTypeByLabel
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
Get the road type for a given label.
Definition road.cpp:254
GetRoadTypeInfo
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:227
SetRoadTypeRoad
void SetRoadTypeRoad(Tile t, RoadType rt)
Set the road road type of a tile.
Definition road_map.h:579
SetRoadTypeTram
void SetRoadTypeTram(Tile t, RoadType rt)
Set the tram road type of a tile.
Definition road_map.h:591
IsLevelCrossing
bool IsLevelCrossing(Tile t)
Return whether a tile is a level crossing.
Definition road_map.h:85
RoadType
RoadType
The different roadtypes we support.
Definition road_type.h:25
INVALID_ROADTYPE
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:30
ROADTYPE_TRAM
@ ROADTYPE_TRAM
Trams.
Definition road_type.h:28
ROADTYPE_ROAD
@ ROADTYPE_ROAD
Basic road type.
Definition road_type.h:27
ROADTYPE_END
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:29
ROADTYPE_BEGIN
@ ROADTYPE_BEGIN
Used for iterations.
Definition road_type.h:26
SlCompatTableHeader
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
Definition saveload.cpp:1924
SlIterateArray
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition saveload.cpp:659
SlObject
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
Definition saveload.cpp:1733
SlTableHeader
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
Definition saveload.cpp:1786
saveload.h
Functions/types related to saving and loading games.
ChunkHandlerRef
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition saveload.h:509
ChunkHandlerTable
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:512
SLE_VAR
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition saveload.h:1002
saveload_internal.h
Declaration of functions used in more save/load files.
IsRoadWaypoint
bool IsRoadWaypoint(Tile t)
Is the station at t a road waypoint?
Definition station_map.h:202
IsStationRoadStop
bool IsStationRoadStop(Tile t)
Is the station at t a road station?
Definition station_map.h:223
HasStationRail
bool HasStationRail(Tile t)
Has this station tile a rail? In other words, is this station tile a rail station or rail waypoint?
Definition station_map.h:135
ChunkHandler
Handlers and description of chunk.
Definition saveload.h:463
LabelObject
Container for a label for rail or road type conversion.
Definition labelmaps_sl.cpp:25
LabelObject::subtype
uint8_t subtype
Subtype of type (road or tram).
Definition labelmaps_sl.cpp:27
LabelObject::label
T label
Label of rail or road type.
Definition labelmaps_sl.cpp:26
Map::Iterate
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:363
RAILChunkHandler
Definition labelmaps_sl.cpp:162
RAILChunkHandler::Load
void Load() const override
Load the chunk.
Definition labelmaps_sl.cpp:182
RAILChunkHandler::Save
void Save() const override
Save the chunk.
Definition labelmaps_sl.cpp:169
ROTTChunkHandler
Definition labelmaps_sl.cpp:197
ROTTChunkHandler::Load
void Load() const override
Load the chunk.
Definition labelmaps_sl.cpp:220
ROTTChunkHandler::Save
void Save() const override
Save the chunk.
Definition labelmaps_sl.cpp:205
SaveLoad
SaveLoad type struct.
Definition saveload.h:717
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
GetTileType
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
MP_ROAD
@ MP_ROAD
A tile with road (or tram tracks)
Definition tile_type.h:50
MP_STATION
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
MP_TUNNELBRIDGE
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
MP_RAILWAY
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
TRANSPORT_RAIL
@ TRANSPORT_RAIL
Transport by train.
Definition transport_type.h:27
TRANSPORT_ROAD
@ TRANSPORT_ROAD
Transport by road vehicle.
Definition transport_type.h:28
GetTunnelBridgeTransportType
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
Definition tunnelbridge_map.h:39