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