OpenTTD Source 20260512-master-g20b387b91f
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 = GRFStatus::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, GetOriginalEngineCount(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 == VehicleType::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{};
324 for (uint8_t bit : SetBitIterator(refit_mask)) {
325 CargoType cargo = GetCargoTranslation(bit, _cur_gps.grffile, true);
326 if (IsValidCargoType(cargo)) result.Set(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 */
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 currencies 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{};
656 for (CargoType cargo_type{}; cargo_type != NUM_CARGO; ++cargo_type) {
657 if (IsDefaultCargo(cargo_type)) original_known_cargoes.Set(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 != VehicleType::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 == VehicleType::Aircraft) {
700 /* Aircraft default to "light" cargoes */
702 _gted[engine].cargo_disallowed = {CargoClass::Liquid};
703 } else if (e->type == VehicleType::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 == VehicleType::Train && e->VehInfo<RailVehicleInfo>().railveh_type != RailVehicleType::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)) _gted[engine].ctt_exclude_mask.Reset(ei->cargo_type);
753 }
754
755 /* Compute refittability */
756 {
757 CargoTypes mask{};
758 CargoTypes not_mask{};
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::Refittability::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)) mask.Set(cs->Index());
769 if (cs->classes.Any(_gted[engine].cargo_disallowed)) not_mask.Set(cs->Index());
770 }
771 }
772
773 CargoTypes invalid_mask = CargoTypes{_cargo_mask}.Flip();
774 ei->refit_mask = mask.Reset(not_mask).Flip(xor_mask).Reset(invalid_mask);
775
776 /* Apply explicit refit includes/excludes. */
777 ei->refit_mask.Set(_gted[engine].ctt_include_mask);
778 ei->refit_mask.Reset(_gted[engine].ctt_exclude_mask);
779
780 /* Custom refit mask callback. */
781 const GRFFile *file = _gted[e->index].defaultcargo_grf;
782 if (file == nullptr) file = e->GetGRF();
783 if (file != nullptr && e->info.callback_mask.Test(VehicleCallbackMask::CustomRefit)) {
784 for (const CargoSpec *cs : CargoSpec::Iterate()) {
785 uint8_t local_slot = file->cargo_map[cs->Index()];
786 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_CUSTOM_REFIT, cs->classes.base(), local_slot, engine, nullptr);
787 switch (callback) {
788 case CALLBACK_FAILED:
789 case 0:
790 break; // Do nothing.
791 case 1: ei->refit_mask.Set(cs->Index()); break;
792 case 2: ei->refit_mask.Reset(cs->Index()); break;
793
794 default: ErrorUnknownCallbackResult(file->grfid, CBID_VEHICLE_CUSTOM_REFIT, callback);
795 }
796 }
797 }
798 }
799
800 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
801 if (IsValidCargoType(ei->cargo_type) && !_cargo_mask.Test(ei->cargo_type)) ei->cargo_type = INVALID_CARGO;
802
803 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
804 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
805 if (!only_defaultcargo && (e->type != VehicleType::Ship || e->VehInfo<ShipVehicleInfo>().old_refittable) && IsValidCargoType(ei->cargo_type) && !ei->refit_mask.Test(ei->cargo_type)) {
806 ei->cargo_type = INVALID_CARGO;
807 }
808
809 /* Check if this engine's cargo type is valid. If not, set to the first refittable
810 * cargo type. Finally disable the vehicle, if there is still no cargo. */
811 if (!IsValidCargoType(ei->cargo_type) && ei->refit_mask.Any()) {
812 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
813 const GRFFile *file = _gted[engine].defaultcargo_grf;
814 if (file == nullptr) file = e->GetGRF();
815 if (file != nullptr && file->grf_version >= 8 && !file->cargo_list.empty()) {
816 /* Use first refittable cargo from cargo translation table */
817 uint8_t best_local_slot = UINT8_MAX;
818 for (CargoType cargo_type : ei->refit_mask) {
819 uint8_t local_slot = file->cargo_map[cargo_type];
820 if (local_slot < best_local_slot) {
821 best_local_slot = local_slot;
822 ei->cargo_type = cargo_type;
823 }
824 }
825 }
826
827 if (!IsValidCargoType(ei->cargo_type)) {
828 /* Use first refittable cargo slot */
829 ei->cargo_type = *ei->refit_mask.begin();
830 }
831 }
832 if (!IsValidCargoType(ei->cargo_type) && e->type == VehicleType::Train && e->VehInfo<RailVehicleInfo>().railveh_type != RailVehicleType::Wagon && e->VehInfo<RailVehicleInfo>().capacity == 0) {
833 /* For train engines which do not carry cargo it does not matter if their cargo type is invalid.
834 * Fallback to the first available instead, if the cargo type has not been changed (as indicated by
835 * cargo_label not being CT_INVALID). */
836 if (GetActiveCargoLabel(ei->cargo_label) != CT_INVALID) {
837 ei->cargo_type = *_standard_cargo_mask.begin();
838 }
839 }
840 if (!IsValidCargoType(ei->cargo_type)) ei->climates = {};
841
842 /* Clear refit_mask for not refittable ships */
843 if (e->type == VehicleType::Ship && !e->VehInfo<ShipVehicleInfo>().old_refittable) {
844 ei->refit_mask.Reset();
845 }
846 }
847}
848
850static void FinaliseCanals()
851{
852 for (uint i = 0; i < CF_END; i++) {
853 if (_water_feature[i].grffile != nullptr) {
854 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
855 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
856 }
857 }
858}
859
862{
863 for (Engine *e : Engine::Iterate()) {
864 if (e->GetGRF() == nullptr) {
865 auto found = std::ranges::find(_engine_mngr.mappings[e->type], e->index, &EngineIDMapping::engine);
866 if (found == std::end(_engine_mngr.mappings[e->type]) || found->grfid != INVALID_GRFID || found->internal_id != found->substitute_id) {
867 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
868 }
869 }
870
871 /* Do final mapping on variant engine ID. */
872 if (e->info.variant_id != EngineID::Invalid()) {
873 e->info.variant_id = GetNewEngineID(e->grf_prop.grffile, e->type, e->info.variant_id.base());
874 }
875
876 if (!e->info.climates.Test(_settings_game.game_creation.landscape)) continue;
877
878 switch (e->type) {
880 for (RailType rt : e->VehInfo<RailVehicleInfo>().railtypes) {
882 }
883 break;
885 default: break;
886 }
887
888 /* Skip wagons, there livery is defined via the engine */
889 if (e->type != VehicleType::Train || e->VehInfo<RailVehicleInfo>().railveh_type != RailVehicleType::Wagon) {
890 LiveryScheme ls = GetEngineLiveryScheme(e->index, EngineID::Invalid(), nullptr);
891 SetBit(_loaded_newgrf_features.used_liveries, ls);
892 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
893
894 if (e->type == VehicleType::Train) {
895 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
896 switch (ls) {
897 case LS_STEAM:
898 case LS_DIESEL:
899 case LS_ELECTRIC:
900 case LS_MONORAIL:
901 case LS_MAGLEV:
902 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
903 break;
904
905 case LS_DMU:
906 case LS_EMU:
907 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
908 break;
909
910 default: NOT_REACHED();
911 }
912 }
913 }
914 }
915
916 /* Check engine variants don't point back on themselves (either directly or via a loop) then set appropriate flags
917 * on variant engine. This is performed separately as all variant engines need to have been resolved.
918 * Use Floyd's cycle-detection algorithm to handle the case where a cycle is present but does
919 * not include the starting engine ID. */
920 for (Engine *e : Engine::Iterate()) {
921 EngineID parent = e->info.variant_id;
922 EngineID parent_slow = parent;
923 bool update_slow = false;
924 while (parent != EngineID::Invalid()) {
925 parent = Engine::Get(parent)->info.variant_id;
926 if (update_slow) parent_slow = Engine::Get(parent_slow)->info.variant_id;
927 update_slow = !update_slow;
928 if (parent != e->index && parent != parent_slow) continue;
929
930 /* Engine looped back on itself, so clear the variant. */
931 e->info.variant_id = EngineID::Invalid();
932
933 GrfMsg(1, "FinaliseEngineArray: Variant of engine {:x} in '{}' loops back on itself", e->grf_prop.local_id, e->GetGRF()->filename);
934 break;
935 }
936
937 if (e->info.variant_id != EngineID::Invalid()) {
938 Engine::Get(e->info.variant_id)->display_flags.Set({EngineDisplayFlag::HasVariants, EngineDisplayFlag::IsFolded});
939 }
940 }
941}
942
945{
946 for (CargoSpec &cs : CargoSpec::array) {
947 if (cs.town_production_effect == TownProductionEffect::Invalid) {
948 /* Set default town production effect by cargo label. */
949 switch (cs.label.base()) {
950 case CT_PASSENGERS.base(): cs.town_production_effect = TownProductionEffect::Passengers; break;
951 case CT_MAIL.base(): cs.town_production_effect = TownProductionEffect::Mail; break;
952 default: cs.town_production_effect = TownProductionEffect::None; break;
953 }
954 }
955 if (!cs.IsValid()) {
956 cs.name = cs.name_single = cs.units_volume = STR_NEWGRF_INVALID_CARGO;
957 cs.quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
958 cs.abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
959 }
960 }
961}
962
974static bool IsHouseSpecValid(HouseSpec &hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const std::string &filename)
975{
976 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) &&
977 (next1 == nullptr || !next1->enabled || next1->building_flags.Any(BUILDING_HAS_1_TILE))) ||
978 (hs.building_flags.Any(BUILDING_HAS_4_TILES) &&
979 (next2 == nullptr || !next2->enabled || next2->building_flags.Any(BUILDING_HAS_1_TILE) ||
980 next3 == nullptr || !next3->enabled || next3->building_flags.Any(BUILDING_HAS_1_TILE)))) {
981 hs.enabled = false;
982 if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs.grf_prop.local_id);
983 return false;
984 }
985
986 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
987 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
988 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
989 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) && next1->population != 0) ||
990 (hs.building_flags.Any(BUILDING_HAS_4_TILES) && (next2->population != 0 || next3->population != 0))) {
991 hs.enabled = false;
992 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);
993 return false;
994 }
995
996 /* Substitute type is also used for override, and having an override with a different size causes crashes.
997 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
998 if (!filename.empty() && (hs.building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs.grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
999 hs.enabled = false;
1000 Debug(grf, 1, "FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs.grf_prop.local_id);
1001 return false;
1002 }
1003
1004 /* Make sure that additional parts of multitile houses are not available. */
1005 if (!hs.building_flags.Any(BUILDING_HAS_1_TILE) && hs.building_availability.Any(HZ_ZONE_ALL) && hs.building_availability.Any(HZ_CLIMATE_ALL)) {
1006 hs.enabled = false;
1007 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);
1008 return false;
1009 }
1010
1011 return true;
1012}
1013
1020static void EnsureEarlyHouse(HouseZones bitmask)
1021{
1023
1024 for (const auto &hs : HouseSpec::Specs()) {
1025 if (!hs.enabled) continue;
1026 if (!hs.building_availability.All(bitmask)) continue;
1027 if (hs.min_year < min_year) min_year = hs.min_year;
1028 }
1029
1030 if (min_year == 0) return;
1031
1032 for (auto &hs : HouseSpec::Specs()) {
1033 if (!hs.enabled) continue;
1034 if (!hs.building_availability.All(bitmask)) continue;
1035 if (hs.min_year == min_year) hs.min_year = CalendarTime::MIN_YEAR;
1036 }
1037}
1038
1046{
1047 /* If there are no houses with start dates before 1930, then all houses
1048 * with start dates of 1930 have them reset to 0. This is in order to be
1049 * compatible with TTDPatch, where if no houses have start dates before
1050 * 1930 and the date is before 1930, the game pretends that this is 1930.
1051 * If there have been any houses defined with start dates before 1930 then
1052 * the dates are left alone.
1053 * On the other hand, why 1930? Just 'fix' the houses with the lowest
1054 * minimum introduction date to 0.
1055 */
1056 for (auto &file : _grf_files) {
1057 if (file.housespec.empty()) continue;
1058
1059 size_t num_houses = file.housespec.size();
1060 for (size_t i = 0; i < num_houses; i++) {
1061 auto &hs = file.housespec[i];
1062
1063 if (hs == nullptr) continue;
1064
1065 const HouseSpec *next1 = (i + 1 < num_houses ? file.housespec[i + 1].get() : nullptr);
1066 const HouseSpec *next2 = (i + 2 < num_houses ? file.housespec[i + 2].get() : nullptr);
1067 const HouseSpec *next3 = (i + 3 < num_houses ? file.housespec[i + 3].get() : nullptr);
1068
1069 if (!IsHouseSpecValid(*hs, next1, next2, next3, file.filename)) continue;
1070
1071 _house_mngr.SetEntitySpec(std::move(*hs));
1072 }
1073
1074 /* Won't be used again */
1075 file.housespec.clear();
1076 file.housespec.shrink_to_fit();
1077 }
1078
1079 for (size_t i = 0; i < HouseSpec::Specs().size(); i++) {
1080 HouseSpec *hs = HouseSpec::Get(i);
1081 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr);
1082 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr);
1083 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : nullptr);
1084
1085 /* We need to check all houses again to we are sure that multitile houses
1086 * did get consecutive IDs and none of the parts are missing. */
1087 if (!IsHouseSpecValid(*hs, next1, next2, next3, std::string{})) {
1088 /* GetHouseNorthPart checks 3 houses that are directly before
1089 * it in the house pool. If any of those houses have multi-tile
1090 * flags set it assumes it's part of a multitile house. Since
1091 * we can have invalid houses in the pool marked as disabled, we
1092 * don't want to have them influencing valid tiles. As such set
1093 * building_flags to zero here to make sure any house following
1094 * this one in the pool is properly handled as 1x1 house. */
1095 hs->building_flags = {};
1096 }
1097
1098 /* Apply default cargo translation map for unset cargo slots */
1099 for (uint i = 0; i < lengthof(hs->accepts_cargo_label); ++i) {
1100 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->accepts_cargo[i] = GetCargoTypeByLabel(hs->accepts_cargo_label[i]);
1101 /* Disable acceptance if cargo type is invalid. */
1102 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->cargo_acceptance[i] = 0;
1103 }
1104 }
1105
1106 HouseZones climate_mask = GetClimateMaskForLandscape();
1107 for (HouseZone climate : climate_mask) {
1108 for (HouseZone zone : HZ_ZONE_ALL) {
1109 EnsureEarlyHouse({climate, zone});
1110 }
1111 }
1112}
1113
1120{
1121 for (auto &file : _grf_files) {
1122 for (auto &indsp : file.industryspec) {
1123 if (indsp == nullptr || !indsp->enabled) continue;
1124
1125 _industry_mngr.SetEntitySpec(std::move(*indsp));
1126 }
1127
1128 for (auto &indtsp : file.indtspec) {
1129 if (indtsp != nullptr) {
1130 _industile_mngr.SetEntitySpec(std::move(*indtsp));
1131 }
1132 }
1133
1134 /* Won't be used again */
1135 file.industryspec.clear();
1136 file.industryspec.shrink_to_fit();
1137 file.indtspec.clear();
1138 file.indtspec.shrink_to_fit();
1139 }
1140
1141 for (auto &indsp : _industry_specs) {
1142 if (indsp.enabled && indsp.grf_prop.HasGrfFile()) {
1143 for (auto &conflicting : indsp.conflicting) {
1144 conflicting = MapNewGRFIndustryType(conflicting, indsp.grf_prop.grfid);
1145 }
1146 }
1147 if (!indsp.enabled) {
1148 indsp.name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
1149 }
1150
1151 /* Apply default cargo translation map for unset cargo slots */
1152 for (size_t i = 0; i < std::size(indsp.produced_cargo_label); ++i) {
1153 if (!IsValidCargoType(indsp.produced_cargo[i])) indsp.produced_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.produced_cargo_label[i]));
1154 }
1155 for (size_t i = 0; i < std::size(indsp.accepts_cargo_label); ++i) {
1156 if (!IsValidCargoType(indsp.accepts_cargo[i])) indsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.accepts_cargo_label[i]));
1157 }
1158 }
1159
1160 for (auto &indtsp : _industry_tile_specs) {
1161 /* Apply default cargo translation map for unset cargo slots */
1162 for (size_t i = 0; i < std::size(indtsp.accepts_cargo_label); ++i) {
1163 if (!IsValidCargoType(indtsp.accepts_cargo[i])) indtsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indtsp.accepts_cargo_label[i]));
1164 }
1165 }
1166}
1167
1174{
1175 for (auto &file : _grf_files) {
1176 for (auto &objectspec : file.objectspec) {
1177 if (objectspec != nullptr && objectspec->grf_prop.HasGrfFile() && objectspec->IsEnabled()) {
1178 _object_mngr.SetEntitySpec(std::move(*objectspec));
1179 }
1180 }
1181
1182 /* Won't be used again */
1183 file.objectspec.clear();
1184 file.objectspec.shrink_to_fit();
1185 }
1186
1188}
1189
1196{
1197 for (auto &file : _grf_files) {
1198 for (auto &as : file.airportspec) {
1199 if (as != nullptr && as->enabled) {
1200 _airport_mngr.SetEntitySpec(std::move(*as));
1201 }
1202 }
1203
1204 for (auto &ats : file.airtspec) {
1205 if (ats != nullptr && ats->enabled) {
1206 _airporttile_mngr.SetEntitySpec(std::move(*ats));
1207 }
1208 }
1209
1210 /* Won't be used again */
1211 file.airportspec.clear();
1212 file.airportspec.shrink_to_fit();
1213 file.airtspec.clear();
1214 file.airtspec.shrink_to_fit();
1215 }
1216}
1217
1220 template <uint8_t TAction>
1221 static void Invoke(ByteReader &buf, GrfLoadingStage stage)
1222 {
1223 switch (stage) {
1230 default: NOT_REACHED();
1231 }
1232 }
1233
1234 using Invoker = void(*)(ByteReader &buf, GrfLoadingStage stage);
1235 static constexpr Invoker funcs[] = { // Must be listed in action order.
1236 Invoke<0x00>, Invoke<0x01>, Invoke<0x02>, Invoke<0x03>, Invoke<0x04>, Invoke<0x05>, Invoke<0x06>, Invoke<0x07>,
1237 Invoke<0x08>, Invoke<0x09>, Invoke<0x0A>, Invoke<0x0B>, Invoke<0x0C>, Invoke<0x0D>, Invoke<0x0E>, Invoke<0x0F>,
1238 Invoke<0x10>, Invoke<0x11>, Invoke<0x12>, Invoke<0x13>, Invoke<0x14>,
1239 };
1240
1241 static void Invoke(uint8_t action, GrfLoadingStage stage, ByteReader &buf)
1242 {
1243 Invoker func = action < std::size(funcs) ? funcs[action] : nullptr;
1244 if (func == nullptr) {
1245 GrfMsg(7, "DecodeSpecialSprite: Skipping unknown action 0x{:02X}", action);
1246 } else {
1247 GrfMsg(7, "DecodeSpecialSprite: Handling action 0x{:02X} in stage {}", action, stage);
1248 func(buf, stage);
1249 }
1250 }
1251};
1252
1253/* Here we perform initial decoding of some special sprites (as are they
1254 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
1255 * partial implementation yet).
1256 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
1257 * a crafted invalid GRF file. We should tell that to the user somehow, or
1258 * better make this more robust in the future. */
1259static void DecodeSpecialSprite(ReusableBuffer<uint8_t> &allocator, uint num, GrfLoadingStage stage)
1260{
1261 uint8_t *buf;
1262 auto it = _grf_line_to_action6_sprite_override.find({_cur_gps.grfconfig->ident.grfid, _cur_gps.nfo_line});
1263 if (it == _grf_line_to_action6_sprite_override.end()) {
1264 /* No preloaded sprite to work with; read the
1265 * pseudo sprite content. */
1266 buf = allocator.Allocate(num);
1267 _cur_gps.file->ReadBlock(buf, num);
1268 } else {
1269 /* Use the preloaded sprite data. */
1270 buf = it->second.data();
1271 assert(it->second.size() == num);
1272 GrfMsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
1273
1274 /* Skip the real (original) content of this action. */
1275 _cur_gps.file->SeekTo(num, SEEK_CUR);
1276 }
1277
1278 ByteReader br(buf, num);
1279
1280 try {
1281 uint8_t action = br.ReadByte();
1282
1283 if (action == 0xFF) {
1284 GrfMsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
1285 } else if (action == 0xFE) {
1286 GrfMsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
1287 } else {
1288 InvokeGrfActionHandler::Invoke(action, stage, br);
1289 }
1290 } catch (...) {
1291 GrfMsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
1292 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
1293 }
1294}
1295
1303{
1304 AutoRestoreBackup cur_file(_cur_gps.file, &file);
1305 AutoRestoreBackup cur_config(_cur_gps.grfconfig, &config);
1306
1307 Debug(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '{}'", config.filename);
1308
1309 uint8_t grf_container_version = file.GetContainerVersion();
1310 if (grf_container_version == 0) {
1311 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1312 return;
1313 }
1314
1315 if (stage == GrfLoadingStage::Init || stage == GrfLoadingStage::Activation) {
1316 /* We need the sprite offsets in the init stage for NewGRF sounds
1317 * and in the activation stage for real sprites. */
1319 } else {
1320 /* Skip sprite section offset if present. */
1321 if (grf_container_version >= 2) file.ReadDword();
1322 }
1323
1324 if (grf_container_version >= 2) {
1325 /* Read compression value. */
1326 uint8_t compression = file.ReadByte();
1327 if (compression != 0) {
1328 Debug(grf, 7, "LoadNewGRFFile: Unsupported compression format");
1329 return;
1330 }
1331 }
1332
1333 /* Skip the first sprite; we don't care about how many sprites this
1334 * does contain; newest TTDPatches and George's longvehicles don't
1335 * neither, apparently. */
1336 uint32_t num = grf_container_version >= 2 ? file.ReadDword() : file.ReadWord();
1337 if (num == 4 && file.ReadByte() == 0xFF) {
1338 file.ReadDword();
1339 } else {
1340 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1341 return;
1342 }
1343
1344 _cur_gps.ClearDataForNextFile();
1345
1346 ReusableBuffer<uint8_t> allocator;
1347
1348 while ((num = (grf_container_version >= 2 ? file.ReadDword() : file.ReadWord())) != 0) {
1349 uint8_t type = file.ReadByte();
1350 _cur_gps.nfo_line++;
1351
1352 if (type == 0xFF) {
1353 if (_cur_gps.skip_sprites == 0) {
1354 /* Limit the special sprites to 1 MiB. */
1355 if (num > 1024 * 1024) {
1356 GrfMsg(0, "LoadNewGRFFile: Unexpectedly large sprite, disabling");
1357 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1358 break;
1359 }
1360
1361 DecodeSpecialSprite(allocator, num, stage);
1362
1363 /* Stop all processing if we are to skip the remaining sprites */
1364 if (_cur_gps.skip_sprites == -1) break;
1365
1366 continue;
1367 } else {
1368 file.SkipBytes(num);
1369 }
1370 } else {
1371 if (_cur_gps.skip_sprites == 0) {
1372 GrfMsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
1373 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1374 break;
1375 }
1376
1377 if (grf_container_version >= 2 && type == 0xFD) {
1378 /* Reference to data section. Container version >= 2 only. */
1379 file.SkipBytes(num);
1380 } else {
1381 file.SkipBytes(7);
1382 SkipSpriteData(file, type, num - 8);
1383 }
1384 }
1385
1386 if (_cur_gps.skip_sprites > 0) _cur_gps.skip_sprites--;
1387 }
1388}
1389
1398void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
1399{
1400 const std::string &filename = config.filename;
1401
1402 /* A .grf file is activated only if it was active when the game was
1403 * started. If a game is loaded, only its active .grfs will be
1404 * reactivated, unless "loadallgraphics on" is used. A .grf file is
1405 * considered active if its action 8 has been processed, i.e. its
1406 * action 8 hasn't been skipped using an action 7.
1407 *
1408 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
1409 * carried out. All others are ignored, because they only need to be
1410 * processed once at initialization. */
1412 _cur_gps.grffile = GetFileByFilename(filename);
1413 if (_cur_gps.grffile == nullptr) UserError("File '{}' lost in cache.\n", filename);
1414 if (stage == GrfLoadingStage::Reserve && config.status != GRFStatus::Initialised) return;
1415 if (stage == GrfLoadingStage::Activation && !config.flags.Test(GRFConfigFlag::Reserved)) return;
1416 }
1417
1418 bool needs_palette_remap = config.palette & GRFP_USE_MASK;
1419 if (temporary) {
1420 SpriteFile temporarySpriteFile(filename, subdir, needs_palette_remap);
1421 LoadNewGRFFileFromFile(config, stage, temporarySpriteFile);
1422 } else {
1423 LoadNewGRFFileFromFile(config, stage, OpenCachedSpriteFile(filename, subdir, needs_palette_remap));
1424 }
1425}
1426
1434static void ActivateOldShore()
1435{
1436 /* Use default graphics, if no shore sprites were loaded.
1437 * Should not happen, as the base set's extra grf should include some. */
1439
1441 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
1442 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
1443 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
1444 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
1445 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
1446 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
1447 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
1448 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
1449 }
1450
1452 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
1453 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
1454 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
1455 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
1456 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
1457 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
1458 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
1459 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
1460
1461 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
1462 * If they would be used somewhen, then these grass tiles will most like not look as needed */
1463 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
1464 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
1465 }
1466}
1467
1472{
1474 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0); // use road depot graphics for "no tracks"
1475 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
1476 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2); // use road depot graphics for "no tracks"
1477 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
1478 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
1479 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
1480 }
1481}
1482
1487{
1489 static constexpr GrfSpecFeatures override_features{GrfSpecFeature::Trains, GrfSpecFeature::RoadVehicles, GrfSpecFeature::Ships, GrfSpecFeature::Aircraft};
1490
1491 /* Evaluate grf overrides */
1492 int num_grfs = (uint)_grf_files.size();
1493 std::vector<int> grf_overrides(num_grfs, -1);
1494 for (int i = 0; i < num_grfs; i++) {
1495 GRFFile &source = _grf_files[i];
1496 auto it = _grf_id_overrides.find(source.grfid);
1497 if (it == std::end(_grf_id_overrides)) continue;
1498 uint32_t override_grfid = it->second;
1499
1500 auto dest = std::ranges::find(_grf_files, override_grfid, &GRFFile::grfid);
1501 if (dest == std::end(_grf_files)) continue;
1502
1503 grf_overrides[i] = static_cast<int>(std::ranges::distance(std::begin(_grf_files), dest));
1504 assert(grf_overrides[i] >= 0);
1505 }
1506
1507 /* Override features and price base multipliers of earlier loaded grfs */
1508 for (int i = 0; i < num_grfs; i++) {
1509 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
1510 GRFFile &source = _grf_files[i];
1511 GRFFile &dest = _grf_files[grf_overrides[i]];
1512
1513 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1514 source.grf_features.Set(features);
1515 dest.grf_features.Set(features);
1516
1517 for (Price p = Price::Begin; p < Price::End; p++) {
1518 /* No price defined -> nothing to do */
1519 if (!features.Test(_price_base_specs[p].grf_feature) || source.price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
1520 Debug(grf, 3, "'{}' overrides price base multiplier {} of '{}'", source.filename, p, dest.filename);
1522 }
1523 }
1524
1525 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
1526 for (int i = num_grfs - 1; i >= 0; i--) {
1527 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
1528 GRFFile &source = _grf_files[i];
1529 GRFFile &dest = _grf_files[grf_overrides[i]];
1530
1531 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1532 source.grf_features.Set(features);
1533 dest.grf_features.Set(features);
1534
1535 for (Price p = Price::Begin; p < Price::End; p++) {
1536 /* Already a price defined -> nothing to do */
1537 if (!features.Test(_price_base_specs[p].grf_feature) || dest.price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
1538 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, source.filename, dest.filename);
1540 }
1541 }
1542
1543 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
1544 for (int i = 0; i < num_grfs; i++) {
1545 if (grf_overrides[i] < 0) continue;
1546 GRFFile &source = _grf_files[i];
1547 GRFFile &dest = _grf_files[grf_overrides[i]];
1548
1549 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1550 source.grf_features.Set(features);
1551 dest.grf_features.Set(features);
1552
1553 for (Price p = Price::Begin; p < Price::End; p++) {
1554 if (!features.Test(_price_base_specs[p].grf_feature)) continue;
1555 if (source.price_base_multipliers[p] != dest.price_base_multipliers[p]) {
1556 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, dest.filename, source.filename);
1557 }
1559 }
1560 }
1561
1562 /* Apply fallback prices for grf version < 8 */
1563 for (auto &file : _grf_files) {
1564 if (file.grf_version >= 8) continue;
1565 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1566 for (Price p = Price::Begin; p < Price::End; p++) {
1567 Price fallback_price = _price_base_specs[p].fallback_price;
1568 if (fallback_price != Price::Invalid && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1569 /* No price multiplier has been set.
1570 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
1571 price_base_multipliers[p] = price_base_multipliers[fallback_price];
1572 }
1573 }
1574 }
1575
1576 /* Decide local/global scope of price base multipliers */
1577 for (auto &file : _grf_files) {
1578 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1579 for (Price p = Price::Begin; p < Price::End; p++) {
1580 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1581 /* No multiplier was set; set it to a neutral value */
1582 price_base_multipliers[p] = 0;
1583 } else {
1584 if (!file.grf_features.Test(_price_base_specs[p].grf_feature)) {
1585 /* The grf does not define any objects of the feature,
1586 * so it must be a difficulty setting. Apply it globally */
1587 Debug(grf, 3, "'{}' sets global price base multiplier {}", file.filename, p);
1588 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
1589 price_base_multipliers[p] = 0;
1590 } else {
1591 Debug(grf, 3, "'{}' sets local price base multiplier {}", file.filename, p);
1592 }
1593 }
1594 }
1595 }
1596}
1597
1598template <typename T>
1599void AddBadgeToSpecs(T &specs, GrfSpecFeature feature, Badge &badge)
1600{
1601 for (auto &spec : specs) {
1602 if (spec == nullptr) continue;
1603 spec->badges.push_back(badge.index);
1604 badge.features.Set(feature);
1605 }
1606}
1607
1609static void FinaliseBadges()
1610{
1611 for (const auto &file : _grf_files) {
1612 Badge *badge = GetBadgeByLabel(fmt::format("newgrf/{:08x}", std::byteswap(file.grfid)));
1613 if (badge == nullptr) continue;
1614
1615 for (Engine *e : Engine::Iterate()) {
1616 if (e->grf_prop.grffile != &file) continue;
1617 e->badges.push_back(badge->index);
1618 badge->features.Set(GetGrfSpecFeature(e->type));
1619 }
1620
1621 AddBadgeToSpecs(file.stations, GrfSpecFeature::Stations, *badge);
1622 AddBadgeToSpecs(file.housespec, GrfSpecFeature::Houses, *badge);
1623 AddBadgeToSpecs(file.industryspec, GrfSpecFeature::Industries, *badge);
1624 AddBadgeToSpecs(file.indtspec, GrfSpecFeature::IndustryTiles, *badge);
1625 AddBadgeToSpecs(file.objectspec, GrfSpecFeature::Objects, *badge);
1626 AddBadgeToSpecs(file.airportspec, GrfSpecFeature::Airports, *badge);
1627 AddBadgeToSpecs(file.airtspec, GrfSpecFeature::AirportTiles, *badge);
1628 AddBadgeToSpecs(file.roadstops, GrfSpecFeature::RoadStops, *badge);
1629 }
1630
1633}
1634
1635extern void InitGRFTownGeneratorNames();
1636
1638static void AfterLoadGRFs()
1639{
1640 /* Cached callback groups are no longer needed. */
1641 ResetCallbacks(true);
1642
1644
1645 /* Clear the action 6 override sprites. */
1646 _grf_line_to_action6_sprite_override.clear();
1647
1649
1650 /* Polish cargoes */
1652
1653 /* Pre-calculate all refit masks after loading GRF files. */
1655
1656 /* Polish engines */
1658
1659 /* Set the actually used Canal properties */
1661
1662 /* Add all new houses to the house array. */
1664
1665 /* Add all new industries to the industry array. */
1667
1668 /* Add all new objects to the object array. */
1670
1672
1673 /* Sort the list of industry types. */
1675
1676 /* Create dynamic list of industry legends for smallmap_gui.cpp */
1678
1679 /* Build the routemap legend, based on the available cargos */
1681
1682 /* Add all new airports to the airports array. */
1685
1686 /* Update the townname generators list */
1688
1689 /* Run all queued vehicle list order changes */
1691
1692 /* Load old shore sprites in new position, if they were replaced by ActionA */
1694
1695 /* Load old tram depot sprites in new position, if no new ones are present */
1697
1698 /* Set up custom rail types */
1699 InitRailTypes();
1700 InitRoadTypes();
1701
1703 if (_gted[e->index].rv_max_speed != 0) {
1704 /* Set RV maximum speed from the mph/0.8 unit value */
1705 e->VehInfo<RoadVehicleInfo>().max_speed = _gted[e->index].rv_max_speed * 4;
1706 }
1707
1709
1710 const GRFFile *file = e->GetGRF();
1711 if (file == nullptr || _gted[e->index].roadtramtype == 0) {
1712 e->VehInfo<RoadVehicleInfo>().roadtype = (rtt == RoadTramType::Tram) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
1713 continue;
1714 }
1715
1716 /* Remove +1 offset. */
1717 _gted[e->index].roadtramtype--;
1718
1719 const std::vector<RoadTypeLabel> *list = (rtt == RoadTramType::Tram) ? &file->tramtype_list : &file->roadtype_list;
1720 if (_gted[e->index].roadtramtype < list->size())
1721 {
1722 RoadTypeLabel rtl = (*list)[_gted[e->index].roadtramtype];
1723 RoadType rt = GetRoadTypeByLabel(rtl);
1724 if (rt != INVALID_ROADTYPE && GetRoadTramType(rt) == rtt) {
1725 e->VehInfo<RoadVehicleInfo>().roadtype = rt;
1726 continue;
1727 }
1728 }
1729
1730 /* Road type is not available, so disable this engine */
1731 e->info.climates = {};
1732 }
1733
1735 RailTypes railtypes{};
1736 for (RailTypeLabel label : _gted[e->index].railtypelabels) {
1737 auto rt = GetRailTypeByLabel(label);
1738 if (rt != INVALID_RAILTYPE) railtypes.Set(rt);
1739 }
1740
1741 if (railtypes.Any()) {
1742 e->VehInfo<RailVehicleInfo>().railtypes = railtypes;
1743 e->VehInfo<RailVehicleInfo>().intended_railtypes = railtypes;
1744 } else {
1745 /* Rail type is not available, so disable this engine */
1746 e->info.climates = {};
1747 }
1748 }
1749
1751
1753
1754 /* Deallocate temporary loading data */
1755 _gted.clear();
1756 _grm_sprites.clear();
1757}
1758
1764void LoadNewGRF(SpriteID load_index, uint num_baseset)
1765{
1766 /* In case of networking we need to "sync" the start values
1767 * so all NewGRFs are loaded equally. For this we use the
1768 * start date of the game and we set the counters, etc. to
1769 * 0 so they're the same too. */
1773
1777
1778 uint64_t tick_counter = TimerGameTick::counter;
1779 uint8_t display_opt = _display_opt;
1780
1781 if (_networking) {
1782 TimerGameCalendar::year = _settings_game.game_creation.starting_year;
1785
1786 TimerGameEconomy::year = TimerGameEconomy::Year{_settings_game.game_creation.starting_year.base()};
1789
1791 _display_opt = 0;
1792 }
1793
1795
1797
1798 /*
1799 * Reset the status of all files, so we can 'retry' to load them.
1800 * This is needed when one for example rearranges the NewGRFs in-game
1801 * and a previously disabled NewGRF becomes usable. If it would not
1802 * be reset, the NewGRF would remain disabled even though it should
1803 * have been enabled.
1804 */
1805 for (const auto &c : _grfconfig) {
1806 if (c->status != GRFStatus::NotFound) c->status = GRFStatus::Unknown;
1807 }
1808
1809 _cur_gps.spriteid = load_index;
1810
1811 /* Load newgrf sprites
1812 * in each loading stage, (try to) open each file specified in the config
1813 * and load information from it. */
1815 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
1816 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
1817 for (const auto &c : _grfconfig) {
1818 if (c->status == GRFStatus::Activated) c->status = GRFStatus::Initialised;
1819 }
1820
1821 if (stage == GrfLoadingStage::Reserve) {
1822 static const std::pair<uint32_t, uint32_t> default_grf_overrides[] = {
1823 { std::byteswap(0x44442202), std::byteswap(0x44440111) }, // UKRS addons modifies UKRS
1824 { std::byteswap(0x6D620402), std::byteswap(0x6D620401) }, // DBSetXL ECS extension modifies DBSetXL
1825 { std::byteswap(0x4D656f20), std::byteswap(0x4D656F17) }, // LV4cut modifies LV4
1826 };
1827 for (const auto &grf_override : default_grf_overrides) {
1828 SetNewGRFOverride(grf_override.first, grf_override.second);
1829 }
1830 }
1831
1832 uint num_grfs = 0;
1833 uint num_non_static = 0;
1834
1835 _cur_gps.stage = stage;
1836 for (const auto &c : _grfconfig) {
1837 if (c->status == GRFStatus::Disabled || c->status == GRFStatus::NotFound) continue;
1838 if (stage > GrfLoadingStage::Init && c->flags.Test(GRFConfigFlag::InitOnly)) continue;
1839
1840 Subdirectory subdir = num_grfs < num_baseset ? Subdirectory::Baseset : Subdirectory::NewGrf;
1841 if (!FioCheckFileExists(c->filename, subdir)) {
1842 Debug(grf, 0, "NewGRF file is missing '{}'; disabling", c->filename);
1843 c->status = GRFStatus::NotFound;
1844 continue;
1845 }
1846
1848
1849 if (!c->flags.Test(GRFConfigFlag::Static) && !c->flags.Test(GRFConfigFlag::System)) {
1850 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
1851 Debug(grf, 0, "'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
1852 c->status = GRFStatus::Disabled;
1853 c->errors.emplace_back(STR_NEWGRF_ERROR_MSG_FATAL, 0, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
1854 continue;
1855 }
1856 num_non_static++;
1857 }
1858
1859 num_grfs++;
1860
1861 LoadNewGRFFile(*c, stage, subdir, false);
1862 if (stage == GrfLoadingStage::Reserve) {
1863 c->flags.Set(GRFConfigFlag::Reserved);
1864 } else if (stage == GrfLoadingStage::Activation) {
1865 c->flags.Reset(GRFConfigFlag::Reserved);
1866 assert(GetFileByGRFID(c->ident.grfid) == _cur_gps.grffile);
1867 ClearTemporaryNewGRFData(_cur_gps.grffile);
1869 Debug(sprite, 2, "LoadNewGRF: Currently {} sprites are loaded", _cur_gps.spriteid);
1870 } else if (stage == GrfLoadingStage::Init && c->flags.Test(GRFConfigFlag::InitOnly)) {
1871 /* We're not going to activate this, so free whatever data we allocated */
1872 ClearTemporaryNewGRFData(_cur_gps.grffile);
1873 }
1874 }
1875 }
1876
1877 /* We've finished reading files. */
1878 _cur_gps.grfconfig = nullptr;
1879 _cur_gps.grffile = nullptr;
1880
1881 /* Pseudo sprite processing is finished; free temporary stuff */
1882 _cur_gps.ClearDataForNextFile();
1883
1884 /* Call any functions that should be run after GRFs have been loaded. */
1885 AfterLoadGRFs();
1886
1887 /* Now revert back to the original situation */
1890 TimerGameCalendar::date_fract = date_fract;
1891
1892 TimerGameEconomy::year = economy_year;
1893 TimerGameEconomy::date = economy_date;
1894 TimerGameEconomy::date_fract = economy_date_fract;
1895
1896 TimerGameTick::counter = tick_counter;
1897 _display_opt = display_opt;
1898}
1899
1915
1922{
1923 switch (feature) {
1928 default: return VehicleType::Invalid;
1929 }
1930}
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 enable_if_t< is_integral_v< T >, T > byteswap(T x) noexcept
Custom implementation of std::byteswap; remove once we build with C++23.
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
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:110
static constexpr CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:75
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
StrongType::Typedef< uint32_t, struct CargoLabelTag, StrongType::Compare > CargoLabel
Globally unique label of a cargo type.
Definition cargo_type.h:17
CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:22
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:35
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:61
void InitializeSortedCargoSpecs()
Initialize the list of sorted cargo specifications.
CargoTypes _cargo_mask
Bitmask of cargo types available.
Definition cargotype.cpp:30
@ Bulk
Bulk cargo (Coal, Grain etc., Ores, Fruit).
Definition cargotype.h:55
@ Mail
Mail.
Definition cargotype.h:52
@ Liquid
Liquids (Oil, Water, Rubber).
Definition cargotype.h:57
@ Passengers
Passengers.
Definition cargotype.h:51
@ Armoured
Armoured cargo (Valuables, Gold, Diamonds).
Definition cargotype.h:54
@ Refrigerated
Refrigerated cargo (Food, Fruit).
Definition cargotype.h:58
@ Express
Express cargo (Goods, Food, Candy, but also possible for passengers).
Definition cargotype.h:53
@ PieceGoods
Piece goods (Livestock, Wood, Steel, Paper).
Definition cargotype.h:56
@ Invalid
Invalid town production effect.
Definition cargotype.h:46
@ Mail
Cargo behaves mail-like for production.
Definition cargotype.h:39
@ Passengers
Cargo behaves passenger-like for production.
Definition cargotype.h:38
@ None
Town will not produce this cargo type.
Definition cargotype.h:37
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 & Reset()
Reset all bits.
constexpr Timpl & Set()
Set all bits.
auto begin() const
Returns an iterator to begin of the set 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.
StrongType::Typedef< int32_t, struct YearTag< struct Calendar >, StrongType::Compare, StrongType::Integer > Year
StrongType::Typedef< int32_t, DateTag< struct Calendar >, StrongType::Compare, StrongType::Integer > Date
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:871
void ResetPriceBaseMultipliers()
Reset changes to the price base multipliers.
Definition economy.cpp:859
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:720
void SetupEngines()
Initialise the engine pool with the data from the original vehicles.
Definition engine.cpp:627
uint8_t GetOriginalEngineCount(VehicleType type)
Get the number of original engines for a VehicleType.
Definition engine.cpp:58
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
@ 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:123
Functions for standard in/out file operations.
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition fileio_type.h:88
@ NewGrf
Subdirectory for all NewGRFs.
Definition fileio_type.h:97
@ Baseset
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:1173
static void FinalisePriceBaseMultipliers()
Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them...
Definition newgrf.cpp:1486
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:1119
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:1195
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:1434
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:1020
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:861
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:1302
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:1764
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:850
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:944
GrfSpecFeature GetGrfSpecFeature(VehicleType type)
Get the GrfSpecFeature associated with a VehicleType.
Definition newgrf.cpp:1905
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:1045
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:1471
void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
Load a particular NewGRF.
Definition newgrf.cpp:1398
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:974
static void AfterLoadGRFs()
Finish loading NewGRFs and execute needed post-processing.
Definition newgrf.cpp:1638
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.
VehicleType GetVehicleType(GrfSpecFeature feature)
Get the VehicleType associated with a GrfSpecFeature.
Definition newgrf.cpp:1921
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:1609
GrfLoadingStage
Stages of loading all NewGRFs.
Definition newgrf.h:48
@ SafetyScan
Checks whether the NewGRF can be used in a static context.
Definition newgrf.h:50
@ Reserve
Third step of NewGRF loading; reserve features and GRMs.
Definition newgrf.h:53
@ Init
Second step of NewGRF loading; load all actions into memory.
Definition newgrf.h:52
@ LabelScan
First step of NewGRF loading; find the 'goto' labels in the NewGRF.
Definition newgrf.h:51
@ Activation
Forth step of NewGRF loading; activate the features.
Definition newgrf.h:54
@ FileScan
Load the Action 8 metadata (GRF ID, name).
Definition newgrf.h:49
@ None
No shore sprites were replaced.
Definition newgrf.h:185
@ Action5
Shore sprites were replaced by Action5.
Definition newgrf.h:186
@ ActionA
Shore sprites were replaced by ActionA (using grass tiles for the corner-shores).
Definition newgrf.h:187
@ WithTrack
Electrified depot graphics with tram track were loaded.
Definition newgrf.h:194
@ None
No tram depot graphics were loaded.
Definition newgrf.h:193
GrfSpecFeature
Definition newgrf.h:72
@ RoadStops
Road stops feature.
Definition newgrf.h:93
@ Trains
Trains feature.
Definition newgrf.h:73
@ RoadVehicles
Road vehicles feature.
Definition newgrf.h:74
@ Invalid
An invalid spec feature.
Definition newgrf.h:103
@ Ships
Ships feature.
Definition newgrf.h:75
@ Houses
Houses feature.
Definition newgrf.h:80
@ Stations
Stations feature.
Definition newgrf.h:77
@ Airports
Airports feature.
Definition newgrf.h:86
@ Aircraft
Aircraft feature.
Definition newgrf.h:76
@ IndustryTiles
Industry tiles feature.
Definition newgrf.h:82
@ Objects
Objects feature.
Definition newgrf.h:88
@ AirportTiles
Airport tiles feature.
Definition newgrf.h:90
@ Industries
Industries feature.
Definition newgrf.h:83
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.
@ NotFound
GRF file was not found in the local cache.
@ Initialised
GRF file has been initialised.
@ Unknown
The status of this grf file is unknown.
@ Disabled
GRF file is disabled.
@ 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
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
RoadTramType
The different types of road type.
Definition road_type.h:37
@ Tram
Tram type.
Definition road_type.h:39
@ Road
Road type.
Definition road_type.h:38
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:75
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.
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:118
std::array< uint8_t, NUM_CARGO > cargo_map
Inverse cargo translation table (CargoType -> local ID).
Definition newgrf.h:140
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road).
Definition newgrf.h:148
std::vector< RoadTypeLabel > tramtype_list
Roadtype translation table (tram).
Definition newgrf.h:151
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:139
uint traininfo_vehicle_width
Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details.
Definition newgrf.h:159
GrfSpecFeatures grf_features
Bitset of GrfSpecFeature the grf uses.
Definition newgrf.h:162
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
Definition newgrf.h:158
std::unordered_map< uint8_t, LanguageMap > language_map
Mappings related to the languages.
Definition newgrf.h:156
std::vector< GRFLabel > labels
List of labels.
Definition newgrf.h:137
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition newgrf.h:163
uint32_t grfid
GRF ID (defined by Action 0x08).
State of features loaded by NewGRFs.
Definition newgrf.h:199
@ 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:1219
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
RailVehicleType railveh_type
Type of rail vehicle.
Definition engine_type.h:76
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:1989
Base class for all vehicles.
VehicleType
Available vehicle types.
@ Ship
Ship vehicle type.
@ Invalid
Non-existing type of vehicle.
@ Aircraft
Aircraft vehicle type.
@ Road
Road vehicle type.
@ Train
Train vehicle type.