OpenTTD Source: src/newgrf.cpp Source File

OpenTTD Source 15.3

newgrf.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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "stdafx.h"
11#include "core/backup_type.hpp"
12#include "core/container_func.hpp"
13#include "company_manager_face.h"
14#include "debug.h"
15#include "fileio_func.h"
16#include "engine_func.h"
17#include "engine_base.h"
18#include "bridge.h"
19#include "town.h"
20#include "newgrf_engine.h"
21#include "newgrf_text.h"
22#include "spritecache.h"
23#include "currency.h"
24#include "landscape.h"
25#include "newgrf_badge.h"
26#include "newgrf_badge_config.h"
27#include "newgrf_cargo.h"
28#include "newgrf_sound.h"
29#include "newgrf_station.h"
30#include "industrytype.h"
31#include "newgrf_canal.h"
32#include "newgrf_townname.h"
33#include "newgrf_industries.h"
34#include "newgrf_airporttiles.h"
35#include "newgrf_airport.h"
36#include "newgrf_object.h"
37#include "network/core/config.h"
38#include "smallmap_gui.h"
39#include "genworld.h"
40#include "error_func.h"
41#include "vehicle_base.h"
42#include "road.h"
43#include "newgrf_roadstop.h"
44#include "newgrf/newgrf_bytereader.h"
45#include "newgrf/newgrf_internal_vehicle.h"
46#include "newgrf/newgrf_internal.h"
47#include "newgrf/newgrf_stringmapping.h"
48
49#include "table/strings.h"
50
51#include "safeguards.h"
52
53/* TTDPatch extended GRF format codec
54 * (c) Petr Baudis 2004 (GPL'd)
55 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
56 *
57 * Contains portions of documentation by TTDPatch team.
58 * Thanks especially to Josef Drexler for the documentation as well as a lot
59 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
60 * served as subject to the initial testing of this codec. */
61
63 static std::vector<GRFFile> _grf_files;
64
65std::span<const GRFFile> GetAllGRFFiles()
66{
67 return _grf_files;
68}
69
71 GrfMiscBits _misc_grf_features{};
72
74 GRFLoadedFeatures _loaded_newgrf_features;
75
76 GrfProcessingState _cur_gps;
77
78 TypedIndexContainer<std::vector<GRFTempEngineData>, EngineID> _gted;
79
90 void GrfMsgI(int severity, const std::string &msg)
91{
92 if (_cur_gps.grfconfig == nullptr) {
93 Debug(grf, severity, "{}", msg);
94 } else {
95 Debug(grf, severity, "[{}:{}] {}", _cur_gps.grfconfig->filename, _cur_gps.nfo_line, msg);
96 }
97}
98
104 GRFFile *GetFileByGRFID(uint32_t grfid)
105{
106 auto it = std::ranges::find(_grf_files, grfid, &GRFFile::grfid);
107 if (it != std::end(_grf_files)) return &*it;
108 return nullptr;
109}
110
116 static GRFFile *GetFileByFilename(const std::string &filename)
117{
118 auto it = std::ranges::find(_grf_files, filename, &GRFFile::filename);
119 if (it != std::end(_grf_files)) return &*it;
120 return nullptr;
121}
122
124 static void ClearTemporaryNewGRFData(GRFFile *gf)
125{
126 gf->labels.clear();
127}
128
135 GRFError *DisableGrf(StringID message, GRFConfig *config)
136{
137 GRFFile *file;
138 if (config != nullptr) {
139 file = GetFileByGRFID(config->ident.grfid);
140 } else {
141 config = _cur_gps.grfconfig;
142 file = _cur_gps.grffile;
143 }
144
145 config->status = GCS_DISABLED;
146 if (file != nullptr) ClearTemporaryNewGRFData(file);
147 if (config == _cur_gps.grfconfig) _cur_gps.skip_sprites = -1;
148
149 if (message == STR_NULL) return nullptr;
150
151 auto it = std::ranges::find(config->errors, _cur_gps.nfo_line, &GRFError::nfo_line);
152 if (it == std::end(config->errors)) {
153 it = config->errors.emplace(it, STR_NEWGRF_ERROR_MSG_FATAL, _cur_gps.nfo_line, message);
154 }
155 if (config == _cur_gps.grfconfig) it->param_value[0] = _cur_gps.nfo_line;
156 return &*it;
157}
158
168 void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig &c)
169{
170 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, &c);
171 error->data = _cur_gps.grfconfig->GetName();
172}
173
174static std::map<uint32_t, uint32_t> _grf_id_overrides;
175
181 void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
182{
183 if (target_grfid == 0) {
184 _grf_id_overrides.erase(source_grfid);
185 GrfMsg(5, "SetNewGRFOverride: Removed override of 0x{:X}", std::byteswap(source_grfid));
186 } else {
187 _grf_id_overrides[source_grfid] = target_grfid;
188 GrfMsg(5, "SetNewGRFOverride: Added override of 0x{:X} to 0x{:X}", std::byteswap(source_grfid), std::byteswap(target_grfid));
189 }
190}
191
196 GRFFile *GetCurrentGRFOverride()
197{
198 auto found = _grf_id_overrides.find(_cur_gps.grffile->grfid);
199 if (found != std::end(_grf_id_overrides)) {
200 GRFFile *grffile = GetFileByGRFID(found->second);
201 if (grffile != nullptr) return grffile;
202 }
203 return nullptr;
204}
205
214 Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16_t internal_id, bool static_access)
215{
216 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
217 * them use the same engine slots. */
218 uint32_t scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
219 if (_settings_game.vehicle.dynamic_engines) {
220 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
221 scope_grfid = file->grfid;
222 if (auto it = _grf_id_overrides.find(file->grfid); it != std::end(_grf_id_overrides)) {
223 scope_grfid = it->second;
224 const GRFFile *grf_match = GetFileByGRFID(scope_grfid);
225 if (grf_match == nullptr) {
226 GrfMsg(5, "Tried mapping from GRFID {:x} to {:x} but target is not loaded", std::byteswap(file->grfid), std::byteswap(scope_grfid));
227 } else {
228 GrfMsg(5, "Mapping from GRFID {:x} to {:x}", std::byteswap(file->grfid), std::byteswap(scope_grfid));
229 }
230 }
231
232 /* Check if the engine is registered in the override manager */
233 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
234 if (engine != EngineID::Invalid()) {
235 Engine *e = Engine::Get(engine);
236 if (!e->grf_prop.HasGrfFile()) {
237 e->grf_prop.SetGRFFile(file);
238 }
239 return e;
240 }
241 }
242
243 /* Check if there is an unreserved slot */
244 EngineID engine = _engine_mngr.UseUnreservedID(type, internal_id, scope_grfid, static_access);
245 if (engine != EngineID::Invalid()) {
246 Engine *e = Engine::Get(engine);
247
248 if (!e->grf_prop.HasGrfFile()) {
249 e->grf_prop.SetGRFFile(file);
250 GrfMsg(5, "Replaced engine at index {} for GRFID {:x}, type {}, index {}", e->index, std::byteswap(file->grfid), type, internal_id);
251 }
252
253 return e;
254 }
255
256 if (static_access) return nullptr;
257
258 if (!Engine::CanAllocateItem()) {
259 GrfMsg(0, "Can't allocate any more engines");
260 return nullptr;
261 }
262
263 size_t engine_pool_size = Engine::GetPoolSize();
264
265 /* ... it's not, so create a new one based off an existing engine */
266 Engine *e = new Engine(type, internal_id);
267 e->grf_prop.SetGRFFile(file);
268
269 /* Reserve the engine slot */
270 _engine_mngr.SetID(type, internal_id, scope_grfid, std::min<uint8_t>(internal_id, _engine_counts[type]), e->index);
271
272 if (engine_pool_size != Engine::GetPoolSize()) {
273 /* Resize temporary engine data ... */
274 _gted.resize(Engine::GetPoolSize());
275 }
276 if (type == VEH_TRAIN) {
277 _gted[e->index].railtypelabels.clear();
278 for (RailType rt : e->VehInfo<RailVehicleInfo>().railtypes) _gted[e->index].railtypelabels.push_back(GetRailTypeInfo(rt)->label);
279 }
280
281 GrfMsg(5, "Created new engine at index {} for GRFID {:x}, type {}, index {}", e->index, std::byteswap(file->grfid), type, internal_id);
282
283 return e;
284}
285
296 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal_id)
297{
298 uint32_t scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
299 if (_settings_game.vehicle.dynamic_engines) {
300 scope_grfid = file->grfid;
301 if (auto it = _grf_id_overrides.find(file->grfid); it != std::end(_grf_id_overrides)) {
302 scope_grfid = it->second;
303 }
304 }
305
306 return _engine_mngr.GetID(type, internal_id, scope_grfid);
307}
308
309
310
311
315CargoTypes TranslateRefitMask(uint32_t refit_mask)
316{
317 CargoTypes result = 0;
318 for (uint8_t bit : SetBitIterator(refit_mask)) {
319 CargoType cargo = GetCargoTranslation(bit, _cur_gps.grffile, true);
320 if (IsValidCargoType(cargo)) SetBit(result, cargo);
321 }
322 return result;
323}
324
332 void ConvertTTDBasePrice(uint32_t base_pointer, std::string_view error_location, Price *index)
333{
334 /* Special value for 'none' */
335 if (base_pointer == 0) {
336 *index = INVALID_PRICE;
337 return;
338 }
339
340 static const uint32_t start = 0x4B34;
341 static const uint32_t size = 6;
342
343 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
344 GrfMsg(1, "{}: Unsupported running cost base 0x{:04X}, ignoring", error_location, base_pointer);
345 return;
346 }
347
348 *index = (Price)((base_pointer - start) / size);
349}
350
357/* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32_t grfid, uint8_t language_id)
358{
359 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
360 const GRFFile *grffile = GetFileByGRFID(grfid);
361 if (grffile == nullptr) return nullptr;
362
363 auto it = grffile->language_map.find(language_id);
364 if (it == std::end(grffile->language_map)) return nullptr;
365
366 return &it->second;
367}
368
373 void GRFUnsafe(ByteReader &)
374{
375 _cur_gps.grfconfig->flags.Set(GRFConfigFlag::Unsafe);
376
377 /* Skip remainder of GRF */
378 _cur_gps.skip_sprites = -1;
379}
380
382 static void ResetNewGRF()
383{
384 _cur_gps.grfconfig = nullptr;
385 _cur_gps.grffile = nullptr;
386 _grf_files.clear();
387
388 /* We store pointers to GRFFiles in many places, so need to ensure that the pointers do not become invalid
389 * due to vector reallocation. Should not happen due to loading taking place in multiple stages, but
390 * reserving when the size is known is good practice anyway. */
391 _grf_files.reserve(_grfconfig.size());
392}
393
395 static void ResetNewGRFErrors()
396{
397 for (const auto &c : _grfconfig) {
398 c->errors.clear();
399 }
400}
401
402extern void ResetCallbacks(bool final);
403extern void ResetGRM();
404
408 void ResetNewGRFData()
409{
410 CleanUpStrings();
411 CleanUpGRFTownNames();
412
413 ResetBadges();
414
415 /* Copy/reset original engine info data */
416 SetupEngines();
417
418 /* Copy/reset original bridge info data */
419 ResetBridges();
420
421 /* Reset rail type information */
422 ResetRailTypes();
423
424 /* Copy/reset original road type info data */
425 ResetRoadTypes();
426
427 /* Allocate temporary refit/cargo class data */
428 _gted.resize(Engine::GetPoolSize());
429
430 /* Fill rail type label temporary data for default trains */
431 for (const Engine *e : Engine::IterateType(VEH_TRAIN)) {
432 _gted[e->index].railtypelabels.clear();
433 for (RailType rt : e->VehInfo<RailVehicleInfo>().railtypes) _gted[e->index].railtypelabels.push_back(GetRailTypeInfo(rt)->label);
434 }
435
436 /* Reset GRM reservations */
437 ResetGRM();
438
439 /* Reset generic feature callback lists */
440 ResetGenericCallbacks();
441
442 /* Reset price base data */
443 ResetPriceBaseMultipliers();
444
445 /* Reset the curencies array */
446 ResetCurrencies();
447
448 /* Reset the house array */
449 ResetHouses();
450
451 /* Reset the industries structures*/
452 ResetIndustries();
453
454 /* Reset the objects. */
455 ObjectClass::Reset();
456 ResetObjects();
457
458 /* Reset station classes */
459 StationClass::Reset();
460
461 /* Reset airport-related structures */
462 AirportClass::Reset();
463 AirportSpec::ResetAirports();
464 AirportTileSpec::ResetAirportTiles();
465
466 /* Reset road stop classes */
467 RoadStopClass::Reset();
468
469 /* Reset canal sprite groups and flags */
470 _water_feature.fill({});
471
472 ResetFaces();
473
474 /* Reset the snowline table. */
475 ClearSnowLine();
476
477 /* Reset NewGRF files */
478 ResetNewGRF();
479
480 /* Reset NewGRF errors. */
481 ResetNewGRFErrors();
482
483 /* Set up the default cargo types */
484 SetupCargoForClimate(_settings_game.game_creation.landscape);
485
486 /* Reset misc GRF features and train list display variables */
487 _misc_grf_features = {};
488
489 _loaded_newgrf_features.has_2CC = false;
490 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
491 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
492 _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_NONE;
493
494 /* Clear all GRF overrides */
495 _grf_id_overrides.clear();
496
497 InitializeSoundPool();
498 _spritegroup_pool.CleanPool();
499 ResetCallbacks(false);
500}
501
505 void ResetPersistentNewGRFData()
506{
507 /* Reset override managers */
508 _engine_mngr.ResetToDefaultMapping();
509 _house_mngr.ResetMapping();
510 _industry_mngr.ResetMapping();
511 _industile_mngr.ResetMapping();
512 _airport_mngr.ResetMapping();
513 _airporttile_mngr.ResetMapping();
514}
515
521 std::span<const CargoLabel> GetCargoTranslationTable(const GRFFile &grffile)
522 {
523 /* Always use the translation table if it's installed. */
524 if (!grffile.cargo_list.empty()) return grffile.cargo_list;
525
526 /* Pre-v7 use climate-dependent "slot" table. */
527 if (grffile.grf_version < 7) return GetClimateDependentCargoTranslationTable();
528
529 /* Otherwise use climate-independent "bitnum" table. */
530 return GetClimateIndependentCargoTranslationTable();
531 }
532
537 static void BuildCargoTranslationMap()
538{
539 _cur_gps.grffile->cargo_map.fill(UINT8_MAX);
540
541 auto cargo_list = GetCargoTranslationTable(*_cur_gps.grffile);
542
543 for (const CargoSpec *cs : CargoSpec::Iterate()) {
544 /* Check the translation table for this cargo's label */
545 int idx = find_index(cargo_list, cs->label);
546 if (idx >= 0) _cur_gps.grffile->cargo_map[cs->Index()] = idx;
547 }
548}
549
554 static void InitNewGRFFile(const GRFConfig &config)
555{
556 GRFFile *newfile = GetFileByFilename(config.filename);
557 if (newfile != nullptr) {
558 /* We already loaded it once. */
559 _cur_gps.grffile = newfile;
560 return;
561 }
562
563 assert(_grf_files.size() < _grf_files.capacity()); // We must not invalidate pointers.
564 _cur_gps.grffile = &_grf_files.emplace_back(config);
565}
566
571GRFFile::GRFFile(const GRFConfig &config)
572{
573 this->filename = config.filename;
574 this->grfid = config.ident.grfid;
575
576 /* Initialise local settings to defaults */
577 this->traininfo_vehicle_pitch = 0;
578 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
579
580 /* Mark price_base_multipliers as 'not set' */
581 this->price_base_multipliers.fill(INVALID_PRICE_MODIFIER);
582
583 /* Initialise rail type map with default rail types */
584 this->railtype_map.fill(INVALID_RAILTYPE);
585 this->railtype_map[0] = RAILTYPE_RAIL;
586 this->railtype_map[1] = RAILTYPE_ELECTRIC;
587 this->railtype_map[2] = RAILTYPE_MONO;
588 this->railtype_map[3] = RAILTYPE_MAGLEV;
589
590 /* Initialise road type map with default road types */
591 this->roadtype_map.fill(INVALID_ROADTYPE);
592 this->roadtype_map[0] = ROADTYPE_ROAD;
593
594 /* Initialise tram type map with default tram types */
595 this->tramtype_map.fill(INVALID_ROADTYPE);
596 this->tramtype_map[0] = ROADTYPE_TRAM;
597
598 /* Copy the initial parameter list */
599 this->param = config.param;
600}
601
602/* Some compilers get confused about vectors of unique_ptrs. */
603GRFFile::GRFFile() = default;
604GRFFile::GRFFile(GRFFile &&other) = default;
605GRFFile::~GRFFile() = default;
606
612 static CargoLabel GetActiveCargoLabel(const std::initializer_list<CargoLabel> &labels)
613{
614 for (const CargoLabel &label : labels) {
615 CargoType cargo_type = GetCargoTypeByLabel(label);
616 if (cargo_type != INVALID_CARGO) return label;
617 }
618 return CT_INVALID;
619}
620
626 static CargoLabel GetActiveCargoLabel(const std::variant<CargoLabel, MixedCargoType> &label)
627{
628 struct visitor {
629 CargoLabel operator()(const CargoLabel &label) { return label; }
630 CargoLabel operator()(const MixedCargoType &mixed)
631 {
632 switch (mixed) {
633 case MCT_LIVESTOCK_FRUIT: return GetActiveCargoLabel({CT_LIVESTOCK, CT_FRUIT});
634 case MCT_GRAIN_WHEAT_MAIZE: return GetActiveCargoLabel({CT_GRAIN, CT_WHEAT, CT_MAIZE});
635 case MCT_VALUABLES_GOLD_DIAMONDS: return GetActiveCargoLabel({CT_VALUABLES, CT_GOLD, CT_DIAMONDS});
636 default: NOT_REACHED();
637 }
638 }
639 };
640
641 return std::visit(visitor{}, label);
642}
643
647 static void CalculateRefitMasks()
648{
649 CargoTypes original_known_cargoes = 0;
650 for (CargoType cargo_type = 0; cargo_type != NUM_CARGO; ++cargo_type) {
651 if (IsDefaultCargo(cargo_type)) SetBit(original_known_cargoes, cargo_type);
652 }
653
654 for (Engine *e : Engine::Iterate()) {
655 EngineID engine = e->index;
656 EngineInfo *ei = &e->info;
657 bool only_defaultcargo;
658
659 /* Apply default cargo translation map if cargo type hasn't been set, either explicitly or by aircraft cargo handling. */
660 if (!IsValidCargoType(e->info.cargo_type)) {
661 e->info.cargo_type = GetCargoTypeByLabel(GetActiveCargoLabel(e->info.cargo_label));
662 }
663
664 /* If the NewGRF did not set any cargo properties, we apply default values. */
665 if (_gted[engine].defaultcargo_grf == nullptr) {
666 /* If the vehicle has any capacity, apply the default refit masks */
667 if (e->type != VEH_TRAIN || e->VehInfo<RailVehicleInfo>().capacity != 0) {
668 static constexpr LandscapeType T = LandscapeType::Temperate;
669 static constexpr LandscapeType A = LandscapeType::Arctic;
670 static constexpr LandscapeType S = LandscapeType::Tropic;
671 static constexpr LandscapeType Y = LandscapeType::Toyland;
672 static const struct DefaultRefitMasks {
673 LandscapeTypes climate;
674 CargoLabel cargo_label;
675 CargoClasses cargo_allowed;
676 CargoClasses cargo_disallowed;
677 } _default_refit_masks[] = {
678 {{T, A, S, Y}, CT_PASSENGERS, {CargoClass::Passengers}, {}},
679 {{T, A, S }, CT_MAIL, {CargoClass::Mail}, {}},
680 {{T, A, S }, CT_VALUABLES, {CargoClass::Armoured}, {CargoClass::Liquid}},
681 {{ Y}, CT_MAIL, {CargoClass::Mail, CargoClass::Armoured}, {CargoClass::Liquid}},
682 {{T, A }, CT_COAL, {CargoClass::Bulk}, {}},
683 {{ S }, CT_COPPER_ORE, {CargoClass::Bulk}, {}},
684 {{ Y}, CT_SUGAR, {CargoClass::Bulk}, {}},
685 {{T, A, S }, CT_OIL, {CargoClass::Liquid}, {}},
686 {{ Y}, CT_COLA, {CargoClass::Liquid}, {}},
687 {{T }, CT_GOODS, {CargoClass::PieceGoods, CargoClass::Express}, {CargoClass::Liquid, CargoClass::Passengers}},
688 {{ A, S }, CT_GOODS, {CargoClass::PieceGoods, CargoClass::Express}, {CargoClass::Liquid, CargoClass::Passengers, CargoClass::Refrigerated}},
689 {{ A, S }, CT_FOOD, {CargoClass::Refrigerated}, {}},
690 {{ Y}, CT_CANDY, {CargoClass::PieceGoods, CargoClass::Express}, {CargoClass::Liquid, CargoClass::Passengers}},
691 };
692
693 if (e->type == VEH_AIRCRAFT) {
694 /* Aircraft default to "light" cargoes */
695 _gted[engine].cargo_allowed = {CargoClass::Passengers, CargoClass::Mail, CargoClass::Armoured, CargoClass::Express};
696 _gted[engine].cargo_disallowed = {CargoClass::Liquid};
697 } else if (e->type == VEH_SHIP) {
698 CargoLabel label = GetActiveCargoLabel(ei->cargo_label);
699 switch (label.base()) {
700 case CT_PASSENGERS.base():
701 /* Ferries */
702 _gted[engine].cargo_allowed = {CargoClass::Passengers};
703 _gted[engine].cargo_disallowed = {};
704 break;
705 case CT_OIL.base():
706 /* Tankers */
707 _gted[engine].cargo_allowed = {CargoClass::Liquid};
708 _gted[engine].cargo_disallowed = {};
709 break;
710 default:
711 /* Cargo ships */
712 if (_settings_game.game_creation.landscape == LandscapeType::Toyland) {
713 /* No tanker in toyland :( */
714 _gted[engine].cargo_allowed = {CargoClass::Mail, CargoClass::Armoured, CargoClass::Express, CargoClass::Bulk, CargoClass::PieceGoods, CargoClass::Liquid};
715 _gted[engine].cargo_disallowed = {CargoClass::Passengers};
716 } else {
717 _gted[engine].cargo_allowed = {CargoClass::Mail, CargoClass::Armoured, CargoClass::Express, CargoClass::Bulk, CargoClass::PieceGoods};
718 _gted[engine].cargo_disallowed = {CargoClass::Liquid, CargoClass::Passengers};
719 }
720 break;
721 }
722 e->VehInfo<ShipVehicleInfo>().old_refittable = true;
723 } else if (e->type == VEH_TRAIN && e->VehInfo<RailVehicleInfo>().railveh_type != RAILVEH_WAGON) {
724 /* Train engines default to all cargoes, so you can build single-cargo consists with fast engines.
725 * Trains loading multiple cargoes may start stations accepting unwanted cargoes. */
726 _gted[engine].cargo_allowed = {CargoClass::Passengers, CargoClass::Mail, CargoClass::Armoured, CargoClass::Express, CargoClass::Bulk, CargoClass::PieceGoods, CargoClass::Liquid};
727 _gted[engine].cargo_disallowed = {};
728 } else {
729 /* Train wagons and road vehicles are classified by their default cargo type */
730 CargoLabel label = GetActiveCargoLabel(ei->cargo_label);
731 for (const auto &drm : _default_refit_masks) {
732 if (!drm.climate.Test(_settings_game.game_creation.landscape)) continue;
733 if (drm.cargo_label != label) continue;
734
735 _gted[engine].cargo_allowed = drm.cargo_allowed;
736 _gted[engine].cargo_disallowed = drm.cargo_disallowed;
737 break;
738 }
739
740 /* All original cargoes have specialised vehicles, so exclude them */
741 _gted[engine].ctt_exclude_mask = original_known_cargoes;
742 }
743 }
744 _gted[engine].UpdateRefittability(_gted[engine].cargo_allowed.Any());
745
746 if (IsValidCargoType(ei->cargo_type)) ClrBit(_gted[engine].ctt_exclude_mask, ei->cargo_type);
747 }
748
749 /* Compute refittability */
750 {
751 CargoTypes mask = 0;
752 CargoTypes not_mask = 0;
753 CargoTypes xor_mask = ei->refit_mask;
754
755 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
756 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
757 only_defaultcargo = _gted[engine].refittability != GRFTempEngineData::NONEMPTY;
758
759 if (_gted[engine].cargo_allowed.Any()) {
760 /* Build up the list of cargo types from the set cargo classes. */
761 for (const CargoSpec *cs : CargoSpec::Iterate()) {
762 if (cs->classes.Any(_gted[engine].cargo_allowed) && cs->classes.All(_gted[engine].cargo_allowed_required)) SetBit(mask, cs->Index());
763 if (cs->classes.Any(_gted[engine].cargo_disallowed)) SetBit(not_mask, cs->Index());
764 }
765 }
766
767 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
768
769 /* Apply explicit refit includes/excludes. */
770 ei->refit_mask |= _gted[engine].ctt_include_mask;
771 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
772
773 /* Custom refit mask callback. */
774 const GRFFile *file = _gted[e->index].defaultcargo_grf;
775 if (file == nullptr) file = e->GetGRF();
776 if (file != nullptr && e->info.callback_mask.Test(VehicleCallbackMask::CustomRefit)) {
777 for (const CargoSpec *cs : CargoSpec::Iterate()) {
778 uint8_t local_slot = file->cargo_map[cs->Index()];
779 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_CUSTOM_REFIT, cs->classes.base(), local_slot, engine, nullptr);
780 switch (callback) {
781 case CALLBACK_FAILED:
782 case 0:
783 break; // Do nothing.
784 case 1: SetBit(ei->refit_mask, cs->Index()); break;
785 case 2: ClrBit(ei->refit_mask, cs->Index()); break;
786
787 default: ErrorUnknownCallbackResult(file->grfid, CBID_VEHICLE_CUSTOM_REFIT, callback);
788 }
789 }
790 }
791 }
792
793 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
794 if (IsValidCargoType(ei->cargo_type) && !HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = INVALID_CARGO;
795
796 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
797 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
798 if (!only_defaultcargo && (e->type != VEH_SHIP || e->VehInfo<ShipVehicleInfo>().old_refittable) && IsValidCargoType(ei->cargo_type) && !HasBit(ei->refit_mask, ei->cargo_type)) {
799 ei->cargo_type = INVALID_CARGO;
800 }
801
802 /* Check if this engine's cargo type is valid. If not, set to the first refittable
803 * cargo type. Finally disable the vehicle, if there is still no cargo. */
804 if (!IsValidCargoType(ei->cargo_type) && ei->refit_mask != 0) {
805 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
806 const GRFFile *file = _gted[engine].defaultcargo_grf;
807 if (file == nullptr) file = e->GetGRF();
808 if (file != nullptr && file->grf_version >= 8 && !file->cargo_list.empty()) {
809 /* Use first refittable cargo from cargo translation table */
810 uint8_t best_local_slot = UINT8_MAX;
811 for (CargoType cargo_type : SetCargoBitIterator(ei->refit_mask)) {
812 uint8_t local_slot = file->cargo_map[cargo_type];
813 if (local_slot < best_local_slot) {
814 best_local_slot = local_slot;
815 ei->cargo_type = cargo_type;
816 }
817 }
818 }
819
820 if (!IsValidCargoType(ei->cargo_type)) {
821 /* Use first refittable cargo slot */
822 ei->cargo_type = (CargoType)FindFirstBit(ei->refit_mask);
823 }
824 }
825 if (!IsValidCargoType(ei->cargo_type) && e->type == VEH_TRAIN && e->VehInfo<RailVehicleInfo>().railveh_type != RAILVEH_WAGON && e->VehInfo<RailVehicleInfo>().capacity == 0) {
826 /* For train engines which do not carry cargo it does not matter if their cargo type is invalid.
827 * Fallback to the first available instead, if the cargo type has not been changed (as indicated by
828 * cargo_label not being CT_INVALID). */
829 if (GetActiveCargoLabel(ei->cargo_label) != CT_INVALID) {
830 ei->cargo_type = static_cast<CargoType>(FindFirstBit(_standard_cargo_mask));
831 }
832 }
833 if (!IsValidCargoType(ei->cargo_type)) ei->climates = {};
834
835 /* Clear refit_mask for not refittable ships */
836 if (e->type == VEH_SHIP && !e->VehInfo<ShipVehicleInfo>().old_refittable) {
837 ei->refit_mask = 0;
838 }
839 }
840}
841
843 static void FinaliseCanals()
844{
845 for (uint i = 0; i < CF_END; i++) {
846 if (_water_feature[i].grffile != nullptr) {
847 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
848 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
849 }
850 }
851}
852
854 static void FinaliseEngineArray()
855{
856 for (Engine *e : Engine::Iterate()) {
857 if (e->GetGRF() == nullptr) {
858 auto found = std::ranges::find(_engine_mngr.mappings[e->type], e->index, &EngineIDMapping::engine);
859 if (found == std::end(_engine_mngr.mappings[e->type]) || found->grfid != INVALID_GRFID || found->internal_id != found->substitute_id) {
860 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
861 }
862 }
863
864 /* Do final mapping on variant engine ID. */
865 if (e->info.variant_id != EngineID::Invalid()) {
866 e->info.variant_id = GetNewEngineID(e->grf_prop.grffile, e->type, e->info.variant_id.base());
867 }
868
869 if (!e->info.climates.Test(_settings_game.game_creation.landscape)) continue;
870
871 switch (e->type) {
872 case VEH_TRAIN:
873 for (RailType rt : e->VehInfo<RailVehicleInfo>().railtypes) {
874 AppendCopyableBadgeList(e->badges, GetRailTypeInfo(rt)->badges, GSF_TRAINS);
875 }
876 break;
877 case VEH_ROAD: AppendCopyableBadgeList(e->badges, GetRoadTypeInfo(e->VehInfo<RoadVehicleInfo>().roadtype)->badges, GSF_ROADVEHICLES); break;
878 default: break;
879 }
880
881 /* Skip wagons, there livery is defined via the engine */
882 if (e->type != VEH_TRAIN || e->VehInfo<RailVehicleInfo>().railveh_type != RAILVEH_WAGON) {
883 LiveryScheme ls = GetEngineLiveryScheme(e->index, EngineID::Invalid(), nullptr);
884 SetBit(_loaded_newgrf_features.used_liveries, ls);
885 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
886
887 if (e->type == VEH_TRAIN) {
888 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
889 switch (ls) {
890 case LS_STEAM:
891 case LS_DIESEL:
892 case LS_ELECTRIC:
893 case LS_MONORAIL:
894 case LS_MAGLEV:
895 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
896 break;
897
898 case LS_DMU:
899 case LS_EMU:
900 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
901 break;
902
903 default: NOT_REACHED();
904 }
905 }
906 }
907 }
908
909 /* Check engine variants don't point back on themselves (either directly or via a loop) then set appropriate flags
910 * on variant engine. This is performed separately as all variant engines need to have been resolved.
911 * Use Floyd's cycle-detection algorithm to handle the case where a cycle is present but does
912 * not include the starting engine ID. */
913 for (Engine *e : Engine::Iterate()) {
914 EngineID parent = e->info.variant_id;
915 EngineID parent_slow = parent;
916 bool update_slow = false;
917 while (parent != EngineID::Invalid()) {
918 parent = Engine::Get(parent)->info.variant_id;
919 if (update_slow) parent_slow = Engine::Get(parent_slow)->info.variant_id;
920 update_slow = !update_slow;
921 if (parent != e->index && parent != parent_slow) continue;
922
923 /* Engine looped back on itself, so clear the variant. */
924 e->info.variant_id = EngineID::Invalid();
925
926 GrfMsg(1, "FinaliseEngineArray: Variant of engine {:x} in '{}' loops back on itself", e->grf_prop.local_id, e->GetGRF()->filename);
927 break;
928 }
929
930 if (e->info.variant_id != EngineID::Invalid()) {
931 Engine::Get(e->info.variant_id)->display_flags.Set({EngineDisplayFlag::HasVariants, EngineDisplayFlag::IsFolded});
932 }
933 }
934}
935
937 void FinaliseCargoArray()
938{
939 for (CargoSpec &cs : CargoSpec::array) {
940 if (cs.town_production_effect == INVALID_TPE) {
941 /* Set default town production effect by cargo label. */
942 switch (cs.label.base()) {
943 case CT_PASSENGERS.base(): cs.town_production_effect = TPE_PASSENGERS; break;
944 case CT_MAIL.base(): cs.town_production_effect = TPE_MAIL; break;
945 default: cs.town_production_effect = TPE_NONE; break;
946 }
947 }
948 if (!cs.IsValid()) {
949 cs.name = cs.name_single = cs.units_volume = STR_NEWGRF_INVALID_CARGO;
950 cs.quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
951 cs.abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
952 }
953 }
954}
955
967 static bool IsHouseSpecValid(HouseSpec &hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const std::string &filename)
968{
969 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) &&
970 (next1 == nullptr || !next1->enabled || next1->building_flags.Any(BUILDING_HAS_1_TILE))) ||
971 (hs.building_flags.Any(BUILDING_HAS_4_TILES) &&
972 (next2 == nullptr || !next2->enabled || next2->building_flags.Any(BUILDING_HAS_1_TILE) ||
973 next3 == nullptr || !next3->enabled || next3->building_flags.Any(BUILDING_HAS_1_TILE)))) {
974 hs.enabled = false;
975 if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs.grf_prop.local_id);
976 return false;
977 }
978
979 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
980 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
981 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
982 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) && next1->population != 0) ||
983 (hs.building_flags.Any(BUILDING_HAS_4_TILES) && (next2->population != 0 || next3->population != 0))) {
984 hs.enabled = false;
985 if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines multitile house {} with non-zero population on additional tiles. Disabling house.", filename, hs.grf_prop.local_id);
986 return false;
987 }
988
989 /* Substitute type is also used for override, and having an override with a different size causes crashes.
990 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
991 if (!filename.empty() && (hs.building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs.grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
992 hs.enabled = false;
993 Debug(grf, 1, "FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs.grf_prop.local_id);
994 return false;
995 }
996
997 /* Make sure that additional parts of multitile houses are not available. */
998 if (!hs.building_flags.Any(BUILDING_HAS_1_TILE) && hs.building_availability.Any(HZ_ZONE_ALL) && hs.building_availability.Any(HZ_CLIMATE_ALL)) {
999 hs.enabled = false;
1000 if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} without a size but marked it as available. Disabling house.", filename, hs.grf_prop.local_id);
1001 return false;
1002 }
1003
1004 return true;
1005}
1006
1013 static void EnsureEarlyHouse(HouseZones bitmask)
1014{
1015 TimerGameCalendar::Year min_year = CalendarTime::MAX_YEAR;
1016
1017 for (const auto &hs : HouseSpec::Specs()) {
1018 if (!hs.enabled) continue;
1019 if (!hs.building_availability.All(bitmask)) continue;
1020 if (hs.min_year < min_year) min_year = hs.min_year;
1021 }
1022
1023 if (min_year == 0) return;
1024
1025 for (auto &hs : HouseSpec::Specs()) {
1026 if (!hs.enabled) continue;
1027 if (!hs.building_availability.All(bitmask)) continue;
1028 if (hs.min_year == min_year) hs.min_year = CalendarTime::MIN_YEAR;
1029 }
1030}
1031
1038 static void FinaliseHouseArray()
1039{
1040 /* If there are no houses with start dates before 1930, then all houses
1041 * with start dates of 1930 have them reset to 0. This is in order to be
1042 * compatible with TTDPatch, where if no houses have start dates before
1043 * 1930 and the date is before 1930, the game pretends that this is 1930.
1044 * If there have been any houses defined with start dates before 1930 then
1045 * the dates are left alone.
1046 * On the other hand, why 1930? Just 'fix' the houses with the lowest
1047 * minimum introduction date to 0.
1048 */
1049 for (auto &file : _grf_files) {
1050 if (file.housespec.empty()) continue;
1051
1052 size_t num_houses = file.housespec.size();
1053 for (size_t i = 0; i < num_houses; i++) {
1054 auto &hs = file.housespec[i];
1055
1056 if (hs == nullptr) continue;
1057
1058 const HouseSpec *next1 = (i + 1 < num_houses ? file.housespec[i + 1].get() : nullptr);
1059 const HouseSpec *next2 = (i + 2 < num_houses ? file.housespec[i + 2].get() : nullptr);
1060 const HouseSpec *next3 = (i + 3 < num_houses ? file.housespec[i + 3].get() : nullptr);
1061
1062 if (!IsHouseSpecValid(*hs, next1, next2, next3, file.filename)) continue;
1063
1064 _house_mngr.SetEntitySpec(std::move(*hs));
1065 }
1066
1067 /* Won't be used again */
1068 file.housespec.clear();
1069 file.housespec.shrink_to_fit();
1070 }
1071
1072 for (size_t i = 0; i < HouseSpec::Specs().size(); i++) {
1073 HouseSpec *hs = HouseSpec::Get(i);
1074 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr);
1075 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr);
1076 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : nullptr);
1077
1078 /* We need to check all houses again to we are sure that multitile houses
1079 * did get consecutive IDs and none of the parts are missing. */
1080 if (!IsHouseSpecValid(*hs, next1, next2, next3, std::string{})) {
1081 /* GetHouseNorthPart checks 3 houses that are directly before
1082 * it in the house pool. If any of those houses have multi-tile
1083 * flags set it assumes it's part of a multitile house. Since
1084 * we can have invalid houses in the pool marked as disabled, we
1085 * don't want to have them influencing valid tiles. As such set
1086 * building_flags to zero here to make sure any house following
1087 * this one in the pool is properly handled as 1x1 house. */
1088 hs->building_flags = {};
1089 }
1090
1091 /* Apply default cargo translation map for unset cargo slots */
1092 for (uint i = 0; i < lengthof(hs->accepts_cargo_label); ++i) {
1093 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->accepts_cargo[i] = GetCargoTypeByLabel(hs->accepts_cargo_label[i]);
1094 /* Disable acceptance if cargo type is invalid. */
1095 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->cargo_acceptance[i] = 0;
1096 }
1097 }
1098
1099 HouseZones climate_mask = GetClimateMaskForLandscape();
1100 for (HouseZone climate : climate_mask) {
1101 for (HouseZone zone : HZ_ZONE_ALL) {
1102 EnsureEarlyHouse({climate, zone});
1103 }
1104 }
1105}
1106
1112 static void FinaliseIndustriesArray()
1113{
1114 for (auto &file : _grf_files) {
1115 for (auto &indsp : file.industryspec) {
1116 if (indsp == nullptr || !indsp->enabled) continue;
1117
1118 _industry_mngr.SetEntitySpec(std::move(*indsp));
1119 }
1120
1121 for (auto &indtsp : file.indtspec) {
1122 if (indtsp != nullptr) {
1123 _industile_mngr.SetEntitySpec(std::move(*indtsp));
1124 }
1125 }
1126
1127 /* Won't be used again */
1128 file.industryspec.clear();
1129 file.industryspec.shrink_to_fit();
1130 file.indtspec.clear();
1131 file.indtspec.shrink_to_fit();
1132 }
1133
1134 for (auto &indsp : _industry_specs) {
1135 if (indsp.enabled && indsp.grf_prop.HasGrfFile()) {
1136 for (auto &conflicting : indsp.conflicting) {
1137 conflicting = MapNewGRFIndustryType(conflicting, indsp.grf_prop.grfid);
1138 }
1139 }
1140 if (!indsp.enabled) {
1141 indsp.name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
1142 }
1143
1144 /* Apply default cargo translation map for unset cargo slots */
1145 for (size_t i = 0; i < std::size(indsp.produced_cargo_label); ++i) {
1146 if (!IsValidCargoType(indsp.produced_cargo[i])) indsp.produced_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.produced_cargo_label[i]));
1147 }
1148 for (size_t i = 0; i < std::size(indsp.accepts_cargo_label); ++i) {
1149 if (!IsValidCargoType(indsp.accepts_cargo[i])) indsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.accepts_cargo_label[i]));
1150 }
1151 }
1152
1153 for (auto &indtsp : _industry_tile_specs) {
1154 /* Apply default cargo translation map for unset cargo slots */
1155 for (size_t i = 0; i < std::size(indtsp.accepts_cargo_label); ++i) {
1156 if (!IsValidCargoType(indtsp.accepts_cargo[i])) indtsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indtsp.accepts_cargo_label[i]));
1157 }
1158 }
1159}
1160
1166 static void FinaliseObjectsArray()
1167{
1168 for (auto &file : _grf_files) {
1169 for (auto &objectspec : file.objectspec) {
1170 if (objectspec != nullptr && objectspec->grf_prop.HasGrfFile() && objectspec->IsEnabled()) {
1171 _object_mngr.SetEntitySpec(std::move(*objectspec));
1172 }
1173 }
1174
1175 /* Won't be used again */
1176 file.objectspec.clear();
1177 file.objectspec.shrink_to_fit();
1178 }
1179
1180 ObjectSpec::BindToClasses();
1181}
1182
1188 static void FinaliseAirportsArray()
1189{
1190 for (auto &file : _grf_files) {
1191 for (auto &as : file.airportspec) {
1192 if (as != nullptr && as->enabled) {
1193 _airport_mngr.SetEntitySpec(std::move(*as));
1194 }
1195 }
1196
1197 for (auto &ats : file.airtspec) {
1198 if (ats != nullptr && ats->enabled) {
1199 _airporttile_mngr.SetEntitySpec(std::move(*ats));
1200 }
1201 }
1202
1203 /* Won't be used again */
1204 file.airportspec.clear();
1205 file.airportspec.shrink_to_fit();
1206 file.airtspec.clear();
1207 file.airtspec.shrink_to_fit();
1208 }
1209}
1210
1212 struct InvokeGrfActionHandler {
1213 template <uint8_t TAction>
1214 static void Invoke(ByteReader &buf, GrfLoadingStage stage)
1215 {
1216 switch (stage) {
1217 case GLS_FILESCAN: GrfActionHandler<TAction>::FileScan(buf); break;
1218 case GLS_SAFETYSCAN: GrfActionHandler<TAction>::SafetyScan(buf); break;
1219 case GLS_LABELSCAN: GrfActionHandler<TAction>::LabelScan(buf); break;
1220 case GLS_INIT: GrfActionHandler<TAction>::Init(buf); break;
1221 case GLS_RESERVE: GrfActionHandler<TAction>::Reserve(buf); break;
1222 case GLS_ACTIVATION: GrfActionHandler<TAction>::Activation(buf); break;
1223 default: NOT_REACHED();
1224 }
1225 }
1226
1227 using Invoker = void(*)(ByteReader &buf, GrfLoadingStage stage);
1228 static constexpr Invoker funcs[] = { // Must be listed in action order.
1229 Invoke<0x00>, Invoke<0x01>, Invoke<0x02>, Invoke<0x03>, Invoke<0x04>, Invoke<0x05>, Invoke<0x06>, Invoke<0x07>,
1230 Invoke<0x08>, Invoke<0x09>, Invoke<0x0A>, Invoke<0x0B>, Invoke<0x0C>, Invoke<0x0D>, Invoke<0x0E>, Invoke<0x0F>,
1231 Invoke<0x10>, Invoke<0x11>, Invoke<0x12>, Invoke<0x13>, Invoke<0x14>,
1232 };
1233
1234 static void Invoke(uint8_t action, GrfLoadingStage stage, ByteReader &buf)
1235 {
1236 Invoker func = action < std::size(funcs) ? funcs[action] : nullptr;
1237 if (func == nullptr) {
1238 GrfMsg(7, "DecodeSpecialSprite: Skipping unknown action 0x{:02X}", action);
1239 } else {
1240 GrfMsg(7, "DecodeSpecialSprite: Handling action 0x{:02X} in stage {}", action, stage);
1241 func(buf, stage);
1242 }
1243 }
1244};
1245
1246/* Here we perform initial decoding of some special sprites (as are they
1247 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
1248 * partial implementation yet).
1249 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
1250 * a crafted invalid GRF file. We should tell that to the user somehow, or
1251 * better make this more robust in the future. */
1252static void DecodeSpecialSprite(ReusableBuffer<uint8_t> &allocator, uint num, GrfLoadingStage stage)
1253{
1254 uint8_t *buf;
1255 auto it = _grf_line_to_action6_sprite_override.find({_cur_gps.grfconfig->ident.grfid, _cur_gps.nfo_line});
1256 if (it == _grf_line_to_action6_sprite_override.end()) {
1257 /* No preloaded sprite to work with; read the
1258 * pseudo sprite content. */
1259 buf = allocator.Allocate(num);
1260 _cur_gps.file->ReadBlock(buf, num);
1261 } else {
1262 /* Use the preloaded sprite data. */
1263 buf = it->second.data();
1264 assert(it->second.size() == num);
1265 GrfMsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
1266
1267 /* Skip the real (original) content of this action. */
1268 _cur_gps.file->SeekTo(num, SEEK_CUR);
1269 }
1270
1271 ByteReader br(buf, num);
1272
1273 try {
1274 uint8_t action = br.ReadByte();
1275
1276 if (action == 0xFF) {
1277 GrfMsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
1278 } else if (action == 0xFE) {
1279 GrfMsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
1280 } else {
1281 InvokeGrfActionHandler::Invoke(action, stage, br);
1282 }
1283 } catch (...) {
1284 GrfMsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
1285 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
1286 }
1287}
1288
1295 static void LoadNewGRFFileFromFile(GRFConfig &config, GrfLoadingStage stage, SpriteFile &file)
1296{
1297 AutoRestoreBackup cur_file(_cur_gps.file, &file);
1298 AutoRestoreBackup cur_config(_cur_gps.grfconfig, &config);
1299
1300 Debug(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '{}'", config.filename);
1301
1302 uint8_t grf_container_version = file.GetContainerVersion();
1303 if (grf_container_version == 0) {
1304 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1305 return;
1306 }
1307
1308 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
1309 /* We need the sprite offsets in the init stage for NewGRF sounds
1310 * and in the activation stage for real sprites. */
1311 ReadGRFSpriteOffsets(file);
1312 } else {
1313 /* Skip sprite section offset if present. */
1314 if (grf_container_version >= 2) file.ReadDword();
1315 }
1316
1317 if (grf_container_version >= 2) {
1318 /* Read compression value. */
1319 uint8_t compression = file.ReadByte();
1320 if (compression != 0) {
1321 Debug(grf, 7, "LoadNewGRFFile: Unsupported compression format");
1322 return;
1323 }
1324 }
1325
1326 /* Skip the first sprite; we don't care about how many sprites this
1327 * does contain; newest TTDPatches and George's longvehicles don't
1328 * neither, apparently. */
1329 uint32_t num = grf_container_version >= 2 ? file.ReadDword() : file.ReadWord();
1330 if (num == 4 && file.ReadByte() == 0xFF) {
1331 file.ReadDword();
1332 } else {
1333 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1334 return;
1335 }
1336
1337 _cur_gps.ClearDataForNextFile();
1338
1339 ReusableBuffer<uint8_t> allocator;
1340
1341 while ((num = (grf_container_version >= 2 ? file.ReadDword() : file.ReadWord())) != 0) {
1342 uint8_t type = file.ReadByte();
1343 _cur_gps.nfo_line++;
1344
1345 if (type == 0xFF) {
1346 if (_cur_gps.skip_sprites == 0) {
1347 /* Limit the special sprites to 1 MiB. */
1348 if (num > 1024 * 1024) {
1349 GrfMsg(0, "LoadNewGRFFile: Unexpectedly large sprite, disabling");
1350 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1351 break;
1352 }
1353
1354 DecodeSpecialSprite(allocator, num, stage);
1355
1356 /* Stop all processing if we are to skip the remaining sprites */
1357 if (_cur_gps.skip_sprites == -1) break;
1358
1359 continue;
1360 } else {
1361 file.SkipBytes(num);
1362 }
1363 } else {
1364 if (_cur_gps.skip_sprites == 0) {
1365 GrfMsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
1366 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1367 break;
1368 }
1369
1370 if (grf_container_version >= 2 && type == 0xFD) {
1371 /* Reference to data section. Container version >= 2 only. */
1372 file.SkipBytes(num);
1373 } else {
1374 file.SkipBytes(7);
1375 SkipSpriteData(file, type, num - 8);
1376 }
1377 }
1378
1379 if (_cur_gps.skip_sprites > 0) _cur_gps.skip_sprites--;
1380 }
1381}
1382
1391 void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
1392{
1393 const std::string &filename = config.filename;
1394
1395 /* A .grf file is activated only if it was active when the game was
1396 * started. If a game is loaded, only its active .grfs will be
1397 * reactivated, unless "loadallgraphics on" is used. A .grf file is
1398 * considered active if its action 8 has been processed, i.e. its
1399 * action 8 hasn't been skipped using an action 7.
1400 *
1401 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
1402 * carried out. All others are ignored, because they only need to be
1403 * processed once at initialization. */
1404 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
1405 _cur_gps.grffile = GetFileByFilename(filename);
1406 if (_cur_gps.grffile == nullptr) UserError("File '{}' lost in cache.\n", filename);
1407 if (stage == GLS_RESERVE && config.status != GCS_INITIALISED) return;
1408 if (stage == GLS_ACTIVATION && !config.flags.Test(GRFConfigFlag::Reserved)) return;
1409 }
1410
1411 bool needs_palette_remap = config.palette & GRFP_USE_MASK;
1412 if (temporary) {
1413 SpriteFile temporarySpriteFile(filename, subdir, needs_palette_remap);
1414 LoadNewGRFFileFromFile(config, stage, temporarySpriteFile);
1415 } else {
1416 LoadNewGRFFileFromFile(config, stage, OpenCachedSpriteFile(filename, subdir, needs_palette_remap));
1417 }
1418}
1419
1427 static void ActivateOldShore()
1428{
1429 /* Use default graphics, if no shore sprites were loaded.
1430 * Should not happen, as the base set's extra grf should include some. */
1431 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
1432
1433 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
1434 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
1435 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
1436 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
1437 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
1438 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
1439 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
1440 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
1441 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
1442 }
1443
1444 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
1445 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
1446 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
1447 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
1448 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
1449 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
1450 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
1451 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
1452 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
1453
1454 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
1455 * If they would be used somewhen, then these grass tiles will most like not look as needed */
1456 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
1457 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
1458 }
1459}
1460
1464 static void ActivateOldTramDepot()
1465{
1466 if (_loaded_newgrf_features.tram == TRAMWAY_REPLACE_DEPOT_WITH_TRACK) {
1467 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0); // use road depot graphics for "no tracks"
1468 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
1469 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2); // use road depot graphics for "no tracks"
1470 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
1471 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
1472 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
1473 }
1474}
1475
1479 static void FinalisePriceBaseMultipliers()
1480{
1481 extern const PriceBaseSpec _price_base_specs[];
1483 static constexpr GrfSpecFeatures override_features{GSF_TRAINS, GSF_ROADVEHICLES, GSF_SHIPS, GSF_AIRCRAFT};
1484
1485 /* Evaluate grf overrides */
1486 int num_grfs = (uint)_grf_files.size();
1487 std::vector<int> grf_overrides(num_grfs, -1);
1488 for (int i = 0; i < num_grfs; i++) {
1489 GRFFile &source = _grf_files[i];
1490 auto it = _grf_id_overrides.find(source.grfid);
1491 if (it == std::end(_grf_id_overrides)) continue;
1492 uint32_t override_grfid = it->second;
1493
1494 auto dest = std::ranges::find(_grf_files, override_grfid, &GRFFile::grfid);
1495 if (dest == std::end(_grf_files)) continue;
1496
1497 grf_overrides[i] = static_cast<int>(std::ranges::distance(std::begin(_grf_files), dest));
1498 assert(grf_overrides[i] >= 0);
1499 }
1500
1501 /* Override features and price base multipliers of earlier loaded grfs */
1502 for (int i = 0; i < num_grfs; i++) {
1503 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
1504 GRFFile &source = _grf_files[i];
1505 GRFFile &dest = _grf_files[grf_overrides[i]];
1506
1507 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1508 source.grf_features.Set(features);
1509 dest.grf_features.Set(features);
1510
1511 for (Price p = PR_BEGIN; p < PR_END; p++) {
1512 /* No price defined -> nothing to do */
1513 if (!features.Test(_price_base_specs[p].grf_feature) || source.price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
1514 Debug(grf, 3, "'{}' overrides price base multiplier {} of '{}'", source.filename, p, dest.filename);
1515 dest.price_base_multipliers[p] = source.price_base_multipliers[p];
1516 }
1517 }
1518
1519 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
1520 for (int i = num_grfs - 1; i >= 0; i--) {
1521 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
1522 GRFFile &source = _grf_files[i];
1523 GRFFile &dest = _grf_files[grf_overrides[i]];
1524
1525 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1526 source.grf_features.Set(features);
1527 dest.grf_features.Set(features);
1528
1529 for (Price p = PR_BEGIN; p < PR_END; p++) {
1530 /* Already a price defined -> nothing to do */
1531 if (!features.Test(_price_base_specs[p].grf_feature) || dest.price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
1532 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, source.filename, dest.filename);
1533 dest.price_base_multipliers[p] = source.price_base_multipliers[p];
1534 }
1535 }
1536
1537 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
1538 for (int i = 0; i < num_grfs; i++) {
1539 if (grf_overrides[i] < 0) continue;
1540 GRFFile &source = _grf_files[i];
1541 GRFFile &dest = _grf_files[grf_overrides[i]];
1542
1543 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1544 source.grf_features.Set(features);
1545 dest.grf_features.Set(features);
1546
1547 for (Price p = PR_BEGIN; p < PR_END; p++) {
1548 if (!features.Test(_price_base_specs[p].grf_feature)) continue;
1549 if (source.price_base_multipliers[p] != dest.price_base_multipliers[p]) {
1550 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, dest.filename, source.filename);
1551 }
1552 source.price_base_multipliers[p] = dest.price_base_multipliers[p];
1553 }
1554 }
1555
1556 /* Apply fallback prices for grf version < 8 */
1557 for (auto &file : _grf_files) {
1558 if (file.grf_version >= 8) continue;
1559 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1560 for (Price p = PR_BEGIN; p < PR_END; p++) {
1561 Price fallback_price = _price_base_specs[p].fallback_price;
1562 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1563 /* No price multiplier has been set.
1564 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
1565 price_base_multipliers[p] = price_base_multipliers[fallback_price];
1566 }
1567 }
1568 }
1569
1570 /* Decide local/global scope of price base multipliers */
1571 for (auto &file : _grf_files) {
1572 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1573 for (Price p = PR_BEGIN; p < PR_END; p++) {
1574 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1575 /* No multiplier was set; set it to a neutral value */
1576 price_base_multipliers[p] = 0;
1577 } else {
1578 if (!file.grf_features.Test(_price_base_specs[p].grf_feature)) {
1579 /* The grf does not define any objects of the feature,
1580 * so it must be a difficulty setting. Apply it globally */
1581 Debug(grf, 3, "'{}' sets global price base multiplier {}", file.filename, p);
1582 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
1583 price_base_multipliers[p] = 0;
1584 } else {
1585 Debug(grf, 3, "'{}' sets local price base multiplier {}", file.filename, p);
1586 }
1587 }
1588 }
1589 }
1590}
1591
1592template <typename T>
1593void AddBadgeToSpecs(T &specs, GrfSpecFeature feature, Badge &badge)
1594{
1595 for (auto &spec : specs) {
1596 if (spec == nullptr) continue;
1597 spec->badges.push_back(badge.index);
1598 badge.features.Set(feature);
1599 }
1600}
1601
1603 static void FinaliseBadges()
1604{
1605 for (const auto &file : _grf_files) {
1606 Badge *badge = GetBadgeByLabel(fmt::format("newgrf/{:08x}", std::byteswap(file.grfid)));
1607 if (badge == nullptr) continue;
1608
1609 for (Engine *e : Engine::Iterate()) {
1610 if (e->grf_prop.grffile != &file) continue;
1611 e->badges.push_back(badge->index);
1612 badge->features.Set(static_cast<GrfSpecFeature>(GSF_TRAINS + e->type));
1613 }
1614
1615 AddBadgeToSpecs(file.stations, GSF_STATIONS, *badge);
1616 AddBadgeToSpecs(file.housespec, GSF_HOUSES, *badge);
1617 AddBadgeToSpecs(file.industryspec, GSF_INDUSTRIES, *badge);
1618 AddBadgeToSpecs(file.indtspec, GSF_INDUSTRYTILES, *badge);
1619 AddBadgeToSpecs(file.objectspec, GSF_OBJECTS, *badge);
1620 AddBadgeToSpecs(file.airportspec, GSF_AIRPORTS, *badge);
1621 AddBadgeToSpecs(file.airtspec, GSF_AIRPORTTILES, *badge);
1622 AddBadgeToSpecs(file.roadstops, GSF_ROADSTOPS, *badge);
1623 }
1624
1625 ApplyBadgeFeaturesToClassBadges();
1626 AddBadgeClassesToConfiguration();
1627}
1628
1629extern void InitGRFTownGeneratorNames();
1630
1632 static void AfterLoadGRFs()
1633{
1634 /* Cached callback groups are no longer needed. */
1635 ResetCallbacks(true);
1636
1637 FinaliseStringMapping();
1638
1639 /* Clear the action 6 override sprites. */
1640 _grf_line_to_action6_sprite_override.clear();
1641
1642 FinaliseBadges();
1643
1644 /* Polish cargoes */
1645 FinaliseCargoArray();
1646
1647 /* Pre-calculate all refit masks after loading GRF files. */
1648 CalculateRefitMasks();
1649
1650 /* Polish engines */
1651 FinaliseEngineArray();
1652
1653 /* Set the actually used Canal properties */
1654 FinaliseCanals();
1655
1656 /* Add all new houses to the house array. */
1657 FinaliseHouseArray();
1658
1659 /* Add all new industries to the industry array. */
1660 FinaliseIndustriesArray();
1661
1662 /* Add all new objects to the object array. */
1663 FinaliseObjectsArray();
1664
1665 InitializeSortedCargoSpecs();
1666
1667 /* Sort the list of industry types. */
1668 SortIndustryTypes();
1669
1670 /* Create dynamic list of industry legends for smallmap_gui.cpp */
1671 BuildIndustriesLegend();
1672
1673 /* Build the routemap legend, based on the available cargos */
1674 BuildLinkStatsLegend();
1675
1676 /* Add all new airports to the airports array. */
1677 FinaliseAirportsArray();
1678 BindAirportSpecs();
1679
1680 /* Update the townname generators list */
1681 InitGRFTownGeneratorNames();
1682
1683 /* Run all queued vehicle list order changes */
1684 CommitVehicleListOrderChanges();
1685
1686 /* Load old shore sprites in new position, if they were replaced by ActionA */
1687 ActivateOldShore();
1688
1689 /* Load old tram depot sprites in new position, if no new ones are present */
1690 ActivateOldTramDepot();
1691
1692 /* Set up custom rail types */
1693 InitRailTypes();
1694 InitRoadTypes();
1695
1696 for (Engine *e : Engine::IterateType(VEH_ROAD)) {
1697 if (_gted[e->index].rv_max_speed != 0) {
1698 /* Set RV maximum speed from the mph/0.8 unit value */
1699 e->VehInfo<RoadVehicleInfo>().max_speed = _gted[e->index].rv_max_speed * 4;
1700 }
1701
1702 RoadTramType rtt = e->info.misc_flags.Test(EngineMiscFlag::RoadIsTram) ? RTT_TRAM : RTT_ROAD;
1703
1704 const GRFFile *file = e->GetGRF();
1705 if (file == nullptr || _gted[e->index].roadtramtype == 0) {
1706 e->VehInfo<RoadVehicleInfo>().roadtype = (rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
1707 continue;
1708 }
1709
1710 /* Remove +1 offset. */
1711 _gted[e->index].roadtramtype--;
1712
1713 const std::vector<RoadTypeLabel> *list = (rtt == RTT_TRAM) ? &file->tramtype_list : &file->roadtype_list;
1714 if (_gted[e->index].roadtramtype < list->size())
1715 {
1716 RoadTypeLabel rtl = (*list)[_gted[e->index].roadtramtype];
1717 RoadType rt = GetRoadTypeByLabel(rtl);
1718 if (rt != INVALID_ROADTYPE && GetRoadTramType(rt) == rtt) {
1719 e->VehInfo<RoadVehicleInfo>().roadtype = rt;
1720 continue;
1721 }
1722 }
1723
1724 /* Road type is not available, so disable this engine */
1725 e->info.climates = {};
1726 }
1727
1728 for (Engine *e : Engine::IterateType(VEH_TRAIN)) {
1729 RailTypes railtypes{};
1730 for (RailTypeLabel label : _gted[e->index].railtypelabels) {
1731 auto rt = GetRailTypeByLabel(label);
1732 if (rt != INVALID_RAILTYPE) railtypes.Set(rt);
1733 }
1734
1735 if (railtypes.Any()) {
1736 e->VehInfo<RailVehicleInfo>().railtypes = railtypes;
1737 e->VehInfo<RailVehicleInfo>().intended_railtypes = railtypes;
1738 } else {
1739 /* Rail type is not available, so disable this engine */
1740 e->info.climates = {};
1741 }
1742 }
1743
1744 SetYearEngineAgingStops();
1745
1746 FinalisePriceBaseMultipliers();
1747
1748 /* Deallocate temporary loading data */
1749 _gted.clear();
1750 _grm_sprites.clear();
1751}
1752
1758 void LoadNewGRF(SpriteID load_index, uint num_baseset)
1759{
1760 /* In case of networking we need to "sync" the start values
1761 * so all NewGRFs are loaded equally. For this we use the
1762 * start date of the game and we set the counters, etc. to
1763 * 0 so they're the same too. */
1764 TimerGameCalendar::Date date = TimerGameCalendar::date;
1765 TimerGameCalendar::Year year = TimerGameCalendar::year;
1766 TimerGameCalendar::DateFract date_fract = TimerGameCalendar::date_fract;
1767
1768 TimerGameEconomy::Date economy_date = TimerGameEconomy::date;
1769 TimerGameEconomy::Year economy_year = TimerGameEconomy::year;
1770 TimerGameEconomy::DateFract economy_date_fract = TimerGameEconomy::date_fract;
1771
1772 uint64_t tick_counter = TimerGameTick::counter;
1773 uint8_t display_opt = _display_opt;
1774
1775 if (_networking) {
1776 TimerGameCalendar::year = _settings_game.game_creation.starting_year;
1777 TimerGameCalendar::date = TimerGameCalendar::ConvertYMDToDate(TimerGameCalendar::year, 0, 1);
1778 TimerGameCalendar::date_fract = 0;
1779
1780 TimerGameEconomy::year = TimerGameEconomy::Year{_settings_game.game_creation.starting_year.base()};
1781 TimerGameEconomy::date = TimerGameEconomy::ConvertYMDToDate(TimerGameEconomy::year, 0, 1);
1782 TimerGameEconomy::date_fract = 0;
1783
1784 TimerGameTick::counter = 0;
1785 _display_opt = 0;
1786 }
1787
1788 InitializePatchFlags();
1789
1790 ResetNewGRFData();
1791
1792 /*
1793 * Reset the status of all files, so we can 'retry' to load them.
1794 * This is needed when one for example rearranges the NewGRFs in-game
1795 * and a previously disabled NewGRF becomes usable. If it would not
1796 * be reset, the NewGRF would remain disabled even though it should
1797 * have been enabled.
1798 */
1799 for (const auto &c : _grfconfig) {
1800 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
1801 }
1802
1803 _cur_gps.spriteid = load_index;
1804
1805 /* Load newgrf sprites
1806 * in each loading stage, (try to) open each file specified in the config
1807 * and load information from it. */
1808 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
1809 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
1810 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
1811 for (const auto &c : _grfconfig) {
1812 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
1813 }
1814
1815 if (stage == GLS_RESERVE) {
1816 static const std::pair<uint32_t, uint32_t> default_grf_overrides[] = {
1817 { std::byteswap(0x44442202), std::byteswap(0x44440111) }, // UKRS addons modifies UKRS
1818 { std::byteswap(0x6D620402), std::byteswap(0x6D620401) }, // DBSetXL ECS extension modifies DBSetXL
1819 { std::byteswap(0x4D656f20), std::byteswap(0x4D656F17) }, // LV4cut modifies LV4
1820 };
1821 for (const auto &grf_override : default_grf_overrides) {
1822 SetNewGRFOverride(grf_override.first, grf_override.second);
1823 }
1824 }
1825
1826 uint num_grfs = 0;
1827 uint num_non_static = 0;
1828
1829 _cur_gps.stage = stage;
1830 for (const auto &c : _grfconfig) {
1831 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
1832 if (stage > GLS_INIT && c->flags.Test(GRFConfigFlag::InitOnly)) continue;
1833
1834 Subdirectory subdir = num_grfs < num_baseset ? BASESET_DIR : NEWGRF_DIR;
1835 if (!FioCheckFileExists(c->filename, subdir)) {
1836 Debug(grf, 0, "NewGRF file is missing '{}'; disabling", c->filename);
1837 c->status = GCS_NOT_FOUND;
1838 continue;
1839 }
1840
1841 if (stage == GLS_LABELSCAN) InitNewGRFFile(*c);
1842
1843 if (!c->flags.Test(GRFConfigFlag::Static) && !c->flags.Test(GRFConfigFlag::System)) {
1844 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
1845 Debug(grf, 0, "'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
1846 c->status = GCS_DISABLED;
1847 c->errors.emplace_back(STR_NEWGRF_ERROR_MSG_FATAL, 0, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
1848 continue;
1849 }
1850 num_non_static++;
1851 }
1852
1853 num_grfs++;
1854
1855 LoadNewGRFFile(*c, stage, subdir, false);
1856 if (stage == GLS_RESERVE) {
1857 c->flags.Set(GRFConfigFlag::Reserved);
1858 } else if (stage == GLS_ACTIVATION) {
1859 c->flags.Reset(GRFConfigFlag::Reserved);
1860 assert(GetFileByGRFID(c->ident.grfid) == _cur_gps.grffile);
1861 ClearTemporaryNewGRFData(_cur_gps.grffile);
1862 BuildCargoTranslationMap();
1863 Debug(sprite, 2, "LoadNewGRF: Currently {} sprites are loaded", _cur_gps.spriteid);
1864 } else if (stage == GLS_INIT && c->flags.Test(GRFConfigFlag::InitOnly)) {
1865 /* We're not going to activate this, so free whatever data we allocated */
1866 ClearTemporaryNewGRFData(_cur_gps.grffile);
1867 }
1868 }
1869 }
1870
1871 /* We've finished reading files. */
1872 _cur_gps.grfconfig = nullptr;
1873 _cur_gps.grffile = nullptr;
1874
1875 /* Pseudo sprite processing is finished; free temporary stuff */
1876 _cur_gps.ClearDataForNextFile();
1877
1878 /* Call any functions that should be run after GRFs have been loaded. */
1879 AfterLoadGRFs();
1880
1881 /* Now revert back to the original situation */
1882 TimerGameCalendar::year = year;
1883 TimerGameCalendar::date = date;
1884 TimerGameCalendar::date_fract = date_fract;
1885
1886 TimerGameEconomy::year = economy_year;
1887 TimerGameEconomy::date = economy_date;
1888 TimerGameEconomy::date_fract = economy_date_fract;
1889
1890 TimerGameTick::counter = tick_counter;
1891 _display_opt = display_opt;
1892}
backup_type.hpp
Class for backupping variables and making sure they are restored later.
SetBit
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
Definition bitmath_func.hpp:121
FindFirstBit
constexpr uint8_t FindFirstBit(T x)
Search the first set bit in a value.
Definition bitmath_func.hpp:189
HasBit
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
Definition bitmath_func.hpp:103
ClrBit
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
Definition bitmath_func.hpp:139
bridge.h
Header file for bridges.
ResetBridges
void ResetBridges()
Reset the data been eventually changed by the grf loaded.
Definition tunnelbridge_cmd.cpp:83
CT_INVALID
static constexpr CargoLabel CT_INVALID
Invalid cargo type.
Definition cargo_type.h:70
CargoType
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:21
IsValidCargoType
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:104
MixedCargoType
MixedCargoType
Mixed cargo types for definitions with cargo that can vary depending on climate.
Definition cargo_type.h:82
MCT_GRAIN_WHEAT_MAIZE
@ MCT_GRAIN_WHEAT_MAIZE
Cargo can be grain, wheat or maize.
Definition cargo_type.h:84
MCT_LIVESTOCK_FRUIT
@ MCT_LIVESTOCK_FRUIT
Cargo can be livestock or fruit.
Definition cargo_type.h:83
MCT_VALUABLES_GOLD_DIAMONDS
@ MCT_VALUABLES_GOLD_DIAMONDS
Cargo can be valuables, gold or diamonds.
Definition cargo_type.h:85
CT_PASSENGERS
static constexpr CargoLabel CT_PASSENGERS
Available types of cargo Labels may be re-used between different climates.
Definition cargo_type.h:29
NUM_CARGO
static const CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:73
GetClimateDependentCargoTranslationTable
std::span< const CargoLabel > GetClimateDependentCargoTranslationTable()
Get default climate-dependent cargo translation table for a NewGRF, used if the NewGRF does not provi...
Definition cargotype.cpp:113
IsDefaultCargo
bool IsDefaultCargo(CargoType cargo_type)
Test if a cargo is a default cargo type.
Definition cargotype.cpp:150
_standard_cargo_mask
CargoTypes _standard_cargo_mask
Bitmask of real cargo types available.
Definition cargotype.cpp:36
GetClimateIndependentCargoTranslationTable
std::span< const CargoLabel > GetClimateIndependentCargoTranslationTable()
Get default climate-independent cargo translation table for a NewGRF, used if the NewGRF does not pro...
Definition cargotype.cpp:122
SetupCargoForClimate
void SetupCargoForClimate(LandscapeType l)
Set up the default cargo types for the given landscape type.
Definition cargotype.cpp:62
InitializeSortedCargoSpecs
void InitializeSortedCargoSpecs()
Initialize the list of sorted cargo specifications.
Definition cargotype.cpp:223
_cargo_mask
CargoTypes _cargo_mask
Bitmask of cargo types available.
Definition cargotype.cpp:31
CargoClass::Bulk
@ Bulk
Bulk cargo (Coal, Grain etc., Ores, Fruit)
CargoClass::Mail
@ Mail
Mail.
CargoClass::Liquid
@ Liquid
Liquids (Oil, Water, Rubber)
CargoClass::Passengers
@ Passengers
Passengers.
CargoClass::Armoured
@ Armoured
Armoured cargo (Valuables, Gold, Diamonds)
CargoClass::Refrigerated
@ Refrigerated
Refrigerated cargo (Food, Fruit)
CargoClass::Express
@ Express
Express cargo (Goods, Food, Candy, but also possible for passengers)
CargoClass::PieceGoods
@ PieceGoods
Piece goods (Livestock, Wood, Steel, Paper)
INVALID_TPE
@ INVALID_TPE
Invalid town production effect.
Definition cargotype.h:45
TPE_NONE
@ TPE_NONE
Town will not produce this cargo type.
Definition cargotype.h:36
TPE_PASSENGERS
@ TPE_PASSENGERS
Cargo behaves passenger-like for production.
Definition cargotype.h:37
TPE_MAIL
@ TPE_MAIL
Cargo behaves mail-like for production.
Definition cargotype.h:38
Badge
Definition newgrf_badge.h:20
Badge::index
BadgeID index
Index assigned to badge.
Definition newgrf_badge.h:23
Badge::features
GrfSpecFeatures features
Bitmask of which features use this badge.
Definition newgrf_badge.h:27
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
BaseBitSet::Set
constexpr Timpl & Set()
Set all bits.
Definition base_bitset_type.hpp:40
BaseBitSet::Any
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Definition base_bitset_type.hpp:170
ByteReader
Class to read from a NewGRF file.
Definition newgrf_bytereader.h:18
Engine
Definition engine_base.h:38
Engine::IterateType
static Pool::IterateWrapperFiltered< Engine, EngineTypeFilter > IterateType(VehicleType vt, size_t from=0)
Returns an iterable ensemble of all valid engines of the given type.
Definition engine_base.h:197
Engine::grf_prop
CargoGRFFileProps grf_prop
Link to NewGRF.
Definition engine_base.h:71
EnumBitSet
Enum-as-bit-set wrapper.
Definition enum_type.hpp:177
HouseOverrideManager::SetEntitySpec
void SetEntitySpec(HouseSpec &&hs)
Install the specs into the HouseSpecs array It will find itself the proper slot on which it will go.
Definition newgrf_commons.cpp:160
IndustryOverrideManager::SetEntitySpec
void SetEntitySpec(IndustrySpec &&inds)
Method to install the new industry data in its proper slot The slot assignment is internal of this me...
Definition newgrf_commons.cpp:248
NewGRFClass::Reset
static void Reset()
Reset the classes, i.e.
Definition newgrf_class_func.h:16
ObjectOverrideManager::SetEntitySpec
void SetEntitySpec(ObjectSpec &&spec)
Method to install the new object data in its proper slot The slot assignment is internal of this meth...
Definition newgrf_commons.cpp:303
OverrideManagerBase::ResetMapping
void ResetMapping()
Resets the mapping, which is used while initializing game.
Definition newgrf_commons.cpp:73
RailTypeInfo::label
RailTypeLabel label
Unique 32 bit rail type identifier.
Definition rail.h:225
RandomAccessFile::ReadBlock
void ReadBlock(void *ptr, size_t size)
Read a block.
Definition random_access_file.cpp:145
RandomAccessFile::SeekTo
void SeekTo(size_t pos, int mode)
Seek in the current file.
Definition random_access_file.cpp:90
RandomAccessFile::ReadByte
uint8_t ReadByte()
Read a byte from the file.
Definition random_access_file.cpp:107
RandomAccessFile::ReadDword
uint32_t ReadDword()
Read a double word (32 bits) from the file (in low endian format).
Definition random_access_file.cpp:134
RandomAccessFile::SkipBytes
void SkipBytes(size_t n)
Skip n bytes ahead in the file.
Definition random_access_file.cpp:163
RandomAccessFile::ReadWord
uint16_t ReadWord()
Read a word (16 bits) from the file (in low endian format).
Definition random_access_file.cpp:124
ReusableBuffer
A reusable buffer that can be used for places that temporary allocate a bit of memory and do that ver...
Definition alloc_type.hpp:22
ReusableBuffer::Allocate
T * Allocate(size_t count)
Get buffer of at least count times T.
Definition alloc_type.hpp:34
SpriteFile
RandomAccessFile with some extra information specific for sprite files.
Definition sprite_file_type.hpp:19
SpriteFile::GetContainerVersion
uint8_t GetContainerVersion() const
Get the version number of container type used by the file.
Definition sprite_file_type.hpp:38
TimerGameCalendar::ConvertYMDToDate
static Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
Definition timer_game_calendar.cpp:55
TimerGameCalendar::date
static Date date
Current date in days (day counter).
Definition timer_game_calendar.h:33
TimerGameCalendar::year
static Year year
Current year, starting at 0.
Definition timer_game_calendar.h:31
TimerGameCalendar::date_fract
static DateFract date_fract
Fractional part of the day.
Definition timer_game_calendar.h:34
TimerGameConst< struct Calendar >::MIN_YEAR
static constexpr TimerGame< struct Calendar >::Year MIN_YEAR
The absolute minimum year in OTTD.
Definition timer_game_common.h:176
TimerGameConst< struct Calendar >::MAX_YEAR
static constexpr TimerGame< struct Calendar >::Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date,...
Definition timer_game_common.h:173
TimerGameEconomy::date
static Date date
Current date in days (day counter).
Definition timer_game_economy.h:38
TimerGameEconomy::year
static Year year
Current year, starting at 0.
Definition timer_game_economy.h:36
TimerGameEconomy::date_fract
static DateFract date_fract
Fractional part of the day.
Definition timer_game_economy.h:39
TimerGameEconomy::ConvertYMDToDate
static Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
Definition timer_game_economy.cpp:67
TimerGameTick::counter
static TickCounter counter
Monotonic counter, in ticks, since start of game.
Definition timer_game_tick.h:60
TimerGame< struct Calendar >::DateFract
uint16_t DateFract
The fraction of a date we're in, i.e.
Definition timer_game_common.h:38
TypedIndexContainer
A sort-of mixin that implements 'at(pos)' and 'operator[](pos)' only for a specific type.
Definition convertible_through_base.hpp:38
ResetFaces
void ResetFaces()
Reset company manager face styles to default.
Definition company_cmd.cpp:1378
company_manager_face.h
Functionality related to the company manager's face.
config.h
Configuration options of the network stuff.
NETWORK_MAX_GRF_COUNT
static const uint NETWORK_MAX_GRF_COUNT
Maximum number of GRFs that can be sent.
Definition config.h:90
container_func.hpp
Some simple functions to help with accessing containers.
find_index
int find_index(Container const &container, typename Container::const_reference item)
Helper function to get the index of an item Consider using std::set, std::unordered_set or std::flat_...
Definition container_func.hpp:41
ResetCurrencies
void ResetCurrencies(bool preserve_custom)
Will fill _currency_specs array with default values from origin_currency_specs Called only from newgr...
Definition currency.cpp:163
currency.h
Functions to handle different currencies.
debug.h
Functions related to debugging.
Debug
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
SetPriceBaseMultiplier
void SetPriceBaseMultiplier(Price price, int factor)
Change a price base by the given factor.
Definition economy.cpp:882
ResetPriceBaseMultipliers
void ResetPriceBaseMultipliers()
Reset changes to the price base multipliers.
Definition economy.cpp:870
Price
Price
Enumeration of all base prices for use with Prices.
Definition economy_type.h:95
SetYearEngineAgingStops
void SetYearEngineAgingStops()
Compute the value for _year_engine_aging_stops.
Definition engine.cpp:692
_engine_counts
const uint8_t _engine_counts[4]
Number of engines of each vehicle type in original engine data.
Definition engine.cpp:54
SetupEngines
void SetupEngines()
Initialise the engine pool with the data from the original vehicles.
Definition engine.cpp:600
engine_base.h
Base class for engines.
EngineDisplayFlag::HasVariants
@ HasVariants
Set if engine has variants.
EngineDisplayFlag::IsFolded
@ IsFolded
Set if display of variants should be folded (hidden).
engine_func.h
Functions related to engines.
EngineMiscFlag::RoadIsTram
@ RoadIsTram
Road vehicle is a tram/light rail vehicle.
RAILVEH_WAGON
@ RAILVEH_WAGON
simple wagon, not motorized
Definition engine_type.h:34
error_func.h
Error reporting related functions.
FioCheckFileExists
bool FioCheckFileExists(std::string_view filename, Subdirectory subdir)
Check whether the given file exists.
Definition fileio.cpp:121
fileio_func.h
Functions for Standard In/Out file operations.
Subdirectory
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition fileio_type.h:88
NEWGRF_DIR
@ NEWGRF_DIR
Subdirectory for all NewGRFs.
Definition fileio_type.h:97
BASESET_DIR
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
Definition fileio_type.h:96
genworld.h
Functions related to world/map generation.
SpriteID
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
ClearSnowLine
void ClearSnowLine()
Clear the variable snow line table and free the memory.
Definition landscape.cpp:638
GetClimateMaskForLandscape
HouseZones GetClimateMaskForLandscape()
Get the HouseZones climate mask for the current landscape type.
Definition town_cmd.cpp:2366
NUM_HOUSES
static const HouseID NUM_HOUSES
Total number of houses.
Definition house.h:29
HouseZone
HouseZone
Definition house.h:55
ResetIndustries
void ResetIndustries()
This function initialize the spec arrays of both industry and industry tiles.
Definition industry_cmd.cpp:83
SortIndustryTypes
void SortIndustryTypes()
Initialize the list of sorted industry types.
Definition industry_gui.cpp:249
industrytype.h
Industry type specs.
landscape.h
Functions related to OTTD's landscape.
LandscapeType
LandscapeType
Landscape types.
Definition landscape_type.h:16
LiveryScheme
LiveryScheme
List of different livery schemes.
Definition livery.h:22
_networking
bool _networking
are we in networking mode?
Definition network.cpp:67
FinaliseObjectsArray
static void FinaliseObjectsArray()
Add all new objects to the object array.
Definition newgrf.cpp:1166
FinalisePriceBaseMultipliers
static void FinalisePriceBaseMultipliers()
Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them...
Definition newgrf.cpp:1479
GetActiveCargoLabel
static CargoLabel GetActiveCargoLabel(const std::initializer_list< CargoLabel > &labels)
Find first cargo label that exists and is active from a list of cargo labels.
Definition newgrf.cpp:612
FinaliseIndustriesArray
static void FinaliseIndustriesArray()
Add all new industries to the industry array.
Definition newgrf.cpp:1112
GetCargoTranslationTable
std::span< const CargoLabel > GetCargoTranslationTable(const GRFFile &grffile)
Get the cargo translation table to use for the given GRF file.
Definition newgrf.cpp:521
_grf_files
static std::vector< GRFFile > _grf_files
List of all loaded GRF files.
Definition newgrf.cpp:63
ResetPersistentNewGRFData
void ResetPersistentNewGRFData()
Reset NewGRF data which is stored persistently in savegames.
Definition newgrf.cpp:505
FinaliseAirportsArray
static void FinaliseAirportsArray()
Add all new airports to the airport array.
Definition newgrf.cpp:1188
GetFileByFilename
static GRFFile * GetFileByFilename(const std::string &filename)
Obtain a NewGRF file by its filename.
Definition newgrf.cpp:116
GetCurrentGRFOverride
GRFFile * GetCurrentGRFOverride()
Get overridden GRF for current GRF if present.
Definition newgrf.cpp:196
ConvertTTDBasePrice
void ConvertTTDBasePrice(uint32_t base_pointer, std::string_view error_location, Price *index)
Converts TTD(P) Base Price pointers into the enum used by OTTD See http://wiki.ttdpatch....
Definition newgrf.cpp:332
SetNewGRFOverride
void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
Set the override for a NewGRF.
Definition newgrf.cpp:181
GRFUnsafe
void GRFUnsafe(ByteReader &)
Set the current NewGRF as unsafe for static use.
Definition newgrf.cpp:373
GetNewEngine
Engine * GetNewEngine(const GRFFile *file, VehicleType type, uint16_t internal_id, bool static_access)
Returns the engine associated to a certain internal_id, resp.
Definition newgrf.cpp:214
ActivateOldShore
static void ActivateOldShore()
Relocates the old shore sprites at new positions.
Definition newgrf.cpp:1427
EnsureEarlyHouse
static void EnsureEarlyHouse(HouseZones bitmask)
Make sure there is at least one house available in the year 0 for the given climate / housezone combi...
Definition newgrf.cpp:1013
_gted
TypedIndexContainer< std::vector< GRFTempEngineData >, EngineID > _gted
Temporary engine data used during NewGRF loading.
Definition newgrf.cpp:78
FinaliseEngineArray
static void FinaliseEngineArray()
Check for invalid engines.
Definition newgrf.cpp:854
ResetNewGRFErrors
static void ResetNewGRFErrors()
Clear all NewGRF errors.
Definition newgrf.cpp:395
LoadNewGRFFileFromFile
static void LoadNewGRFFileFromFile(GRFConfig &config, GrfLoadingStage stage, SpriteFile &file)
Load a particular NewGRF from a SpriteFile.
Definition newgrf.cpp:1295
_loaded_newgrf_features
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition newgrf.cpp:74
LoadNewGRF
void LoadNewGRF(SpriteID load_index, uint num_baseset)
Load all the NewGRFs.
Definition newgrf.cpp:1758
ClearTemporaryNewGRFData
static void ClearTemporaryNewGRFData(GRFFile *gf)
Reset all NewGRFData that was used only while processing data.
Definition newgrf.cpp:124
DisableStaticNewGRFInfluencingNonStaticNewGRFs
void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig &c)
Disable a static NewGRF when it is influencing another (non-static) NewGRF as this could cause desync...
Definition newgrf.cpp:168
FinaliseCanals
static void FinaliseCanals()
Set to use the correct action0 properties for each canal feature.
Definition newgrf.cpp:843
ResetNewGRFData
void ResetNewGRFData()
Reset all NewGRF loaded data.
Definition newgrf.cpp:408
CalculateRefitMasks
static void CalculateRefitMasks()
Precalculate refit masks from cargo classes for all vehicles.
Definition newgrf.cpp:647
FinaliseCargoArray
void FinaliseCargoArray()
Check for invalid cargoes.
Definition newgrf.cpp:937
BuildCargoTranslationMap
static void BuildCargoTranslationMap()
Construct the Cargo Mapping.
Definition newgrf.cpp:537
GrfMsgI
void GrfMsgI(int severity, const std::string &msg)
Debug() function dedicated to newGRF debugging messages Function is essentially the same as Debug(grf...
Definition newgrf.cpp:90
GetNewEngineID
EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal_id)
Return the ID of a new engine.
Definition newgrf.cpp:296
GetFileByGRFID
GRFFile * GetFileByGRFID(uint32_t grfid)
Obtain a NewGRF file by its grfID.
Definition newgrf.cpp:104
_misc_grf_features
GrfMiscBits _misc_grf_features
Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E.
Definition newgrf.cpp:71
FinaliseHouseArray
static void FinaliseHouseArray()
Add all new houses to the house array.
Definition newgrf.cpp:1038
InitNewGRFFile
static void InitNewGRFFile(const GRFConfig &config)
Prepare loading a NewGRF file with its config.
Definition newgrf.cpp:554
ActivateOldTramDepot
static void ActivateOldTramDepot()
Relocate the old tram depot sprites to the new position, if no new ones were loaded.
Definition newgrf.cpp:1464
LoadNewGRFFile
void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
Load a particular NewGRF.
Definition newgrf.cpp:1391
IsHouseSpecValid
static bool IsHouseSpecValid(HouseSpec &hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const std::string &filename)
Check if a given housespec is valid and disable it if it's not.
Definition newgrf.cpp:967
AfterLoadGRFs
static void AfterLoadGRFs()
Finish loading NewGRFs and execute needed post-processing.
Definition newgrf.cpp:1632
DisableGrf
GRFError * DisableGrf(StringID message, GRFConfig *config)
Disable a GRF.
Definition newgrf.cpp:135
ResetNewGRF
static void ResetNewGRF()
Reset and clear all NewGRFs.
Definition newgrf.cpp:382
InitGRFTownGeneratorNames
void InitGRFTownGeneratorNames()
Allocate memory for the NewGRF town names.
Definition newgrf_townname.cpp:80
TranslateRefitMask
CargoTypes TranslateRefitMask(uint32_t refit_mask)
Translate the refit mask.
Definition newgrf.cpp:315
FinaliseBadges
static void FinaliseBadges()
Finish up applying badges to things.
Definition newgrf.cpp:1603
SHORE_REPLACE_ACTION_A
@ SHORE_REPLACE_ACTION_A
Shore sprites were replaced by ActionA (using grass tiles for the corner-shores).
Definition newgrf.h:178
SHORE_REPLACE_NONE
@ SHORE_REPLACE_NONE
No shore sprites were replaced.
Definition newgrf.h:176
SHORE_REPLACE_ACTION_5
@ SHORE_REPLACE_ACTION_5
Shore sprites were replaced by Action5.
Definition newgrf.h:177
TRAMWAY_REPLACE_DEPOT_WITH_TRACK
@ TRAMWAY_REPLACE_DEPOT_WITH_TRACK
Electrified depot graphics with tram track were loaded.
Definition newgrf.h:184
TRAMWAY_REPLACE_DEPOT_NONE
@ TRAMWAY_REPLACE_DEPOT_NONE
No tram depot graphics were loaded.
Definition newgrf.h:183
GrfSpecFeature
GrfSpecFeature
Definition newgrf.h:68
InitializePatchFlags
void InitializePatchFlags()
Initialize the TTDPatch flags.
Definition newgrf_act7_9.cpp:28
BindAirportSpecs
void BindAirportSpecs()
Tie all airportspecs to their class.
Definition newgrf_airport.cpp:128
newgrf_airport.h
NewGRF handling of airports.
newgrf_airporttiles.h
NewGRF handling of airport tiles.
ApplyBadgeFeaturesToClassBadges
void ApplyBadgeFeaturesToClassBadges()
Apply features from all badges to their badge classes.
Definition newgrf_badge.cpp:267
AppendCopyableBadgeList
void AppendCopyableBadgeList(std::vector< BadgeID > &dst, std::span< const BadgeID > src, GrfSpecFeature feature)
Append copyable badges from a list onto another.
Definition newgrf_badge.cpp:250
GetBadgeByLabel
Badge * GetBadgeByLabel(std::string_view label)
Get a badge by label if it exists.
Definition newgrf_badge.cpp:124
ResetBadges
void ResetBadges()
Reset badges to the default state.
Definition newgrf_badge.cpp:72
newgrf_badge.h
Functions related to NewGRF badges.
AddBadgeClassesToConfiguration
void AddBadgeClassesToConfiguration()
Add current badge classes to user configuration.
Definition newgrf_badge_config.cpp:76
newgrf_badge_config.h
Functions related to NewGRF badge configuration.
newgrf_bytereader.h
NewGRF buffer reader definition.
VehicleCallbackMask::CustomRefit
@ CustomRefit
Custom refit mask.
CBID_VEHICLE_CUSTOM_REFIT
@ CBID_VEHICLE_CUSTOM_REFIT
Called to get custom engine refit mask.
Definition newgrf_callbacks.h:295
CALLBACK_FAILED
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
Definition newgrf_callbacks.h:439
_water_feature
std::array< WaterFeature, CF_END > _water_feature
Table of canal 'feature' sprite groups.
Definition newgrf_canal.cpp:20
newgrf_canal.h
Handling of NewGRF canals.
GetCargoTranslation
CargoType GetCargoTranslation(uint8_t cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoType.
Definition newgrf_cargo.cpp:80
newgrf_cargo.h
Cargo support for NewGRFs.
ErrorUnknownCallbackResult
void ErrorUnknownCallbackResult(uint32_t grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
Definition newgrf_commons.cpp:517
_grfconfig
GRFConfigList _grfconfig
First item in list of current GRF set up.
Definition newgrf_config.cpp:154
GCS_INITIALISED
@ GCS_INITIALISED
GRF file has been initialised.
Definition newgrf_config.h:37
GCS_DISABLED
@ GCS_DISABLED
GRF file is disabled.
Definition newgrf_config.h:35
GCS_NOT_FOUND
@ GCS_NOT_FOUND
GRF file was not found in the local cache.
Definition newgrf_config.h:36
GCS_UNKNOWN
@ GCS_UNKNOWN
The status of this grf file is unknown.
Definition newgrf_config.h:34
GCS_ACTIVATED
@ GCS_ACTIVATED
GRF file has been activated.
Definition newgrf_config.h:38
InitOnly
@ InitOnly
GRF file is processed up to GLS_INIT.
Definition newgrf_config.h:26
Reserved
@ Reserved
GRF file passed GLS_RESERVE stage.
Definition newgrf_config.h:27
System
@ System
GRF file is an openttd-internal system grf.
Definition newgrf_config.h:21
Static
@ Static
GRF file is used statically (can be used in any MP game)
Definition newgrf_config.h:23
Unsafe
@ Unsafe
GRF file is unsafe for static usage.
Definition newgrf_config.h:22
GRFP_USE_MASK
@ GRFP_USE_MASK
Bitmask to get only the use palette use states.
Definition newgrf_config.h:68
GetVehicleCallback
uint16_t GetVehicleCallback(CallbackID callback, uint32_t param1, uint32_t param2, EngineID engine, const Vehicle *v, std::span< int32_t > regs100)
Evaluate a newgrf callback for vehicles.
Definition newgrf_engine.cpp:1198
CommitVehicleListOrderChanges
void CommitVehicleListOrderChanges()
Determine default engine sorting and execute recorded ListOrderChanges from AlterVehicleListOrder.
Definition newgrf_engine.cpp:1375
newgrf_engine.h
Functions for NewGRF engines.
ResetGenericCallbacks
void ResetGenericCallbacks()
Reset all generic feature callback sprite groups.
Definition newgrf_generic.cpp:94
MapNewGRFIndustryType
IndustryType MapNewGRFIndustryType(IndustryType grf_type, uint32_t grf_id)
Map the GRF local type to an industry type.
Definition newgrf_industries.cpp:41
newgrf_industries.h
Functions for NewGRF industries.
newgrf_internal.h
NewGRF internal processing state.
newgrf_internal_vehicle.h
NewGRF internal processing state for vehicles.
ResetObjects
void ResetObjects()
This function initialize the spec arrays of objects.
Definition newgrf_object.cpp:125
newgrf_object.h
Functions related to NewGRF objects.
newgrf_roadstop.h
NewGRF definitions and structures for road stops.
newgrf_sound.h
Functions related to NewGRF provided sounds.
newgrf_station.h
Header file for NewGRF stations.
FinaliseStringMapping
void FinaliseStringMapping()
Finalise all string mappings.
Definition newgrf_stringmapping.cpp:159
newgrf_stringmapping.h
NewGRF string mapping definition.
CleanUpStrings
void CleanUpStrings()
House cleaning.
Definition newgrf_text.cpp:675
newgrf_text.h
Header of Action 04 "universal holder" structure and functions.
newgrf_townname.h
Header of Action 0F "universal holder" structure and functions.
GetRailTypeByLabel
RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels)
Get the rail type for a given label.
Definition rail.cpp:195
InitRailTypes
void InitRailTypes()
Resolve sprites of custom rail types.
Definition rail_cmd.cpp:130
ResetRailTypes
void ResetRailTypes()
Reset all rail type information to its default values.
Definition rail_cmd.cpp:65
GetRailTypeInfo
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition rail.h:300
RailType
RailType
Enumeration for all possible railtypes.
Definition rail_type.h:25
RAILTYPE_MONO
@ RAILTYPE_MONO
Monorail.
Definition rail_type.h:29
INVALID_RAILTYPE
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition rail_type.h:32
RAILTYPE_ELECTRIC
@ RAILTYPE_ELECTRIC
Electric rails.
Definition rail_type.h:28
RAILTYPE_RAIL
@ RAILTYPE_RAIL
Standard non-electric rails.
Definition rail_type.h:27
RAILTYPE_MAGLEV
@ RAILTYPE_MAGLEV
Maglev.
Definition rail_type.h:30
GetRoadTypeByLabel
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
Get the road type for a given label.
Definition road.cpp:265
road.h
Road specific functions.
ResetRoadTypes
void ResetRoadTypes()
Reset all road type information to its default values.
Definition road_cmd.cpp:63
InitRoadTypes
void InitRoadTypes()
Resolve sprites of custom road types.
Definition road_cmd.cpp:111
GetRoadTypeInfo
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:215
RoadTramType
RoadTramType
The different types of road type.
Definition road_type.h:37
RTT_ROAD
@ RTT_ROAD
Road road type.
Definition road_type.h:38
RTT_TRAM
@ RTT_TRAM
Tram road type.
Definition road_type.h:39
RoadType
RoadType
The different roadtypes we support.
Definition road_type.h:23
INVALID_ROADTYPE
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
ROADTYPE_TRAM
@ ROADTYPE_TRAM
Trams.
Definition road_type.h:26
ROADTYPE_ROAD
@ ROADTYPE_ROAD
Basic road type.
Definition road_type.h:25
safeguards.h
A number of safeguards to prevent using unsafe methods.
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
BuildLinkStatsLegend
void BuildLinkStatsLegend()
Populate legend table for the link stat view.
Definition smallmap_gui.cpp:219
BuildIndustriesLegend
void BuildIndustriesLegend()
Fills an array for the industries legends.
Definition smallmap_gui.cpp:189
smallmap_gui.h
Smallmap GUI functions.
OpenCachedSpriteFile
SpriteFile & OpenCachedSpriteFile(const std::string &filename, Subdirectory subdir, bool palette_remap)
Open/get the SpriteFile that is cached for use in the sprite cache.
Definition spritecache.cpp:87
SkipSpriteData
bool SkipSpriteData(SpriteFile &file, uint8_t type, uint16_t num)
Skip the given amount of sprite graphics data.
Definition spritecache.cpp:104
ReadGRFSpriteOffsets
void ReadGRFSpriteOffsets(SpriteFile &file)
Parse the sprite section of GRFs.
Definition spritecache.cpp:558
spritecache.h
Functions to cache sprites in memory.
SPR_SHORE_BASE
static const SpriteID SPR_SHORE_BASE
shore tiles - action 05-0D
Definition sprites.h:226
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
lengthof
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
StringID
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition strings_type.h:19
AirportSpec::ResetAirports
static void ResetAirports()
This function initializes the airportspec array.
Definition newgrf_airport.cpp:115
AirportTileSpec::ResetAirportTiles
static void ResetAirportTiles()
This function initializes the tile array of AirportTileSpec.
Definition newgrf_airporttiles.cpp:60
AutoRestoreBackup
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Definition backup_type.hpp:150
CargoSpec
Specification of a cargo type.
Definition cargotype.h:74
CargoSpec::Iterate
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:192
CargoSpec::array
static CargoSpec array[NUM_CARGO]
Array holding all CargoSpecs.
Definition cargotype.h:198
EngineInfo
Information about a vehicle.
Definition engine_type.h:198
EngineInfo::climates
LandscapeTypes climates
Climates supported by the engine.
Definition engine_type.h:204
EngineOverrideManager::ResetToDefaultMapping
void ResetToDefaultMapping()
Initializes the EngineOverrideManager with the default engines.
Definition engine.cpp:508
EngineOverrideManager::UseUnreservedID
EngineID UseUnreservedID(VehicleType type, uint16_t grf_local_id, uint32_t grfid, bool static_access)
Look for an unreserved EngineID matching the local id, and reserve it if found.
Definition engine.cpp:548
EngineOverrideManager::GetID
EngineID GetID(VehicleType type, uint16_t grf_local_id, uint32_t grfid)
Looks up an EngineID in the EngineOverrideManager.
Definition engine.cpp:529
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition newgrf_config.h:158
GRFConfig::palette
uint8_t palette
GRFPalette, bitset.
Definition newgrf_config.h:182
GRFConfig::errors
std::vector< GRFError > errors
NOSAVE: Error/Warning during GRF loading (Action 0x0B)
Definition newgrf_config.h:174
GRFConfig::param
std::vector< uint32_t > param
GRF parameters.
Definition newgrf_config.h:185
GRFConfig::status
GRFStatus status
NOSAVE: GRFStatus, enum.
Definition newgrf_config.h:179
GRFConfig::flags
GRFConfigFlags flags
NOSAVE: GCF_Flags, bitset.
Definition newgrf_config.h:178
GRFConfig::filename
std::string filename
Filename - either with or without full path.
Definition newgrf_config.h:170
GRFConfig::ident
GRFIdentifier ident
grfid and md5sum to uniquely identify newgrfs
Definition newgrf_config.h:168
GRFConfig::GetName
std::string GetName() const
Get the name of this grf.
Definition newgrf_config.cpp:85
GRFError
Information about why GRF had problems during initialisation.
Definition newgrf_config.h:109
GRFError::nfo_line
uint32_t nfo_line
Line within NewGRF of error.
Definition newgrf_config.h:117
GRFError::data
std::string data
Additional data for message and custom_message.
Definition newgrf_config.h:114
GRFFilePropsBase::local_id
uint16_t local_id
id defined by the grf file for this entity
Definition newgrf_commons.h:316
GRFFilePropsBase::SetGRFFile
void SetGRFFile(const struct GRFFile *grffile)
Set the NewGRF file, and its grfid, associated with grf props.
Definition newgrf_commons.cpp:735
GRFFilePropsBase::HasGrfFile
bool HasGrfFile() const
Test if this entity was introduced by NewGRF.
Definition newgrf_commons.h:326
GRFFile
Dynamic data of a loaded NewGRF.
Definition newgrf.h:114
GRFFile::cargo_map
std::array< uint8_t, NUM_CARGO > cargo_map
Inverse cargo translation table (CargoType -> local ID)
Definition newgrf.h:136
GRFFile::roadtype_list
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road)
Definition newgrf.h:144
GRFFile::tramtype_list
std::vector< RoadTypeLabel > tramtype_list
Roadtype translation table (tram)
Definition newgrf.h:147
GRFFile::cargo_list
std::vector< CargoLabel > cargo_list
Cargo translation table (local ID -> label)
Definition newgrf.h:135
GRFFile::traininfo_vehicle_width
uint traininfo_vehicle_width
Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details.
Definition newgrf.h:155
GRFFile::grf_features
GrfSpecFeatures grf_features
Bitset of GrfSpecFeature the grf uses.
Definition newgrf.h:158
GRFFile::traininfo_vehicle_pitch
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
Definition newgrf.h:154
GRFFile::language_map
std::unordered_map< uint8_t, LanguageMap > language_map
Mappings related to the languages.
Definition newgrf.h:152
GRFFile::labels
std::vector< GRFLabel > labels
List of labels.
Definition newgrf.h:133
GRFFile::price_base_multipliers
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition newgrf.h:159
GRFIdentifier::grfid
uint32_t grfid
GRF ID (defined by Action 0x08)
Definition newgrf_config.h:84
GRFLoadedFeatures
Definition newgrf.h:188
GRFLoadedFeatures::has_2CC
bool has_2CC
Set if any vehicle is loaded which uses 2cc (two company colours).
Definition newgrf.h:189
GRFLoadedFeatures::shore
ShoreReplacement shore
In which way shore sprites were replaced.
Definition newgrf.h:191
GRFLoadedFeatures::used_liveries
uint64_t used_liveries
Bitmask of LiveryScheme used by the defined engines.
Definition newgrf.h:190
GRFLoadedFeatures::tram
TramReplacement tram
In which way tram depots were replaced.
Definition newgrf.h:192
GRFTempEngineData::NONEMPTY
@ NONEMPTY
GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not av...
Definition newgrf_internal_vehicle.h:24
GameCreationSettings::landscape
LandscapeType landscape
the landscape we're currently in
Definition settings_type.h:395
GameCreationSettings::starting_year
TimerGameCalendar::Year starting_year
starting date
Definition settings_type.h:380
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition settings_type.h:634
GameSettings::vehicle
VehicleSettings vehicle
options for vehicles
Definition settings_type.h:641
GrfActionHandler
GRF action handler.
Definition newgrf_internal.h:37
GrfProcessingState
Temporary data during loading of GRFs.
Definition newgrf_internal.h:49
GrfProcessingState::file
SpriteFile * file
File of currently processed GRF file.
Definition newgrf_internal.h:66
GrfProcessingState::grffile
GRFFile * grffile
Currently processed GRF file.
Definition newgrf_internal.h:67
GrfProcessingState::nfo_line
uint32_t nfo_line
Currently processed pseudo sprite number in the GRF.
Definition newgrf_internal.h:69
GrfProcessingState::spriteid
SpriteID spriteid
First available SpriteID for loading realsprites.
Definition newgrf_internal.h:63
GrfProcessingState::grfconfig
GRFConfig * grfconfig
Config of the currently processed GRF file.
Definition newgrf_internal.h:68
GrfProcessingState::ClearDataForNextFile
void ClearDataForNextFile()
Clear temporary data before processing the next file in the current loading stage.
Definition newgrf_internal.h:78
GrfProcessingState::stage
GrfLoadingStage stage
Current loading stage.
Definition newgrf_internal.h:62
GrfProcessingState::skip_sprites
int skip_sprites
Number of pseudo sprites to skip before processing the next one. (-1 to skip to end of file)
Definition newgrf_internal.h:72
HouseSpec
Definition house.h:98
HouseSpec::accepts_cargo
CargoType accepts_cargo[HOUSE_NUM_ACCEPTS]
input cargo slots
Definition house.h:108
HouseSpec::grf_prop
SubstituteGRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:114
HouseSpec::enabled
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:111
HouseSpec::accepts_cargo_label
CargoLabel accepts_cargo_label[HOUSE_ORIGINAL_NUM_ACCEPTS]
input landscape cargo slots
Definition house.h:126
HouseSpec::Get
static HouseSpec * Get(size_t house_id)
Get the spec for a house ID.
Definition newgrf_house.cpp:70
HouseSpec::building_flags
BuildingFlags building_flags
some flags that describe the house (size, stadium etc...)
Definition house.h:109
HouseSpec::population
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:102
HouseSpec::cargo_acceptance
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:107
HouseSpec::building_availability
HouseZones building_availability
where can it be built (climates, zones)
Definition house.h:110
HouseSpec::Specs
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Definition newgrf_house.cpp:51
InvokeGrfActionHandler
Helper class to invoke a GrfActionHandler.
Definition newgrf.cpp:1212
LanguageMap
Mapping of language data between a NewGRF and OpenTTD.
Definition newgrf_text_type.h:35
LanguageMap::GetLanguageMap
static const LanguageMap * GetLanguageMap(uint32_t grfid, uint8_t language_id)
Get the language map associated with a given NewGRF and language.
Definition newgrf.cpp:357
ObjectSpec::BindToClasses
static void BindToClasses()
Tie all ObjectSpecs to their class.
Definition newgrf_object.cpp:115
PoolID< uint16_t, struct EngineIDTag, 64000, 0xFFFF >
Pool::PoolItem<&_engine_pool >::Iterate
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition pool_type.hpp:436
Pool::PoolItem<&_engine_pool >::GetPoolSize
static size_t GetPoolSize()
Returns first unused index.
Definition pool_type.hpp:408
Pool::PoolItem<&_engine_pool >::Get
static Titem * Get(auto index)
Returns Titem with given index.
Definition pool_type.hpp:387
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition pool_type.hpp:286
Pool::PoolItem<&_engine_pool >::CanAllocateItem
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Definition pool_type.hpp:357
Pool::CleanPool
void CleanPool() override
Virtual method that deletes all items in the pool.
PriceBaseSpec
Describes properties of price bases.
Definition newgrf.h:198
PriceBaseSpec::fallback_price
Price fallback_price
Fallback price multiplier for new prices but old grfs.
Definition newgrf.h:202
PriceBaseSpec::grf_feature
GrfSpecFeature grf_feature
GRF Feature that decides whether price multipliers apply locally or globally, GSF_END if none.
Definition newgrf.h:201
RailVehicleInfo
Information about a rail vehicle.
Definition engine_type.h:74
RailVehicleInfo::capacity
uint8_t capacity
Cargo capacity of vehicle; For multiheaded engines the capacity of each single engine.
Definition engine_type.h:87
RoadVehicleInfo
Information about a road vehicle.
Definition engine_type.h:146
RoadVehicleInfo::roadtype
RoadType roadtype
Road type.
Definition engine_type.h:160
SetBitIterator
Iterable ensemble of each set bit in a value.
Definition bitmath_func.hpp:277
ShipVehicleInfo
Information about a ship vehicle.
Definition engine_type.h:99
ShipVehicleInfo::old_refittable
bool old_refittable
Is ship refittable; only used during initialisation. Later use EngineInfo::refit_mask.
Definition engine_type.h:107
StrongType::Typedef< uint32_t, struct CargoLabelTag, StrongType::Compare >
VehicleSettings::dynamic_engines
bool dynamic_engines
enable dynamic allocation of engine data
Definition settings_type.h:532
town.h
Base of the town class.
_display_opt
uint8_t _display_opt
What do we want to draw/do?
Definition transparency_gui.cpp:26
GetEngineLiveryScheme
LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
Determines the LiveryScheme for a vehicle.
Definition vehicle.cpp:1951
vehicle_base.h
Base class for all vehicles.
VehicleType
VehicleType
Available vehicle types.
Definition vehicle_type.h:22
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition vehicle_type.h:26
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition vehicle_type.h:28
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition vehicle_type.h:27
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition vehicle_type.h:25