OpenTTD Source 20250312-master-gcdcc6b491d
station_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 "../station_base.h"
16#include "../waypoint_base.h"
17#include "../roadstop_base.h"
18#include "../vehicle_base.h"
19#include "../newgrf_station.h"
20#include "../newgrf_roadstop.h"
21#include "../timer/timer_game_calendar.h"
22
23#include "table/strings.h"
24
25#include "../safeguards.h"
26
32{
33 if (!o->IsType(OT_GOTO_STATION)) return;
34
35 const Station *st = Station::Get(o->GetDestination().ToStationID());
36 if ((st->had_vehicle_of_type & HVOT_WAYPOINT) == 0) return;
37
38 o->MakeGoToWaypoint(o->GetDestination().ToStationID());
39}
40
46{
47 /* Buoy orders become waypoint orders */
48 for (OrderList *ol : OrderList::Iterate()) {
49 VehicleType vt = ol->GetFirstSharedVehicle()->type;
50 if (vt != VEH_SHIP && vt != VEH_TRAIN) continue;
51
52 for (Order *o = ol->GetFirstOrder(); o != nullptr; o = o->next) UpdateWaypointOrder(o);
53 }
54
55 for (Vehicle *v : Vehicle::Iterate()) {
56 VehicleType vt = v->type;
57 if (vt != VEH_SHIP && vt != VEH_TRAIN) continue;
58
59 UpdateWaypointOrder(&v->current_order);
60 }
61
62 /* Now make the stations waypoints */
63 for (Station *st : Station::Iterate()) {
64 if ((st->had_vehicle_of_type & HVOT_WAYPOINT) == 0) continue;
65
66 StationID index = st->index;
67 TileIndex xy = st->xy;
68 Town *town = st->town;
69 StringID string_id = st->string_id;
70 std::string name = st->name;
71 TimerGameCalendar::Date build_date = st->build_date;
72 /* TTDPatch could use "buoys with rail station" for rail waypoints */
73 bool train = st->train_station.tile != INVALID_TILE;
74 TileArea train_st = st->train_station;
75
76 /* Delete the station, so we can make it a real waypoint. */
77 delete st;
78
79 /* Stations and waypoints are in the same pool, so if a station
80 * is deleted there must be place for a Waypoint. */
82 Waypoint *wp = new (index) Waypoint(xy);
83 wp->town = town;
84 wp->string_id = train ? STR_SV_STNAME_WAYPOINT : STR_SV_STNAME_BUOY;
85 wp->name = name;
86 wp->delete_ctr = 0; // Just reset delete counter for once.
87 wp->build_date = build_date;
88 wp->owner = train ? GetTileOwner(xy) : OWNER_NONE;
89
90 if (IsInsideBS(string_id, STR_SV_STNAME_BUOY, 9)) wp->town_cn = string_id - STR_SV_STNAME_BUOY;
91
92 if (train) {
93 /* When we make a rail waypoint of the station, convert the map as well. */
94 for (TileIndex t : train_st) {
95 Tile tile(t);
96 if (!IsTileType(tile, MP_STATION) || GetStationIndex(tile) != index) continue;
97
98 SB(tile.m6(), 3, 3, to_underlying(StationType::RailWaypoint));
99 wp->rect.BeforeAddTile(t, StationRect::ADD_FORCE);
100 }
101
102 wp->train_station = train_st;
104 } else if (IsBuoyTile(xy) && GetStationIndex(xy) == index) {
105 wp->rect.BeforeAddTile(xy, StationRect::ADD_FORCE);
107 }
108 }
109}
110
111void AfterLoadStations()
112{
113 /* Update the speclists of all stations to point to the currently loaded custom stations. */
114 for (BaseStation *st : BaseStation::Iterate()) {
115 for (auto &sm : GetStationSpecList<StationSpec>(st)) {
116 if (sm.grfid == 0) continue;
117 sm.spec = StationClass::GetByGrf(sm.grfid, sm.localidx);
118 }
119 for (auto &sm : GetStationSpecList<RoadStopSpec>(st)) {
120 if (sm.grfid == 0) continue;
121 sm.spec = RoadStopClass::GetByGrf(sm.grfid, sm.localidx);
122 }
123
124 if (Station::IsExpected(st)) {
125 Station *sta = Station::From(st);
126 for (const RoadStop *rs = sta->bus_stops; rs != nullptr; rs = rs->next) sta->bus_station.Add(rs->xy);
127 for (const RoadStop *rs = sta->truck_stops; rs != nullptr; rs = rs->next) sta->truck_station.Add(rs->xy);
128 }
129
131 RoadStopUpdateCachedTriggers(st);
132 }
133
134 /* Station blocked, wires and pylon flags need to be stored in the map. This is effectively cached data, so no
135 * version check is necessary. */
136 for (const auto t : Map::Iterate()) {
137 if (HasStationTileRail(t)) SetRailStationTileFlags(t, GetStationSpec(t));
138 }
139}
140
145{
146 /* First construct the drive through entries */
147 for (RoadStop *rs : RoadStop::Iterate()) {
148 if (IsDriveThroughStopTile(rs->xy)) rs->MakeDriveThrough();
149 }
150 /* And then rebuild the data in those entries */
151 for (RoadStop *rs : RoadStop::Iterate()) {
152 if (!HasBit(rs->status, RoadStop::RSSFB_BASE_ENTRY)) continue;
153
154 rs->GetEntry(DIAGDIR_NE)->Rebuild(rs);
155 rs->GetEntry(DIAGDIR_NW)->Rebuild(rs);
156 }
157}
158
159static const SaveLoad _roadstop_desc[] = {
160 SLE_VAR(RoadStop, xy, SLE_UINT32),
161 SLE_VAR(RoadStop, status, SLE_UINT8),
163};
164
165static uint16_t _waiting_acceptance;
166static uint32_t _old_num_flows;
167static uint16_t _cargo_source;
168static uint32_t _cargo_source_xy;
169static uint8_t _cargo_periods;
170static Money _cargo_feeder_share;
171
172std::list<CargoPacket *> _packets;
173uint32_t _old_num_dests;
174
176 StationID source;
177 StationID via;
178 uint32_t share;
179 bool restricted;
180};
181
182typedef std::pair<const StationID, std::list<CargoPacket *> > StationCargoPair;
183
184static OldPersistentStorage _old_st_persistent_storage;
185
191static void SwapPackets(GoodsEntry *ge)
192{
193 StationCargoPacketMap &ge_packets = const_cast<StationCargoPacketMap &>(*ge->GetOrCreateData().cargo.Packets());
194
195 if (_packets.empty()) {
196 std::map<StationID, std::list<CargoPacket *> >::iterator it(ge_packets.find(StationID::Invalid()));
197 if (it == ge_packets.end()) {
198 return;
199 } else {
200 it->second.swap(_packets);
201 }
202 } else {
203 assert(ge_packets[StationID::Invalid()].empty());
204 ge_packets[StationID::Invalid()].swap(_packets);
205 }
206}
207
208template <typename T>
209class SlStationSpecList : public VectorSaveLoadHandler<SlStationSpecList<T>, BaseStation, SpecMapping<T>> {
210public:
211 inline static const SaveLoad description[] = {
212 SLE_CONDVAR(SpecMapping<T>, grfid, SLE_UINT32, SLV_27, SL_MAX_VERSION),
213 SLE_CONDVAR(SpecMapping<T>, localidx, SLE_FILE_U8 | SLE_VAR_U16, SLV_27, SLV_EXTEND_ENTITY_MAPPING),
215 };
216 inline const static SaveLoadCompatTable compat_description = _station_spec_list_sl_compat;
217
218 static inline uint8_t last_num_specs;
219
220 std::vector<SpecMapping<T>> &GetVector(BaseStation *bst) const override { return GetStationSpecList<T>(bst); }
221
222 size_t GetLength() const override
223 {
225 }
226};
227
228/* Instantiate SlStationSpecList classes. */
229template class SlStationSpecList<StationSpec>;
231
233public:
234 inline static const SaveLoad description[] = {
235 SLE_VAR(StationCargoPair, first, SLE_UINT16),
236 SLE_REFLIST(StationCargoPair, second, REF_CARGO_PACKET),
237 };
238 inline const static SaveLoadCompatTable compat_description = _station_cargo_sl_compat;
239
240 void Save(GoodsEntry *ge) const override
241 {
242 if (!ge->HasData()) {
244 return;
245 }
246
247 const auto *packets = ge->GetData().cargo.Packets();
248 SlSetStructListLength(packets->MapSize());
249 for (StationCargoPacketMap::ConstMapIterator it(packets->begin()); it != packets->end(); ++it) {
250 SlObject(const_cast<StationCargoPacketMap::value_type *>(&(*it)), this->GetDescription());
251 }
252 }
253
254 void Load(GoodsEntry *ge) const override
255 {
256 size_t num_dests = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? _old_num_dests : SlGetStructListLength(UINT32_MAX);
257 if (num_dests == 0) return;
258
260 StationCargoPair pair;
261 for (uint j = 0; j < num_dests; ++j) {
262 SlObject(&pair, this->GetLoadDescription());
263 const_cast<StationCargoPacketMap &>(*(data.cargo.Packets()))[pair.first].swap(pair.second);
264 assert(pair.second.empty());
265 }
266 }
267
268 void FixPointers(GoodsEntry *ge) const override
269 {
270 if (!ge->HasData()) return;
271
272 for (StationCargoPacketMap::ConstMapIterator it = ge->GetData().cargo.Packets()->begin(); it != ge->GetData().cargo.Packets()->end(); ++it) {
273 SlObject(const_cast<StationCargoPair *>(&(*it)), this->GetDescription());
274 }
275 }
276};
277
279public:
280 inline static const SaveLoad description[] = {
281 SLE_VAR(FlowSaveLoad, source, SLE_UINT16),
282 SLE_VAR(FlowSaveLoad, via, SLE_UINT16),
283 SLE_VAR(FlowSaveLoad, share, SLE_UINT32),
284 SLE_CONDVAR(FlowSaveLoad, restricted, SLE_BOOL, SLV_187, SL_MAX_VERSION),
285 };
286 inline const static SaveLoadCompatTable compat_description = _station_flow_sl_compat;
287
288 void Save(GoodsEntry *ge) const override
289 {
290 if (!ge->HasData()) {
292 return;
293 }
294
295 size_t num_flows = 0;
296 for (const auto &it : ge->GetData().flows) {
297 num_flows += it.second.GetShares()->size();
298 }
299 SlSetStructListLength(num_flows);
300
301 for (const auto &outer_it : ge->GetData().flows) {
302 const FlowStat::SharesMap *shares = outer_it.second.GetShares();
303 uint32_t sum_shares = 0;
304 FlowSaveLoad flow{};
305 flow.source = outer_it.first;
306 for (auto &inner_it : *shares) {
307 flow.via = inner_it.second;
308 flow.share = inner_it.first - sum_shares;
309 flow.restricted = inner_it.first > outer_it.second.GetUnrestricted();
310 sum_shares = inner_it.first;
311 assert(flow.share > 0);
312 SlObject(&flow, this->GetDescription());
313 }
314 }
315 }
316
317 void Load(GoodsEntry *ge) const override
318 {
319 size_t num_flows = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? _old_num_flows : SlGetStructListLength(UINT32_MAX);
320 if (num_flows == 0) return;
321
323 FlowSaveLoad flow{};
324 FlowStat *fs = nullptr;
325 StationID prev_source = StationID::Invalid();
326 for (uint32_t j = 0; j < num_flows; ++j) {
327 SlObject(&flow, this->GetLoadDescription());
328 if (fs == nullptr || prev_source != flow.source) {
329 fs = &(data.flows.emplace(flow.source, FlowStat(flow.via, flow.share, flow.restricted))).first->second;
330 } else {
331 fs->AppendShare(flow.via, flow.share, flow.restricted);
332 }
333 prev_source = flow.source;
334 }
335 }
336};
337
338class SlStationGoods : public DefaultSaveLoadHandler<SlStationGoods, BaseStation> {
339public:
340 static inline uint cargo_reserved_count;
341
342 inline static const SaveLoad description[] = {
343 SLEG_CONDVAR("waiting_acceptance", _waiting_acceptance, SLE_UINT16, SL_MIN_VERSION, SLV_68),
344 SLE_CONDVAR(GoodsEntry, status, SLE_UINT8, SLV_68, SL_MAX_VERSION),
345 SLE_VAR(GoodsEntry, time_since_pickup, SLE_UINT8),
346 SLE_VAR(GoodsEntry, rating, SLE_UINT8),
347 SLEG_CONDVAR("cargo_source", _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_7),
348 SLEG_CONDVAR("cargo_source", _cargo_source, SLE_UINT16, SLV_7, SLV_68),
349 SLEG_CONDVAR("cargo_source_xy", _cargo_source_xy, SLE_UINT32, SLV_44, SLV_68),
350 SLEG_CONDVAR("cargo_days", _cargo_periods, SLE_UINT8, SL_MIN_VERSION, SLV_68),
351 SLE_VAR(GoodsEntry, last_speed, SLE_UINT8),
352 SLE_VAR(GoodsEntry, last_age, SLE_UINT8),
353 SLEG_CONDVAR("cargo_feeder_share", _cargo_feeder_share, SLE_FILE_U32 | SLE_VAR_I64, SLV_14, SLV_65),
354 SLEG_CONDVAR("cargo_feeder_share", _cargo_feeder_share, SLE_INT64, SLV_65, SLV_68),
355 SLE_CONDVAR(GoodsEntry, amount_fract, SLE_UINT8, SLV_150, SL_MAX_VERSION),
356 SLEG_CONDREFLIST("packets", _packets, REF_CARGO_PACKET, SLV_68, SLV_183),
357 SLEG_CONDVAR("old_num_dests", _old_num_dests, SLE_UINT32, SLV_183, SLV_SAVELOAD_LIST_LENGTH),
358 SLEG_CONDVAR("cargo.reserved_count", SlStationGoods::cargo_reserved_count, SLE_UINT, SLV_181, SL_MAX_VERSION),
359 SLE_CONDVAR(GoodsEntry, link_graph, SLE_UINT16, SLV_183, SL_MAX_VERSION),
360 SLE_CONDVAR(GoodsEntry, node, SLE_UINT16, SLV_183, SL_MAX_VERSION),
361 SLEG_CONDVAR("old_num_flows", _old_num_flows, SLE_UINT32, SLV_183, SLV_SAVELOAD_LIST_LENGTH),
362 SLE_CONDVAR(GoodsEntry, max_waiting_cargo, SLE_UINT32, SLV_183, SL_MAX_VERSION),
365 };
366
367 inline const static SaveLoadCompatTable compat_description = _station_goods_sl_compat;
368
373 size_t GetNumCargo() const
374 {
375 if (IsSavegameVersionBefore(SLV_55)) return 12;
378 /* Read from the savegame how long the list is. */
380 }
381
382 void Save(BaseStation *bst) const override
383 {
384 Station *st = Station::From(bst);
385
387
388 for (GoodsEntry &ge : st->goods) {
389 SlStationGoods::cargo_reserved_count = ge.HasData() ? ge.GetData().cargo.reserved_count : 0;
390 SlObject(&ge, this->GetDescription());
391 }
392 }
393
394 void Load(BaseStation *bst) const override
395 {
396 Station *st = Station::From(bst);
397
398 /* Before savegame version 161, persistent storages were not stored in a pool. */
400 /* Store the old persistent storage. The GRFID will be added later. */
402 st->airport.psa = new PersistentStorage(0, 0, TileIndex{});
403 std::copy(std::begin(_old_st_persistent_storage.storage), std::end(_old_st_persistent_storage.storage), std::begin(st->airport.psa->storage));
404 }
405
406 auto end = std::next(std::begin(st->goods), std::min(this->GetNumCargo(), std::size(st->goods)));
407 for (auto it = std::begin(st->goods); it != end; ++it) {
408 GoodsEntry &ge = *it;
409 SlObject(&ge, this->GetLoadDescription());
410 if (!IsSavegameVersionBefore(SLV_181) && SlStationGoods::cargo_reserved_count != 0) {
411 ge.GetOrCreateData().cargo.reserved_count = SlStationGoods::cargo_reserved_count;
412 }
414 SwapPackets(&ge);
415 }
417 AssignBit(ge.status, GoodsEntry::GES_ACCEPTANCE, HasBit(_waiting_acceptance, 15));
418 if (GB(_waiting_acceptance, 0, 12) != 0) {
419 /* In old versions, enroute_from used 0xFF as StationID::Invalid() */
420 StationID source = (IsSavegameVersionBefore(SLV_7) && _cargo_source == 0xFF) ? StationID::Invalid() : static_cast<StationID>(_cargo_source);
421
422 /* Make sure we can allocate the CargoPacket. This is safe
423 * as there can only be ~64k stations and 32 cargoes in these
424 * savegame versions. As the CargoPacketPool has more than
425 * 16 million entries; it fits by an order of magnitude. */
427
428 /* Don't construct the packet with station here, because that'll fail with old savegames */
429 CargoPacket *cp = new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, source, TileIndex{_cargo_source_xy}, _cargo_feeder_share);
430 ge.GetOrCreateData().cargo.Append(cp, StationID::Invalid());
432 }
433 }
434 }
435 }
436
437 void FixPointers(BaseStation *bst) const override
438 {
439 Station *st = Station::From(bst);
440
442 auto end = std::next(std::begin(st->goods), std::min(num_cargo, std::size(st->goods)));
443 for (auto it = std::begin(st->goods); it != end; ++it) {
444 GoodsEntry &ge = *it;
446 SwapPackets(&ge); // We have to swap back again to be in the format pre-183 expects.
447 SlObject(&ge, this->GetDescription());
448 SwapPackets(&ge);
449 } else {
450 SlObject(&ge, this->GetDescription());
451 }
452 }
453 }
454};
455
456static const SaveLoad _old_station_desc[] = {
457 SLE_CONDVAR(Station, xy, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
458 SLE_CONDVAR(Station, xy, SLE_UINT32, SLV_6, SL_MAX_VERSION),
459 SLE_CONDVAR(Station, train_station.tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
460 SLE_CONDVAR(Station, train_station.tile, SLE_UINT32, SLV_6, SL_MAX_VERSION),
461 SLE_CONDVAR(Station, airport.tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
462 SLE_CONDVAR(Station, airport.tile, SLE_UINT32, SLV_6, SL_MAX_VERSION),
463 SLE_REF(Station, town, REF_TOWN),
464 SLE_VAR(Station, train_station.w, SLE_FILE_U8 | SLE_VAR_U16),
465 SLE_CONDVAR(Station, train_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_2, SL_MAX_VERSION),
466
467 SLE_VAR(Station, string_id, SLE_STRINGID),
469 SLE_CONDVAR(Station, indtype, SLE_UINT8, SLV_103, SL_MAX_VERSION),
470 SLE_CONDVAR(Station, had_vehicle_of_type, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SLV_122),
471 SLE_CONDVAR(Station, had_vehicle_of_type, SLE_UINT8, SLV_122, SL_MAX_VERSION),
472
473 SLE_VAR(Station, time_since_load, SLE_UINT8),
474 SLE_VAR(Station, time_since_unload, SLE_UINT8),
475 SLE_VAR(Station, delete_ctr, SLE_UINT8),
476 SLE_VAR(Station, owner, SLE_UINT8),
477 SLE_VAR(Station, facilities, SLE_UINT8),
478 SLE_VAR(Station, airport.type, SLE_UINT8),
479 SLE_CONDVARNAME(Station, airport.blocks, "airport.flags", SLE_VAR_U64 | SLE_FILE_U16, SL_MIN_VERSION, SLV_3),
480 SLE_CONDVARNAME(Station, airport.blocks, "airport.flags", SLE_VAR_U64 | SLE_FILE_U32, SLV_3, SLV_46),
481 SLE_CONDVARNAME(Station, airport.blocks, "airport.flags", SLE_UINT64, SLV_46, SL_MAX_VERSION),
482
483 SLE_CONDVAR(Station, last_vehicle_type, SLE_UINT8, SLV_26, SL_MAX_VERSION),
484
485 SLE_CONDVAR(Station, build_date, SLE_FILE_U16 | SLE_VAR_I32, SLV_3, SLV_31),
486 SLE_CONDVAR(Station, build_date, SLE_INT32, SLV_31, SL_MAX_VERSION),
487
490
491 /* Used by newstations for graphic variations */
492 SLE_CONDVAR(Station, random_bits, SLE_UINT16, SLV_27, SL_MAX_VERSION),
493 SLE_CONDVAR(Station, waiting_triggers, SLE_UINT8, SLV_27, SL_MAX_VERSION),
495
497
500};
501
504
505 void Load() const override
506 {
507 const std::vector<SaveLoad> slt = SlCompatTableHeader(_old_station_desc, _old_station_sl_compat);
508
509 _cargo_source_xy = 0;
510 _cargo_periods = 0;
511 _cargo_feeder_share = 0;
512
513 int index;
514 while ((index = SlIterateArray()) != -1) {
515 Station *st = new (StationID(index)) Station();
516
517 _waiting_acceptance = 0;
518 SlObject(st, slt);
519 }
520 }
521
522 void FixPointers() const override
523 {
524 /* From SLV_123 we store stations in STNN; before that in STNS. So do not
525 * fix pointers when the version is SLV_123 or up, as that would fix
526 * pointers twice: once in STNN chunk and once here. */
527 if (!IsSavegameVersionBefore(SLV_123)) return;
528
529 for (Station *st : Station::Iterate()) {
530 SlObject(st, _old_station_desc);
531 }
532 }
533};
534
535class SlRoadStopTileData : public VectorSaveLoadHandler<SlRoadStopTileData, BaseStation, RoadStopTileData> {
536public:
537 inline static const SaveLoad description[] = {
538 SLE_VAR(RoadStopTileData, tile, SLE_UINT32),
539 SLE_VAR(RoadStopTileData, random_bits, SLE_UINT8),
540 SLE_VAR(RoadStopTileData, animation_frame, SLE_UINT8),
541 };
542 inline const static SaveLoadCompatTable compat_description = {};
543
544 std::vector<RoadStopTileData> &GetVector(BaseStation *bst) const override { return bst->custom_roadstop_tile_data; }
545};
546
551class SlStationBase : public DefaultSaveLoadHandler<SlStationBase, BaseStation> {
552public:
553 inline static const SaveLoad description[] = {
554 SLE_VAR(BaseStation, xy, SLE_UINT32),
556 SLE_VAR(BaseStation, string_id, SLE_STRINGID),
557 SLE_SSTR(BaseStation, name, SLE_STR | SLF_ALLOW_CONTROL),
558 SLE_VAR(BaseStation, delete_ctr, SLE_UINT8),
559 SLE_VAR(BaseStation, owner, SLE_UINT8),
560 SLE_VAR(BaseStation, facilities, SLE_UINT8),
561 SLE_VAR(BaseStation, build_date, SLE_INT32),
562
563 /* Used by newstations for graphic variations */
564 SLE_VAR(BaseStation, random_bits, SLE_UINT16),
565 SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8),
567 };
568 inline const static SaveLoadCompatTable compat_description = _station_base_sl_compat;
569
570 void Save(BaseStation *bst) const override
571 {
572 SlObject(bst, this->GetDescription());
573 }
574
575 void Load(BaseStation *bst) const override
576 {
577 SlObject(bst, this->GetLoadDescription());
578 }
579
580 void FixPointers(BaseStation *bst) const override
581 {
582 SlObject(bst, this->GetDescription());
583 }
584};
585
589class SlStationNormal : public DefaultSaveLoadHandler<SlStationNormal, BaseStation> {
590public:
591 inline static const SaveLoad description[] = {
592 SLEG_STRUCT("base", SlStationBase),
593 SLE_VAR(Station, train_station.tile, SLE_UINT32),
594 SLE_VAR(Station, train_station.w, SLE_FILE_U8 | SLE_VAR_U16),
595 SLE_VAR(Station, train_station.h, SLE_FILE_U8 | SLE_VAR_U16),
596
597 SLE_REF(Station, bus_stops, REF_ROADSTOPS),
598 SLE_REF(Station, truck_stops, REF_ROADSTOPS),
599 SLE_CONDVAR(Station, ship_station.tile, SLE_UINT32, SLV_MULTITILE_DOCKS, SL_MAX_VERSION),
600 SLE_CONDVAR(Station, ship_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION),
601 SLE_CONDVAR(Station, ship_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION),
602 SLE_CONDVAR(Station, docking_station.tile, SLE_UINT32, SLV_MULTITILE_DOCKS, SL_MAX_VERSION),
603 SLE_CONDVAR(Station, docking_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION),
604 SLE_CONDVAR(Station, docking_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION),
605 SLE_VAR(Station, airport.tile, SLE_UINT32),
606 SLE_CONDVAR(Station, airport.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_140, SL_MAX_VERSION),
607 SLE_CONDVAR(Station, airport.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_140, SL_MAX_VERSION),
608 SLE_VAR(Station, airport.type, SLE_UINT8),
609 SLE_CONDVAR(Station, airport.layout, SLE_UINT8, SLV_145, SL_MAX_VERSION),
610 SLE_VARNAME(Station, airport.blocks, "airport.flags", SLE_UINT64),
611 SLE_CONDVAR(Station, airport.rotation, SLE_UINT8, SLV_145, SL_MAX_VERSION),
612 SLEG_CONDARR("storage", _old_st_persistent_storage.storage, SLE_UINT32, 16, SLV_145, SLV_161),
614
615 SLE_VAR(Station, indtype, SLE_UINT8),
616
617 SLE_VAR(Station, time_since_load, SLE_UINT8),
618 SLE_VAR(Station, time_since_unload, SLE_UINT8),
619 SLE_VAR(Station, last_vehicle_type, SLE_UINT8),
620 SLE_VAR(Station, had_vehicle_of_type, SLE_UINT8),
621 SLE_REFLIST(Station, loading_vehicles, REF_VEHICLE),
622 SLE_CONDVAR(Station, always_accepted, SLE_FILE_U32 | SLE_VAR_U64, SLV_127, SLV_EXTEND_CARGOTYPES),
623 SLE_CONDVAR(Station, always_accepted, SLE_UINT64, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION),
626 };
627 inline const static SaveLoadCompatTable compat_description = _station_normal_sl_compat;
628
629 void Save(BaseStation *bst) const override
630 {
631 if (bst->facilities.Test(StationFacility::Waypoint)) return;
632 SlObject(bst, this->GetDescription());
633 }
634
635 void Load(BaseStation *bst) const override
636 {
637 if (bst->facilities.Test(StationFacility::Waypoint)) return;
638 SlObject(bst, this->GetLoadDescription());
639 }
640
641 void FixPointers(BaseStation *bst) const override
642 {
643 if (bst->facilities.Test(StationFacility::Waypoint)) return;
644 SlObject(bst, this->GetDescription());
645 }
646};
647
648class SlStationWaypoint : public DefaultSaveLoadHandler<SlStationWaypoint, BaseStation> {
649public:
650 inline static const SaveLoad description[] = {
651 SLEG_STRUCT("base", SlStationBase),
652 SLE_VAR(Waypoint, town_cn, SLE_UINT16),
653
654 SLE_CONDVAR(Waypoint, train_station.tile, SLE_UINT32, SLV_124, SL_MAX_VERSION),
655 SLE_CONDVAR(Waypoint, train_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION),
656 SLE_CONDVAR(Waypoint, train_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION),
657 SLE_CONDVAR(Waypoint, waypoint_flags, SLE_UINT16, SLV_ROAD_WAYPOINTS, SL_MAX_VERSION),
658 SLE_CONDVAR(Waypoint, road_waypoint_area.tile, SLE_UINT32, SLV_ROAD_WAYPOINTS, SL_MAX_VERSION),
659 SLE_CONDVAR(Waypoint, road_waypoint_area.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_ROAD_WAYPOINTS, SL_MAX_VERSION),
660 SLE_CONDVAR(Waypoint, road_waypoint_area.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_ROAD_WAYPOINTS, SL_MAX_VERSION),
661 };
662 inline const static SaveLoadCompatTable compat_description = _station_waypoint_sl_compat;
663
664 void Save(BaseStation *bst) const override
665 {
666 if (!bst->facilities.Test(StationFacility::Waypoint)) return;
667 SlObject(bst, this->GetDescription());
668 }
669
670 void Load(BaseStation *bst) const override
671 {
672 if (!bst->facilities.Test(StationFacility::Waypoint)) return;
673 SlObject(bst, this->GetLoadDescription());
674 }
675
676 void FixPointers(BaseStation *bst) const override
677 {
678 if (!bst->facilities.Test(StationFacility::Waypoint)) return;
679 SlObject(bst, this->GetDescription());
680 }
681};
682
683static const SaveLoad _station_desc[] = {
684 SLE_SAVEBYTE(BaseStation, facilities),
685 SLEG_STRUCT("normal", SlStationNormal),
686 SLEG_STRUCT("waypoint", SlStationWaypoint),
690};
691
693 STNNChunkHandler() : ChunkHandler('STNN', CH_TABLE) {}
694
695 void Save() const override
696 {
697 SlTableHeader(_station_desc);
698
699 /* Write the stations */
700 for (BaseStation *st : BaseStation::Iterate()) {
701 SlSetArrayIndex(st->index);
702 SlObject(st, _station_desc);
703 }
704 }
705
706
707 void Load() const override
708 {
709 const std::vector<SaveLoad> slt = SlCompatTableHeader(_station_desc, _station_sl_compat);
710
711 _old_num_flows = 0;
712
713 int index;
714 while ((index = SlIterateArray()) != -1) {
715 bool waypoint = static_cast<StationFacilities>(SlReadByte()).Test(StationFacility::Waypoint);
716
717 BaseStation *bst = waypoint ? (BaseStation *)new (StationID(index)) Waypoint() : new (StationID(index)) Station();
718 SlObject(bst, slt);
719 }
720 }
721
722 void FixPointers() const override
723 {
724 /* From SLV_123 we store stations in STNN; before that in STNS. So do not
725 * fix pointers when the version is below SLV_123, as that would fix
726 * pointers twice: once in STNS chunk and once here. */
727 if (IsSavegameVersionBefore(SLV_123)) return;
728
729 for (BaseStation *bst : BaseStation::Iterate()) {
730 SlObject(bst, _station_desc);
731 }
732 }
733};
734
736 ROADChunkHandler() : ChunkHandler('ROAD', CH_TABLE) {}
737
738 void Save() const override
739 {
740 SlTableHeader(_roadstop_desc);
741
742 for (RoadStop *rs : RoadStop::Iterate()) {
743 SlSetArrayIndex(rs->index);
744 SlObject(rs, _roadstop_desc);
745 }
746 }
747
748 void Load() const override
749 {
750 const std::vector<SaveLoad> slt = SlCompatTableHeader(_roadstop_desc, _roadstop_sl_compat);
751
752 int index;
753
754 while ((index = SlIterateArray()) != -1) {
755 RoadStop *rs = new (RoadStopID(index)) RoadStop(INVALID_TILE);
756
757 SlObject(rs, slt);
758 }
759 }
760
761 void FixPointers() const override
762 {
763 for (RoadStop *rs : RoadStop::Iterate()) {
764 SlObject(rs, _roadstop_desc);
765 }
766 }
767};
768
769static const STNSChunkHandler STNS;
770static const STNNChunkHandler STNN;
771static const ROADChunkHandler ROAD;
772static const ChunkHandlerRef station_chunk_handlers[] = {
773 STNS,
774 STNN,
775 ROAD,
776};
777
778extern const ChunkHandlerTable _station_chunk_handlers(station_chunk_handlers);
std::vector< SpecMapping< T > > & GetStationSpecList(BaseStation *bst)
Get spec mapping list for each supported custom spec type.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T AssignBit(T &x, const uint8_t y, bool value)
Assigns a bit in a variable.
constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d)
Set n bits in x starting at bit s to d.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
static const CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:75
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Timpl & Set()
Set all bits.
const Tcont * Packets() const
Returns a pointer to the cargo packet list (so you can iterate over it etc).
Default handler for saving/loading an object to/from disk.
Definition saveload.h:586
SaveLoadTable GetDescription() const override
Definition saveload.h:588
Flow statistics telling how much flow should be sent along a link.
void AppendShare(StationID st, uint flow, bool restricted=false)
Add some flow to the end of the shares map.
Hand-rolled multimap as map of lists.
Definition multimap.hpp:225
static const Tspec * GetByGrf(uint32_t grfid, uint16_t local_id)
Retrieve a spec by GRF location.
SaveLoadTable GetLoadDescription() const
Get the description for how to load the chunk.
std::vector< RoadStopTileData > & GetVector(BaseStation *bst) const override
Get instance of vector to load/save.
SaveLoad handler for the BaseStation, which all other stations / waypoints make use of.
size_t GetNumCargo() const
Get the number of cargoes used by this savegame version.
SaveLoad handler for a normal station (read: not a waypoint).
size_t GetLength() const override
Get number of elements to load into vector.
static uint8_t last_num_specs
Number of specs of the last loaded station.
std::vector< SpecMapping< T > > & GetVector(BaseStation *bst) const override
Get instance of vector to load/save.
void Append(CargoPacket *cp, StationID next)
Appends the given cargo packet to the range of packets with the same next station.
uint reserved_count
Amount of cargo being reserved for loading.
Wrapper class to abstract away the way the tiles are stored.
Definition map_func.h:25
debug_inline uint8_t & m6()
General purpose.
Definition map_func.h:173
Default handler for saving/loading a vector to/from disk.
Definition saveload.h:1372
static constexpr Owner OWNER_NONE
The tile has no ownership.
@ DIAGDIR_NE
Northeast, upper right on your monitor.
@ DIAGDIR_NW
Northwest.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Definition enum_type.hpp:17
constexpr bool IsInsideBS(const T x, const size_t base, const size_t size)
Checks if a value is between a window started at some base point.
void StationUpdateCachedTriggers(BaseStation *st)
Update the cached animation trigger bitmask for a station.
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
size_t SlGetStructListLength(size_t limit)
Get the length of this list; if it exceeds the limit, error out.
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition saveload.cpp:663
uint8_t SlReadByte()
Wrapper for reading a byte from the buffer.
Definition saveload.cpp:396
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
void SlSetStructListLength(size_t length)
Set the length of this list.
Functions/types related to saving and loading games.
#define SLEG_CONDARR(name, variable, type, length, from, to)
Storage of a global fixed-size array of SL_VAR elements in some savegame versions.
Definition saveload.h:1135
#define SLEG_STRUCTLIST(name, handler)
Storage of a list of structs in every savegame version.
Definition saveload.h:1246
#define SLEG_CONDVAR(name, variable, type, from, to)
Storage of a global variable in some savegame versions.
Definition saveload.h:1114
@ SLF_ALLOW_CONTROL
Allow control codes in the strings.
Definition saveload.h:693
#define SLE_VARNAME(base, variable, name, type)
Storage of a variable in every version of a savegame.
Definition saveload.h:1016
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition saveload.h:514
@ REF_TOWN
Load/save a reference to a town.
Definition saveload.h:609
@ REF_CARGO_PACKET
Load/save a reference to a cargo packet.
Definition saveload.h:613
@ REF_STORAGE
Load/save a reference to a persistent storage.
Definition saveload.h:615
@ REF_VEHICLE
Load/save a reference to a vehicle.
Definition saveload.h:607
@ REF_ROADSTOPS
Load/save a reference to a bus/truck stop.
Definition saveload.h:611
#define SLEG_CONDREFLIST(name, variable, type, from, to)
Storage of a global reference list in some savegame versions.
Definition saveload.h:1164
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:517
#define SLE_SAVEBYTE(base, variable)
Only write byte during saving; never read it during loading.
Definition saveload.h:1088
#define SLE_REF(base, variable, type)
Storage of a reference in every version of a savegame.
Definition saveload.h:1024
#define SLE_CONDREFLIST(base, variable, type, from, to)
Storage of a list of SL_REF elements in some savegame versions.
Definition saveload.h:959
#define SLE_REFLIST(base, variable, type)
Storage of a list of SL_REF elements in every savegame version.
Definition saveload.h:1068
std::span< const struct SaveLoadCompat > SaveLoadCompatTable
A table of SaveLoadCompat entries.
Definition saveload.h:523
#define SLEG_STRUCT(name, handler)
Storage of a structs in every savegame version.
Definition saveload.h:1223
#define SLE_CONDSSTR(base, variable, type, from, to)
Storage of a std::string in some savegame versions.
Definition saveload.h:938
#define SLE_CONDVAR(base, variable, type, from, to)
Storage of a variable in some savegame versions.
Definition saveload.h:873
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition saveload.h:1268
#define SLE_SSTR(base, variable, type)
Storage of a std::string in every savegame version.
Definition saveload.h:1051
@ SLV_150
150 20857
Definition saveload.h:223
@ SLV_84
84 11822
Definition saveload.h:143
@ SLV_26
26 4466
Definition saveload.h:74
@ SLV_ROAD_WAYPOINTS
338 PR#12572 Road waypoints
Definition saveload.h:385
@ SLV_103
103 14598
Definition saveload.h:166
@ SLV_44
44 8144
Definition saveload.h:95
@ SLV_6
6.0 1721 6.1 1768
Definition saveload.h:46
@ SLV_181
181 25012
Definition saveload.h:260
@ SLV_EXTEND_CARGOTYPES
199 PR#6802 Extend cargotypes to 64
Definition saveload.h:282
@ SLV_SAVELOAD_LIST_LENGTH
293 PR#9374 Consistency in list length with SL_STRUCT / SL_STRUCTLIST / SL_DEQUE / SL_REFLIST.
Definition saveload.h:331
@ SLV_65
65 10210
Definition saveload.h:121
@ SLV_123
123 16909
Definition saveload.h:190
@ SLV_46
46 8705
Definition saveload.h:98
@ SLV_122
122 16855
Definition saveload.h:189
@ SLV_140
140 19382
Definition saveload.h:211
@ SLV_MULTITILE_DOCKS
216 PR#7380 Multiple docks per station.
Definition saveload.h:303
@ SL_MAX_VERSION
Highest possible saveload version.
Definition saveload.h:404
@ SL_MIN_VERSION
First savegame version.
Definition saveload.h:31
@ SLV_3
3.x lost
Definition saveload.h:36
@ SLV_145
145 20376
Definition saveload.h:217
@ SLV_57
57 9691
Definition saveload.h:111
@ SLV_68
68 10266
Definition saveload.h:124
@ SLV_NEWGRF_ROAD_STOPS
303 PR#10144 NewGRF road stops.
Definition saveload.h:343
@ SLV_2
2.0 0.3.0 2.1 0.3.1, 0.3.2
Definition saveload.h:34
@ SLV_187
187 25899 Linkgraph - restricted flows
Definition saveload.h:267
@ SLV_27
27 4757
Definition saveload.h:75
@ SLV_127
127 17439
Definition saveload.h:195
@ SLV_14
14.0 2441
Definition saveload.h:57
@ SLV_55
55 9638
Definition saveload.h:109
@ SLV_161
161 22567
Definition saveload.h:236
@ SLV_7
7.0 1770
Definition saveload.h:48
@ SLV_124
124 16993
Definition saveload.h:191
@ SLV_183
183 25363 Cargodist
Definition saveload.h:262
@ SLV_31
31 5999
Definition saveload.h:80
@ SLV_EXTEND_ENTITY_MAPPING
311 PR#10672 Extend entity mapping range.
Definition saveload.h:353
@ SLV_ROAD_STOP_TILE_DATA
340 PR#12883 Move storage of road stop tile data, also save for road waypoints.
Definition saveload.h:388
#define SLE_CONDREF(base, variable, type, from, to)
Storage of a reference in some savegame versions.
Definition saveload.h:894
#define SLEG_CONDSTRUCTLIST(name, handler, from, to)
Storage of a list of structs in some savegame versions.
Definition saveload.h:1183
@ CH_READONLY
Chunk is never saved.
Definition saveload.h:464
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition saveload.h:1007
#define SLE_CONDVARNAME(base, variable, name, type, from, to)
Storage of a variable in some savegame versions.
Definition saveload.h:884
void SetRailStationTileFlags(TileIndex tile, const StationSpec *statspec)
Set rail station tile flags for the given tile.
bool IsDriveThroughStopTile(Tile t)
Is tile t a drive through road stop station or waypoint?
StationID GetStationIndex(Tile t)
Get StationID from a tile.
Definition station_map.h:28
bool HasStationTileRail(Tile t)
Has this station tile a rail? In other words, is this station tile a rail station or rail waypoint?
bool IsBuoyTile(Tile t)
Is tile t a buoy tile?
static void UpdateWaypointOrder(Order *o)
Update the buoy orders to be waypoint orders.
void MoveBuoysToWaypoints()
Perform all steps to upgrade from the old station buoys to the new version that uses waypoints.
void AfterLoadRoadStops()
(Re)building of road stop caches after loading a savegame.
static void SwapPackets(GoodsEntry *ge)
Swap the temporary packets with the packets without specific destination in the given goods entry.
Loading of station chunks before table headers were added.
const SaveLoadCompat _station_base_sl_compat[]
Original field order for SlStationBase.
const SaveLoadCompat _roadstop_sl_compat[]
Original field order for _roadstop_desc.
const SaveLoadCompat _station_sl_compat[]
Original field order for _station_desc.
const SaveLoadCompat _station_cargo_sl_compat[]
Original field order for SlStationCargo.
const SaveLoadCompat _station_goods_sl_compat[]
Original field order for SlStationGoods.
const SaveLoadCompat _station_flow_sl_compat[]
Original field order for SlStationFlow.
const SaveLoadCompat _station_waypoint_sl_compat[]
Original field order for SlStationWaypoint.
const SaveLoadCompat _station_normal_sl_compat[]
Original field order for SlStationNormal.
const SaveLoadCompat _old_station_sl_compat[]
Original field order for _old_station_desc.
const SaveLoadCompat _station_spec_list_sl_compat[]
Original field order for SlStationSpecList.
@ HVOT_WAYPOINT
Station is a waypoint (NewGRF only!)
@ Dock
Station with a dock.
@ Waypoint
Station is a waypoint.
@ Train
Station with train station.
@ Airport
Station with an airport.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
PersistentStorage * psa
Persistent storage for NewGRF airports.
Base class for all station-ish types.
StringID string_id
Default name (town area) of station.
StationFacilities facilities
The facilities that this station has.
TileArea train_station
Tile area the train 'station' part covers.
Owner owner
The owner of this station.
uint8_t delete_ctr
Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is ...
StationRect rect
NOSAVE: Station spread out rectangle maintained by StationRect::xxx() functions.
Town * town
The town this station is associated with.
std::vector< RoadStopTileData > custom_roadstop_tile_data
List of custom road stop tile data.
TimerGameCalendar::Date build_date
Date of construction.
std::string name
Custom name.
Container for cargo from the same location and time.
Definition cargopacket.h:41
Handlers and description of chunk.
Definition saveload.h:468
FlowStatMap flows
Planned flows through this station.
StationCargoList cargo
The cargo packets of cargo waiting in this station.
Stores station stats for a single cargo.
debug_inline const GoodsEntryData & GetData() const
Get optional cargo packet/flow data.
uint8_t status
Status of this cargo, see GoodsEntryStatus.
@ GES_ACCEPTANCE
Set when the station accepts the cargo currently for final deliveries.
@ GES_RATING
This indicates whether a cargo has a rating at the station.
GoodsEntryData & GetOrCreateData()
Get optional cargo packet/flow data.
debug_inline bool HasData() const
Test if this goods entry has optional cargo packet/flow data.
Size related data of the map.
Definition map_func.h:206
Shared order list linking together the linked list of orders and the list of vehicles sharing this or...
Definition order_base.h:258
DestinationID GetDestination() const
Gets the destination of this order.
Definition order_base.h:103
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition order_base.h:70
void MakeGoToWaypoint(StationID destination)
Makes this order a Go To Waypoint order.
Order * next
Pointer to next order. If nullptr, end of list.
Definition order_base.h:59
Represents the covered area of e.g.
void Add(TileIndex to_add)
Add a single tile to a tile area; enlarge if needed.
Definition tilearea.cpp:43
Class for persistent storage of data.
StorageType storage
Memory for the storage array.
Class for pooled persistent storage of data.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Tindex index
Index of this pool item.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
void FixPointers() const override
Fix the pointers.
void Load() const override
Load the chunk.
void Save() const override
Save the chunk.
Road stop specification.
A Stop for a Road Vehicle.
@ RSSFB_BASE_ENTRY
Non-zero when the entries on this road stop are the primary, i.e. the ones to delete.
void FixPointers() const override
Fix the pointers.
void Save() const override
Save the chunk.
void Load() const override
Load the chunk.
void Load() const override
Load the chunk.
void FixPointers() const override
Fix the pointers.
SaveLoad type struct.
Definition saveload.h:722
static bool IsExpected(const BaseStation *st)
Helper for checking whether the given station is of this type.
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
static Station * Get(auto index)
Gets station with given index.
static Station * From(BaseStation *st)
Converts a BaseStation to SpecializedStation with type checking.
Station specification.
Station data structure.
RoadStop * bus_stops
All the road stops.
std::array< GoodsEntry, NUM_CARGO > goods
Goods at this station.
TileArea bus_station
Tile area the bus 'station' part covers.
Airport airport
Tile area the airport covers.
TileArea truck_station
Tile area the truck 'station' part covers.
RoadStop * truck_stops
All the truck stops.
Town data structure.
Definition town.h:52
std::string name
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition town.h:61
Vehicle data structure.
Representation of a waypoint.
uint16_t town_cn
The N-1th waypoint for this town (consecutive number)
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition tile_map.h:178
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
VehicleType
Available vehicle types.
@ VEH_SHIP
Ship vehicle type.
@ VEH_TRAIN
Train vehicle type.