OpenTTD Source 20250702-master-g226b098c55
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 <http://www.gnu.org/licenses/>.
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
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
63static std::vector<GRFFile> _grf_files;
64
65std::span<const GRFFile> GetAllGRFFiles()
66{
67 return _grf_files;
68}
69
72
75
76GrfProcessingState _cur_gps;
77
79
90void 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
104GRFFile *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
116static 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
125{
126 gf->labels.clear();
127}
128
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 config->error = {STR_NEWGRF_ERROR_MSG_FATAL, message};
152 if (config == _cur_gps.grfconfig) config->error->param_value[0] = _cur_gps.nfo_line;
153 return &config->error.value();
154}
155
166{
167 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, &c);
168 error->data = _cur_gps.grfconfig->GetName();
169}
170
171static std::map<uint32_t, uint32_t> _grf_id_overrides;
172
178void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
179{
180 if (target_grfid == 0) {
181 _grf_id_overrides.erase(source_grfid);
182 GrfMsg(5, "SetNewGRFOverride: Removed override of 0x{:X}", std::byteswap(source_grfid));
183 } else {
184 _grf_id_overrides[source_grfid] = target_grfid;
185 GrfMsg(5, "SetNewGRFOverride: Added override of 0x{:X} to 0x{:X}", std::byteswap(source_grfid), std::byteswap(target_grfid));
186 }
187}
188
194{
195 auto found = _grf_id_overrides.find(_cur_gps.grffile->grfid);
196 if (found != std::end(_grf_id_overrides)) {
197 GRFFile *grffile = GetFileByGRFID(found->second);
198 if (grffile != nullptr) return grffile;
199 }
200 return nullptr;
201}
202
211Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16_t internal_id, bool static_access)
212{
213 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
214 * them use the same engine slots. */
215 uint32_t scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
217 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
218 scope_grfid = file->grfid;
219 if (auto it = _grf_id_overrides.find(file->grfid); it != std::end(_grf_id_overrides)) {
220 scope_grfid = it->second;
221 const GRFFile *grf_match = GetFileByGRFID(scope_grfid);
222 if (grf_match == nullptr) {
223 GrfMsg(5, "Tried mapping from GRFID {:x} to {:x} but target is not loaded", std::byteswap(file->grfid), std::byteswap(scope_grfid));
224 } else {
225 GrfMsg(5, "Mapping from GRFID {:x} to {:x}", std::byteswap(file->grfid), std::byteswap(scope_grfid));
226 }
227 }
228
229 /* Check if the engine is registered in the override manager */
230 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
231 if (engine != EngineID::Invalid()) {
232 Engine *e = Engine::Get(engine);
233 if (!e->grf_prop.HasGrfFile()) {
234 e->grf_prop.SetGRFFile(file);
235 }
236 return e;
237 }
238 }
239
240 /* Check if there is an unreserved slot */
241 EngineID engine = _engine_mngr.UseUnreservedID(type, internal_id, scope_grfid, static_access);
242 if (engine != EngineID::Invalid()) {
243 Engine *e = Engine::Get(engine);
244
245 if (!e->grf_prop.HasGrfFile()) {
246 e->grf_prop.SetGRFFile(file);
247 GrfMsg(5, "Replaced engine at index {} for GRFID {:x}, type {}, index {}", e->index, std::byteswap(file->grfid), type, internal_id);
248 }
249
250 return e;
251 }
252
253 if (static_access) return nullptr;
254
256 GrfMsg(0, "Can't allocate any more engines");
257 return nullptr;
258 }
259
260 size_t engine_pool_size = Engine::GetPoolSize();
261
262 /* ... it's not, so create a new one based off an existing engine */
263 Engine *e = new Engine(type, internal_id);
264 e->grf_prop.SetGRFFile(file);
265
266 /* Reserve the engine slot */
267 _engine_mngr.SetID(type, internal_id, scope_grfid, std::min<uint8_t>(internal_id, _engine_counts[type]), e->index);
268
269 if (engine_pool_size != Engine::GetPoolSize()) {
270 /* Resize temporary engine data ... */
271 _gted.resize(Engine::GetPoolSize());
272 }
273 if (type == VEH_TRAIN) {
274 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
275 }
276
277 GrfMsg(5, "Created new engine at index {} for GRFID {:x}, type {}, index {}", e->index, std::byteswap(file->grfid), type, internal_id);
278
279 return e;
280}
281
292EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal_id)
293{
294 uint32_t scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
296 scope_grfid = file->grfid;
297 if (auto it = _grf_id_overrides.find(file->grfid); it != std::end(_grf_id_overrides)) {
298 scope_grfid = it->second;
299 }
300 }
301
302 return _engine_mngr.GetID(type, internal_id, scope_grfid);
303}
304
305
306
307
311CargoTypes TranslateRefitMask(uint32_t refit_mask)
312{
313 CargoTypes result = 0;
314 for (uint8_t bit : SetBitIterator(refit_mask)) {
315 CargoType cargo = GetCargoTranslation(bit, _cur_gps.grffile, true);
316 if (IsValidCargoType(cargo)) SetBit(result, cargo);
317 }
318 return result;
319}
320
328void ConvertTTDBasePrice(uint32_t base_pointer, std::string_view error_location, Price *index)
329{
330 /* Special value for 'none' */
331 if (base_pointer == 0) {
332 *index = INVALID_PRICE;
333 return;
334 }
335
336 static const uint32_t start = 0x4B34;
337 static const uint32_t size = 6;
338
339 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
340 GrfMsg(1, "{}: Unsupported running cost base 0x{:04X}, ignoring", error_location, base_pointer);
341 return;
342 }
343
344 *index = (Price)((base_pointer - start) / size);
345}
346
353/* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32_t grfid, uint8_t language_id)
354{
355 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
356 const GRFFile *grffile = GetFileByGRFID(grfid);
357 if (grffile == nullptr) return nullptr;
358
359 auto it = grffile->language_map.find(language_id);
360 if (it == std::end(grffile->language_map)) return nullptr;
361
362 return &it->second;
363}
364
370{
372
373 /* Skip remainder of GRF */
374 _cur_gps.skip_sprites = -1;
375}
376
378static void ResetNewGRF()
379{
380 _cur_gps.grfconfig = nullptr;
381 _cur_gps.grffile = nullptr;
382 _grf_files.clear();
383
384 /* We store pointers to GRFFiles in many places, so need to ensure that the pointers do not become invalid
385 * due to vector reallocation. Should not happen due to loading taking place in multiple stages, but
386 * reserving when the size is known is good practice anyway. */
387 _grf_files.reserve(_grfconfig.size());
388}
389
391static void ResetNewGRFErrors()
392{
393 for (const auto &c : _grfconfig) {
394 c->error.reset();
395 }
396}
397
398extern void ResetCallbacks(bool final);
399extern void ResetGRM();
400
405{
407 CleanUpGRFTownNames();
408
409 ResetBadges();
410
411 /* Copy/reset original engine info data */
412 SetupEngines();
413
414 /* Copy/reset original bridge info data */
415 ResetBridges();
416
417 /* Reset rail type information */
419
420 /* Copy/reset original road type info data */
422
423 /* Allocate temporary refit/cargo class data */
424 _gted.resize(Engine::GetPoolSize());
425
426 /* Fill rail type label temporary data for default trains */
427 for (const Engine *e : Engine::IterateType(VEH_TRAIN)) {
428 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
429 }
430
431 /* Reset GRM reservations */
432 ResetGRM();
433
434 /* Reset generic feature callback lists */
436
437 /* Reset price base data */
439
440 /* Reset the curencies array */
442
443 /* Reset the house array */
444 ResetHouses();
445
446 /* Reset the industries structures*/
448
449 /* Reset the objects. */
451 ResetObjects();
452
453 /* Reset station classes */
455
456 /* Reset airport-related structures */
460
461 /* Reset road stop classes */
463
464 /* Reset canal sprite groups and flags */
465 _water_feature.fill({});
466
467 ResetFaces();
468
469 /* Reset the snowline table. */
471
472 /* Reset NewGRF files */
473 ResetNewGRF();
474
475 /* Reset NewGRF errors. */
477
478 /* Set up the default cargo types */
480
481 /* Reset misc GRF features and train list display variables */
483
485 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
488
489 /* Clear all GRF overrides */
490 _grf_id_overrides.clear();
491
492 InitializeSoundPool();
493 _spritegroup_pool.CleanPool();
494 ResetCallbacks(false);
495}
496
501{
502 /* Reset override managers */
503 _engine_mngr.ResetToDefaultMapping();
504 _house_mngr.ResetMapping();
505 _industry_mngr.ResetMapping();
506 _industile_mngr.ResetMapping();
507 _airport_mngr.ResetMapping();
508 _airporttile_mngr.ResetMapping();
509}
510
516 std::span<const CargoLabel> GetCargoTranslationTable(const GRFFile &grffile)
517 {
518 /* Always use the translation table if it's installed. */
519 if (!grffile.cargo_list.empty()) return grffile.cargo_list;
520
521 /* Pre-v7 use climate-dependent "slot" table. */
522 if (grffile.grf_version < 7) return GetClimateDependentCargoTranslationTable();
523
524 /* Otherwise use climate-independent "bitnum" table. */
526 }
527
533{
534 _cur_gps.grffile->cargo_map.fill(UINT8_MAX);
535
536 auto cargo_list = GetCargoTranslationTable(*_cur_gps.grffile);
537
538 for (const CargoSpec *cs : CargoSpec::Iterate()) {
539 /* Check the translation table for this cargo's label */
540 int idx = find_index(cargo_list, cs->label);
541 if (idx >= 0) _cur_gps.grffile->cargo_map[cs->Index()] = idx;
542 }
543}
544
549static void InitNewGRFFile(const GRFConfig &config)
550{
551 GRFFile *newfile = GetFileByFilename(config.filename);
552 if (newfile != nullptr) {
553 /* We already loaded it once. */
554 _cur_gps.grffile = newfile;
555 return;
556 }
557
558 assert(_grf_files.size() < _grf_files.capacity()); // We must not invalidate pointers.
559 _cur_gps.grffile = &_grf_files.emplace_back(config);
560}
561
566GRFFile::GRFFile(const GRFConfig &config)
567{
568 this->filename = config.filename;
569 this->grfid = config.ident.grfid;
570
571 /* Initialise local settings to defaults */
572 this->traininfo_vehicle_pitch = 0;
573 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
574
575 /* Mark price_base_multipliers as 'not set' */
576 this->price_base_multipliers.fill(INVALID_PRICE_MODIFIER);
577
578 /* Initialise rail type map with default rail types */
579 this->railtype_map.fill(INVALID_RAILTYPE);
580 this->railtype_map[0] = RAILTYPE_RAIL;
581 this->railtype_map[1] = RAILTYPE_ELECTRIC;
582 this->railtype_map[2] = RAILTYPE_MONO;
583 this->railtype_map[3] = RAILTYPE_MAGLEV;
584
585 /* Initialise road type map with default road types */
586 this->roadtype_map.fill(INVALID_ROADTYPE);
587 this->roadtype_map[0] = ROADTYPE_ROAD;
588
589 /* Initialise tram type map with default tram types */
590 this->tramtype_map.fill(INVALID_ROADTYPE);
591 this->tramtype_map[0] = ROADTYPE_TRAM;
592
593 /* Copy the initial parameter list */
594 this->param = config.param;
595}
596
597/* Some compilers get confused about vectors of unique_ptrs. */
598GRFFile::GRFFile() = default;
599GRFFile::GRFFile(GRFFile &&other) = default;
600GRFFile::~GRFFile() = default;
601
607static CargoLabel GetActiveCargoLabel(const std::initializer_list<CargoLabel> &labels)
608{
609 for (const CargoLabel &label : labels) {
610 CargoType cargo_type = GetCargoTypeByLabel(label);
611 if (cargo_type != INVALID_CARGO) return label;
612 }
613 return CT_INVALID;
614}
615
621static CargoLabel GetActiveCargoLabel(const std::variant<CargoLabel, MixedCargoType> &label)
622{
623 struct visitor {
624 CargoLabel operator()(const CargoLabel &label) { return label; }
625 CargoLabel operator()(const MixedCargoType &mixed)
626 {
627 switch (mixed) {
628 case MCT_LIVESTOCK_FRUIT: return GetActiveCargoLabel({CT_LIVESTOCK, CT_FRUIT});
629 case MCT_GRAIN_WHEAT_MAIZE: return GetActiveCargoLabel({CT_GRAIN, CT_WHEAT, CT_MAIZE});
630 case MCT_VALUABLES_GOLD_DIAMONDS: return GetActiveCargoLabel({CT_VALUABLES, CT_GOLD, CT_DIAMONDS});
631 default: NOT_REACHED();
632 }
633 }
634 };
635
636 return std::visit(visitor{}, label);
637}
638
643{
644 CargoTypes original_known_cargoes = 0;
645 for (CargoType cargo_type = 0; cargo_type != NUM_CARGO; ++cargo_type) {
646 if (IsDefaultCargo(cargo_type)) SetBit(original_known_cargoes, cargo_type);
647 }
648
649 for (Engine *e : Engine::Iterate()) {
650 EngineID engine = e->index;
651 EngineInfo *ei = &e->info;
652 bool only_defaultcargo;
653
654 /* Apply default cargo translation map if cargo type hasn't been set, either explicitly or by aircraft cargo handling. */
655 if (!IsValidCargoType(e->info.cargo_type)) {
656 e->info.cargo_type = GetCargoTypeByLabel(GetActiveCargoLabel(e->info.cargo_label));
657 }
658
659 /* If the NewGRF did not set any cargo properties, we apply default values. */
660 if (_gted[engine].defaultcargo_grf == nullptr) {
661 /* If the vehicle has any capacity, apply the default refit masks */
662 if (e->type != VEH_TRAIN || e->u.rail.capacity != 0) {
663 static constexpr LandscapeType T = LandscapeType::Temperate;
664 static constexpr LandscapeType A = LandscapeType::Arctic;
665 static constexpr LandscapeType S = LandscapeType::Tropic;
666 static constexpr LandscapeType Y = LandscapeType::Toyland;
667 static const struct DefaultRefitMasks {
668 LandscapeTypes climate;
669 CargoLabel cargo_label;
670 CargoClasses cargo_allowed;
671 CargoClasses cargo_disallowed;
672 } _default_refit_masks[] = {
673 {{T, A, S, Y}, CT_PASSENGERS, {CargoClass::Passengers}, {}},
674 {{T, A, S }, CT_MAIL, {CargoClass::Mail}, {}},
675 {{T, A, S }, CT_VALUABLES, {CargoClass::Armoured}, {CargoClass::Liquid}},
677 {{T, A }, CT_COAL, {CargoClass::Bulk}, {}},
678 {{ S }, CT_COPPER_ORE, {CargoClass::Bulk}, {}},
679 {{ Y}, CT_SUGAR, {CargoClass::Bulk}, {}},
680 {{T, A, S }, CT_OIL, {CargoClass::Liquid}, {}},
681 {{ Y}, CT_COLA, {CargoClass::Liquid}, {}},
684 {{ A, S }, CT_FOOD, {CargoClass::Refrigerated}, {}},
686 };
687
688 if (e->type == VEH_AIRCRAFT) {
689 /* Aircraft default to "light" cargoes */
691 _gted[engine].cargo_disallowed = {CargoClass::Liquid};
692 } else if (e->type == VEH_SHIP) {
693 CargoLabel label = GetActiveCargoLabel(ei->cargo_label);
694 switch (label.base()) {
695 case CT_PASSENGERS.base():
696 /* Ferries */
697 _gted[engine].cargo_allowed = {CargoClass::Passengers};
698 _gted[engine].cargo_disallowed = {};
699 break;
700 case CT_OIL.base():
701 /* Tankers */
702 _gted[engine].cargo_allowed = {CargoClass::Liquid};
703 _gted[engine].cargo_disallowed = {};
704 break;
705 default:
706 /* Cargo ships */
707 if (_settings_game.game_creation.landscape == LandscapeType::Toyland) {
708 /* No tanker in toyland :( */
710 _gted[engine].cargo_disallowed = {CargoClass::Passengers};
711 } else {
713 _gted[engine].cargo_disallowed = {CargoClass::Liquid, CargoClass::Passengers};
714 }
715 break;
716 }
717 e->u.ship.old_refittable = true;
718 } else if (e->type == VEH_TRAIN && e->u.rail.railveh_type != RAILVEH_WAGON) {
719 /* Train engines default to all cargoes, so you can build single-cargo consists with fast engines.
720 * Trains loading multiple cargoes may start stations accepting unwanted cargoes. */
722 _gted[engine].cargo_disallowed = {};
723 } else {
724 /* Train wagons and road vehicles are classified by their default cargo type */
725 CargoLabel label = GetActiveCargoLabel(ei->cargo_label);
726 for (const auto &drm : _default_refit_masks) {
727 if (!drm.climate.Test(_settings_game.game_creation.landscape)) continue;
728 if (drm.cargo_label != label) continue;
729
730 _gted[engine].cargo_allowed = drm.cargo_allowed;
731 _gted[engine].cargo_disallowed = drm.cargo_disallowed;
732 break;
733 }
734
735 /* All original cargoes have specialised vehicles, so exclude them */
736 _gted[engine].ctt_exclude_mask = original_known_cargoes;
737 }
738 }
739 _gted[engine].UpdateRefittability(_gted[engine].cargo_allowed.Any());
740
741 if (IsValidCargoType(ei->cargo_type)) ClrBit(_gted[engine].ctt_exclude_mask, ei->cargo_type);
742 }
743
744 /* Compute refittability */
745 {
746 CargoTypes mask = 0;
747 CargoTypes not_mask = 0;
748 CargoTypes xor_mask = ei->refit_mask;
749
750 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
751 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
752 only_defaultcargo = _gted[engine].refittability != GRFTempEngineData::NONEMPTY;
753
754 if (_gted[engine].cargo_allowed.Any()) {
755 /* Build up the list of cargo types from the set cargo classes. */
756 for (const CargoSpec *cs : CargoSpec::Iterate()) {
757 if (cs->classes.Any(_gted[engine].cargo_allowed) && cs->classes.All(_gted[engine].cargo_allowed_required)) SetBit(mask, cs->Index());
758 if (cs->classes.Any(_gted[engine].cargo_disallowed)) SetBit(not_mask, cs->Index());
759 }
760 }
761
762 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
763
764 /* Apply explicit refit includes/excludes. */
765 ei->refit_mask |= _gted[engine].ctt_include_mask;
766 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
767
768 /* Custom refit mask callback. */
769 const GRFFile *file = _gted[e->index].defaultcargo_grf;
770 if (file == nullptr) file = e->GetGRF();
771 if (file != nullptr && e->info.callback_mask.Test(VehicleCallbackMask::CustomRefit)) {
772 for (const CargoSpec *cs : CargoSpec::Iterate()) {
773 uint8_t local_slot = file->cargo_map[cs->Index()];
774 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_CUSTOM_REFIT, cs->classes.base(), local_slot, engine, nullptr);
775 switch (callback) {
776 case CALLBACK_FAILED:
777 case 0:
778 break; // Do nothing.
779 case 1: SetBit(ei->refit_mask, cs->Index()); break;
780 case 2: ClrBit(ei->refit_mask, cs->Index()); break;
781
782 default: ErrorUnknownCallbackResult(file->grfid, CBID_VEHICLE_CUSTOM_REFIT, callback);
783 }
784 }
785 }
786 }
787
788 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
789 if (IsValidCargoType(ei->cargo_type) && !HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = INVALID_CARGO;
790
791 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
792 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
793 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && IsValidCargoType(ei->cargo_type) && !HasBit(ei->refit_mask, ei->cargo_type)) {
794 ei->cargo_type = INVALID_CARGO;
795 }
796
797 /* Check if this engine's cargo type is valid. If not, set to the first refittable
798 * cargo type. Finally disable the vehicle, if there is still no cargo. */
799 if (!IsValidCargoType(ei->cargo_type) && ei->refit_mask != 0) {
800 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
801 const GRFFile *file = _gted[engine].defaultcargo_grf;
802 if (file == nullptr) file = e->GetGRF();
803 if (file != nullptr && file->grf_version >= 8 && !file->cargo_list.empty()) {
804 /* Use first refittable cargo from cargo translation table */
805 uint8_t best_local_slot = UINT8_MAX;
806 for (CargoType cargo_type : SetCargoBitIterator(ei->refit_mask)) {
807 uint8_t local_slot = file->cargo_map[cargo_type];
808 if (local_slot < best_local_slot) {
809 best_local_slot = local_slot;
810 ei->cargo_type = cargo_type;
811 }
812 }
813 }
814
815 if (!IsValidCargoType(ei->cargo_type)) {
816 /* Use first refittable cargo slot */
817 ei->cargo_type = (CargoType)FindFirstBit(ei->refit_mask);
818 }
819 }
820 if (!IsValidCargoType(ei->cargo_type) && e->type == VEH_TRAIN && e->u.rail.railveh_type != RAILVEH_WAGON && e->u.rail.capacity == 0) {
821 /* For train engines which do not carry cargo it does not matter if their cargo type is invalid.
822 * Fallback to the first available instead, if the cargo type has not been changed (as indicated by
823 * cargo_label not being CT_INVALID). */
824 if (GetActiveCargoLabel(ei->cargo_label) != CT_INVALID) {
825 ei->cargo_type = static_cast<CargoType>(FindFirstBit(_standard_cargo_mask));
826 }
827 }
828 if (!IsValidCargoType(ei->cargo_type)) ei->climates = {};
829
830 /* Clear refit_mask for not refittable ships */
831 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
832 ei->refit_mask = 0;
833 }
834 }
835}
836
838static void FinaliseCanals()
839{
840 for (uint i = 0; i < CF_END; i++) {
841 if (_water_feature[i].grffile != nullptr) {
842 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
843 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
844 }
845 }
846}
847
850{
851 for (Engine *e : Engine::Iterate()) {
852 if (e->GetGRF() == nullptr) {
853 auto found = std::ranges::find(_engine_mngr.mappings[e->type], e->index, &EngineIDMapping::engine);
854 if (found == std::end(_engine_mngr.mappings[e->type]) || found->grfid != INVALID_GRFID || found->internal_id != found->substitute_id) {
855 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
856 }
857 }
858
859 /* Do final mapping on variant engine ID. */
860 if (e->info.variant_id != EngineID::Invalid()) {
861 e->info.variant_id = GetNewEngineID(e->grf_prop.grffile, e->type, e->info.variant_id.base());
862 }
863
864 if (!e->info.climates.Test(_settings_game.game_creation.landscape)) continue;
865
866 switch (e->type) {
867 case VEH_TRAIN: AppendCopyableBadgeList(e->badges, GetRailTypeInfo(e->u.rail.railtype)->badges, GSF_TRAINS); break;
868 case VEH_ROAD: AppendCopyableBadgeList(e->badges, GetRoadTypeInfo(e->u.road.roadtype)->badges, GSF_ROADVEHICLES); break;
869 default: break;
870 }
871
872 /* Skip wagons, there livery is defined via the engine */
873 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
874 LiveryScheme ls = GetEngineLiveryScheme(e->index, EngineID::Invalid(), nullptr);
876 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
877
878 if (e->type == VEH_TRAIN) {
880 switch (ls) {
881 case LS_STEAM:
882 case LS_DIESEL:
883 case LS_ELECTRIC:
884 case LS_MONORAIL:
885 case LS_MAGLEV:
886 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
887 break;
888
889 case LS_DMU:
890 case LS_EMU:
891 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
892 break;
893
894 default: NOT_REACHED();
895 }
896 }
897 }
898 }
899
900 /* Check engine variants don't point back on themselves (either directly or via a loop) then set appropriate flags
901 * on variant engine. This is performed separately as all variant engines need to have been resolved. */
902 for (Engine *e : Engine::Iterate()) {
903 EngineID parent = e->info.variant_id;
904 while (parent != EngineID::Invalid()) {
905 parent = Engine::Get(parent)->info.variant_id;
906 if (parent != e->index) continue;
907
908 /* Engine looped back on itself, so clear the variant. */
909 e->info.variant_id = EngineID::Invalid();
910
911 GrfMsg(1, "FinaliseEngineArray: Variant of engine {:x} in '{}' loops back on itself", e->grf_prop.local_id, e->GetGRF()->filename);
912 break;
913 }
914
915 if (e->info.variant_id != EngineID::Invalid()) {
916 Engine::Get(e->info.variant_id)->display_flags.Set({EngineDisplayFlag::HasVariants, EngineDisplayFlag::IsFolded});
917 }
918 }
919}
920
923{
924 for (CargoSpec &cs : CargoSpec::array) {
925 if (cs.town_production_effect == INVALID_TPE) {
926 /* Set default town production effect by cargo label. */
927 switch (cs.label.base()) {
928 case CT_PASSENGERS.base(): cs.town_production_effect = TPE_PASSENGERS; break;
929 case CT_MAIL.base(): cs.town_production_effect = TPE_MAIL; break;
930 default: cs.town_production_effect = TPE_NONE; break;
931 }
932 }
933 if (!cs.IsValid()) {
934 cs.name = cs.name_single = cs.units_volume = STR_NEWGRF_INVALID_CARGO;
935 cs.quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
936 cs.abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
937 }
938 }
939}
940
952static bool IsHouseSpecValid(HouseSpec &hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const std::string &filename)
953{
954 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) &&
955 (next1 == nullptr || !next1->enabled || next1->building_flags.Any(BUILDING_HAS_1_TILE))) ||
956 (hs.building_flags.Any(BUILDING_HAS_4_TILES) &&
957 (next2 == nullptr || !next2->enabled || next2->building_flags.Any(BUILDING_HAS_1_TILE) ||
958 next3 == nullptr || !next3->enabled || next3->building_flags.Any(BUILDING_HAS_1_TILE)))) {
959 hs.enabled = false;
960 if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs.grf_prop.local_id);
961 return false;
962 }
963
964 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
965 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
966 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
967 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) && next1->population != 0) ||
968 (hs.building_flags.Any(BUILDING_HAS_4_TILES) && (next2->population != 0 || next3->population != 0))) {
969 hs.enabled = false;
970 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);
971 return false;
972 }
973
974 /* Substitute type is also used for override, and having an override with a different size causes crashes.
975 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
976 if (!filename.empty() && (hs.building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs.grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
977 hs.enabled = false;
978 Debug(grf, 1, "FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs.grf_prop.local_id);
979 return false;
980 }
981
982 /* Make sure that additional parts of multitile houses are not available. */
983 if (!hs.building_flags.Any(BUILDING_HAS_1_TILE) && hs.building_availability.Any(HZ_ZONE_ALL) && hs.building_availability.Any(HZ_CLIMATE_ALL)) {
984 hs.enabled = false;
985 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);
986 return false;
987 }
988
989 return true;
990}
991
998static void EnsureEarlyHouse(HouseZones bitmask)
999{
1001
1002 for (const auto &hs : HouseSpec::Specs()) {
1003 if (!hs.enabled) continue;
1004 if (!hs.building_availability.All(bitmask)) continue;
1005 if (hs.min_year < min_year) min_year = hs.min_year;
1006 }
1007
1008 if (min_year == 0) return;
1009
1010 for (auto &hs : HouseSpec::Specs()) {
1011 if (!hs.enabled) continue;
1012 if (!hs.building_availability.All(bitmask)) continue;
1013 if (hs.min_year == min_year) hs.min_year = CalendarTime::MIN_YEAR;
1014 }
1015}
1016
1024{
1025 /* If there are no houses with start dates before 1930, then all houses
1026 * with start dates of 1930 have them reset to 0. This is in order to be
1027 * compatible with TTDPatch, where if no houses have start dates before
1028 * 1930 and the date is before 1930, the game pretends that this is 1930.
1029 * If there have been any houses defined with start dates before 1930 then
1030 * the dates are left alone.
1031 * On the other hand, why 1930? Just 'fix' the houses with the lowest
1032 * minimum introduction date to 0.
1033 */
1034 for (auto &file : _grf_files) {
1035 if (file.housespec.empty()) continue;
1036
1037 size_t num_houses = file.housespec.size();
1038 for (size_t i = 0; i < num_houses; i++) {
1039 auto &hs = file.housespec[i];
1040
1041 if (hs == nullptr) continue;
1042
1043 const HouseSpec *next1 = (i + 1 < num_houses ? file.housespec[i + 1].get() : nullptr);
1044 const HouseSpec *next2 = (i + 2 < num_houses ? file.housespec[i + 2].get() : nullptr);
1045 const HouseSpec *next3 = (i + 3 < num_houses ? file.housespec[i + 3].get() : nullptr);
1046
1047 if (!IsHouseSpecValid(*hs, next1, next2, next3, file.filename)) continue;
1048
1049 _house_mngr.SetEntitySpec(std::move(*hs));
1050 }
1051
1052 /* Won't be used again */
1053 file.housespec.clear();
1054 file.housespec.shrink_to_fit();
1055 }
1056
1057 for (size_t i = 0; i < HouseSpec::Specs().size(); i++) {
1058 HouseSpec *hs = HouseSpec::Get(i);
1059 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr);
1060 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr);
1061 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : nullptr);
1062
1063 /* We need to check all houses again to we are sure that multitile houses
1064 * did get consecutive IDs and none of the parts are missing. */
1065 if (!IsHouseSpecValid(*hs, next1, next2, next3, std::string{})) {
1066 /* GetHouseNorthPart checks 3 houses that are directly before
1067 * it in the house pool. If any of those houses have multi-tile
1068 * flags set it assumes it's part of a multitile house. Since
1069 * we can have invalid houses in the pool marked as disabled, we
1070 * don't want to have them influencing valid tiles. As such set
1071 * building_flags to zero here to make sure any house following
1072 * this one in the pool is properly handled as 1x1 house. */
1073 hs->building_flags = {};
1074 }
1075
1076 /* Apply default cargo translation map for unset cargo slots */
1077 for (uint i = 0; i < lengthof(hs->accepts_cargo_label); ++i) {
1078 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->accepts_cargo[i] = GetCargoTypeByLabel(hs->accepts_cargo_label[i]);
1079 /* Disable acceptance if cargo type is invalid. */
1080 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->cargo_acceptance[i] = 0;
1081 }
1082 }
1083
1084 HouseZones climate_mask = GetClimateMaskForLandscape();
1085 for (HouseZone climate : climate_mask) {
1086 for (HouseZone zone : HZ_ZONE_ALL) {
1087 EnsureEarlyHouse({climate, zone});
1088 }
1089 }
1090}
1091
1098{
1099 for (auto &file : _grf_files) {
1100 for (auto &indsp : file.industryspec) {
1101 if (indsp == nullptr || !indsp->enabled) continue;
1102
1103 _industry_mngr.SetEntitySpec(std::move(*indsp));
1104 }
1105
1106 for (auto &indtsp : file.indtspec) {
1107 if (indtsp != nullptr) {
1108 _industile_mngr.SetEntitySpec(std::move(*indtsp));
1109 }
1110 }
1111
1112 /* Won't be used again */
1113 file.industryspec.clear();
1114 file.industryspec.shrink_to_fit();
1115 file.indtspec.clear();
1116 file.indtspec.shrink_to_fit();
1117 }
1118
1119 for (auto &indsp : _industry_specs) {
1120 if (indsp.enabled && indsp.grf_prop.HasGrfFile()) {
1121 for (auto &conflicting : indsp.conflicting) {
1122 conflicting = MapNewGRFIndustryType(conflicting, indsp.grf_prop.grfid);
1123 }
1124 }
1125 if (!indsp.enabled) {
1126 indsp.name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
1127 }
1128
1129 /* Apply default cargo translation map for unset cargo slots */
1130 for (size_t i = 0; i < std::size(indsp.produced_cargo_label); ++i) {
1131 if (!IsValidCargoType(indsp.produced_cargo[i])) indsp.produced_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.produced_cargo_label[i]));
1132 }
1133 for (size_t i = 0; i < std::size(indsp.accepts_cargo_label); ++i) {
1134 if (!IsValidCargoType(indsp.accepts_cargo[i])) indsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.accepts_cargo_label[i]));
1135 }
1136 }
1137
1138 for (auto &indtsp : _industry_tile_specs) {
1139 /* Apply default cargo translation map for unset cargo slots */
1140 for (size_t i = 0; i < std::size(indtsp.accepts_cargo_label); ++i) {
1141 if (!IsValidCargoType(indtsp.accepts_cargo[i])) indtsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indtsp.accepts_cargo_label[i]));
1142 }
1143 }
1144}
1145
1152{
1153 for (auto &file : _grf_files) {
1154 for (auto &objectspec : file.objectspec) {
1155 if (objectspec != nullptr && objectspec->grf_prop.HasGrfFile() && objectspec->IsEnabled()) {
1156 _object_mngr.SetEntitySpec(std::move(*objectspec));
1157 }
1158 }
1159
1160 /* Won't be used again */
1161 file.objectspec.clear();
1162 file.objectspec.shrink_to_fit();
1163 }
1164
1166}
1167
1174{
1175 for (auto &file : _grf_files) {
1176 for (auto &as : file.airportspec) {
1177 if (as != nullptr && as->enabled) {
1178 _airport_mngr.SetEntitySpec(std::move(*as));
1179 }
1180 }
1181
1182 for (auto &ats : file.airtspec) {
1183 if (ats != nullptr && ats->enabled) {
1184 _airporttile_mngr.SetEntitySpec(std::move(*ats));
1185 }
1186 }
1187
1188 /* Won't be used again */
1189 file.airportspec.clear();
1190 file.airportspec.shrink_to_fit();
1191 file.airtspec.clear();
1192 file.airtspec.shrink_to_fit();
1193 }
1194}
1195
1198 template <uint8_t TAction>
1199 static void Invoke(ByteReader &buf, GrfLoadingStage stage)
1200 {
1201 switch (stage) {
1202 case GLS_FILESCAN: GrfActionHandler<TAction>::FileScan(buf); break;
1203 case GLS_SAFETYSCAN: GrfActionHandler<TAction>::SafetyScan(buf); break;
1204 case GLS_LABELSCAN: GrfActionHandler<TAction>::LabelScan(buf); break;
1205 case GLS_INIT: GrfActionHandler<TAction>::Init(buf); break;
1206 case GLS_RESERVE: GrfActionHandler<TAction>::Reserve(buf); break;
1207 case GLS_ACTIVATION: GrfActionHandler<TAction>::Activation(buf); break;
1208 default: NOT_REACHED();
1209 }
1210 }
1211
1212 using Invoker = void(*)(ByteReader &buf, GrfLoadingStage stage);
1213 static constexpr Invoker funcs[] = { // Must be listed in action order.
1214 Invoke<0x00>, Invoke<0x01>, Invoke<0x02>, Invoke<0x03>, Invoke<0x04>, Invoke<0x05>, Invoke<0x06>, Invoke<0x07>,
1215 Invoke<0x08>, Invoke<0x09>, Invoke<0x0A>, Invoke<0x0B>, Invoke<0x0C>, Invoke<0x0D>, Invoke<0x0E>, Invoke<0x0F>,
1216 Invoke<0x10>, Invoke<0x11>, Invoke<0x12>, Invoke<0x13>, Invoke<0x14>,
1217 };
1218
1219 static void Invoke(uint8_t action, GrfLoadingStage stage, ByteReader &buf)
1220 {
1221 Invoker func = action < std::size(funcs) ? funcs[action] : nullptr;
1222 if (func == nullptr) {
1223 GrfMsg(7, "DecodeSpecialSprite: Skipping unknown action 0x{:02X}", action);
1224 } else {
1225 GrfMsg(7, "DecodeSpecialSprite: Handling action 0x{:02X} in stage {}", action, stage);
1226 func(buf, stage);
1227 }
1228 }
1229};
1230
1231/* Here we perform initial decoding of some special sprites (as are they
1232 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
1233 * partial implementation yet).
1234 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
1235 * a crafted invalid GRF file. We should tell that to the user somehow, or
1236 * better make this more robust in the future. */
1237static void DecodeSpecialSprite(ReusableBuffer<uint8_t> &allocator, uint num, GrfLoadingStage stage)
1238{
1239 uint8_t *buf;
1240 auto it = _grf_line_to_action6_sprite_override.find({_cur_gps.grfconfig->ident.grfid, _cur_gps.nfo_line});
1241 if (it == _grf_line_to_action6_sprite_override.end()) {
1242 /* No preloaded sprite to work with; read the
1243 * pseudo sprite content. */
1244 buf = allocator.Allocate(num);
1245 _cur_gps.file->ReadBlock(buf, num);
1246 } else {
1247 /* Use the preloaded sprite data. */
1248 buf = it->second.data();
1249 assert(it->second.size() == num);
1250 GrfMsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
1251
1252 /* Skip the real (original) content of this action. */
1253 _cur_gps.file->SeekTo(num, SEEK_CUR);
1254 }
1255
1256 ByteReader br(buf, num);
1257
1258 try {
1259 uint8_t action = br.ReadByte();
1260
1261 if (action == 0xFF) {
1262 GrfMsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
1263 } else if (action == 0xFE) {
1264 GrfMsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
1265 } else {
1266 InvokeGrfActionHandler::Invoke(action, stage, br);
1267 }
1268 } catch (...) {
1269 GrfMsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
1270 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
1271 }
1272}
1273
1280static void LoadNewGRFFileFromFile(GRFConfig &config, GrfLoadingStage stage, SpriteFile &file)
1281{
1282 AutoRestoreBackup cur_file(_cur_gps.file, &file);
1283 AutoRestoreBackup cur_config(_cur_gps.grfconfig, &config);
1284
1285 Debug(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '{}'", config.filename);
1286
1287 uint8_t grf_container_version = file.GetContainerVersion();
1288 if (grf_container_version == 0) {
1289 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1290 return;
1291 }
1292
1293 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
1294 /* We need the sprite offsets in the init stage for NewGRF sounds
1295 * and in the activation stage for real sprites. */
1297 } else {
1298 /* Skip sprite section offset if present. */
1299 if (grf_container_version >= 2) file.ReadDword();
1300 }
1301
1302 if (grf_container_version >= 2) {
1303 /* Read compression value. */
1304 uint8_t compression = file.ReadByte();
1305 if (compression != 0) {
1306 Debug(grf, 7, "LoadNewGRFFile: Unsupported compression format");
1307 return;
1308 }
1309 }
1310
1311 /* Skip the first sprite; we don't care about how many sprites this
1312 * does contain; newest TTDPatches and George's longvehicles don't
1313 * neither, apparently. */
1314 uint32_t num = grf_container_version >= 2 ? file.ReadDword() : file.ReadWord();
1315 if (num == 4 && file.ReadByte() == 0xFF) {
1316 file.ReadDword();
1317 } else {
1318 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1319 return;
1320 }
1321
1322 _cur_gps.ClearDataForNextFile();
1323
1324 ReusableBuffer<uint8_t> allocator;
1325
1326 while ((num = (grf_container_version >= 2 ? file.ReadDword() : file.ReadWord())) != 0) {
1327 uint8_t type = file.ReadByte();
1328 _cur_gps.nfo_line++;
1329
1330 if (type == 0xFF) {
1331 if (_cur_gps.skip_sprites == 0) {
1332 /* Limit the special sprites to 1 MiB. */
1333 if (num > 1024 * 1024) {
1334 GrfMsg(0, "LoadNewGRFFile: Unexpectedly large sprite, disabling");
1335 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1336 break;
1337 }
1338
1339 DecodeSpecialSprite(allocator, num, stage);
1340
1341 /* Stop all processing if we are to skip the remaining sprites */
1342 if (_cur_gps.skip_sprites == -1) break;
1343
1344 continue;
1345 } else {
1346 file.SkipBytes(num);
1347 }
1348 } else {
1349 if (_cur_gps.skip_sprites == 0) {
1350 GrfMsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
1351 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1352 break;
1353 }
1354
1355 if (grf_container_version >= 2 && type == 0xFD) {
1356 /* Reference to data section. Container version >= 2 only. */
1357 file.SkipBytes(num);
1358 } else {
1359 file.SkipBytes(7);
1360 SkipSpriteData(file, type, num - 8);
1361 }
1362 }
1363
1364 if (_cur_gps.skip_sprites > 0) _cur_gps.skip_sprites--;
1365 }
1366}
1367
1376void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
1377{
1378 const std::string &filename = config.filename;
1379
1380 /* A .grf file is activated only if it was active when the game was
1381 * started. If a game is loaded, only its active .grfs will be
1382 * reactivated, unless "loadallgraphics on" is used. A .grf file is
1383 * considered active if its action 8 has been processed, i.e. its
1384 * action 8 hasn't been skipped using an action 7.
1385 *
1386 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
1387 * carried out. All others are ignored, because they only need to be
1388 * processed once at initialization. */
1389 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
1390 _cur_gps.grffile = GetFileByFilename(filename);
1391 if (_cur_gps.grffile == nullptr) UserError("File '{}' lost in cache.\n", filename);
1392 if (stage == GLS_RESERVE && config.status != GCS_INITIALISED) return;
1393 if (stage == GLS_ACTIVATION && !config.flags.Test(GRFConfigFlag::Reserved)) return;
1394 }
1395
1396 bool needs_palette_remap = config.palette & GRFP_USE_MASK;
1397 if (temporary) {
1398 SpriteFile temporarySpriteFile(filename, subdir, needs_palette_remap);
1399 LoadNewGRFFileFromFile(config, stage, temporarySpriteFile);
1400 } else {
1401 LoadNewGRFFileFromFile(config, stage, OpenCachedSpriteFile(filename, subdir, needs_palette_remap));
1402 }
1403}
1404
1412static void ActivateOldShore()
1413{
1414 /* Use default graphics, if no shore sprites were loaded.
1415 * Should not happen, as the base set's extra grf should include some. */
1417
1419 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
1420 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
1421 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
1422 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
1423 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
1424 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
1425 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
1426 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
1427 }
1428
1430 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
1431 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
1432 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
1433 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
1434 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
1435 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
1436 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
1437 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
1438
1439 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
1440 * If they would be used somewhen, then these grass tiles will most like not look as needed */
1441 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
1442 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
1443 }
1444}
1445
1450{
1452 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0); // use road depot graphics for "no tracks"
1453 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
1454 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2); // use road depot graphics for "no tracks"
1455 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
1456 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
1457 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
1458 }
1459}
1460
1465{
1466 extern const PriceBaseSpec _price_base_specs[];
1468 static constexpr GrfSpecFeatures override_features{GSF_TRAINS, GSF_ROADVEHICLES, GSF_SHIPS, GSF_AIRCRAFT};
1469
1470 /* Evaluate grf overrides */
1471 int num_grfs = (uint)_grf_files.size();
1472 std::vector<int> grf_overrides(num_grfs, -1);
1473 for (int i = 0; i < num_grfs; i++) {
1474 GRFFile &source = _grf_files[i];
1475 auto it = _grf_id_overrides.find(source.grfid);
1476 if (it == std::end(_grf_id_overrides)) continue;
1477 uint32_t override_grfid = it->second;
1478
1479 auto dest = std::ranges::find(_grf_files, override_grfid, &GRFFile::grfid);
1480 if (dest == std::end(_grf_files)) continue;
1481
1482 grf_overrides[i] = static_cast<int>(std::ranges::distance(std::begin(_grf_files), dest));
1483 assert(grf_overrides[i] >= 0);
1484 }
1485
1486 /* Override features and price base multipliers of earlier loaded grfs */
1487 for (int i = 0; i < num_grfs; i++) {
1488 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
1489 GRFFile &source = _grf_files[i];
1490 GRFFile &dest = _grf_files[grf_overrides[i]];
1491
1492 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1493 source.grf_features.Set(features);
1494 dest.grf_features.Set(features);
1495
1496 for (Price p = PR_BEGIN; p < PR_END; p++) {
1497 /* No price defined -> nothing to do */
1498 if (!features.Test(_price_base_specs[p].grf_feature) || source.price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
1499 Debug(grf, 3, "'{}' overrides price base multiplier {} of '{}'", source.filename, p, dest.filename);
1501 }
1502 }
1503
1504 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
1505 for (int i = num_grfs - 1; i >= 0; i--) {
1506 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
1507 GRFFile &source = _grf_files[i];
1508 GRFFile &dest = _grf_files[grf_overrides[i]];
1509
1510 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1511 source.grf_features.Set(features);
1512 dest.grf_features.Set(features);
1513
1514 for (Price p = PR_BEGIN; p < PR_END; p++) {
1515 /* Already a price defined -> nothing to do */
1516 if (!features.Test(_price_base_specs[p].grf_feature) || dest.price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
1517 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, source.filename, dest.filename);
1519 }
1520 }
1521
1522 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
1523 for (int i = 0; i < num_grfs; i++) {
1524 if (grf_overrides[i] < 0) continue;
1525 GRFFile &source = _grf_files[i];
1526 GRFFile &dest = _grf_files[grf_overrides[i]];
1527
1528 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1529 source.grf_features.Set(features);
1530 dest.grf_features.Set(features);
1531
1532 for (Price p = PR_BEGIN; p < PR_END; p++) {
1533 if (!features.Test(_price_base_specs[p].grf_feature)) continue;
1534 if (source.price_base_multipliers[p] != dest.price_base_multipliers[p]) {
1535 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, dest.filename, source.filename);
1536 }
1538 }
1539 }
1540
1541 /* Apply fallback prices for grf version < 8 */
1542 for (auto &file : _grf_files) {
1543 if (file.grf_version >= 8) continue;
1544 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1545 for (Price p = PR_BEGIN; p < PR_END; p++) {
1546 Price fallback_price = _price_base_specs[p].fallback_price;
1547 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1548 /* No price multiplier has been set.
1549 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
1550 price_base_multipliers[p] = price_base_multipliers[fallback_price];
1551 }
1552 }
1553 }
1554
1555 /* Decide local/global scope of price base multipliers */
1556 for (auto &file : _grf_files) {
1557 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1558 for (Price p = PR_BEGIN; p < PR_END; p++) {
1559 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1560 /* No multiplier was set; set it to a neutral value */
1561 price_base_multipliers[p] = 0;
1562 } else {
1563 if (!file.grf_features.Test(_price_base_specs[p].grf_feature)) {
1564 /* The grf does not define any objects of the feature,
1565 * so it must be a difficulty setting. Apply it globally */
1566 Debug(grf, 3, "'{}' sets global price base multiplier {}", file.filename, p);
1567 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
1568 price_base_multipliers[p] = 0;
1569 } else {
1570 Debug(grf, 3, "'{}' sets local price base multiplier {}", file.filename, p);
1571 }
1572 }
1573 }
1574 }
1575}
1576
1577template <typename T>
1578void AddBadgeToSpecs(T &specs, GrfSpecFeature feature, Badge &badge)
1579{
1580 for (auto &spec : specs) {
1581 if (spec == nullptr) continue;
1582 spec->badges.push_back(badge.index);
1583 badge.features.Set(feature);
1584 }
1585}
1586
1588static void FinaliseBadges()
1589{
1590 for (const auto &file : _grf_files) {
1591 Badge *badge = GetBadgeByLabel(fmt::format("newgrf/{:08x}", std::byteswap(file.grfid)));
1592 if (badge == nullptr) continue;
1593
1594 for (Engine *e : Engine::Iterate()) {
1595 if (e->grf_prop.grffile != &file) continue;
1596 e->badges.push_back(badge->index);
1597 badge->features.Set(static_cast<GrfSpecFeature>(GSF_TRAINS + e->type));
1598 }
1599
1600 AddBadgeToSpecs(file.stations, GSF_STATIONS, *badge);
1601 AddBadgeToSpecs(file.housespec, GSF_HOUSES, *badge);
1602 AddBadgeToSpecs(file.industryspec, GSF_INDUSTRIES, *badge);
1603 AddBadgeToSpecs(file.indtspec, GSF_INDUSTRYTILES, *badge);
1604 AddBadgeToSpecs(file.objectspec, GSF_OBJECTS, *badge);
1605 AddBadgeToSpecs(file.airportspec, GSF_AIRPORTS, *badge);
1606 AddBadgeToSpecs(file.airtspec, GSF_AIRPORTTILES, *badge);
1607 AddBadgeToSpecs(file.roadstops, GSF_ROADSTOPS, *badge);
1608 }
1609
1612}
1613
1614extern void InitGRFTownGeneratorNames();
1615
1617static void AfterLoadGRFs()
1618{
1619 /* Cached callback groups are no longer needed. */
1620 ResetCallbacks(true);
1621
1623
1624 /* Clear the action 6 override sprites. */
1625 _grf_line_to_action6_sprite_override.clear();
1626
1628
1629 /* Polish cargoes */
1631
1632 /* Pre-calculate all refit masks after loading GRF files. */
1634
1635 /* Polish engines */
1637
1638 /* Set the actually used Canal properties */
1640
1641 /* Add all new houses to the house array. */
1643
1644 /* Add all new industries to the industry array. */
1646
1647 /* Add all new objects to the object array. */
1649
1651
1652 /* Sort the list of industry types. */
1654
1655 /* Create dynamic list of industry legends for smallmap_gui.cpp */
1657
1658 /* Build the routemap legend, based on the available cargos */
1660
1661 /* Add all new airports to the airports array. */
1664
1665 /* Update the townname generators list */
1667
1668 /* Run all queued vehicle list order changes */
1670
1671 /* Load old shore sprites in new position, if they were replaced by ActionA */
1673
1674 /* Load old tram depot sprites in new position, if no new ones are present */
1676
1677 /* Set up custom rail types */
1678 InitRailTypes();
1679 InitRoadTypes();
1680
1681 for (Engine *e : Engine::IterateType(VEH_ROAD)) {
1682 if (_gted[e->index].rv_max_speed != 0) {
1683 /* Set RV maximum speed from the mph/0.8 unit value */
1684 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
1685 }
1686
1687 RoadTramType rtt = e->info.misc_flags.Test(EngineMiscFlag::RoadIsTram) ? RTT_TRAM : RTT_ROAD;
1688
1689 const GRFFile *file = e->GetGRF();
1690 if (file == nullptr || _gted[e->index].roadtramtype == 0) {
1691 e->u.road.roadtype = (rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
1692 continue;
1693 }
1694
1695 /* Remove +1 offset. */
1696 _gted[e->index].roadtramtype--;
1697
1698 const std::vector<RoadTypeLabel> *list = (rtt == RTT_TRAM) ? &file->tramtype_list : &file->roadtype_list;
1699 if (_gted[e->index].roadtramtype < list->size())
1700 {
1701 RoadTypeLabel rtl = (*list)[_gted[e->index].roadtramtype];
1702 RoadType rt = GetRoadTypeByLabel(rtl);
1703 if (rt != INVALID_ROADTYPE && GetRoadTramType(rt) == rtt) {
1704 e->u.road.roadtype = rt;
1705 continue;
1706 }
1707 }
1708
1709 /* Road type is not available, so disable this engine */
1710 e->info.climates = {};
1711 }
1712
1714 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
1715 if (railtype == INVALID_RAILTYPE) {
1716 /* Rail type is not available, so disable this engine */
1717 e->info.climates = {};
1718 } else {
1719 e->u.rail.railtype = railtype;
1720 e->u.rail.intended_railtype = railtype;
1721 }
1722 }
1723
1725
1727
1728 /* Deallocate temporary loading data */
1729 _gted.clear();
1730 _grm_sprites.clear();
1731}
1732
1738void LoadNewGRF(SpriteID load_index, uint num_baseset)
1739{
1740 /* In case of networking we need to "sync" the start values
1741 * so all NewGRFs are loaded equally. For this we use the
1742 * start date of the game and we set the counters, etc. to
1743 * 0 so they're the same too. */
1747
1751
1752 uint64_t tick_counter = TimerGameTick::counter;
1753 uint8_t display_opt = _display_opt;
1754
1755 if (_networking) {
1759
1763
1765 _display_opt = 0;
1766 }
1767
1769
1771
1772 /*
1773 * Reset the status of all files, so we can 'retry' to load them.
1774 * This is needed when one for example rearranges the NewGRFs in-game
1775 * and a previously disabled NewGRF becomes usable. If it would not
1776 * be reset, the NewGRF would remain disabled even though it should
1777 * have been enabled.
1778 */
1779 for (const auto &c : _grfconfig) {
1780 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
1781 }
1782
1783 _cur_gps.spriteid = load_index;
1784
1785 /* Load newgrf sprites
1786 * in each loading stage, (try to) open each file specified in the config
1787 * and load information from it. */
1788 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
1789 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
1790 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
1791 for (const auto &c : _grfconfig) {
1792 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
1793 }
1794
1795 if (stage == GLS_RESERVE) {
1796 static const std::pair<uint32_t, uint32_t> default_grf_overrides[] = {
1797 { std::byteswap(0x44442202), std::byteswap(0x44440111) }, // UKRS addons modifies UKRS
1798 { std::byteswap(0x6D620402), std::byteswap(0x6D620401) }, // DBSetXL ECS extension modifies DBSetXL
1799 { std::byteswap(0x4D656f20), std::byteswap(0x4D656F17) }, // LV4cut modifies LV4
1800 };
1801 for (const auto &grf_override : default_grf_overrides) {
1802 SetNewGRFOverride(grf_override.first, grf_override.second);
1803 }
1804 }
1805
1806 uint num_grfs = 0;
1807 uint num_non_static = 0;
1808
1809 _cur_gps.stage = stage;
1810 for (const auto &c : _grfconfig) {
1811 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
1812 if (stage > GLS_INIT && c->flags.Test(GRFConfigFlag::InitOnly)) continue;
1813
1814 Subdirectory subdir = num_grfs < num_baseset ? BASESET_DIR : NEWGRF_DIR;
1815 if (!FioCheckFileExists(c->filename, subdir)) {
1816 Debug(grf, 0, "NewGRF file is missing '{}'; disabling", c->filename);
1817 c->status = GCS_NOT_FOUND;
1818 continue;
1819 }
1820
1821 if (stage == GLS_LABELSCAN) InitNewGRFFile(*c);
1822
1823 if (!c->flags.Test(GRFConfigFlag::Static) && !c->flags.Test(GRFConfigFlag::System)) {
1824 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
1825 Debug(grf, 0, "'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
1826 c->status = GCS_DISABLED;
1827 c->error = {STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED};
1828 continue;
1829 }
1830 num_non_static++;
1831 }
1832
1833 num_grfs++;
1834
1835 LoadNewGRFFile(*c, stage, subdir, false);
1836 if (stage == GLS_RESERVE) {
1837 c->flags.Set(GRFConfigFlag::Reserved);
1838 } else if (stage == GLS_ACTIVATION) {
1839 c->flags.Reset(GRFConfigFlag::Reserved);
1840 assert(GetFileByGRFID(c->ident.grfid) == _cur_gps.grffile);
1843 Debug(sprite, 2, "LoadNewGRF: Currently {} sprites are loaded", _cur_gps.spriteid);
1844 } else if (stage == GLS_INIT && c->flags.Test(GRFConfigFlag::InitOnly)) {
1845 /* We're not going to activate this, so free whatever data we allocated */
1847 }
1848 }
1849 }
1850
1851 /* We've finished reading files. */
1852 _cur_gps.grfconfig = nullptr;
1853 _cur_gps.grffile = nullptr;
1854
1855 /* Pseudo sprite processing is finished; free temporary stuff */
1856 _cur_gps.ClearDataForNextFile();
1857
1858 /* Call any functions that should be run after GRFs have been loaded. */
1859 AfterLoadGRFs();
1860
1861 /* Now revert back to the original situation */
1864 TimerGameCalendar::date_fract = date_fract;
1865
1866 TimerGameEconomy::year = economy_year;
1867 TimerGameEconomy::date = economy_date;
1868 TimerGameEconomy::date_fract = economy_date_fract;
1869
1870 TimerGameTick::counter = tick_counter;
1871 _display_opt = display_opt;
1872}
Class for backupping variables and making sure they are restored later.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
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 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:72
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:23
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:106
MixedCargoType
Mixed cargo types for definitions with cargo that can vary depending on climate.
Definition cargo_type.h:84
@ MCT_GRAIN_WHEAT_MAIZE
Cargo can be grain, wheat or maize.
Definition cargo_type.h:86
@ MCT_LIVESTOCK_FRUIT
Cargo can be livestock or fruit.
Definition cargo_type.h:85
@ MCT_VALUABLES_GOLD_DIAMONDS
Cargo can be valuables, gold or diamonds.
Definition cargo_type.h:87
static constexpr CargoLabel CT_PASSENGERS
Available types of cargo Labels may be re-used between different climates.
Definition cargo_type.h:31
static const CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:75
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.
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:227
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:90
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:162
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:885
void ResetPriceBaseMultipliers()
Reset changes to the price base multipliers.
Definition economy.cpp:873
Price
Enumeration of all base prices for use with Prices.
void SetYearEngineAgingStops()
Compute the value for _year_engine_aging_stops.
Definition engine.cpp:693
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:601
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
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
Definition house.h:55
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.
LiveryScheme
List of different livery schemes.
Definition livery.h:21
bool _networking
are we in networking mode?
Definition network.cpp:67
static void FinaliseObjectsArray()
Add all new objects to the object array.
Definition newgrf.cpp:1151
static void FinalisePriceBaseMultipliers()
Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them...
Definition newgrf.cpp:1464
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:607
static void FinaliseIndustriesArray()
Add all new industries to the industry array.
Definition newgrf.cpp:1097
std::span< const CargoLabel > GetCargoTranslationTable(const GRFFile &grffile)
Get the cargo translation table to use for the given GRF file.
Definition newgrf.cpp:516
static std::vector< GRFFile > _grf_files
List of all loaded GRF files.
Definition newgrf.cpp:63
void ResetPersistentNewGRFData()
Reset NewGRF data which is stored persistently in savegames.
Definition newgrf.cpp:500
static void FinaliseAirportsArray()
Add all new airports to the airport array.
Definition newgrf.cpp:1173
static GRFFile * GetFileByFilename(const std::string &filename)
Obtain a NewGRF file by its filename.
Definition newgrf.cpp:116
GRFFile * GetCurrentGRFOverride()
Get overridden GRF for current GRF if present.
Definition newgrf.cpp:193
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:328
void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
Set the override for a NewGRF.
Definition newgrf.cpp:178
void GRFUnsafe(ByteReader &)
Set the current NewGRF as unsafe for static use.
Definition newgrf.cpp:369
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:211
static void ActivateOldShore()
Relocates the old shore sprites at new positions.
Definition newgrf.cpp:1412
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:998
TypedIndexContainer< std::vector< GRFTempEngineData >, EngineID > _gted
Temporary engine data used during NewGRF loading.
Definition newgrf.cpp:78
static void FinaliseEngineArray()
Check for invalid engines.
Definition newgrf.cpp:849
static void ResetNewGRFErrors()
Clear all NewGRF errors.
Definition newgrf.cpp:391
static void LoadNewGRFFileFromFile(GRFConfig &config, GrfLoadingStage stage, SpriteFile &file)
Load a particular NewGRF from a SpriteFile.
Definition newgrf.cpp:1280
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition newgrf.cpp:74
void LoadNewGRF(SpriteID load_index, uint num_baseset)
Load all the NewGRFs.
Definition newgrf.cpp:1738
static void ClearTemporaryNewGRFData(GRFFile *gf)
Reset all NewGRFData that was used only while processing data.
Definition newgrf.cpp:124
void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig &c)
Disable a static NewGRF when it is influencing another (non-static) NewGRF as this could cause desync...
Definition newgrf.cpp:165
static void FinaliseCanals()
Set to use the correct action0 properties for each canal feature.
Definition newgrf.cpp:838
void ResetNewGRFData()
Reset all NewGRF loaded data.
Definition newgrf.cpp:404
static void CalculateRefitMasks()
Precalculate refit masks from cargo classes for all vehicles.
Definition newgrf.cpp:642
void FinaliseCargoArray()
Check for invalid cargoes.
Definition newgrf.cpp:922
static void BuildCargoTranslationMap()
Construct the Cargo Mapping.
Definition newgrf.cpp:532
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
EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal_id)
Return the ID of a new engine.
Definition newgrf.cpp:292
GRFFile * GetFileByGRFID(uint32_t grfid)
Obtain a NewGRF file by its grfID.
Definition newgrf.cpp:104
GrfMiscBits _misc_grf_features
Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E.
Definition newgrf.cpp:71
static void FinaliseHouseArray()
Add all new houses to the house array.
Definition newgrf.cpp:1023
static void InitNewGRFFile(const GRFConfig &config)
Prepare loading a NewGRF file with its config.
Definition newgrf.cpp:549
static void ActivateOldTramDepot()
Replocate the old tram depot sprites to the new position, if no new ones were loaded.
Definition newgrf.cpp:1449
void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
Load a particular NewGRF.
Definition newgrf.cpp:1376
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:952
static void AfterLoadGRFs()
Finish loading NewGRFs and execute needed post-processing.
Definition newgrf.cpp:1617
GRFError * DisableGrf(StringID message, GRFConfig *config)
Disable a GRF.
Definition newgrf.cpp:135
static void ResetNewGRF()
Reset and clear all NewGRFs.
Definition newgrf.cpp:378
void InitGRFTownGeneratorNames()
Allocate memory for the NewGRF town names.
CargoTypes TranslateRefitMask(uint32_t refit_mask)
Translate the refit mask.
Definition newgrf.cpp:311
static void FinaliseBadges()
Finish up applying badges to things.
Definition newgrf.cpp:1588
@ SHORE_REPLACE_ACTION_A
Shore sprites were replaced by ActionA (using grass tiles for the corner-shores).
Definition newgrf.h:178
@ SHORE_REPLACE_NONE
No shore sprites were replaced.
Definition newgrf.h:176
@ SHORE_REPLACE_ACTION_5
Shore sprites were replaced by Action5.
Definition newgrf.h:177
@ TRAMWAY_REPLACE_DEPOT_WITH_TRACK
Electrified depot graphics with tram track were loaded.
Definition newgrf.h:184
@ TRAMWAY_REPLACE_DEPOT_NONE
No tram depot graphics were loaded.
Definition newgrf.h:183
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.
@ InitOnly
GRF file is processed up to GLS_INIT.
@ Reserved
GRF file passed GLS_RESERVE stage.
@ System
GRF file is an openttd-internal system grf.
@ Static
GRF file is used statically (can be used in any MP game)
@ Unsafe
GRF file is unsafe for static usage.
@ 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.
RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels)
Get the rail type for a given label.
Definition rail.cpp:313
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:253
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:230
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:509
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:549
EngineID GetID(VehicleType type, uint16_t grf_local_id, uint32_t grfid)
Looks up an EngineID in the EngineOverrideManager.
Definition engine.cpp:530
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:77
Information about GRF, used in the game and (part of it) in savegames.
uint8_t palette
GRFPalette, bitset.
std::vector< uint32_t > param
GRF parameters.
GRFStatus status
NOSAVE: GRFStatus, enum.
std::optional< GRFError > error
NOSAVE: Error/Warning during GRF loading (Action 0x0B)
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.
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:158
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:159
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:189
ShoreReplacement shore
In which way shore sprites were replaced.
Definition newgrf.h:191
uint64_t used_liveries
Bitmask of LiveryScheme used by the defined engines.
Definition newgrf.h:190
TramReplacement tram
In which way tram depots were replaced.
Definition newgrf.h:192
@ 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:108
SubstituteGRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:114
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:111
CargoLabel accepts_cargo_label[HOUSE_ORIGINAL_NUM_ACCEPTS]
input landscape cargo slots
Definition house.h:126
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:109
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:102
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:107
HouseZones building_availability
where can it be built (climates, zones)
Definition house.h:110
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Helper class to invoke a GrfActionHandler.
Definition newgrf.cpp:1197
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:353
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 Titem * Get(auto index)
Returns Titem with given index.
Tindex index
Index of this pool item.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
void CleanPool() override
Virtual method that deletes all items in the pool.
Describes properties of price bases.
Definition newgrf.h:198
Price fallback_price
Fallback price multiplier for new prices but old grfs.
Definition newgrf.h:202
GrfSpecFeature grf_feature
GRF Feature that decides whether price multipliers apply locally or globally, GSF_END if none.
Definition newgrf.h:201
RailType railtype
Railtype, mangled if elrail is disabled.
Definition engine_type.h:51
Iterable ensemble of each set bit in a value.
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:1940
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.