OpenTTD Source 20260711-master-g3fb3006dff
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_func.h"
24#include "landscape.h"
25#include "newgrf_badge.h"
26#include "newgrf_badge_config.h"
27#include "newgrf_cargo.h"
28#include "newgrf_sound.h"
29#include "newgrf_station.h"
30#include "industrytype.h"
31#include "newgrf_canal.h"
32#include "newgrf_townname.h"
33#include "newgrf_industries.h"
34#include "newgrf_airporttiles.h"
35#include "newgrf_airport.h"
36#include "newgrf_object.h"
37#include "network/core/config.h"
38#include "smallmap_gui.h"
39#include "genworld.h"
40#include "error_func.h"
41#include "vehicle_base.h"
42#include "road.h"
43#include "newgrf_roadstop.h"
48
49#include "table/strings.h"
50#include "table/pricebase.h"
51
52#include "safeguards.h"
53
54/* TTDPatch extended GRF format codec
55 * (c) Petr Baudis 2004 (GPL'd)
56 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
57 *
58 * Contains portions of documentation by TTDPatch team.
59 * Thanks especially to Josef Drexler for the documentation as well as a lot
60 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
61 * served as subject to the initial testing of this codec. */
62
64static std::vector<GRFFile> _grf_files;
65
66std::span<const GRFFile> GetAllGRFFiles()
67{
68 return _grf_files;
69}
70
73
76
77GrfProcessingState _cur_gps;
78
80
91void GrfMsgI(int severity, const std::string &msg)
92{
93 if (_cur_gps.grfconfig == nullptr) {
94 Debug(grf, severity, "{}", msg);
95 } else {
96 Debug(grf, severity, "[{}:{}] {}", _cur_gps.grfconfig->filename, _cur_gps.nfo_line, msg);
97 }
98}
99
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<GrfID, GrfID> _grf_id_overrides;
179
185void SetNewGRFOverride(GrfID source_grfid, GrfID target_grfid)
186{
187 if (target_grfid == 0) {
188 _grf_id_overrides.erase(source_grfid);
189 GrfMsg(5, "SetNewGRFOverride: Removed override of {:X}", std::byteswap(source_grfid));
190 } else {
191 _grf_id_overrides[source_grfid] = target_grfid;
192 GrfMsg(5, "SetNewGRFOverride: Added override of {:X} to {: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 GrfID 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 GrfID 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(GrfID grfid, GRFLanguage language_id)
364{
365 const GRFFile *grffile = GetFileByGRFID(grfid);
366 if (grffile == nullptr) return nullptr;
367
368 auto it = grffile->language_map.find(language_id);
369 if (it == std::end(grffile->language_map)) return nullptr;
370
371 return &it->second;
372}
373
379{
380 _cur_gps.grfconfig->flags.Set(GRFConfigFlag::Unsafe);
381
382 /* Skip remainder of GRF */
383 _cur_gps.skip_sprites = -1;
384}
385
387static void ResetNewGRF()
388{
389 _cur_gps.grfconfig = nullptr;
390 _cur_gps.grffile = nullptr;
391 _grf_files.clear();
392
393 /* We store pointers to GRFFiles in many places, so need to ensure that the pointers do not become invalid
394 * due to vector reallocation. Should not happen due to loading taking place in multiple stages, but
395 * reserving when the size is known is good practice anyway. */
396 _grf_files.reserve(_grfconfig.size());
397}
398
400static void ResetNewGRFErrors()
401{
402 for (const auto &c : _grfconfig) {
403 c->errors.clear();
404 }
405}
406
407extern void ResetCallbacks(bool final);
408extern void ResetGRM();
409
414{
416 CleanUpGRFTownNames();
417
418 ResetBadges();
419
420 /* Copy/reset original engine info data */
421 SetupEngines();
422
423 /* Copy/reset original bridge info data */
424 ResetBridges();
425
426 /* Reset rail type information */
428
429 /* Copy/reset original road type info data */
431
432 /* Allocate temporary refit/cargo class data */
433 _gted.resize(Engine::GetPoolSize());
434
435 /* Fill rail type label temporary data for default trains */
437 _gted[e->index].railtypelabels.clear();
438 for (RailType rt : e->VehInfo<RailVehicleInfo>().railtypes) _gted[e->index].railtypelabels.push_back(GetRailTypeInfo(rt)->label);
439 }
440
441 /* Reset GRM reservations */
442 ResetGRM();
443
444 /* Reset generic feature callback lists */
446
447 /* Reset price base data */
449
450 /* Reset the currencies array */
452
453 /* Reset the house array */
454 ResetHouses();
455
456 /* Reset the industries structures*/
458
459 /* Reset the objects. */
461 ResetObjects();
462
463 /* Reset station classes */
465
466 /* Reset airport-related structures */
470
471 /* Reset road stop classes */
473
474 /* Reset canal sprite groups and flags */
475 _water_feature.fill({});
476
477 ResetFaces();
478
479 /* Reset the snowline table. */
481
482 /* Reset NewGRF files */
483 ResetNewGRF();
484
485 /* Reset NewGRF errors. */
487
488 /* Set up the default cargo types */
489 SetupCargoForClimate(_settings_game.game_creation.landscape);
490
491 /* Reset misc GRF features and train list display variables */
493
494 _loaded_newgrf_features.has_2CC = false;
498
499 /* Clear all GRF overrides */
500 _grf_id_overrides.clear();
501
502 InitializeSoundPool();
503 _spritegroup_pool.CleanPool();
504 ResetCallbacks(false);
505}
506
511{
512 /* Reset override managers */
513 _engine_mngr.ResetToDefaultMapping();
514 _house_mngr.ResetMapping();
515 _industry_mngr.ResetMapping();
516 _industile_mngr.ResetMapping();
517 _airport_mngr.ResetMapping();
518 _airporttile_mngr.ResetMapping();
519}
520
526std::span<const CargoLabel> GetCargoTranslationTable(const GRFFile &grffile)
527{
528 /* Always use the translation table if it's installed. */
529 if (!grffile.cargo_list.empty()) return grffile.cargo_list;
530
531 /* Pre-v7 use climate-dependent "slot" table. */
532 if (grffile.grf_version < 7) return GetClimateDependentCargoTranslationTable();
533
534 /* Otherwise use climate-independent "bitnum" table. */
536}
537
543{
544 _cur_gps.grffile->cargo_map.fill(UINT8_MAX);
545
546 auto cargo_list = GetCargoTranslationTable(*_cur_gps.grffile);
547
548 for (const CargoSpec *cs : CargoSpec::Iterate()) {
549 /* Check the translation table for this cargo's label */
550 int idx = find_index(cargo_list, cs->label);
551 if (idx >= 0) _cur_gps.grffile->cargo_map[cs->Index()] = idx;
552 }
553}
554
559static void InitNewGRFFile(const GRFConfig &config)
560{
561 GRFFile *newfile = GetFileByFilename(config.filename);
562 if (newfile != nullptr) {
563 /* We already loaded it once. */
564 _cur_gps.grffile = newfile;
565 return;
566 }
567
568 assert(_grf_files.size() < _grf_files.capacity()); // We must not invalidate pointers.
569 _cur_gps.grffile = &_grf_files.emplace_back(config);
570}
571
577{
578 this->filename = config.filename;
579 this->grfid = config.ident.grfid;
580
581 /* Initialise local settings to defaults */
582 this->traininfo_vehicle_pitch = 0;
583 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
584
585 /* Mark price_base_multipliers as 'not set' */
586 this->price_base_multipliers.fill(INVALID_PRICE_MODIFIER);
587
588 /* Initialise rail type map with default rail types */
589 this->railtype_map.fill(INVALID_RAILTYPE);
590 this->railtype_map[0] = RAILTYPE_RAIL;
591 this->railtype_map[1] = RAILTYPE_ELECTRIC;
592 this->railtype_map[2] = RAILTYPE_MONO;
593 this->railtype_map[3] = RAILTYPE_MAGLEV;
594
595 /* Initialise road type map with default road types */
596 this->roadtype_map.fill(INVALID_ROADTYPE);
597 this->roadtype_map[0] = ROADTYPE_ROAD;
598
599 /* Initialise tram type map with default tram types */
600 this->tramtype_map.fill(INVALID_ROADTYPE);
601 this->tramtype_map[0] = ROADTYPE_TRAM;
602
603 /* Copy the initial parameter list */
604 this->param = config.param;
605}
606
607/* Some compilers get confused about vectors of unique_ptrs. */
608GRFFile::GRFFile() = default;
609GRFFile::GRFFile(GRFFile &&other) = default;
610GRFFile::~GRFFile() = default;
611
617static CargoLabel GetActiveCargoLabel(const std::initializer_list<CargoLabel> &labels)
618{
619 for (const CargoLabel &label : labels) {
620 CargoType cargo_type = GetCargoTypeByLabel(label);
621 if (cargo_type != INVALID_CARGO) return label;
622 }
623 return CT_INVALID;
624}
625
631static CargoLabel GetActiveCargoLabel(const std::variant<CargoLabel, MixedCargoType> &label)
632{
633 struct visitor {
634 CargoLabel operator()(const CargoLabel &label) { return label; }
635 CargoLabel operator()(const MixedCargoType &mixed)
636 {
637 switch (mixed) {
638 case MCT_LIVESTOCK_FRUIT: return GetActiveCargoLabel({CT_LIVESTOCK, CT_FRUIT});
639 case MCT_GRAIN_WHEAT_MAIZE: return GetActiveCargoLabel({CT_GRAIN, CT_WHEAT, CT_MAIZE});
640 case MCT_VALUABLES_GOLD_DIAMONDS: return GetActiveCargoLabel({CT_VALUABLES, CT_GOLD, CT_DIAMONDS});
641 default: NOT_REACHED();
642 }
643 }
644 };
645
646 return std::visit(visitor{}, label);
647}
648
653{
654 CargoTypes original_known_cargoes{};
655 for (CargoType cargo_type : EnumRange(NUM_CARGO)) {
656 if (IsDefaultCargo(cargo_type)) original_known_cargoes.Set(cargo_type);
657 }
658
659 for (Engine *e : Engine::Iterate()) {
660 EngineID engine = e->index;
661 EngineInfo *ei = &e->info;
662 bool only_defaultcargo;
663
664 /* Apply default cargo translation map if cargo type hasn't been set, either explicitly or by aircraft cargo handling. */
665 if (!IsValidCargoType(e->info.cargo_type)) {
666 e->info.cargo_type = GetCargoTypeByLabel(GetActiveCargoLabel(e->info.cargo_label));
667 }
668
669 /* If the NewGRF did not set any cargo properties, we apply default values. */
670 if (_gted[engine].defaultcargo_grf == nullptr) {
671 /* If the vehicle has any capacity, apply the default refit masks */
672 if (e->type != VehicleType::Train || e->VehInfo<RailVehicleInfo>().capacity != 0) {
673 static constexpr LandscapeType T = LandscapeType::Temperate;
674 static constexpr LandscapeType A = LandscapeType::Arctic;
675 static constexpr LandscapeType S = LandscapeType::Tropic;
676 static constexpr LandscapeType Y = LandscapeType::Toyland;
677 static const struct DefaultRefitMasks {
678 LandscapeTypes climate;
679 CargoLabel cargo_label;
680 CargoClasses cargo_allowed;
681 CargoClasses cargo_disallowed;
682 } _default_refit_masks[] = {
683 {{T, A, S, Y}, CT_PASSENGERS, {CargoClass::Passengers}, {}},
684 {{T, A, S }, CT_MAIL, {CargoClass::Mail}, {}},
685 {{T, A, S }, CT_VALUABLES, {CargoClass::Armoured}, {CargoClass::Liquid}},
687 {{T, A }, CT_COAL, {CargoClass::Bulk}, {}},
688 {{ S }, CT_COPPER_ORE, {CargoClass::Bulk}, {}},
689 {{ Y}, CT_SUGAR, {CargoClass::Bulk}, {}},
690 {{T, A, S }, CT_OIL, {CargoClass::Liquid}, {}},
691 {{ Y}, CT_COLA, {CargoClass::Liquid}, {}},
694 {{ A, S }, CT_FOOD, {CargoClass::Refrigerated}, {}},
696 };
697
698 if (e->type == VehicleType::Aircraft) {
699 /* Aircraft default to "light" cargoes */
701 _gted[engine].cargo_disallowed = {CargoClass::Liquid};
702 } else if (e->type == VehicleType::Ship) {
703 CargoLabel label = GetActiveCargoLabel(ei->cargo_label);
704 switch (label.base()) {
705 case CT_PASSENGERS.base():
706 /* Ferries */
707 _gted[engine].cargo_allowed = {CargoClass::Passengers};
708 _gted[engine].cargo_disallowed = {};
709 break;
710 case CT_OIL.base():
711 /* Tankers */
712 _gted[engine].cargo_allowed = {CargoClass::Liquid};
713 _gted[engine].cargo_disallowed = {};
714 break;
715 default:
716 /* Cargo ships */
717 if (_settings_game.game_creation.landscape == LandscapeType::Toyland) {
718 /* No tanker in toyland :( */
720 _gted[engine].cargo_disallowed = {CargoClass::Passengers};
721 } else {
723 _gted[engine].cargo_disallowed = {CargoClass::Liquid, CargoClass::Passengers};
724 }
725 break;
726 }
727 e->VehInfo<ShipVehicleInfo>().old_refittable = true;
728 } else if (e->type == VehicleType::Train && e->VehInfo<RailVehicleInfo>().railveh_type != RailVehicleType::Wagon) {
729 /* Train engines default to all cargoes, so you can build single-cargo consists with fast engines.
730 * Trains loading multiple cargoes may start stations accepting unwanted cargoes. */
732 _gted[engine].cargo_disallowed = {};
733 } else {
734 /* Train wagons and road vehicles are classified by their default cargo type */
735 CargoLabel label = GetActiveCargoLabel(ei->cargo_label);
736 for (const auto &drm : _default_refit_masks) {
737 if (!drm.climate.Test(_settings_game.game_creation.landscape)) continue;
738 if (drm.cargo_label != label) continue;
739
740 _gted[engine].cargo_allowed = drm.cargo_allowed;
741 _gted[engine].cargo_disallowed = drm.cargo_disallowed;
742 break;
743 }
744
745 /* All original cargoes have specialised vehicles, so exclude them */
746 _gted[engine].ctt_exclude_mask = original_known_cargoes;
747 }
748 }
749 _gted[engine].UpdateRefittability(_gted[engine].cargo_allowed.Any());
750
751 if (IsValidCargoType(ei->cargo_type)) _gted[engine].ctt_exclude_mask.Reset(ei->cargo_type);
752 }
753
754 /* Compute refittability */
755 {
756 CargoTypes mask{};
757 CargoTypes not_mask{};
758 CargoTypes xor_mask = ei->refit_mask;
759
760 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
761 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
762 only_defaultcargo = _gted[engine].refittability != GRFTempEngineData::Refittability::NonEmpty;
763
764 if (_gted[engine].cargo_allowed.Any()) {
765 /* Build up the list of cargo types from the set cargo classes. */
766 for (const CargoSpec *cs : CargoSpec::Iterate()) {
767 if (cs->classes.Any(_gted[engine].cargo_allowed) && cs->classes.All(_gted[engine].cargo_allowed_required)) mask.Set(cs->Index());
768 if (cs->classes.Any(_gted[engine].cargo_disallowed)) not_mask.Set(cs->Index());
769 }
770 }
771
772 CargoTypes invalid_mask = CargoTypes{_cargo_mask}.Flip();
773 ei->refit_mask = mask.Reset(not_mask).Flip(xor_mask).Reset(invalid_mask);
774
775 /* Apply explicit refit includes/excludes. */
776 ei->refit_mask.Set(_gted[engine].ctt_include_mask);
777 ei->refit_mask.Reset(_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: ei->refit_mask.Set(cs->Index()); break;
791 case 2: ei->refit_mask.Reset(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) && !_cargo_mask.Test(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 != VehicleType::Ship || e->VehInfo<ShipVehicleInfo>().old_refittable) && IsValidCargoType(ei->cargo_type) && !ei->refit_mask.Test(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.Any()) {
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 : 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 = *ei->refit_mask.begin();
829 }
830 }
831 if (!IsValidCargoType(ei->cargo_type) && e->type == VehicleType::Train && e->VehInfo<RailVehicleInfo>().railveh_type != RailVehicleType::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 = *_standard_cargo_mask.begin();
837 }
838 }
839 if (!IsValidCargoType(ei->cargo_type)) ei->climates = {};
840
841 /* Clear refit_mask for not refittable ships */
842 if (e->type == VehicleType::Ship && !e->VehInfo<ShipVehicleInfo>().old_refittable) {
843 ei->refit_mask.Reset();
844 }
845 }
846}
847
849static void FinaliseCanals()
850{
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) {
879 for (RailType rt : e->VehInfo<RailVehicleInfo>().railtypes) {
881 }
882 break;
884 default: break;
885 }
886
887 /* Skip wagons, there livery is defined via the engine */
888 if (e->type != VehicleType::Train || e->VehInfo<RailVehicleInfo>().railveh_type != RailVehicleType::Wagon) {
889 LiveryScheme ls = GetEngineLiveryScheme(e->index, EngineID::Invalid(), nullptr);
890 _loaded_newgrf_features.used_liveries.Set(ls);
891 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
892
893 if (e->type == VehicleType::Train) {
895 switch (ls) {
902 break;
903
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 == TownProductionEffect::Invalid) {
947 /* Set default town production effect by cargo label. */
948 switch (cs.label.base()) {
949 case CT_PASSENGERS.base(): cs.town_production_effect = TownProductionEffect::Passengers; break;
950 case CT_MAIL.base(): cs.town_production_effect = TownProductionEffect::Mail; break;
951 default: cs.town_production_effect = TownProductionEffect::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{
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 != GRFStatus::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"
1475 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2); // use road depot graphics for "no tracks"
1479 }
1480}
1481
1486{
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 GrfID 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 : EnumRange(Price::End)) {
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 : EnumRange(Price::End)) {
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 : EnumRange(Price::End)) {
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 : EnumRange(Price::End)) {
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 : EnumRange(Price::End)) {
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(GetGrfSpecFeature(e->type));
1618 }
1619
1620 AddBadgeToSpecs(file.stations, GrfSpecFeature::Stations, *badge);
1621 AddBadgeToSpecs(file.housespec, GrfSpecFeature::Houses, *badge);
1622 AddBadgeToSpecs(file.industryspec, GrfSpecFeature::Industries, *badge);
1623 AddBadgeToSpecs(file.indtspec, GrfSpecFeature::IndustryTiles, *badge);
1624 AddBadgeToSpecs(file.objectspec, GrfSpecFeature::Objects, *badge);
1625 AddBadgeToSpecs(file.airportspec, GrfSpecFeature::Airports, *badge);
1626 AddBadgeToSpecs(file.airtspec, GrfSpecFeature::AirportTiles, *badge);
1627 AddBadgeToSpecs(file.roadstops, GrfSpecFeature::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
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
1708
1709 const GRFFile *file = e->GetGRF();
1710 if (file == nullptr || _gted[e->index].roadtramtype == 0) {
1711 e->VehInfo<RoadVehicleInfo>().roadtype = (rtt == RoadTramType::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 == RoadTramType::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. */
1772
1773 AutoRestoreBackup backup_economy_date{TimerGameEconomy::date};
1774 AutoRestoreBackup backup_economy_year{TimerGameEconomy::year};
1775 AutoRestoreBackup backup_economy_date_fract{TimerGameEconomy::date_fract};
1776
1777 AutoRestoreBackup backup_tick_counter{TimerGameTick::counter};
1778 AutoRestoreBackup backup_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.Reset();
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 != GRFStatus::NotFound) c->status = GRFStatus::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 == GRFStatus::Activated) c->status = GRFStatus::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 == GRFStatus::Disabled || c->status == GRFStatus::NotFound) continue;
1837 if (stage > GrfLoadingStage::Init && c->flags.Test(GRFConfigFlag::InitOnly)) continue;
1838
1839 Subdirectory subdir = num_grfs < num_baseset ? Subdirectory::Baseset : Subdirectory::NewGrf;
1840 if (!FioCheckFileExists(c->filename, subdir)) {
1841 Debug(grf, 0, "NewGRF file is missing '{}'; disabling", c->filename);
1842 c->status = GRFStatus::NotFound;
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 = GRFStatus::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
1902
1909{
1910 switch (feature) {
1915 default: return VehicleType::Invalid;
1916 }
1917}
Class for backupping variables and making sure they are restored later.
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
EnumBitSet< CargoType, uint64_t > CargoTypes
Bitset of CargoType elements.
Definition cargo_type.h:113
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
EnumBitSet< CargoClass, uint16_t > CargoClasses
Bitset of CargoClass elements.
Definition cargotype.h:70
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:72
Iterate a range of enum values.
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
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 newg...
Definition currency.cpp:162
Functions to handle different currencies.
Functions related to debugging.
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
void SetPriceBaseMultiplier(Price price, int factor)
Change a price base by the given factor.
Definition economy.cpp:869
void ResetPriceBaseMultipliers()
Reset changes to the price base multipliers.
Definition economy.cpp:857
Price
Enumeration of all base prices for use with Prices.
@ Invalid
Invalid base price.
@ End
Price base end marker.
void SetYearEngineAgingStops()
Compute the value for _year_engine_aging_stops.
Definition engine.cpp:728
void SetupEngines()
Initialise the engine pool with the data from the original vehicles.
Definition engine.cpp:635
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
EnumBitSet< HouseZone, uint16_t > HouseZones
Bitset of HouseZone elements.
Definition house.h:75
HouseZone
Concentric rings of zoning around the centre of a town.
Definition house.h:59
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.
EnumBitSet< LandscapeType, uint8_t > LandscapeTypes
Bitset of LandscapeType elements.
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
@ Maglev
Maglev engines.
Definition livery.h:31
@ Steam
Steam engines.
Definition livery.h:27
@ EMU
EMUs and their passenger wagons.
Definition livery.h:33
@ Diesel
Diesel engines.
Definition livery.h:28
@ Default
Default scheme.
Definition livery.h:24
@ PassengerWagonDiesel
Passenger wagons attached to diesel engines.
Definition livery.h:35
@ Electric
Electric engines.
Definition livery.h:29
@ Monorail
Monorail engines.
Definition livery.h:30
@ PassengerWagonSteam
Passenger wagons attached to steam engines.
Definition livery.h:34
@ FreightWagon
Freight wagons.
Definition livery.h:39
@ DMU
DMUs and their passenger wagons.
Definition livery.h:32
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:617
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:526
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:510
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 GRFUnsafe(ByteReader &)
Set the current NewGRF as unsafe for static use.
Definition newgrf.cpp:378
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:400
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:413
static void CalculateRefitMasks()
Precalculate refit masks from cargo classes for all vehicles.
Definition newgrf.cpp:652
void FinaliseCargoArray()
Check for invalid cargoes.
Definition newgrf.cpp:943
GrfSpecFeature GetGrfSpecFeature(VehicleType type)
Get the GrfSpecFeature associated with a VehicleType.
Definition newgrf.cpp:1892
static void BuildCargoTranslationMap()
Construct the Cargo Mapping.
Definition newgrf.cpp:542
GRFFile * GetFileByGRFID(GrfID grfid)
Obtain a NewGRF file by its grfID.
Definition newgrf.cpp:105
void SetNewGRFOverride(GrfID source_grfid, GrfID target_grfid)
Set the override for a NewGRF.
Definition newgrf.cpp:185
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
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:559
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:387
void InitGRFTownGeneratorNames()
Allocate memory for the NewGRF town names.
VehicleType GetVehicleType(GrfSpecFeature feature)
Get the VehicleType associated with a GrfSpecFeature.
Definition newgrf.cpp:1908
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:54
@ SafetyScan
Checks whether the NewGRF can be used in a static context.
Definition newgrf.h:56
@ Reserve
Third step of NewGRF loading; reserve features and GRMs.
Definition newgrf.h:59
@ End
End marker.
Definition newgrf.h:61
@ Init
Second step of NewGRF loading; load all actions into memory.
Definition newgrf.h:58
@ LabelScan
First step of NewGRF loading; find the 'goto' labels in the NewGRF.
Definition newgrf.h:57
@ Activation
Forth step of NewGRF loading; activate the features.
Definition newgrf.h:60
@ FileScan
Load the Action 8 metadata (GRF ID, name).
Definition newgrf.h:55
@ None
No shore sprites were replaced.
Definition newgrf.h:191
@ Action5
Shore sprites were replaced by Action5.
Definition newgrf.h:192
@ ActionA
Shore sprites were replaced by ActionA (using grass tiles for the corner-shores).
Definition newgrf.h:193
CanalFeature
List of different canal 'features'.
Definition newgrf.h:27
@ End
End marker.
Definition newgrf.h:37
@ WithTrack
Electrified depot graphics with tram track were loaded.
Definition newgrf.h:200
@ None
No tram depot graphics were loaded.
Definition newgrf.h:199
EnumBitSet< GrfMiscBit, uint8_t > GrfMiscBits
Bitset of GrfMiscBit elements.
Definition newgrf.h:76
GrfSpecFeature
Definition newgrf.h:78
@ RoadStops
Road stops feature.
Definition newgrf.h:99
@ Trains
Trains feature.
Definition newgrf.h:79
@ RoadVehicles
Road vehicles feature.
Definition newgrf.h:80
@ Invalid
An invalid spec feature.
Definition newgrf.h:109
@ Ships
Ships feature.
Definition newgrf.h:81
@ Houses
Houses feature.
Definition newgrf.h:86
@ Stations
Stations feature.
Definition newgrf.h:83
@ Airports
Airports feature.
Definition newgrf.h:92
@ Aircraft
Aircraft feature.
Definition newgrf.h:82
@ IndustryTiles
Industry tiles feature.
Definition newgrf.h:88
@ Objects
Objects feature.
Definition newgrf.h:94
@ AirportTiles
Airport tiles feature.
Definition newgrf.h:96
@ Industries
Industries feature.
Definition newgrf.h:89
EnumBitSet< GrfSpecFeature, uint32_t, GrfSpecFeature::End > GrfSpecFeatures
Bitset of GrfSpecFeature elements.
Definition newgrf.h:113
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.
EnumIndexArray< WaterFeature, CanalFeature, CanalFeature::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(GrfID 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, GrfID 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.
GRFLanguage
Incomplete enumeration of the (New)GRF languages.
Header of Action 0F "universal holder" structure and functions.
uint32_t GrfID
The unique identifier of a NewGRF.
Definition newgrf_type.h:15
static const GrfID INVALID_GRFID
An invalid NewGRF.
Definition newgrf_type.h:17
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:303
EnumBitSet< RailType, uint64_t > RailTypes
Bitset of RailType elements.
Definition rail_type.h:36
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:217
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_TRAMWAY_DEPOT_WITH_TRACK
Definition sprites.h:311
static const SpriteID SPR_TRAMWAY_DEPOT_NO_TRACK
Definition sprites.h:318
static const SpriteID SPR_ROAD_DEPOT
Definition sprites.h:660
static const SpriteID SPR_FLAT_GRASS_TILE
Definition sprites.h:671
static const SpriteID SPR_ORIGINALSHORE_START
Definition sprites.h:245
static const SpriteID SPR_SHORE_BASE
Definition sprites.h:243
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:77
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:194
static CargoSpec array[NUM_CARGO]
Array holding all CargoSpecs.
Definition cargotype.h:200
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:124
std::array< uint8_t, NUM_CARGO > cargo_map
Inverse cargo translation table (CargoType -> local ID).
Definition newgrf.h:146
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road).
Definition newgrf.h:154
std::vector< RoadTypeLabel > tramtype_list
Roadtype translation table (tram).
Definition newgrf.h:157
GRFFile(const GRFConfig &config)
Constructor for GRFFile.
Definition newgrf.cpp:576
std::vector< CargoLabel > cargo_list
Cargo translation table (local ID -> label).
Definition newgrf.h:145
std::unordered_map< GRFLanguage, LanguageMap > language_map
Mappings related to the languages.
Definition newgrf.h:162
uint traininfo_vehicle_width
Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details.
Definition newgrf.h:165
GrfSpecFeatures grf_features
Bitset of GrfSpecFeature the grf uses.
Definition newgrf.h:168
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
Definition newgrf.h:164
std::vector< GRFLabel > labels
List of labels.
Definition newgrf.h:143
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition newgrf.h:169
GrfID grfid
GRF ID (defined by Action 0x08).
State of features loaded by NewGRFs.
Definition newgrf.h:205
@ 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:116
SubstituteGRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:122
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:119
CargoLabel accepts_cargo_label[HOUSE_ORIGINAL_NUM_ACCEPTS]
input landscape cargo slots
Definition house.h:134
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:117
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:110
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:115
HouseZones building_availability
where can it be built (climates, zones)
Definition house.h:118
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(GrfID grfid, GRFLanguage 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 T * Create(Targs &&... args)
static Engine * Get(auto index)
static bool CanAllocateItem(size_t n=1)
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.
DisplayOptions _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:1996
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.