OpenTTD Source  20241108-master-g80f628063a
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 
24 template <typename T>
25 struct LabelObject {
26  T label = {};
27  uint8_t subtype = 0;
28 };
29 
30 static std::vector<LabelObject<RailTypeLabel>> _railtype_list;
31 static 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 (TileIndex 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 
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:
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 
149 {
152 
154 }
155 
156 void 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 
235 static const RAILChunkHandler RAIL;
236 static const ROTTChunkHandler ROTT;
237 
238 static const ChunkHandlerRef labelmaps_chunk_handlers[] = {
239  RAIL,
240  ROTT,
241 };
242 
243 extern 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
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition: saveload.cpp:658
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
Definition: saveload.cpp:1888
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
Definition: saveload.cpp:1750
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
Definition: saveload.cpp:1697
Functions/types related to saving and loading games.
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition: saveload.h:505
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition: saveload.h:508
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition: saveload.h:975
Declaration of functions used in more save/load files.
bool IsRoadWaypoint(Tile t)
Is the station at t a road waypoint?
Definition: station_map.h:202
bool IsStationRoadStop(Tile t)
Is the station at t a road station?
Definition: station_map.h:223
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
Handlers and description of chunk.
Definition: saveload.h:459
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:711
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...