OpenTTD Source 20260311-master-g511d3794ce
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
9
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
72GrfMiscBits _misc_grf_features{};
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
129{
130 gf->labels.clear();
131}
132
140{
141 GRFFile *file;
142 if (config != nullptr) {
143 file = GetFileByGRFID(config->ident.grfid);
144 } else {
145 config = _cur_gps.grfconfig;
146 file = _cur_gps.grffile;
147 }
148
149 config->status = GCS_DISABLED;
150 if (file != nullptr) ClearTemporaryNewGRFData(file);
151 if (config == _cur_gps.grfconfig) _cur_gps.skip_sprites = -1;
152
153 if (message == STR_NULL) return nullptr;
154
155 auto it = std::ranges::find(config->errors, _cur_gps.nfo_line, &GRFError::nfo_line);
156 if (it == std::end(config->errors)) {
157 it = config->errors.emplace(it, STR_NEWGRF_ERROR_MSG_FATAL, _cur_gps.nfo_line, message);
158 }
159 if (config == _cur_gps.grfconfig) it->param_value[0] = _cur_gps.nfo_line;
160 return &*it;
161}
162
173{
174 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, &c);
175 error->data = _cur_gps.grfconfig->GetName();
176}
177
178static std::map<uint32_t, uint32_t> _grf_id_overrides;
179
185void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
186{
187 if (target_grfid == 0) {
188 _grf_id_overrides.erase(source_grfid);
189 GrfMsg(5, "SetNewGRFOverride: Removed override of 0x{:X}", std::byteswap(source_grfid));
190 } else {
191 _grf_id_overrides[source_grfid] = target_grfid;
192 GrfMsg(5, "SetNewGRFOverride: Added override of 0x{:X} to 0x{:X}", std::byteswap(source_grfid), std::byteswap(target_grfid));
193 }
194}
195
201{
202 auto found = _grf_id_overrides.find(_cur_gps.grffile->grfid);
203 if (found != std::end(_grf_id_overrides)) {
204 GRFFile *grffile = GetFileByGRFID(found->second);
205 if (grffile != nullptr) return grffile;
206 }
207 return nullptr;
208}
209
218Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16_t internal_id, bool static_access)
219{
220 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
221 * them use the same engine slots. */
222 uint32_t scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
223 if (_settings_game.vehicle.dynamic_engines) {
224 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
225 scope_grfid = file->grfid;
226 if (auto it = _grf_id_overrides.find(file->grfid); it != std::end(_grf_id_overrides)) {
227 scope_grfid = it->second;
228 const GRFFile *grf_match = GetFileByGRFID(scope_grfid);
229 if (grf_match == nullptr) {
230 GrfMsg(5, "Tried mapping from GRFID {:x} to {:x} but target is not loaded", std::byteswap(file->grfid), std::byteswap(scope_grfid));
231 } else {
232 GrfMsg(5, "Mapping from GRFID {:x} to {:x}", std::byteswap(file->grfid), std::byteswap(scope_grfid));
233 }
234 }
235
236 /* Check if the engine is registered in the override manager */
237 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
238 if (engine != EngineID::Invalid()) {
239 Engine *e = Engine::Get(engine);
240 if (!e->grf_prop.HasGrfFile()) {
241 e->grf_prop.SetGRFFile(file);
242 }
243 return e;
244 }
245 }
246
247 /* Check if there is an unreserved slot */
248 EngineID engine = _engine_mngr.UseUnreservedID(type, internal_id, scope_grfid, static_access);
249 if (engine != EngineID::Invalid()) {
250 Engine *e = Engine::Get(engine);
251
252 if (!e->grf_prop.HasGrfFile()) {
253 e->grf_prop.SetGRFFile(file);
254 GrfMsg(5, "Replaced engine at index {} for GRFID {:x}, type {}, index {}", e->index, std::byteswap(file->grfid), type, internal_id);
255 }
256
257 return e;
258 }
259
260 if (static_access) return nullptr;
261
263 GrfMsg(0, "Can't allocate any more engines");
264 return nullptr;
265 }
266
267 size_t engine_pool_size = Engine::GetPoolSize();
268
269 /* ... it's not, so create a new one based off an existing engine */
270 Engine *e = Engine::Create(type, internal_id);
271 e->grf_prop.SetGRFFile(file);
272
273 /* Reserve the engine slot */
274 _engine_mngr.SetID(type, internal_id, scope_grfid, std::min<uint8_t>(internal_id, _engine_counts[type]), e->index);
275
276 if (engine_pool_size != Engine::GetPoolSize()) {
277 /* Resize temporary engine data ... */
278 _gted.resize(Engine::GetPoolSize());
279 }
280 if (type == VEH_TRAIN) {
281 _gted[e->index].railtypelabels.clear();
282 for (RailType rt : e->VehInfo<RailVehicleInfo>().railtypes) _gted[e->index].railtypelabels.push_back(GetRailTypeInfo(rt)->label);
283 }
284
285 GrfMsg(5, "Created new engine at index {} for GRFID {:x}, type {}, index {}", e->index, std::byteswap(file->grfid), type, internal_id);
286
287 return e;
288}
289
300EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal_id)
301{
302 uint32_t scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
303 if (_settings_game.vehicle.dynamic_engines) {
304 scope_grfid = file->grfid;
305 if (auto it = _grf_id_overrides.find(file->grfid); it != std::end(_grf_id_overrides)) {
306 scope_grfid = it->second;
307 }
308 }
309
310 return _engine_mngr.GetID(type, internal_id, scope_grfid);
311}
312
313
314
315
321CargoTypes TranslateRefitMask(uint32_t refit_mask)
322{
323 CargoTypes result = 0;
324 for (uint8_t bit : SetBitIterator(refit_mask)) {
325 CargoType cargo = GetCargoTranslation(bit, _cur_gps.grffile, true);
326 if (IsValidCargoType(cargo)) SetBit(result, cargo);
327 }
328 return result;
329}
330
338void ConvertTTDBasePrice(uint32_t base_pointer, std::string_view error_location, Price *index)
339{
340 /* Special value for 'none' */
341 if (base_pointer == 0) {
342 *index = Price::Invalid;
343 return;
344 }
345
346 static const uint32_t start = 0x4B34;
347 static const uint32_t size = 6;
348
349 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= to_underlying(Price::End)) {
350 GrfMsg(1, "{}: Unsupported running cost base 0x{:04X}, ignoring", error_location, base_pointer);
351 return;
352 }
353
354 *index = (Price)((base_pointer - start) / size);
355}
356
363/* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32_t grfid, uint8_t language_id)
364{
365 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
366 const GRFFile *grffile = GetFileByGRFID(grfid);
367 if (grffile == nullptr) return nullptr;
368
369 auto it = grffile->language_map.find(language_id);
370 if (it == std::end(grffile->language_map)) return nullptr;
371
372 return &it->second;
373}
374
380{
381 _cur_gps.grfconfig->flags.Set(GRFConfigFlag::Unsafe);
382
383 /* Skip remainder of GRF */
384 _cur_gps.skip_sprites = -1;
385}
386
388static void ResetNewGRF()
389{
390 _cur_gps.grfconfig = nullptr;
391 _cur_gps.grffile = nullptr;
392 _grf_files.clear();
393
394 /* We store pointers to GRFFiles in many places, so need to ensure that the pointers do not become invalid
395 * due to vector reallocation. Should not happen due to loading taking place in multiple stages, but
396 * reserving when the size is known is good practice anyway. */
397 _grf_files.reserve(_grfconfig.size());
398}
399
401static void ResetNewGRFErrors()
402{
403 for (const auto &c : _grfconfig) {
404 c->errors.clear();
405 }
406}
407
408extern void ResetCallbacks(bool final);
409extern void ResetGRM();
410
415{
417 CleanUpGRFTownNames();
418
419 ResetBadges();
420
421 /* Copy/reset original engine info data */
422 SetupEngines();
423
424 /* Copy/reset original bridge info data */
425 ResetBridges();
426
427 /* Reset rail type information */
429
430 /* Copy/reset original road type info data */
432
433 /* Allocate temporary refit/cargo class data */
434 _gted.resize(Engine::GetPoolSize());
435
436 /* Fill rail type label temporary data for default trains */
437 for (const Engine *e : Engine::IterateType(VEH_TRAIN)) {
438 _gted[e->index].railtypelabels.clear();
439 for (RailType rt : e->VehInfo<RailVehicleInfo>().railtypes) _gted[e->index].railtypelabels.push_back(GetRailTypeInfo(rt)->label);
440 }
441
442 /* Reset GRM reservations */
443 ResetGRM();
444
445 /* Reset generic feature callback lists */
447
448 /* Reset price base data */
450
451 /* Reset the curencies array */
453
454 /* Reset the house array */
455 ResetHouses();
456
457 /* Reset the industries structures*/
459
460 /* Reset the objects. */
462 ResetObjects();
463
464 /* Reset station classes */
466
467 /* Reset airport-related structures */
471
472 /* Reset road stop classes */
474
475 /* Reset canal sprite groups and flags */
476 _water_feature.fill({});
477
478 ResetFaces();
479
480 /* Reset the snowline table. */
482
483 /* Reset NewGRF files */
484 ResetNewGRF();
485
486 /* Reset NewGRF errors. */
488
489 /* Set up the default cargo types */
490 SetupCargoForClimate(_settings_game.game_creation.landscape);
491
492 /* Reset misc GRF features and train list display variables */
494
495 _loaded_newgrf_features.has_2CC = false;
496 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
499
500 /* Clear all GRF overrides */
501 _grf_id_overrides.clear();
502
503 InitializeSoundPool();
504 _spritegroup_pool.CleanPool();
505 ResetCallbacks(false);
506}
507
512{
513 /* Reset override managers */
514 _engine_mngr.ResetToDefaultMapping();
515 _house_mngr.ResetMapping();
516 _industry_mngr.ResetMapping();
517 _industile_mngr.ResetMapping();
518 _airport_mngr.ResetMapping();
519 _airporttile_mngr.ResetMapping();
520}
521
527std::span<const CargoLabel> GetCargoTranslationTable(const GRFFile &grffile)
528{
529 /* Always use the translation table if it's installed. */
530 if (!grffile.cargo_list.empty()) return grffile.cargo_list;
531
532 /* Pre-v7 use climate-dependent "slot" table. */
533 if (grffile.grf_version < 7) return GetClimateDependentCargoTranslationTable();
534
535 /* Otherwise use climate-independent "bitnum" table. */
537}
538
544{
545 _cur_gps.grffile->cargo_map.fill(UINT8_MAX);
546
547 auto cargo_list = GetCargoTranslationTable(*_cur_gps.grffile);
548
549 for (const CargoSpec *cs : CargoSpec::Iterate()) {
550 /* Check the translation table for this cargo's label */
551 int idx = find_index(cargo_list, cs->label);
552 if (idx >= 0) _cur_gps.grffile->cargo_map[cs->Index()] = idx;
553 }
554}
555
560static void InitNewGRFFile(const GRFConfig &config)
561{
562 GRFFile *newfile = GetFileByFilename(config.filename);
563 if (newfile != nullptr) {
564 /* We already loaded it once. */
565 _cur_gps.grffile = newfile;
566 return;
567 }
568
569 assert(_grf_files.size() < _grf_files.capacity()); // We must not invalidate pointers.
570 _cur_gps.grffile = &_grf_files.emplace_back(config);
571}
572
578{
579 this->filename = config.filename;
580 this->grfid = config.ident.grfid;
581
582 /* Initialise local settings to defaults */
583 this->traininfo_vehicle_pitch = 0;
584 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
585
586 /* Mark price_base_multipliers as 'not set' */
587 this->price_base_multipliers.fill(INVALID_PRICE_MODIFIER);
588
589 /* Initialise rail type map with default rail types */
590 this->railtype_map.fill(INVALID_RAILTYPE);
591 this->railtype_map[0] = RAILTYPE_RAIL;
592 this->railtype_map[1] = RAILTYPE_ELECTRIC;
593 this->railtype_map[2] = RAILTYPE_MONO;
594 this->railtype_map[3] = RAILTYPE_MAGLEV;
595
596 /* Initialise road type map with default road types */
597 this->roadtype_map.fill(INVALID_ROADTYPE);
598 this->roadtype_map[0] = ROADTYPE_ROAD;
599
600 /* Initialise tram type map with default tram types */
601 this->tramtype_map.fill(INVALID_ROADTYPE);
602 this->tramtype_map[0] = ROADTYPE_TRAM;
603
604 /* Copy the initial parameter list */
605 this->param = config.param;
606}
607
608/* Some compilers get confused about vectors of unique_ptrs. */
609GRFFile::GRFFile() = default;
610GRFFile::GRFFile(GRFFile &&other) = default;
611GRFFile::~GRFFile() = default;
612
618static CargoLabel GetActiveCargoLabel(const std::initializer_list<CargoLabel> &labels)
619{
620 for (const CargoLabel &label : labels) {
621 CargoType cargo_type = GetCargoTypeByLabel(label);
622 if (cargo_type != INVALID_CARGO) return label;
623 }
624 return CT_INVALID;
625}
626
632static CargoLabel GetActiveCargoLabel(const std::variant<CargoLabel, MixedCargoType> &label)
633{
634 struct visitor {
635 CargoLabel operator()(const CargoLabel &label) { return label; }
636 CargoLabel operator()(const MixedCargoType &mixed)
637 {
638 switch (mixed) {
639 case MCT_LIVESTOCK_FRUIT: return GetActiveCargoLabel({CT_LIVESTOCK, CT_FRUIT});
640 case MCT_GRAIN_WHEAT_MAIZE: return GetActiveCargoLabel({CT_GRAIN, CT_WHEAT, CT_MAIZE});
641 case MCT_VALUABLES_GOLD_DIAMONDS: return GetActiveCargoLabel({CT_VALUABLES, CT_GOLD, CT_DIAMONDS});
642 default: NOT_REACHED();
643 }
644 }
645 };
646
647 return std::visit(visitor{}, label);
648}
649
654{
655 CargoTypes original_known_cargoes = 0;
656 for (CargoType cargo_type = 0; cargo_type != NUM_CARGO; ++cargo_type) {
657 if (IsDefaultCargo(cargo_type)) SetBit(original_known_cargoes, cargo_type);
658 }
659
660 for (Engine *e : Engine::Iterate()) {
661 EngineID engine = e->index;
662 EngineInfo *ei = &e->info;
663 bool only_defaultcargo;
664
665 /* Apply default cargo translation map if cargo type hasn't been set, either explicitly or by aircraft cargo handling. */
666 if (!IsValidCargoType(e->info.cargo_type)) {
667 e->info.cargo_type = GetCargoTypeByLabel(GetActiveCargoLabel(e->info.cargo_label));
668 }
669
670 /* If the NewGRF did not set any cargo properties, we apply default values. */
671 if (_gted[engine].defaultcargo_grf == nullptr) {
672 /* If the vehicle has any capacity, apply the default refit masks */
673 if (e->type != VEH_TRAIN || e->VehInfo<RailVehicleInfo>().capacity != 0) {
674 static constexpr LandscapeType T = LandscapeType::Temperate;
675 static constexpr LandscapeType A = LandscapeType::Arctic;
676 static constexpr LandscapeType S = LandscapeType::Tropic;
677 static constexpr LandscapeType Y = LandscapeType::Toyland;
678 static const struct DefaultRefitMasks {
679 LandscapeTypes climate;
680 CargoLabel cargo_label;
681 CargoClasses cargo_allowed;
682 CargoClasses cargo_disallowed;
683 } _default_refit_masks[] = {
684 {{T, A, S, Y}, CT_PASSENGERS, {CargoClass::Passengers}, {}},
685 {{T, A, S }, CT_MAIL, {CargoClass::Mail}, {}},
686 {{T, A, S }, CT_VALUABLES, {CargoClass::Armoured}, {CargoClass::Liquid}},
688 {{T, A }, CT_COAL, {CargoClass::Bulk}, {}},
689 {{ S }, CT_COPPER_ORE, {CargoClass::Bulk}, {}},
690 {{ Y}, CT_SUGAR, {CargoClass::Bulk}, {}},
691 {{T, A, S }, CT_OIL, {CargoClass::Liquid}, {}},
692 {{ Y}, CT_COLA, {CargoClass::Liquid}, {}},
695 {{ A, S }, CT_FOOD, {CargoClass::Refrigerated}, {}},
697 };
698
699 if (e->type == VEH_AIRCRAFT) {
700 /* Aircraft default to "light" cargoes */
702 _gted[engine].cargo_disallowed = {CargoClass::Liquid};
703 } else if (e->type == VEH_SHIP) {
704 CargoLabel label = GetActiveCargoLabel(ei->cargo_label);
705 switch (label.base()) {
706 case CT_PASSENGERS.base():
707 /* Ferries */
708 _gted[engine].cargo_allowed = {CargoClass::Passengers};
709 _gted[engine].cargo_disallowed = {};
710 break;
711 case CT_OIL.base():
712 /* Tankers */
713 _gted[engine].cargo_allowed = {CargoClass::Liquid};
714 _gted[engine].cargo_disallowed = {};
715 break;
716 default:
717 /* Cargo ships */
718 if (_settings_game.game_creation.landscape == LandscapeType::Toyland) {
719 /* No tanker in toyland :( */
721 _gted[engine].cargo_disallowed = {CargoClass::Passengers};
722 } else {
724 _gted[engine].cargo_disallowed = {CargoClass::Liquid, CargoClass::Passengers};
725 }
726 break;
727 }
728 e->VehInfo<ShipVehicleInfo>().old_refittable = true;
729 } else if (e->type == VEH_TRAIN && e->VehInfo<RailVehicleInfo>().railveh_type != RAILVEH_WAGON) {
730 /* Train engines default to all cargoes, so you can build single-cargo consists with fast engines.
731 * Trains loading multiple cargoes may start stations accepting unwanted cargoes. */
733 _gted[engine].cargo_disallowed = {};
734 } else {
735 /* Train wagons and road vehicles are classified by their default cargo type */
736 CargoLabel label = GetActiveCargoLabel(ei->cargo_label);
737 for (const auto &drm : _default_refit_masks) {
738 if (!drm.climate.Test(_settings_game.game_creation.landscape)) continue;
739 if (drm.cargo_label != label) continue;
740
741 _gted[engine].cargo_allowed = drm.cargo_allowed;
742 _gted[engine].cargo_disallowed = drm.cargo_disallowed;
743 break;
744 }
745
746 /* All original cargoes have specialised vehicles, so exclude them */
747 _gted[engine].ctt_exclude_mask = original_known_cargoes;
748 }
749 }
750 _gted[engine].UpdateRefittability(_gted[engine].cargo_allowed.Any());
751
752 if (IsValidCargoType(ei->cargo_type)) ClrBit(_gted[engine].ctt_exclude_mask, ei->cargo_type);
753 }
754
755 /* Compute refittability */
756 {
757 CargoTypes mask = 0;
758 CargoTypes not_mask = 0;
759 CargoTypes xor_mask = ei->refit_mask;
760
761 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
762 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
763 only_defaultcargo = _gted[engine].refittability != GRFTempEngineData::NONEMPTY;
764
765 if (_gted[engine].cargo_allowed.Any()) {
766 /* Build up the list of cargo types from the set cargo classes. */
767 for (const CargoSpec *cs : CargoSpec::Iterate()) {
768 if (cs->classes.Any(_gted[engine].cargo_allowed) && cs->classes.All(_gted[engine].cargo_allowed_required)) SetBit(mask, cs->Index());
769 if (cs->classes.Any(_gted[engine].cargo_disallowed)) SetBit(not_mask, cs->Index());
770 }
771 }
772
773 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
774
775 /* Apply explicit refit includes/excludes. */
776 ei->refit_mask |= _gted[engine].ctt_include_mask;
777 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
778
779 /* Custom refit mask callback. */
780 const GRFFile *file = _gted[e->index].defaultcargo_grf;
781 if (file == nullptr) file = e->GetGRF();
782 if (file != nullptr && e->info.callback_mask.Test(VehicleCallbackMask::CustomRefit)) {
783 for (const CargoSpec *cs : CargoSpec::Iterate()) {
784 uint8_t local_slot = file->cargo_map[cs->Index()];
785 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_CUSTOM_REFIT, cs->classes.base(), local_slot, engine, nullptr);
786 switch (callback) {
787 case CALLBACK_FAILED:
788 case 0:
789 break; // Do nothing.
790 case 1: SetBit(ei->refit_mask, cs->Index()); break;
791 case 2: ClrBit(ei->refit_mask, cs->Index()); break;
792
793 default: ErrorUnknownCallbackResult(file->grfid, CBID_VEHICLE_CUSTOM_REFIT, callback);
794 }
795 }
796 }
797 }
798
799 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
800 if (IsValidCargoType(ei->cargo_type) && !HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = INVALID_CARGO;
801
802 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
803 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
804 if (!only_defaultcargo && (e->type != VEH_SHIP || e->VehInfo<ShipVehicleInfo>().old_refittable) && IsValidCargoType(ei->cargo_type) && !HasBit(ei->refit_mask, ei->cargo_type)) {
805 ei->cargo_type = INVALID_CARGO;
806 }
807
808 /* Check if this engine's cargo type is valid. If not, set to the first refittable
809 * cargo type. Finally disable the vehicle, if there is still no cargo. */
810 if (!IsValidCargoType(ei->cargo_type) && ei->refit_mask != 0) {
811 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
812 const GRFFile *file = _gted[engine].defaultcargo_grf;
813 if (file == nullptr) file = e->GetGRF();
814 if (file != nullptr && file->grf_version >= 8 && !file->cargo_list.empty()) {
815 /* Use first refittable cargo from cargo translation table */
816 uint8_t best_local_slot = UINT8_MAX;
817 for (CargoType cargo_type : SetCargoBitIterator(ei->refit_mask)) {
818 uint8_t local_slot = file->cargo_map[cargo_type];
819 if (local_slot < best_local_slot) {
820 best_local_slot = local_slot;
821 ei->cargo_type = cargo_type;
822 }
823 }
824 }
825
826 if (!IsValidCargoType(ei->cargo_type)) {
827 /* Use first refittable cargo slot */
828 ei->cargo_type = (CargoType)FindFirstBit(ei->refit_mask);
829 }
830 }
831 if (!IsValidCargoType(ei->cargo_type) && e->type == VEH_TRAIN && e->VehInfo<RailVehicleInfo>().railveh_type != RAILVEH_WAGON && e->VehInfo<RailVehicleInfo>().capacity == 0) {
832 /* For train engines which do not carry cargo it does not matter if their cargo type is invalid.
833 * Fallback to the first available instead, if the cargo type has not been changed (as indicated by
834 * cargo_label not being CT_INVALID). */
835 if (GetActiveCargoLabel(ei->cargo_label) != CT_INVALID) {
836 ei->cargo_type = static_cast<CargoType>(FindFirstBit(_standard_cargo_mask));
837 }
838 }
839 if (!IsValidCargoType(ei->cargo_type)) ei->climates = {};
840
841 /* Clear refit_mask for not refittable ships */
842 if (e->type == VEH_SHIP && !e->VehInfo<ShipVehicleInfo>().old_refittable) {
843 ei->refit_mask = 0;
844 }
845 }
846}
847
849static void FinaliseCanals()
850{
851 for (uint i = 0; i < CF_END; i++) {
852 if (_water_feature[i].grffile != nullptr) {
853 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
854 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
855 }
856 }
857}
858
861{
862 for (Engine *e : Engine::Iterate()) {
863 if (e->GetGRF() == nullptr) {
864 auto found = std::ranges::find(_engine_mngr.mappings[e->type], e->index, &EngineIDMapping::engine);
865 if (found == std::end(_engine_mngr.mappings[e->type]) || found->grfid != INVALID_GRFID || found->internal_id != found->substitute_id) {
866 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
867 }
868 }
869
870 /* Do final mapping on variant engine ID. */
871 if (e->info.variant_id != EngineID::Invalid()) {
872 e->info.variant_id = GetNewEngineID(e->grf_prop.grffile, e->type, e->info.variant_id.base());
873 }
874
875 if (!e->info.climates.Test(_settings_game.game_creation.landscape)) continue;
876
877 switch (e->type) {
878 case VEH_TRAIN:
879 for (RailType rt : e->VehInfo<RailVehicleInfo>().railtypes) {
880 AppendCopyableBadgeList(e->badges, GetRailTypeInfo(rt)->badges, GSF_TRAINS);
881 }
882 break;
883 case VEH_ROAD: AppendCopyableBadgeList(e->badges, GetRoadTypeInfo(e->VehInfo<RoadVehicleInfo>().roadtype)->badges, GSF_ROADVEHICLES); break;
884 default: break;
885 }
886
887 /* Skip wagons, there livery is defined via the engine */
888 if (e->type != VEH_TRAIN || e->VehInfo<RailVehicleInfo>().railveh_type != RAILVEH_WAGON) {
889 LiveryScheme ls = GetEngineLiveryScheme(e->index, EngineID::Invalid(), nullptr);
890 SetBit(_loaded_newgrf_features.used_liveries, ls);
891 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
892
893 if (e->type == VEH_TRAIN) {
894 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
895 switch (ls) {
896 case LS_STEAM:
897 case LS_DIESEL:
898 case LS_ELECTRIC:
899 case LS_MONORAIL:
900 case LS_MAGLEV:
901 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
902 break;
903
904 case LS_DMU:
905 case LS_EMU:
906 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
907 break;
908
909 default: NOT_REACHED();
910 }
911 }
912 }
913 }
914
915 /* Check engine variants don't point back on themselves (either directly or via a loop) then set appropriate flags
916 * on variant engine. This is performed separately as all variant engines need to have been resolved.
917 * Use Floyd's cycle-detection algorithm to handle the case where a cycle is present but does
918 * not include the starting engine ID. */
919 for (Engine *e : Engine::Iterate()) {
920 EngineID parent = e->info.variant_id;
921 EngineID parent_slow = parent;
922 bool update_slow = false;
923 while (parent != EngineID::Invalid()) {
924 parent = Engine::Get(parent)->info.variant_id;
925 if (update_slow) parent_slow = Engine::Get(parent_slow)->info.variant_id;
926 update_slow = !update_slow;
927 if (parent != e->index && parent != parent_slow) continue;
928
929 /* Engine looped back on itself, so clear the variant. */
930 e->info.variant_id = EngineID::Invalid();
931
932 GrfMsg(1, "FinaliseEngineArray: Variant of engine {:x} in '{}' loops back on itself", e->grf_prop.local_id, e->GetGRF()->filename);
933 break;
934 }
935
936 if (e->info.variant_id != EngineID::Invalid()) {
937 Engine::Get(e->info.variant_id)->display_flags.Set({EngineDisplayFlag::HasVariants, EngineDisplayFlag::IsFolded});
938 }
939 }
940}
941
944{
945 for (CargoSpec &cs : CargoSpec::array) {
946 if (cs.town_production_effect == INVALID_TPE) {
947 /* Set default town production effect by cargo label. */
948 switch (cs.label.base()) {
949 case CT_PASSENGERS.base(): cs.town_production_effect = TPE_PASSENGERS; break;
950 case CT_MAIL.base(): cs.town_production_effect = TPE_MAIL; break;
951 default: cs.town_production_effect = TPE_NONE; break;
952 }
953 }
954 if (!cs.IsValid()) {
955 cs.name = cs.name_single = cs.units_volume = STR_NEWGRF_INVALID_CARGO;
956 cs.quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
957 cs.abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
958 }
959 }
960}
961
973static bool IsHouseSpecValid(HouseSpec &hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const std::string &filename)
974{
975 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) &&
976 (next1 == nullptr || !next1->enabled || next1->building_flags.Any(BUILDING_HAS_1_TILE))) ||
977 (hs.building_flags.Any(BUILDING_HAS_4_TILES) &&
978 (next2 == nullptr || !next2->enabled || next2->building_flags.Any(BUILDING_HAS_1_TILE) ||
979 next3 == nullptr || !next3->enabled || next3->building_flags.Any(BUILDING_HAS_1_TILE)))) {
980 hs.enabled = false;
981 if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs.grf_prop.local_id);
982 return false;
983 }
984
985 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
986 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
987 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
988 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) && next1->population != 0) ||
989 (hs.building_flags.Any(BUILDING_HAS_4_TILES) && (next2->population != 0 || next3->population != 0))) {
990 hs.enabled = false;
991 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);
992 return false;
993 }
994
995 /* Substitute type is also used for override, and having an override with a different size causes crashes.
996 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
997 if (!filename.empty() && (hs.building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs.grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
998 hs.enabled = false;
999 Debug(grf, 1, "FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs.grf_prop.local_id);
1000 return false;
1001 }
1002
1003 /* Make sure that additional parts of multitile houses are not available. */
1004 if (!hs.building_flags.Any(BUILDING_HAS_1_TILE) && hs.building_availability.Any(HZ_ZONE_ALL) && hs.building_availability.Any(HZ_CLIMATE_ALL)) {
1005 hs.enabled = false;
1006 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);
1007 return false;
1008 }
1009
1010 return true;
1011}
1012
1019static void EnsureEarlyHouse(HouseZones bitmask)
1020{
1021 TimerGameCalendar::Year min_year = CalendarTime::MAX_YEAR;
1022
1023 for (const auto &hs : HouseSpec::Specs()) {
1024 if (!hs.enabled) continue;
1025 if (!hs.building_availability.All(bitmask)) continue;
1026 if (hs.min_year < min_year) min_year = hs.min_year;
1027 }
1028
1029 if (min_year == 0) return;
1030
1031 for (auto &hs : HouseSpec::Specs()) {
1032 if (!hs.enabled) continue;
1033 if (!hs.building_availability.All(bitmask)) continue;
1034 if (hs.min_year == min_year) hs.min_year = CalendarTime::MIN_YEAR;
1035 }
1036}
1037
1045{
1046 /* If there are no houses with start dates before 1930, then all houses
1047 * with start dates of 1930 have them reset to 0. This is in order to be
1048 * compatible with TTDPatch, where if no houses have start dates before
1049 * 1930 and the date is before 1930, the game pretends that this is 1930.
1050 * If there have been any houses defined with start dates before 1930 then
1051 * the dates are left alone.
1052 * On the other hand, why 1930? Just 'fix' the houses with the lowest
1053 * minimum introduction date to 0.
1054 */
1055 for (auto &file : _grf_files) {
1056 if (file.housespec.empty()) continue;
1057
1058 size_t num_houses = file.housespec.size();
1059 for (size_t i = 0; i < num_houses; i++) {
1060 auto &hs = file.housespec[i];
1061
1062 if (hs == nullptr) continue;
1063
1064 const HouseSpec *next1 = (i + 1 < num_houses ? file.housespec[i + 1].get() : nullptr);
1065 const HouseSpec *next2 = (i + 2 < num_houses ? file.housespec[i + 2].get() : nullptr);
1066 const HouseSpec *next3 = (i + 3 < num_houses ? file.housespec[i + 3].get() : nullptr);
1067
1068 if (!IsHouseSpecValid(*hs, next1, next2, next3, file.filename)) continue;
1069
1070 _house_mngr.SetEntitySpec(std::move(*hs));
1071 }
1072
1073 /* Won't be used again */
1074 file.housespec.clear();
1075 file.housespec.shrink_to_fit();
1076 }
1077
1078 for (size_t i = 0; i < HouseSpec::Specs().size(); i++) {
1079 HouseSpec *hs = HouseSpec::Get(i);
1080 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr);
1081 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr);
1082 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : nullptr);
1083
1084 /* We need to check all houses again to we are sure that multitile houses
1085 * did get consecutive IDs and none of the parts are missing. */
1086 if (!IsHouseSpecValid(*hs, next1, next2, next3, std::string{})) {
1087 /* GetHouseNorthPart checks 3 houses that are directly before
1088 * it in the house pool. If any of those houses have multi-tile
1089 * flags set it assumes it's part of a multitile house. Since
1090 * we can have invalid houses in the pool marked as disabled, we
1091 * don't want to have them influencing valid tiles. As such set
1092 * building_flags to zero here to make sure any house following
1093 * this one in the pool is properly handled as 1x1 house. */
1094 hs->building_flags = {};
1095 }
1096
1097 /* Apply default cargo translation map for unset cargo slots */
1098 for (uint i = 0; i < lengthof(hs->accepts_cargo_label); ++i) {
1099 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->accepts_cargo[i] = GetCargoTypeByLabel(hs->accepts_cargo_label[i]);
1100 /* Disable acceptance if cargo type is invalid. */
1101 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->cargo_acceptance[i] = 0;
1102 }
1103 }
1104
1105 HouseZones climate_mask = GetClimateMaskForLandscape();
1106 for (HouseZone climate : climate_mask) {
1107 for (HouseZone zone : HZ_ZONE_ALL) {
1108 EnsureEarlyHouse({climate, zone});
1109 }
1110 }
1111}
1112
1119{
1120 for (auto &file : _grf_files) {
1121 for (auto &indsp : file.industryspec) {
1122 if (indsp == nullptr || !indsp->enabled) continue;
1123
1124 _industry_mngr.SetEntitySpec(std::move(*indsp));
1125 }
1126
1127 for (auto &indtsp : file.indtspec) {
1128 if (indtsp != nullptr) {
1129 _industile_mngr.SetEntitySpec(std::move(*indtsp));
1130 }
1131 }
1132
1133 /* Won't be used again */
1134 file.industryspec.clear();
1135 file.industryspec.shrink_to_fit();
1136 file.indtspec.clear();
1137 file.indtspec.shrink_to_fit();
1138 }
1139
1140 for (auto &indsp : _industry_specs) {
1141 if (indsp.enabled && indsp.grf_prop.HasGrfFile()) {
1142 for (auto &conflicting : indsp.conflicting) {
1143 conflicting = MapNewGRFIndustryType(conflicting, indsp.grf_prop.grfid);
1144 }
1145 }
1146 if (!indsp.enabled) {
1147 indsp.name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
1148 }
1149
1150 /* Apply default cargo translation map for unset cargo slots */
1151 for (size_t i = 0; i < std::size(indsp.produced_cargo_label); ++i) {
1152 if (!IsValidCargoType(indsp.produced_cargo[i])) indsp.produced_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.produced_cargo_label[i]));
1153 }
1154 for (size_t i = 0; i < std::size(indsp.accepts_cargo_label); ++i) {
1155 if (!IsValidCargoType(indsp.accepts_cargo[i])) indsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.accepts_cargo_label[i]));
1156 }
1157 }
1158
1159 for (auto &indtsp : _industry_tile_specs) {
1160 /* Apply default cargo translation map for unset cargo slots */
1161 for (size_t i = 0; i < std::size(indtsp.accepts_cargo_label); ++i) {
1162 if (!IsValidCargoType(indtsp.accepts_cargo[i])) indtsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indtsp.accepts_cargo_label[i]));
1163 }
1164 }
1165}
1166
1173{
1174 for (auto &file : _grf_files) {
1175 for (auto &objectspec : file.objectspec) {
1176 if (objectspec != nullptr && objectspec->grf_prop.HasGrfFile() && objectspec->IsEnabled()) {
1177 _object_mngr.SetEntitySpec(std::move(*objectspec));
1178 }
1179 }
1180
1181 /* Won't be used again */
1182 file.objectspec.clear();
1183 file.objectspec.shrink_to_fit();
1184 }
1185
1187}
1188
1195{
1196 for (auto &file : _grf_files) {
1197 for (auto &as : file.airportspec) {
1198 if (as != nullptr && as->enabled) {
1199 _airport_mngr.SetEntitySpec(std::move(*as));
1200 }
1201 }
1202
1203 for (auto &ats : file.airtspec) {
1204 if (ats != nullptr && ats->enabled) {
1205 _airporttile_mngr.SetEntitySpec(std::move(*ats));
1206 }
1207 }
1208
1209 /* Won't be used again */
1210 file.airportspec.clear();
1211 file.airportspec.shrink_to_fit();
1212 file.airtspec.clear();
1213 file.airtspec.shrink_to_fit();
1214 }
1215}
1216
1219 template <uint8_t TAction>
1220 static void Invoke(ByteReader &buf, GrfLoadingStage stage)
1221 {
1222 switch (stage) {
1229 default: NOT_REACHED();
1230 }
1231 }
1232
1233 using Invoker = void(*)(ByteReader &buf, GrfLoadingStage stage);
1234 static constexpr Invoker funcs[] = { // Must be listed in action order.
1235 Invoke<0x00>, Invoke<0x01>, Invoke<0x02>, Invoke<0x03>, Invoke<0x04>, Invoke<0x05>, Invoke<0x06>, Invoke<0x07>,
1236 Invoke<0x08>, Invoke<0x09>, Invoke<0x0A>, Invoke<0x0B>, Invoke<0x0C>, Invoke<0x0D>, Invoke<0x0E>, Invoke<0x0F>,
1237 Invoke<0x10>, Invoke<0x11>, Invoke<0x12>, Invoke<0x13>, Invoke<0x14>,
1238 };
1239
1240 static void Invoke(uint8_t action, GrfLoadingStage stage, ByteReader &buf)
1241 {
1242 Invoker func = action < std::size(funcs) ? funcs[action] : nullptr;
1243 if (func == nullptr) {
1244 GrfMsg(7, "DecodeSpecialSprite: Skipping unknown action 0x{:02X}", action);
1245 } else {
1246 GrfMsg(7, "DecodeSpecialSprite: Handling action 0x{:02X} in stage {}", action, stage);
1247 func(buf, stage);
1248 }
1249 }
1250};
1251
1252/* Here we perform initial decoding of some special sprites (as are they
1253 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
1254 * partial implementation yet).
1255 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
1256 * a crafted invalid GRF file. We should tell that to the user somehow, or
1257 * better make this more robust in the future. */
1258static void DecodeSpecialSprite(ReusableBuffer<uint8_t> &allocator, uint num, GrfLoadingStage stage)
1259{
1260 uint8_t *buf;
1261 auto it = _grf_line_to_action6_sprite_override.find({_cur_gps.grfconfig->ident.grfid, _cur_gps.nfo_line});
1262 if (it == _grf_line_to_action6_sprite_override.end()) {
1263 /* No preloaded sprite to work with; read the
1264 * pseudo sprite content. */
1265 buf = allocator.Allocate(num);
1266 _cur_gps.file->ReadBlock(buf, num);
1267 } else {
1268 /* Use the preloaded sprite data. */
1269 buf = it->second.data();
1270 assert(it->second.size() == num);
1271 GrfMsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
1272
1273 /* Skip the real (original) content of this action. */
1274 _cur_gps.file->SeekTo(num, SEEK_CUR);
1275 }
1276
1277 ByteReader br(buf, num);
1278
1279 try {
1280 uint8_t action = br.ReadByte();
1281
1282 if (action == 0xFF) {
1283 GrfMsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
1284 } else if (action == 0xFE) {
1285 GrfMsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
1286 } else {
1287 InvokeGrfActionHandler::Invoke(action, stage, br);
1288 }
1289 } catch (...) {
1290 GrfMsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
1291 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
1292 }
1293}
1294
1302{
1303 AutoRestoreBackup cur_file(_cur_gps.file, &file);
1304 AutoRestoreBackup cur_config(_cur_gps.grfconfig, &config);
1305
1306 Debug(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '{}'", config.filename);
1307
1308 uint8_t grf_container_version = file.GetContainerVersion();
1309 if (grf_container_version == 0) {
1310 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1311 return;
1312 }
1313
1314 if (stage == GrfLoadingStage::Init || stage == GrfLoadingStage::Activation) {
1315 /* We need the sprite offsets in the init stage for NewGRF sounds
1316 * and in the activation stage for real sprites. */
1318 } else {
1319 /* Skip sprite section offset if present. */
1320 if (grf_container_version >= 2) file.ReadDword();
1321 }
1322
1323 if (grf_container_version >= 2) {
1324 /* Read compression value. */
1325 uint8_t compression = file.ReadByte();
1326 if (compression != 0) {
1327 Debug(grf, 7, "LoadNewGRFFile: Unsupported compression format");
1328 return;
1329 }
1330 }
1331
1332 /* Skip the first sprite; we don't care about how many sprites this
1333 * does contain; newest TTDPatches and George's longvehicles don't
1334 * neither, apparently. */
1335 uint32_t num = grf_container_version >= 2 ? file.ReadDword() : file.ReadWord();
1336 if (num == 4 && file.ReadByte() == 0xFF) {
1337 file.ReadDword();
1338 } else {
1339 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1340 return;
1341 }
1342
1343 _cur_gps.ClearDataForNextFile();
1344
1345 ReusableBuffer<uint8_t> allocator;
1346
1347 while ((num = (grf_container_version >= 2 ? file.ReadDword() : file.ReadWord())) != 0) {
1348 uint8_t type = file.ReadByte();
1349 _cur_gps.nfo_line++;
1350
1351 if (type == 0xFF) {
1352 if (_cur_gps.skip_sprites == 0) {
1353 /* Limit the special sprites to 1 MiB. */
1354 if (num > 1024 * 1024) {
1355 GrfMsg(0, "LoadNewGRFFile: Unexpectedly large sprite, disabling");
1356 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1357 break;
1358 }
1359
1360 DecodeSpecialSprite(allocator, num, stage);
1361
1362 /* Stop all processing if we are to skip the remaining sprites */
1363 if (_cur_gps.skip_sprites == -1) break;
1364
1365 continue;
1366 } else {
1367 file.SkipBytes(num);
1368 }
1369 } else {
1370 if (_cur_gps.skip_sprites == 0) {
1371 GrfMsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
1372 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1373 break;
1374 }
1375
1376 if (grf_container_version >= 2 && type == 0xFD) {
1377 /* Reference to data section. Container version >= 2 only. */
1378 file.SkipBytes(num);
1379 } else {
1380 file.SkipBytes(7);
1381 SkipSpriteData(file, type, num - 8);
1382 }
1383 }
1384
1385 if (_cur_gps.skip_sprites > 0) _cur_gps.skip_sprites--;
1386 }
1387}
1388
1397void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
1398{
1399 const std::string &filename = config.filename;
1400
1401 /* A .grf file is activated only if it was active when the game was
1402 * started. If a game is loaded, only its active .grfs will be
1403 * reactivated, unless "loadallgraphics on" is used. A .grf file is
1404 * considered active if its action 8 has been processed, i.e. its
1405 * action 8 hasn't been skipped using an action 7.
1406 *
1407 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
1408 * carried out. All others are ignored, because they only need to be
1409 * processed once at initialization. */
1411 _cur_gps.grffile = GetFileByFilename(filename);
1412 if (_cur_gps.grffile == nullptr) UserError("File '{}' lost in cache.\n", filename);
1413 if (stage == GrfLoadingStage::Reserve && config.status != GCS_INITIALISED) return;
1414 if (stage == GrfLoadingStage::Activation && !config.flags.Test(GRFConfigFlag::Reserved)) return;
1415 }
1416
1417 bool needs_palette_remap = config.palette & GRFP_USE_MASK;
1418 if (temporary) {
1419 SpriteFile temporarySpriteFile(filename, subdir, needs_palette_remap);
1420 LoadNewGRFFileFromFile(config, stage, temporarySpriteFile);
1421 } else {
1422 LoadNewGRFFileFromFile(config, stage, OpenCachedSpriteFile(filename, subdir, needs_palette_remap));
1423 }
1424}
1425
1433static void ActivateOldShore()
1434{
1435 /* Use default graphics, if no shore sprites were loaded.
1436 * Should not happen, as the base set's extra grf should include some. */
1438
1440 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
1441 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
1442 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
1443 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
1444 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
1445 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
1446 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
1447 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
1448 }
1449
1451 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
1452 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
1453 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
1454 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
1455 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
1456 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
1457 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
1458 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
1459
1460 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
1461 * If they would be used somewhen, then these grass tiles will most like not look as needed */
1462 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
1463 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
1464 }
1465}
1466
1471{
1473 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0); // use road depot graphics for "no tracks"
1474 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
1475 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2); // use road depot graphics for "no tracks"
1476 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
1477 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
1478 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
1479 }
1480}
1481
1486{
1488 static constexpr GrfSpecFeatures override_features{GSF_TRAINS, GSF_ROADVEHICLES, GSF_SHIPS, GSF_AIRCRAFT};
1489
1490 /* Evaluate grf overrides */
1491 int num_grfs = (uint)_grf_files.size();
1492 std::vector<int> grf_overrides(num_grfs, -1);
1493 for (int i = 0; i < num_grfs; i++) {
1494 GRFFile &source = _grf_files[i];
1495 auto it = _grf_id_overrides.find(source.grfid);
1496 if (it == std::end(_grf_id_overrides)) continue;
1497 uint32_t override_grfid = it->second;
1498
1499 auto dest = std::ranges::find(_grf_files, override_grfid, &GRFFile::grfid);
1500 if (dest == std::end(_grf_files)) continue;
1501
1502 grf_overrides[i] = static_cast<int>(std::ranges::distance(std::begin(_grf_files), dest));
1503 assert(grf_overrides[i] >= 0);
1504 }
1505
1506 /* Override features and price base multipliers of earlier loaded grfs */
1507 for (int i = 0; i < num_grfs; i++) {
1508 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
1509 GRFFile &source = _grf_files[i];
1510 GRFFile &dest = _grf_files[grf_overrides[i]];
1511
1512 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1513 source.grf_features.Set(features);
1514 dest.grf_features.Set(features);
1515
1516 for (Price p = Price::Begin; p < Price::End; p++) {
1517 /* No price defined -> nothing to do */
1518 if (!features.Test(_price_base_specs[p].grf_feature) || source.price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
1519 Debug(grf, 3, "'{}' overrides price base multiplier {} of '{}'", source.filename, p, dest.filename);
1521 }
1522 }
1523
1524 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
1525 for (int i = num_grfs - 1; i >= 0; i--) {
1526 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
1527 GRFFile &source = _grf_files[i];
1528 GRFFile &dest = _grf_files[grf_overrides[i]];
1529
1530 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1531 source.grf_features.Set(features);
1532 dest.grf_features.Set(features);
1533
1534 for (Price p = Price::Begin; p < Price::End; p++) {
1535 /* Already a price defined -> nothing to do */
1536 if (!features.Test(_price_base_specs[p].grf_feature) || dest.price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
1537 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, source.filename, dest.filename);
1539 }
1540 }
1541
1542 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
1543 for (int i = 0; i < num_grfs; i++) {
1544 if (grf_overrides[i] < 0) continue;
1545 GRFFile &source = _grf_files[i];
1546 GRFFile &dest = _grf_files[grf_overrides[i]];
1547
1548 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1549 source.grf_features.Set(features);
1550 dest.grf_features.Set(features);
1551
1552 for (Price p = Price::Begin; p < Price::End; p++) {
1553 if (!features.Test(_price_base_specs[p].grf_feature)) continue;
1554 if (source.price_base_multipliers[p] != dest.price_base_multipliers[p]) {
1555 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, dest.filename, source.filename);
1556 }
1558 }
1559 }
1560
1561 /* Apply fallback prices for grf version < 8 */
1562 for (auto &file : _grf_files) {
1563 if (file.grf_version >= 8) continue;
1564 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1565 for (Price p = Price::Begin; p < Price::End; p++) {
1566 Price fallback_price = _price_base_specs[p].fallback_price;
1567 if (fallback_price != Price::Invalid && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1568 /* No price multiplier has been set.
1569 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
1570 price_base_multipliers[p] = price_base_multipliers[fallback_price];
1571 }
1572 }
1573 }
1574
1575 /* Decide local/global scope of price base multipliers */
1576 for (auto &file : _grf_files) {
1577 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1578 for (Price p = Price::Begin; p < Price::End; p++) {
1579 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1580 /* No multiplier was set; set it to a neutral value */
1581 price_base_multipliers[p] = 0;
1582 } else {
1583 if (!file.grf_features.Test(_price_base_specs[p].grf_feature)) {
1584 /* The grf does not define any objects of the feature,
1585 * so it must be a difficulty setting. Apply it globally */
1586 Debug(grf, 3, "'{}' sets global price base multiplier {}", file.filename, p);
1587 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
1588 price_base_multipliers[p] = 0;
1589 } else {
1590 Debug(grf, 3, "'{}' sets local price base multiplier {}", file.filename, p);
1591 }
1592 }
1593 }
1594 }
1595}
1596
1597template <typename T>
1598void AddBadgeToSpecs(T &specs, GrfSpecFeature feature, Badge &badge)
1599{
1600 for (auto &spec : specs) {
1601 if (spec == nullptr) continue;
1602 spec->badges.push_back(badge.index);
1603 badge.features.Set(feature);
1604 }
1605}
1606
1608static void FinaliseBadges()
1609{
1610 for (const auto &file : _grf_files) {
1611 Badge *badge = GetBadgeByLabel(fmt::format("newgrf/{:08x}", std::byteswap(file.grfid)));
1612 if (badge == nullptr) continue;
1613
1614 for (Engine *e : Engine::Iterate()) {
1615 if (e->grf_prop.grffile != &file) continue;
1616 e->badges.push_back(badge->index);
1617 badge->features.Set(static_cast<GrfSpecFeature>(GSF_TRAINS + e->type));
1618 }
1619
1620 AddBadgeToSpecs(file.stations, GSF_STATIONS, *badge);
1621 AddBadgeToSpecs(file.housespec, GSF_HOUSES, *badge);
1622 AddBadgeToSpecs(file.industryspec, GSF_INDUSTRIES, *badge);
1623 AddBadgeToSpecs(file.indtspec, GSF_INDUSTRYTILES, *badge);
1624 AddBadgeToSpecs(file.objectspec, GSF_OBJECTS, *badge);
1625 AddBadgeToSpecs(file.airportspec, GSF_AIRPORTS, *badge);
1626 AddBadgeToSpecs(file.airtspec, GSF_AIRPORTTILES, *badge);
1627 AddBadgeToSpecs(file.roadstops, GSF_ROADSTOPS, *badge);
1628 }
1629
1632}
1633
1634extern void InitGRFTownGeneratorNames();
1635
1637static void AfterLoadGRFs()
1638{
1639 /* Cached callback groups are no longer needed. */
1640 ResetCallbacks(true);
1641
1643
1644 /* Clear the action 6 override sprites. */
1645 _grf_line_to_action6_sprite_override.clear();
1646
1648
1649 /* Polish cargoes */
1651
1652 /* Pre-calculate all refit masks after loading GRF files. */
1654
1655 /* Polish engines */
1657
1658 /* Set the actually used Canal properties */
1660
1661 /* Add all new houses to the house array. */
1663
1664 /* Add all new industries to the industry array. */
1666
1667 /* Add all new objects to the object array. */
1669
1671
1672 /* Sort the list of industry types. */
1674
1675 /* Create dynamic list of industry legends for smallmap_gui.cpp */
1677
1678 /* Build the routemap legend, based on the available cargos */
1680
1681 /* Add all new airports to the airports array. */
1684
1685 /* Update the townname generators list */
1687
1688 /* Run all queued vehicle list order changes */
1690
1691 /* Load old shore sprites in new position, if they were replaced by ActionA */
1693
1694 /* Load old tram depot sprites in new position, if no new ones are present */
1696
1697 /* Set up custom rail types */
1698 InitRailTypes();
1699 InitRoadTypes();
1700
1701 for (Engine *e : Engine::IterateType(VEH_ROAD)) {
1702 if (_gted[e->index].rv_max_speed != 0) {
1703 /* Set RV maximum speed from the mph/0.8 unit value */
1704 e->VehInfo<RoadVehicleInfo>().max_speed = _gted[e->index].rv_max_speed * 4;
1705 }
1706
1707 RoadTramType rtt = e->info.misc_flags.Test(EngineMiscFlag::RoadIsTram) ? RTT_TRAM : RTT_ROAD;
1708
1709 const GRFFile *file = e->GetGRF();
1710 if (file == nullptr || _gted[e->index].roadtramtype == 0) {
1711 e->VehInfo<RoadVehicleInfo>().roadtype = (rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
1712 continue;
1713 }
1714
1715 /* Remove +1 offset. */
1716 _gted[e->index].roadtramtype--;
1717
1718 const std::vector<RoadTypeLabel> *list = (rtt == RTT_TRAM) ? &file->tramtype_list : &file->roadtype_list;
1719 if (_gted[e->index].roadtramtype < list->size())
1720 {
1721 RoadTypeLabel rtl = (*list)[_gted[e->index].roadtramtype];
1722 RoadType rt = GetRoadTypeByLabel(rtl);
1723 if (rt != INVALID_ROADTYPE && GetRoadTramType(rt) == rtt) {
1724 e->VehInfo<RoadVehicleInfo>().roadtype = rt;
1725 continue;
1726 }
1727 }
1728
1729 /* Road type is not available, so disable this engine */
1730 e->info.climates = {};
1731 }
1732
1734 RailTypes railtypes{};
1735 for (RailTypeLabel label : _gted[e->index].railtypelabels) {
1736 auto rt = GetRailTypeByLabel(label);
1737 if (rt != INVALID_RAILTYPE) railtypes.Set(rt);
1738 }
1739
1740 if (railtypes.Any()) {
1741 e->VehInfo<RailVehicleInfo>().railtypes = railtypes;
1742 e->VehInfo<RailVehicleInfo>().intended_railtypes = railtypes;
1743 } else {
1744 /* Rail type is not available, so disable this engine */
1745 e->info.climates = {};
1746 }
1747 }
1748
1750
1752
1753 /* Deallocate temporary loading data */
1754 _gted.clear();
1755 _grm_sprites.clear();
1756}
1757
1763void LoadNewGRF(SpriteID load_index, uint num_baseset)
1764{
1765 /* In case of networking we need to "sync" the start values
1766 * so all NewGRFs are loaded equally. For this we use the
1767 * start date of the game and we set the counters, etc. to
1768 * 0 so they're the same too. */
1769 TimerGameCalendar::Date date = TimerGameCalendar::date;
1770 TimerGameCalendar::Year year = TimerGameCalendar::year;
1772
1773 TimerGameEconomy::Date economy_date = TimerGameEconomy::date;
1774 TimerGameEconomy::Year economy_year = TimerGameEconomy::year;
1776
1777 uint64_t tick_counter = TimerGameTick::counter;
1778 uint8_t display_opt = _display_opt;
1779
1780 if (_networking) {
1781 TimerGameCalendar::year = _settings_game.game_creation.starting_year;
1784
1785 TimerGameEconomy::year = TimerGameEconomy::Year{_settings_game.game_creation.starting_year.base()};
1788
1790 _display_opt = 0;
1791 }
1792
1794
1796
1797 /*
1798 * Reset the status of all files, so we can 'retry' to load them.
1799 * This is needed when one for example rearranges the NewGRFs in-game
1800 * and a previously disabled NewGRF becomes usable. If it would not
1801 * be reset, the NewGRF would remain disabled even though it should
1802 * have been enabled.
1803 */
1804 for (const auto &c : _grfconfig) {
1805 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
1806 }
1807
1808 _cur_gps.spriteid = load_index;
1809
1810 /* Load newgrf sprites
1811 * in each loading stage, (try to) open each file specified in the config
1812 * and load information from it. */
1814 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
1815 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
1816 for (const auto &c : _grfconfig) {
1817 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
1818 }
1819
1820 if (stage == GrfLoadingStage::Reserve) {
1821 static const std::pair<uint32_t, uint32_t> default_grf_overrides[] = {
1822 { std::byteswap(0x44442202), std::byteswap(0x44440111) }, // UKRS addons modifies UKRS
1823 { std::byteswap(0x6D620402), std::byteswap(0x6D620401) }, // DBSetXL ECS extension modifies DBSetXL
1824 { std::byteswap(0x4D656f20), std::byteswap(0x4D656F17) }, // LV4cut modifies LV4
1825 };
1826 for (const auto &grf_override : default_grf_overrides) {
1827 SetNewGRFOverride(grf_override.first, grf_override.second);
1828 }
1829 }
1830
1831 uint num_grfs = 0;
1832 uint num_non_static = 0;
1833
1834 _cur_gps.stage = stage;
1835 for (const auto &c : _grfconfig) {
1836 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
1837 if (stage > GrfLoadingStage::Init && c->flags.Test(GRFConfigFlag::InitOnly)) continue;
1838
1839 Subdirectory subdir = num_grfs < num_baseset ? BASESET_DIR : NEWGRF_DIR;
1840 if (!FioCheckFileExists(c->filename, subdir)) {
1841 Debug(grf, 0, "NewGRF file is missing '{}'; disabling", c->filename);
1842 c->status = GCS_NOT_FOUND;
1843 continue;
1844 }
1845
1847
1848 if (!c->flags.Test(GRFConfigFlag::Static) && !c->flags.Test(GRFConfigFlag::System)) {
1849 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
1850 Debug(grf, 0, "'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
1851 c->status = GCS_DISABLED;
1852 c->errors.emplace_back(STR_NEWGRF_ERROR_MSG_FATAL, 0, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
1853 continue;
1854 }
1855 num_non_static++;
1856 }
1857
1858 num_grfs++;
1859
1860 LoadNewGRFFile(*c, stage, subdir, false);
1861 if (stage == GrfLoadingStage::Reserve) {
1862 c->flags.Set(GRFConfigFlag::Reserved);
1863 } else if (stage == GrfLoadingStage::Activation) {
1864 c->flags.Reset(GRFConfigFlag::Reserved);
1865 assert(GetFileByGRFID(c->ident.grfid) == _cur_gps.grffile);
1866 ClearTemporaryNewGRFData(_cur_gps.grffile);
1868 Debug(sprite, 2, "LoadNewGRF: Currently {} sprites are loaded", _cur_gps.spriteid);
1869 } else if (stage == GrfLoadingStage::Init && c->flags.Test(GRFConfigFlag::InitOnly)) {
1870 /* We're not going to activate this, so free whatever data we allocated */
1871 ClearTemporaryNewGRFData(_cur_gps.grffile);
1872 }
1873 }
1874 }
1875
1876 /* We've finished reading files. */
1877 _cur_gps.grfconfig = nullptr;
1878 _cur_gps.grffile = nullptr;
1879
1880 /* Pseudo sprite processing is finished; free temporary stuff */
1881 _cur_gps.ClearDataForNextFile();
1882
1883 /* Call any functions that should be run after GRFs have been loaded. */
1884 AfterLoadGRFs();
1885
1886 /* Now revert back to the original situation */
1889 TimerGameCalendar::date_fract = date_fract;
1890
1891 TimerGameEconomy::year = economy_year;
1892 TimerGameEconomy::date = economy_date;
1893 TimerGameEconomy::date_fract = economy_date_fract;
1894
1895 TimerGameTick::counter = tick_counter;
1896 _display_opt = display_opt;
1897}
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 enable_if_t< is_integral_v< T >, T > byteswap(T x) noexcept
Custom implementation of std::byteswap; remove once we build with C++23.
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:108
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
StrongType::Typedef< uint32_t, struct CargoLabelTag, StrongType::Compare > CargoLabel
Globally unique label of a cargo type.
Definition cargo_type.h:16
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).
Definition cargotype.h:54
@ Mail
Mail.
Definition cargotype.h:51
@ Liquid
Liquids (Oil, Water, Rubber).
Definition cargotype.h:56
@ Passengers
Passengers.
Definition cargotype.h:50
@ Armoured
Armoured cargo (Valuables, Gold, Diamonds).
Definition cargotype.h:53
@ Refrigerated
Refrigerated cargo (Food, Fruit).
Definition cargotype.h:57
@ Express
Express cargo (Goods, Food, Candy, but also possible for passengers).
Definition cargotype.h:52
@ PieceGoods
Piece goods (Livestock, Wood, Steel, Paper).
Definition cargotype.h:55
@ 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
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
static constexpr TimerGame< struct Calendar >::Year MAX_YEAR
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.
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:697
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.
Definition engine_base.h:28
@ IsFolded
Set if display of variants should be folded (hidden).
Definition engine_base.h:29
Functions related to engines.
@ RoadIsTram
Road vehicle is a tram/light rail vehicle.
PoolID< uint16_t, struct EngineIDTag, 64000, 0xFFFF > EngineID
Unique identification number of an engine.
Definition engine_type.h:26
@ RAILVEH_WAGON
simple wagon, not motorized
Definition engine_type.h:34
#define T
Climate temperate.
Definition engines.h:91
#define Y
Climate toyland.
Definition engines.h:97
#define A
Climate sub-arctic.
Definition engines.h:93
#define S
Climate sub-tropic.
Definition engines.h:95
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:21
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:67
static void FinaliseObjectsArray()
Add all new objects to the object array.
Definition newgrf.cpp:1172
static void FinalisePriceBaseMultipliers()
Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them...
Definition newgrf.cpp:1485
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:618
static void FinaliseIndustriesArray()
Add all new industries to the industry array.
Definition newgrf.cpp:1118
std::span< const CargoLabel > GetCargoTranslationTable(const GRFFile &grffile)
Get the cargo translation table to use for the given GRF file.
Definition newgrf.cpp:527
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:511
static void FinaliseAirportsArray()
Add all new airports to the airport array.
Definition newgrf.cpp:1194
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:200
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:338
void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
Set the override for a NewGRF.
Definition newgrf.cpp:185
void GRFUnsafe(ByteReader &)
Set the current NewGRF as unsafe for static use.
Definition newgrf.cpp:379
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:218
static void ActivateOldShore()
Relocates the old shore sprites at new positions.
Definition newgrf.cpp:1433
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:1019
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:860
static void ResetNewGRFErrors()
Clear all NewGRF errors.
Definition newgrf.cpp:401
static void LoadNewGRFFileFromFile(GRFConfig &config, GrfLoadingStage stage, SpriteFile &file)
Load a particular NewGRF from a SpriteFile.
Definition newgrf.cpp:1301
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:1763
static void ClearTemporaryNewGRFData(GRFFile *gf)
Reset all NewGRFData that was used only while processing data.
Definition newgrf.cpp:128
void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig &c)
Disable a static NewGRF when it is influencing another (non-static) NewGRF as this could cause desync...
Definition newgrf.cpp:172
static void FinaliseCanals()
Set to use the correct action0 properties for each canal feature.
Definition newgrf.cpp:849
void ResetNewGRFData()
Reset all NewGRF loaded data.
Definition newgrf.cpp:414
static void CalculateRefitMasks()
Precalculate refit masks from cargo classes for all vehicles.
Definition newgrf.cpp:653
void FinaliseCargoArray()
Check for invalid cargoes.
Definition newgrf.cpp:943
static void BuildCargoTranslationMap()
Construct the Cargo Mapping.
Definition newgrf.cpp:543
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:300
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:1044
static void InitNewGRFFile(const GRFConfig &config)
Prepare loading a NewGRF file with its config.
Definition newgrf.cpp:560
static void ActivateOldTramDepot()
Relocate the old tram depot sprites to the new position, if no new ones were loaded.
Definition newgrf.cpp:1470
void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
Load a particular NewGRF.
Definition newgrf.cpp:1397
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:973
static void AfterLoadGRFs()
Finish loading NewGRFs and execute needed post-processing.
Definition newgrf.cpp:1637
GRFError * DisableGrf(StringID message, GRFConfig *config)
Disable a GRF.
Definition newgrf.cpp:139
static void ResetNewGRF()
Reset and clear all NewGRFs.
Definition newgrf.cpp:388
void InitGRFTownGeneratorNames()
Allocate memory for the NewGRF town names.
CargoTypes TranslateRefitMask(uint32_t refit_mask)
Translate the refit mask.
Definition newgrf.cpp:321
static void FinaliseBadges()
Finish up applying badges to things.
Definition newgrf.cpp:1608
GrfLoadingStage
Stages of loading all NewGRFs.
Definition newgrf.h:47
@ Reserve
Third step of NewGRF loading; reserve features and GRMs.
Definition newgrf.h:52
@ Init
Second step of NewGRF loading; load all actions into memory.
Definition newgrf.h:51
@ LabelScan
First step of NewGRF loading; find the 'goto' labels in the NewGRF.
Definition newgrf.h:50
@ SafetyScan
Checks whether the NewGRF can be used in a static context.
Definition newgrf.h:49
@ FileScan
Load the Action 8 metadata (GRF ID, name).
Definition newgrf.h:48
@ Activation
Forth step of NewGRF loading; activate the features.
Definition newgrf.h:53
@ SHORE_REPLACE_ACTION_A
Shore sprites were replaced by ActionA (using grass tiles for the corner-shores).
Definition newgrf.h:185
@ SHORE_REPLACE_NONE
No shore sprites were replaced.
Definition newgrf.h:183
@ SHORE_REPLACE_ACTION_5
Shore sprites were replaced by Action5.
Definition newgrf.h:184
@ TRAMWAY_REPLACE_DEPOT_WITH_TRACK
Electrified depot graphics with tram track were loaded.
Definition newgrf.h:191
@ TRAMWAY_REPLACE_DEPOT_NONE
No tram depot graphics were loaded.
Definition newgrf.h:190
GrfSpecFeature
Definition newgrf.h:71
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 GrfLoadingStage::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 GrfLoadingStage::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.
void ResetHouses()
Reset and initialise house specs.
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:197
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:301
EnumBitSet< RailType, uint64_t > RailTypes
Allow incrementing of Track variables.
Definition rail_type.h:38
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:191
static CargoSpec array[NUM_CARGO]
Array holding all CargoSpecs.
Definition cargotype.h:197
Information about a vehicle.
LandscapeTypes climates
Climates supported by the engine.
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
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:117
std::array< uint8_t, NUM_CARGO > cargo_map
Inverse cargo translation table (CargoType -> local ID).
Definition newgrf.h:139
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road).
Definition newgrf.h:147
std::vector< RoadTypeLabel > tramtype_list
Roadtype translation table (tram).
Definition newgrf.h:150
GRFFile(const GRFConfig &config)
Constructor for GRFFile.
Definition newgrf.cpp:577
std::vector< CargoLabel > cargo_list
Cargo translation table (local ID -> label).
Definition newgrf.h:138
uint traininfo_vehicle_width
Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details.
Definition newgrf.h:158
GrfSpecFeatures grf_features
Bitset of GrfSpecFeature the grf uses.
Definition newgrf.h:161
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
Definition newgrf.h:157
std::unordered_map< uint8_t, LanguageMap > language_map
Mappings related to the languages.
Definition newgrf.h:155
std::vector< GRFLabel > labels
List of labels.
Definition newgrf.h:136
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition newgrf.h:162
uint32_t grfid
GRF ID (defined by Action 0x08).
@ NONEMPTY
GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not av...
static void FileScan(ByteReader &buf)
Implementation of the GrfLoadingStage::FileScan stage of this action.
static void SafetyScan(ByteReader &buf)
Implementation of the GrfLoadingStage::SafetyScan stage of this action.
static void Reserve(ByteReader &buf)
Implementation of the GrfLoadingStage::Reserve stage of this action.
static void Activation(ByteReader &buf)
Implementation of the GrfLoadingStage::Activation stage of this action.
static void Init(ByteReader &buf)
Implementation of the GrfLoadingStage::Init stage of this action.
static void LabelScan(ByteReader &buf)
Implementation of the GrfLoadingStage::LabelScan stage of this action.
Temporary data during loading of GRFs.
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:1218
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:363
static void BindToClasses()
Tie all ObjectSpecs to their class.
static Pool::IterateWrapper< Engine > Iterate(size_t from=0)
static Engine * Get(auto index)
static bool CanAllocateItem(size_t n=1)
static T * Create(Targs &&... args)
Information about a rail vehicle.
Definition engine_type.h:74
RailTypes railtypes
Railtypes, mangled if elrail is disabled.
Definition engine_type.h:78
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.
uint16_t subst_id
The id of the entity to replace.
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:1992
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.