OpenTTD Source 20260721-master-g25ec12c62d
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 "string_func.h"
20#include "town.h"
21#include "newgrf_engine.h"
22#include "newgrf_text.h"
23#include "spritecache.h"
24#include "currency_func.h"
25#include "landscape.h"
26#include "newgrf_badge.h"
27#include "newgrf_badge_config.h"
28#include "newgrf_cargo.h"
29#include "newgrf_sound.h"
30#include "newgrf_station.h"
31#include "industrytype.h"
32#include "newgrf_canal.h"
33#include "newgrf_townname.h"
34#include "newgrf_industries.h"
35#include "newgrf_airporttiles.h"
36#include "newgrf_airport.h"
37#include "newgrf_object.h"
38#include "network/core/config.h"
39#include "smallmap_gui.h"
40#include "genworld.h"
41#include "error_func.h"
42#include "vehicle_base.h"
43#include "road.h"
44#include "newgrf_roadstop.h"
49
50#include "table/strings.h"
51#include "table/pricebase.h"
52
53#include "safeguards.h"
54
55/* TTDPatch extended GRF format codec
56 * (c) Petr Baudis 2004 (GPL'd)
57 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
58 *
59 * Contains portions of documentation by TTDPatch team.
60 * Thanks especially to Josef Drexler for the documentation as well as a lot
61 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
62 * served as subject to the initial testing of this codec. */
63
65static std::vector<GRFFile> _grf_files;
66
67std::span<const GRFFile> GetAllGRFFiles()
68{
69 return _grf_files;
70}
71
74
77
78GrfProcessingState _cur_gps;
79
81
92void GrfMsgI(int severity, const std::string &msg)
93{
94 if (_cur_gps.grfconfig == nullptr) {
95 Debug(grf, severity, "{}", msg);
96 } else {
97 Debug(grf, severity, "[{}:{}] {}", _cur_gps.grfconfig->filename, _cur_gps.nfo_line, msg);
98 }
99}
100
107{
108 auto it = std::ranges::find(_grf_files, grfid, &GRFFile::grfid);
109 if (it != std::end(_grf_files)) return &*it;
110 return nullptr;
111}
112
118static GRFFile *GetFileByFilename(const std::string &filename)
119{
120 auto it = std::ranges::find(_grf_files, filename, &GRFFile::filename);
121 if (it != std::end(_grf_files)) return &*it;
122 return nullptr;
123}
124
130{
131 gf->labels.clear();
132}
133
141{
142 GRFFile *file;
143 if (config != nullptr) {
144 file = GetFileByGRFID(config->ident.grfid);
145 } else {
146 config = _cur_gps.grfconfig;
147 file = _cur_gps.grffile;
148 }
149
150 config->status = GRFStatus::Disabled;
151 if (file != nullptr) ClearTemporaryNewGRFData(file);
152 if (config == _cur_gps.grfconfig) _cur_gps.skip_sprites = -1;
153
154 if (message == STR_NULL) return nullptr;
155
156 auto it = std::ranges::find(config->errors, _cur_gps.nfo_line, &GRFError::nfo_line);
157 if (it == std::end(config->errors)) {
158 it = config->errors.emplace(it, STR_NEWGRF_ERROR_MSG_FATAL, _cur_gps.nfo_line, message);
159 }
160 if (config == _cur_gps.grfconfig) it->param_value[0] = _cur_gps.nfo_line;
161 return &*it;
162}
163
174{
175 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, &c);
176 error->data = _cur_gps.grfconfig->GetName();
177}
178
179static std::map<GrfID, GrfID> _grf_id_overrides;
180
186void SetNewGRFOverride(GrfID source_grfid, GrfID target_grfid)
187{
188 if (target_grfid.Empty()) {
189 _grf_id_overrides.erase(source_grfid);
190 GrfMsg(5, "SetNewGRFOverride: Removed override of {}", FormatArrayAsHex(source_grfid));
191 } else {
192 _grf_id_overrides[source_grfid] = target_grfid;
193 GrfMsg(5, "SetNewGRFOverride: Added override of {} to {}", FormatArrayAsHex(source_grfid), FormatArrayAsHex(target_grfid));
194 }
195}
196
202{
203 auto found = _grf_id_overrides.find(_cur_gps.grffile->grfid);
204 if (found != std::end(_grf_id_overrides)) {
205 GRFFile *grffile = GetFileByGRFID(found->second);
206 if (grffile != nullptr) return grffile;
207 }
208 return nullptr;
209}
210
219Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16_t internal_id, bool static_access)
220{
221 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
222 * them use the same engine slots. */
223 GrfID scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
224 if (_settings_game.vehicle.dynamic_engines) {
225 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
226 scope_grfid = file->grfid;
227 if (auto it = _grf_id_overrides.find(file->grfid); it != std::end(_grf_id_overrides)) {
228 scope_grfid = it->second;
229 const GRFFile *grf_match = GetFileByGRFID(scope_grfid);
230 if (grf_match == nullptr) {
231 GrfMsg(5, "Tried mapping from GRFID {} to {} but target is not loaded", FormatArrayAsHex(file->grfid), FormatArrayAsHex(scope_grfid));
232 } else {
233 GrfMsg(5, "Mapping from GRFID {} to {}", FormatArrayAsHex(file->grfid), FormatArrayAsHex(scope_grfid));
234 }
235 }
236
237 /* Check if the engine is registered in the override manager */
238 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
239 if (engine != EngineID::Invalid()) {
240 Engine *e = Engine::Get(engine);
241 if (!e->grf_prop.HasGrfFile()) {
242 e->grf_prop.SetGRFFile(file);
243 }
244 return e;
245 }
246 }
247
248 /* Check if there is an unreserved slot */
249 EngineID engine = _engine_mngr.UseUnreservedID(type, internal_id, scope_grfid, static_access);
250 if (engine != EngineID::Invalid()) {
251 Engine *e = Engine::Get(engine);
252
253 if (!e->grf_prop.HasGrfFile()) {
254 e->grf_prop.SetGRFFile(file);
255 GrfMsg(5, "Replaced engine at index {} for GRFID {}, type {}, index {}", e->index, FormatArrayAsHex(file->grfid), type, internal_id);
256 }
257
258 return e;
259 }
260
261 if (static_access) return nullptr;
262
264 GrfMsg(0, "Can't allocate any more engines");
265 return nullptr;
266 }
267
268 size_t engine_pool_size = Engine::GetPoolSize();
269
270 /* ... it's not, so create a new one based off an existing engine */
271 Engine *e = Engine::Create(type, internal_id);
272 e->grf_prop.SetGRFFile(file);
273
274 /* Reserve the engine slot */
275 _engine_mngr.SetID(type, internal_id, scope_grfid, std::min<uint8_t>(internal_id, GetOriginalEngineCount(type)), e->index);
276
277 if (engine_pool_size != Engine::GetPoolSize()) {
278 /* Resize temporary engine data ... */
279 _gted.resize(Engine::GetPoolSize());
280 }
281 if (type == VehicleType::Train) {
282 _gted[e->index].railtypelabels.clear();
283 for (RailType rt : e->VehInfo<RailVehicleInfo>().railtypes) _gted[e->index].railtypelabels.push_back(GetRailTypeInfo(rt)->label);
284 }
285
286 GrfMsg(5, "Created new engine at index {} for GRFID {}, type {}, index {}", e->index, FormatArrayAsHex(file->grfid), type, internal_id);
287
288 return e;
289}
290
301EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal_id)
302{
303 GrfID scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
304 if (_settings_game.vehicle.dynamic_engines) {
305 scope_grfid = file->grfid;
306 if (auto it = _grf_id_overrides.find(file->grfid); it != std::end(_grf_id_overrides)) {
307 scope_grfid = it->second;
308 }
309 }
310
311 return _engine_mngr.GetID(type, internal_id, scope_grfid);
312}
313
314
315
316
322CargoTypes TranslateRefitMask(uint32_t refit_mask)
323{
324 CargoTypes result{};
325 for (uint8_t bit : SetBitIterator(refit_mask)) {
326 CargoType cargo = GetCargoTranslation(bit, _cur_gps.grffile, true);
327 if (IsValidCargoType(cargo)) result.Set(cargo);
328 }
329 return result;
330}
331
339void ConvertTTDBasePrice(uint32_t base_pointer, std::string_view error_location, Price *index)
340{
341 /* Special value for 'none' */
342 if (base_pointer == 0) {
343 *index = Price::Invalid;
344 return;
345 }
346
347 static const uint32_t start = 0x4B34;
348 static const uint32_t size = 6;
349
350 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= to_underlying(Price::End)) {
351 GrfMsg(1, "{}: Unsupported running cost base 0x{:04X}, ignoring", error_location, base_pointer);
352 return;
353 }
354
355 *index = (Price)((base_pointer - start) / size);
356}
357
364/* static */ const LanguageMap *LanguageMap::GetLanguageMap(GrfID grfid, GRFLanguage language_id)
365{
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;
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 : EnumRange(NUM_CARGO)) {
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 if (label == CT_PASSENGERS) {
706 /* Ferries */
707 _gted[engine].cargo_allowed = {CargoClass::Passengers};
708 _gted[engine].cargo_disallowed = {};
709 } else if (label == CT_OIL) {
710 /* Tankers */
711 _gted[engine].cargo_allowed = {CargoClass::Liquid};
712 _gted[engine].cargo_disallowed = {};
713 } else if (_settings_game.game_creation.landscape == LandscapeType::Toyland) {
714 /* No tanker in toyland :( so include liquids in the cargo ships */
716 _gted[engine].cargo_disallowed = {CargoClass::Passengers};
717 } else {
718 /* Cargo ships */
720 _gted[engine].cargo_disallowed = {CargoClass::Liquid, CargoClass::Passengers};
721 }
722 e->VehInfo<ShipVehicleInfo>().old_refittable = true;
723 } else if (e->type == VehicleType::Train && e->VehInfo<RailVehicleInfo>().railveh_type != RailVehicleType::Wagon) {
724 /* Train engines default to all cargoes, so you can build single-cargo consists with fast engines.
725 * Trains loading multiple cargoes may start stations accepting unwanted cargoes. */
727 _gted[engine].cargo_disallowed = {};
728 } else {
729 /* Train wagons and road vehicles are classified by their default cargo type */
730 CargoLabel label = GetActiveCargoLabel(ei->cargo_label);
731 for (const auto &drm : _default_refit_masks) {
732 if (!drm.climate.Test(_settings_game.game_creation.landscape)) continue;
733 if (drm.cargo_label != label) continue;
734
735 _gted[engine].cargo_allowed = drm.cargo_allowed;
736 _gted[engine].cargo_disallowed = drm.cargo_disallowed;
737 break;
738 }
739
740 /* All original cargoes have specialised vehicles, so exclude them */
741 _gted[engine].ctt_exclude_mask = original_known_cargoes;
742 }
743 }
744 _gted[engine].UpdateRefittability(_gted[engine].cargo_allowed.Any());
745
746 if (IsValidCargoType(ei->cargo_type)) _gted[engine].ctt_exclude_mask.Reset(ei->cargo_type);
747 }
748
749 /* Compute refittability */
750 {
751 CargoTypes mask{};
752 CargoTypes not_mask{};
753 CargoTypes xor_mask = ei->refit_mask;
754
755 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
756 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
757 only_defaultcargo = _gted[engine].refittability != GRFTempEngineData::Refittability::NonEmpty;
758
759 if (_gted[engine].cargo_allowed.Any()) {
760 /* Build up the list of cargo types from the set cargo classes. */
761 for (const CargoSpec *cs : CargoSpec::Iterate()) {
762 if (cs->classes.Any(_gted[engine].cargo_allowed) && cs->classes.All(_gted[engine].cargo_allowed_required)) mask.Set(cs->Index());
763 if (cs->classes.Any(_gted[engine].cargo_disallowed)) not_mask.Set(cs->Index());
764 }
765 }
766
767 CargoTypes invalid_mask = CargoTypes{_cargo_mask}.Flip();
768 ei->refit_mask = mask.Reset(not_mask).Flip(xor_mask).Reset(invalid_mask);
769
770 /* Apply explicit refit includes/excludes. */
771 ei->refit_mask.Set(_gted[engine].ctt_include_mask);
772 ei->refit_mask.Reset(_gted[engine].ctt_exclude_mask);
773
774 /* Custom refit mask callback. */
775 const GRFFile *file = _gted[e->index].defaultcargo_grf;
776 if (file == nullptr) file = e->GetGRF();
777 if (file != nullptr && e->info.callback_mask.Test(VehicleCallbackMask::CustomRefit)) {
778 for (const CargoSpec *cs : CargoSpec::Iterate()) {
779 uint8_t local_slot = file->cargo_map[cs->Index()];
780 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_CUSTOM_REFIT, cs->classes.base(), local_slot, engine, nullptr);
781 switch (callback) {
782 case CALLBACK_FAILED:
783 case 0:
784 break; // Do nothing.
785 case 1: ei->refit_mask.Set(cs->Index()); break;
786 case 2: ei->refit_mask.Reset(cs->Index()); break;
787
788 default: ErrorUnknownCallbackResult(file->grfid, CBID_VEHICLE_CUSTOM_REFIT, callback);
789 }
790 }
791 }
792 }
793
794 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
795 if (IsValidCargoType(ei->cargo_type) && !_cargo_mask.Test(ei->cargo_type)) ei->cargo_type = INVALID_CARGO;
796
797 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
798 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
799 if (!only_defaultcargo && (e->type != VehicleType::Ship || e->VehInfo<ShipVehicleInfo>().old_refittable) && IsValidCargoType(ei->cargo_type) && !ei->refit_mask.Test(ei->cargo_type)) {
800 ei->cargo_type = INVALID_CARGO;
801 }
802
803 /* Check if this engine's cargo type is valid. If not, set to the first refittable
804 * cargo type. Finally disable the vehicle, if there is still no cargo. */
805 if (!IsValidCargoType(ei->cargo_type) && ei->refit_mask.Any()) {
806 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
807 const GRFFile *file = _gted[engine].defaultcargo_grf;
808 if (file == nullptr) file = e->GetGRF();
809 if (file != nullptr && file->grf_version >= 8 && !file->cargo_list.empty()) {
810 /* Use first refittable cargo from cargo translation table */
811 uint8_t best_local_slot = UINT8_MAX;
812 for (CargoType cargo_type : ei->refit_mask) {
813 uint8_t local_slot = file->cargo_map[cargo_type];
814 if (local_slot < best_local_slot) {
815 best_local_slot = local_slot;
816 ei->cargo_type = cargo_type;
817 }
818 }
819 }
820
821 if (!IsValidCargoType(ei->cargo_type)) {
822 /* Use first refittable cargo slot */
823 ei->cargo_type = *ei->refit_mask.begin();
824 }
825 }
826 if (!IsValidCargoType(ei->cargo_type) && e->type == VehicleType::Train && e->VehInfo<RailVehicleInfo>().railveh_type != RailVehicleType::Wagon && e->VehInfo<RailVehicleInfo>().capacity == 0) {
827 /* For train engines which do not carry cargo it does not matter if their cargo type is invalid.
828 * Fallback to the first available instead, if the cargo type has not been changed (as indicated by
829 * cargo_label not being CT_INVALID). */
830 if (GetActiveCargoLabel(ei->cargo_label) != CT_INVALID) {
831 ei->cargo_type = *_standard_cargo_mask.begin();
832 }
833 }
834 if (!IsValidCargoType(ei->cargo_type)) ei->climates = {};
835
836 /* Clear refit_mask for not refittable ships */
837 if (e->type == VehicleType::Ship && !e->VehInfo<ShipVehicleInfo>().old_refittable) {
838 ei->refit_mask.Reset();
839 }
840 }
841}
842
844static void FinaliseCanals()
845{
847 if (_water_feature[i].grffile != nullptr) {
848 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
849 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
850 }
851 }
852}
853
856{
857 for (Engine *e : Engine::Iterate()) {
858 if (e->GetGRF() == nullptr) {
859 auto found = std::ranges::find(_engine_mngr.mappings[e->type], e->index, &EngineIDMapping::engine);
860 if (found == std::end(_engine_mngr.mappings[e->type]) || found->grfid != INVALID_GRFID || found->internal_id != found->substitute_id) {
861 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
862 }
863 }
864
865 /* Do final mapping on variant engine ID. */
866 if (e->info.variant_id != EngineID::Invalid()) {
867 e->info.variant_id = GetNewEngineID(e->grf_prop.grffile, e->type, e->info.variant_id.base());
868 }
869
870 if (!e->info.climates.Test(_settings_game.game_creation.landscape)) continue;
871
872 switch (e->type) {
874 for (RailType rt : e->VehInfo<RailVehicleInfo>().railtypes) {
876 }
877 break;
879 default: break;
880 }
881
882 /* Skip wagons, there livery is defined via the engine */
883 if (e->type != VehicleType::Train || e->VehInfo<RailVehicleInfo>().railveh_type != RailVehicleType::Wagon) {
884 LiveryScheme ls = GetEngineLiveryScheme(e->index, EngineID::Invalid(), nullptr);
885 _loaded_newgrf_features.used_liveries.Set(ls);
886 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
887
888 if (e->type == VehicleType::Train) {
890 switch (ls) {
897 break;
898
902 break;
903
904 default: NOT_REACHED();
905 }
906 }
907 }
908 }
909
910 /* Check engine variants don't point back on themselves (either directly or via a loop) then set appropriate flags
911 * on variant engine. This is performed separately as all variant engines need to have been resolved.
912 * Use Floyd's cycle-detection algorithm to handle the case where a cycle is present but does
913 * not include the starting engine ID. */
914 for (Engine *e : Engine::Iterate()) {
915 EngineID parent = e->info.variant_id;
916 EngineID parent_slow = parent;
917 bool update_slow = false;
918 while (parent != EngineID::Invalid()) {
919 parent = Engine::Get(parent)->info.variant_id;
920 if (update_slow) parent_slow = Engine::Get(parent_slow)->info.variant_id;
921 update_slow = !update_slow;
922 if (parent != e->index && parent != parent_slow) continue;
923
924 /* Engine looped back on itself, so clear the variant. */
925 e->info.variant_id = EngineID::Invalid();
926
927 GrfMsg(1, "FinaliseEngineArray: Variant of engine {:x} in '{}' loops back on itself", e->grf_prop.local_id, e->GetGRF()->filename);
928 break;
929 }
930
931 if (e->info.variant_id != EngineID::Invalid()) {
932 Engine::Get(e->info.variant_id)->display_flags.Set({EngineDisplayFlag::HasVariants, EngineDisplayFlag::IsFolded});
933 }
934 }
935}
936
939{
940 for (CargoSpec &cs : CargoSpec::array) {
941 if (cs.town_production_effect == TownProductionEffect::Invalid) {
942 /* Set default town production effect by cargo label. */
943 if (cs.label == CT_PASSENGERS) {
944 cs.town_production_effect = TownProductionEffect::Passengers;
945 } else if (cs.label == CT_MAIL) {
946 cs.town_production_effect = TownProductionEffect::Mail;
947 } else {
948 cs.town_production_effect = TownProductionEffect::None;
949 }
950 }
951 if (!cs.IsValid()) {
952 cs.name = cs.name_single = cs.units_volume = STR_NEWGRF_INVALID_CARGO;
953 cs.quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
954 cs.abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
955 }
956 }
957}
958
970static bool IsHouseSpecValid(HouseSpec &hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const std::string &filename)
971{
972 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) &&
973 (next1 == nullptr || !next1->enabled || next1->building_flags.Any(BUILDING_HAS_1_TILE))) ||
974 (hs.building_flags.Any(BUILDING_HAS_4_TILES) &&
975 (next2 == nullptr || !next2->enabled || next2->building_flags.Any(BUILDING_HAS_1_TILE) ||
976 next3 == nullptr || !next3->enabled || next3->building_flags.Any(BUILDING_HAS_1_TILE)))) {
977 hs.enabled = false;
978 if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs.grf_prop.local_id);
979 return false;
980 }
981
982 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
983 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
984 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
985 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) && next1->population != 0) ||
986 (hs.building_flags.Any(BUILDING_HAS_4_TILES) && (next2->population != 0 || next3->population != 0))) {
987 hs.enabled = false;
988 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);
989 return false;
990 }
991
992 /* Substitute type is also used for override, and having an override with a different size causes crashes.
993 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
994 if (!filename.empty() && (hs.building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs.grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
995 hs.enabled = false;
996 Debug(grf, 1, "FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs.grf_prop.local_id);
997 return false;
998 }
999
1000 /* Make sure that additional parts of multitile houses are not available. */
1001 if (!hs.building_flags.Any(BUILDING_HAS_1_TILE) && hs.building_availability.Any(HZ_ZONE_ALL) && hs.building_availability.Any(HZ_CLIMATE_ALL)) {
1002 hs.enabled = false;
1003 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);
1004 return false;
1005 }
1006
1007 return true;
1008}
1009
1016static void EnsureEarlyHouse(HouseZones bitmask)
1017{
1019
1020 for (const auto &hs : HouseSpec::Specs()) {
1021 if (!hs.enabled) continue;
1022 if (!hs.building_availability.All(bitmask)) continue;
1023 if (hs.min_year < min_year) min_year = hs.min_year;
1024 }
1025
1026 if (min_year == 0) return;
1027
1028 for (auto &hs : HouseSpec::Specs()) {
1029 if (!hs.enabled) continue;
1030 if (!hs.building_availability.All(bitmask)) continue;
1031 if (hs.min_year == min_year) hs.min_year = CalendarTime::MIN_YEAR;
1032 }
1033}
1034
1042{
1043 /* If there are no houses with start dates before 1930, then all houses
1044 * with start dates of 1930 have them reset to 0. This is in order to be
1045 * compatible with TTDPatch, where if no houses have start dates before
1046 * 1930 and the date is before 1930, the game pretends that this is 1930.
1047 * If there have been any houses defined with start dates before 1930 then
1048 * the dates are left alone.
1049 * On the other hand, why 1930? Just 'fix' the houses with the lowest
1050 * minimum introduction date to 0.
1051 */
1052 for (auto &file : _grf_files) {
1053 if (file.housespec.empty()) continue;
1054
1055 size_t num_houses = file.housespec.size();
1056 for (size_t i = 0; i < num_houses; i++) {
1057 auto &hs = file.housespec[i];
1058
1059 if (hs == nullptr) continue;
1060
1061 const HouseSpec *next1 = (i + 1 < num_houses ? file.housespec[i + 1].get() : nullptr);
1062 const HouseSpec *next2 = (i + 2 < num_houses ? file.housespec[i + 2].get() : nullptr);
1063 const HouseSpec *next3 = (i + 3 < num_houses ? file.housespec[i + 3].get() : nullptr);
1064
1065 if (!IsHouseSpecValid(*hs, next1, next2, next3, file.filename)) continue;
1066
1067 _house_mngr.SetEntitySpec(std::move(*hs));
1068 }
1069
1070 /* Won't be used again */
1071 file.housespec.clear();
1072 file.housespec.shrink_to_fit();
1073 }
1074
1075 for (size_t i = 0; i < HouseSpec::Specs().size(); i++) {
1076 HouseSpec *hs = HouseSpec::Get(i);
1077 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr);
1078 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr);
1079 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : nullptr);
1080
1081 /* We need to check all houses again to we are sure that multitile houses
1082 * did get consecutive IDs and none of the parts are missing. */
1083 if (!IsHouseSpecValid(*hs, next1, next2, next3, std::string{})) {
1084 /* GetHouseNorthPart checks 3 houses that are directly before
1085 * it in the house pool. If any of those houses have multi-tile
1086 * flags set it assumes it's part of a multitile house. Since
1087 * we can have invalid houses in the pool marked as disabled, we
1088 * don't want to have them influencing valid tiles. As such set
1089 * building_flags to zero here to make sure any house following
1090 * this one in the pool is properly handled as 1x1 house. */
1091 hs->building_flags = {};
1092 }
1093
1094 /* Apply default cargo translation map for unset cargo slots */
1095 for (uint i = 0; i < lengthof(hs->accepts_cargo_label); ++i) {
1096 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->accepts_cargo[i] = GetCargoTypeByLabel(hs->accepts_cargo_label[i]);
1097 /* Disable acceptance if cargo type is invalid. */
1098 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->cargo_acceptance[i] = 0;
1099 }
1100 }
1101
1102 HouseZones climate_mask = GetClimateMaskForLandscape();
1103 for (HouseZone climate : climate_mask) {
1104 for (HouseZone zone : HZ_ZONE_ALL) {
1105 EnsureEarlyHouse({climate, zone});
1106 }
1107 }
1108}
1109
1116{
1117 for (auto &file : _grf_files) {
1118 for (auto &indsp : file.industryspec) {
1119 if (indsp == nullptr || !indsp->enabled) continue;
1120
1121 _industry_mngr.SetEntitySpec(std::move(*indsp));
1122 }
1123
1124 for (auto &indtsp : file.indtspec) {
1125 if (indtsp != nullptr) {
1126 _industile_mngr.SetEntitySpec(std::move(*indtsp));
1127 }
1128 }
1129
1130 /* Won't be used again */
1131 file.industryspec.clear();
1132 file.industryspec.shrink_to_fit();
1133 file.indtspec.clear();
1134 file.indtspec.shrink_to_fit();
1135 }
1136
1137 for (auto &indsp : _industry_specs) {
1138 if (indsp.enabled && indsp.grf_prop.HasGrfFile()) {
1139 for (auto &conflicting : indsp.conflicting) {
1140 conflicting = MapNewGRFIndustryType(conflicting, indsp.grf_prop.grfid);
1141 }
1142 }
1143 if (!indsp.enabled) {
1144 indsp.name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
1145 }
1146
1147 /* Apply default cargo translation map for unset cargo slots */
1148 for (size_t i = 0; i < std::size(indsp.produced_cargo_label); ++i) {
1149 if (!IsValidCargoType(indsp.produced_cargo[i])) indsp.produced_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.produced_cargo_label[i]));
1150 }
1151 for (size_t i = 0; i < std::size(indsp.accepts_cargo_label); ++i) {
1152 if (!IsValidCargoType(indsp.accepts_cargo[i])) indsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.accepts_cargo_label[i]));
1153 }
1154 }
1155
1156 for (auto &indtsp : _industry_tile_specs) {
1157 /* Apply default cargo translation map for unset cargo slots */
1158 for (size_t i = 0; i < std::size(indtsp.accepts_cargo_label); ++i) {
1159 if (!IsValidCargoType(indtsp.accepts_cargo[i])) indtsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indtsp.accepts_cargo_label[i]));
1160 }
1161 }
1162}
1163
1170{
1171 for (auto &file : _grf_files) {
1172 for (auto &objectspec : file.objectspec) {
1173 if (objectspec != nullptr && objectspec->grf_prop.HasGrfFile() && objectspec->IsEnabled()) {
1174 _object_mngr.SetEntitySpec(std::move(*objectspec));
1175 }
1176 }
1177
1178 /* Won't be used again */
1179 file.objectspec.clear();
1180 file.objectspec.shrink_to_fit();
1181 }
1182
1184}
1185
1192{
1193 for (auto &file : _grf_files) {
1194 for (auto &as : file.airportspec) {
1195 if (as != nullptr && as->enabled) {
1196 _airport_mngr.SetEntitySpec(std::move(*as));
1197 }
1198 }
1199
1200 for (auto &ats : file.airtspec) {
1201 if (ats != nullptr && ats->enabled) {
1202 _airporttile_mngr.SetEntitySpec(std::move(*ats));
1203 }
1204 }
1205
1206 /* Won't be used again */
1207 file.airportspec.clear();
1208 file.airportspec.shrink_to_fit();
1209 file.airtspec.clear();
1210 file.airtspec.shrink_to_fit();
1211 }
1212}
1213
1216 template <uint8_t TAction>
1217 static void Invoke(ByteReader &buf, GrfLoadingStage stage)
1218 {
1219 switch (stage) {
1226 default: NOT_REACHED();
1227 }
1228 }
1229
1230 using Invoker = void(*)(ByteReader &buf, GrfLoadingStage stage);
1231 static constexpr Invoker funcs[] = { // Must be listed in action order.
1232 Invoke<0x00>, Invoke<0x01>, Invoke<0x02>, Invoke<0x03>, Invoke<0x04>, Invoke<0x05>, Invoke<0x06>, Invoke<0x07>,
1233 Invoke<0x08>, Invoke<0x09>, Invoke<0x0A>, Invoke<0x0B>, Invoke<0x0C>, Invoke<0x0D>, Invoke<0x0E>, Invoke<0x0F>,
1234 Invoke<0x10>, Invoke<0x11>, Invoke<0x12>, Invoke<0x13>, Invoke<0x14>,
1235 };
1236
1237 static void Invoke(uint8_t action, GrfLoadingStage stage, ByteReader &buf)
1238 {
1239 Invoker func = action < std::size(funcs) ? funcs[action] : nullptr;
1240 if (func == nullptr) {
1241 GrfMsg(7, "DecodeSpecialSprite: Skipping unknown action 0x{:02X}", action);
1242 } else {
1243 GrfMsg(7, "DecodeSpecialSprite: Handling action 0x{:02X} in stage {}", action, stage);
1244 func(buf, stage);
1245 }
1246 }
1247};
1248
1249/* Here we perform initial decoding of some special sprites (as are they
1250 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
1251 * partial implementation yet).
1252 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
1253 * a crafted invalid GRF file. We should tell that to the user somehow, or
1254 * better make this more robust in the future. */
1255static void DecodeSpecialSprite(ReusableBuffer<uint8_t> &allocator, uint num, GrfLoadingStage stage)
1256{
1257 uint8_t *buf;
1258 auto it = _grf_line_to_action6_sprite_override.find({_cur_gps.grfconfig->ident.grfid, _cur_gps.nfo_line});
1259 if (it == _grf_line_to_action6_sprite_override.end()) {
1260 /* No preloaded sprite to work with; read the
1261 * pseudo sprite content. */
1262 buf = allocator.Allocate(num);
1263 _cur_gps.file->ReadBlock(buf, num);
1264 } else {
1265 /* Use the preloaded sprite data. */
1266 buf = it->second.data();
1267 assert(it->second.size() == num);
1268 GrfMsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
1269
1270 /* Skip the real (original) content of this action. */
1271 _cur_gps.file->SeekTo(num, SEEK_CUR);
1272 }
1273
1274 ByteReader br(buf, num);
1275
1276 try {
1277 uint8_t action = br.ReadByte();
1278
1279 if (action == 0xFF) {
1280 GrfMsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
1281 } else if (action == 0xFE) {
1282 GrfMsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
1283 } else {
1284 InvokeGrfActionHandler::Invoke(action, stage, br);
1285 }
1286 } catch (...) {
1287 GrfMsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
1288 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
1289 }
1290}
1291
1299{
1300 AutoRestoreBackup cur_file(_cur_gps.file, &file);
1301 AutoRestoreBackup cur_config(_cur_gps.grfconfig, &config);
1302
1303 Debug(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '{}'", config.filename);
1304
1305 uint8_t grf_container_version = file.GetContainerVersion();
1306 if (grf_container_version == 0) {
1307 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1308 return;
1309 }
1310
1311 if (stage == GrfLoadingStage::Init || stage == GrfLoadingStage::Activation) {
1312 /* We need the sprite offsets in the init stage for NewGRF sounds
1313 * and in the activation stage for real sprites. */
1315 } else {
1316 /* Skip sprite section offset if present. */
1317 if (grf_container_version >= 2) file.ReadDword();
1318 }
1319
1320 if (grf_container_version >= 2) {
1321 /* Read compression value. */
1322 uint8_t compression = file.ReadByte();
1323 if (compression != 0) {
1324 Debug(grf, 7, "LoadNewGRFFile: Unsupported compression format");
1325 return;
1326 }
1327 }
1328
1329 /* Skip the first sprite; we don't care about how many sprites this
1330 * does contain; newest TTDPatches and George's longvehicles don't
1331 * neither, apparently. */
1332 uint32_t num = grf_container_version >= 2 ? file.ReadDword() : file.ReadWord();
1333 if (num == 4 && file.ReadByte() == 0xFF) {
1334 file.ReadDword();
1335 } else {
1336 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1337 return;
1338 }
1339
1340 _cur_gps.ClearDataForNextFile();
1341
1342 ReusableBuffer<uint8_t> allocator;
1343
1344 while ((num = (grf_container_version >= 2 ? file.ReadDword() : file.ReadWord())) != 0) {
1345 uint8_t type = file.ReadByte();
1346 _cur_gps.nfo_line++;
1347
1348 if (type == 0xFF) {
1349 if (_cur_gps.skip_sprites == 0) {
1350 /* Limit the special sprites to 1 MiB. */
1351 if (num > 1024 * 1024) {
1352 GrfMsg(0, "LoadNewGRFFile: Unexpectedly large sprite, disabling");
1353 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1354 break;
1355 }
1356
1357 DecodeSpecialSprite(allocator, num, stage);
1358
1359 /* Stop all processing if we are to skip the remaining sprites */
1360 if (_cur_gps.skip_sprites == -1) break;
1361
1362 continue;
1363 } else {
1364 file.SkipBytes(num);
1365 }
1366 } else {
1367 if (_cur_gps.skip_sprites == 0) {
1368 GrfMsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
1369 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1370 break;
1371 }
1372
1373 if (grf_container_version >= 2 && type == 0xFD) {
1374 /* Reference to data section. Container version >= 2 only. */
1375 file.SkipBytes(num);
1376 } else {
1377 file.SkipBytes(7);
1378 SkipSpriteData(file, type, num - 8);
1379 }
1380 }
1381
1382 if (_cur_gps.skip_sprites > 0) _cur_gps.skip_sprites--;
1383 }
1384}
1385
1394void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
1395{
1396 const std::string &filename = config.filename;
1397
1398 /* A .grf file is activated only if it was active when the game was
1399 * started. If a game is loaded, only its active .grfs will be
1400 * reactivated, unless "loadallgraphics on" is used. A .grf file is
1401 * considered active if its action 8 has been processed, i.e. its
1402 * action 8 hasn't been skipped using an action 7.
1403 *
1404 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
1405 * carried out. All others are ignored, because they only need to be
1406 * processed once at initialization. */
1408 _cur_gps.grffile = GetFileByFilename(filename);
1409 if (_cur_gps.grffile == nullptr) UserError("File '{}' lost in cache.\n", filename);
1410 if (stage == GrfLoadingStage::Reserve && config.status != GRFStatus::Initialised) return;
1411 if (stage == GrfLoadingStage::Activation && !config.flags.Test(GRFConfigFlag::Reserved)) return;
1412 }
1413
1414 bool needs_palette_remap = config.palette & GRFP_USE_MASK;
1415 if (temporary) {
1416 SpriteFile temporarySpriteFile(filename, subdir, needs_palette_remap);
1417 LoadNewGRFFileFromFile(config, stage, temporarySpriteFile);
1418 } else {
1419 LoadNewGRFFileFromFile(config, stage, OpenCachedSpriteFile(filename, subdir, needs_palette_remap));
1420 }
1421}
1422
1430static void ActivateOldShore()
1431{
1432 /* Use default graphics, if no shore sprites were loaded.
1433 * Should not happen, as the base set's extra grf should include some. */
1435
1437 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
1438 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
1439 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
1440 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
1441 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
1442 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
1443 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
1444 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
1445 }
1446
1448 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
1449 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
1450 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
1451 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
1452 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
1453 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
1454 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
1455 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
1456
1457 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
1458 * If they would be used somewhen, then these grass tiles will most like not look as needed */
1459 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
1460 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
1461 }
1462}
1463
1468{
1470 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0); // use road depot graphics for "no tracks"
1472 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2); // use road depot graphics for "no tracks"
1476 }
1477}
1478
1483{
1486
1487 /* Evaluate grf overrides */
1488 int num_grfs = (uint)_grf_files.size();
1489 std::vector<int> grf_overrides(num_grfs, -1);
1490 for (int i = 0; i < num_grfs; i++) {
1491 GRFFile &source = _grf_files[i];
1492 auto it = _grf_id_overrides.find(source.grfid);
1493 if (it == std::end(_grf_id_overrides)) continue;
1494 GrfID override_grfid = it->second;
1495
1496 auto dest = std::ranges::find(_grf_files, override_grfid, &GRFFile::grfid);
1497 if (dest == std::end(_grf_files)) continue;
1498
1499 grf_overrides[i] = static_cast<int>(std::ranges::distance(std::begin(_grf_files), dest));
1500 assert(grf_overrides[i] >= 0);
1501 }
1502
1503 /* Override features and price base multipliers of earlier loaded grfs */
1504 for (int i = 0; i < num_grfs; i++) {
1505 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
1506 GRFFile &source = _grf_files[i];
1507 GRFFile &dest = _grf_files[grf_overrides[i]];
1508
1509 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1510 source.grf_features.Set(features);
1511 dest.grf_features.Set(features);
1512
1513 for (Price p : EnumRange(Price::End)) {
1514 /* No price defined -> nothing to do */
1515 if (!features.Test(_price_base_specs[p].grf_feature) || source.price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
1516 Debug(grf, 3, "'{}' overrides price base multiplier {} of '{}'", source.filename, p, dest.filename);
1518 }
1519 }
1520
1521 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
1522 for (int i = num_grfs - 1; i >= 0; i--) {
1523 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
1524 GRFFile &source = _grf_files[i];
1525 GRFFile &dest = _grf_files[grf_overrides[i]];
1526
1527 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1528 source.grf_features.Set(features);
1529 dest.grf_features.Set(features);
1530
1531 for (Price p : EnumRange(Price::End)) {
1532 /* Already a price defined -> nothing to do */
1533 if (!features.Test(_price_base_specs[p].grf_feature) || dest.price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
1534 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, source.filename, dest.filename);
1536 }
1537 }
1538
1539 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
1540 for (int i = 0; i < num_grfs; i++) {
1541 if (grf_overrides[i] < 0) continue;
1542 GRFFile &source = _grf_files[i];
1543 GRFFile &dest = _grf_files[grf_overrides[i]];
1544
1545 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1546 source.grf_features.Set(features);
1547 dest.grf_features.Set(features);
1548
1549 for (Price p : EnumRange(Price::End)) {
1550 if (!features.Test(_price_base_specs[p].grf_feature)) continue;
1551 if (source.price_base_multipliers[p] != dest.price_base_multipliers[p]) {
1552 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, dest.filename, source.filename);
1553 }
1555 }
1556 }
1557
1558 /* Apply fallback prices for grf version < 8 */
1559 for (auto &file : _grf_files) {
1560 if (file.grf_version >= 8) continue;
1561 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1562 for (Price p : EnumRange(Price::End)) {
1563 Price fallback_price = _price_base_specs[p].fallback_price;
1564 if (fallback_price != Price::Invalid && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1565 /* No price multiplier has been set.
1566 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
1567 price_base_multipliers[p] = price_base_multipliers[fallback_price];
1568 }
1569 }
1570 }
1571
1572 /* Decide local/global scope of price base multipliers */
1573 for (auto &file : _grf_files) {
1574 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1575 for (Price p : EnumRange(Price::End)) {
1576 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1577 /* No multiplier was set; set it to a neutral value */
1578 price_base_multipliers[p] = 0;
1579 } else {
1580 if (!file.grf_features.Test(_price_base_specs[p].grf_feature)) {
1581 /* The grf does not define any objects of the feature,
1582 * so it must be a difficulty setting. Apply it globally */
1583 Debug(grf, 3, "'{}' sets global price base multiplier {}", file.filename, p);
1584 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
1585 price_base_multipliers[p] = 0;
1586 } else {
1587 Debug(grf, 3, "'{}' sets local price base multiplier {}", file.filename, p);
1588 }
1589 }
1590 }
1591 }
1592}
1593
1594template <typename T>
1595void AddBadgeToSpecs(T &specs, GrfSpecFeature feature, Badge &badge)
1596{
1597 for (auto &spec : specs) {
1598 if (spec == nullptr) continue;
1599 spec->badges.push_back(badge.index);
1600 badge.features.Set(feature);
1601 }
1602}
1603
1605static void FinaliseBadges()
1606{
1607 for (const auto &file : _grf_files) {
1608 Badge *badge = GetBadgeByLabel(fmt::format("newgrf/{}", FormatArrayAsHex(file.grfid)));
1609 if (badge == nullptr) continue;
1610
1611 for (Engine *e : Engine::Iterate()) {
1612 if (e->grf_prop.grffile != &file) continue;
1613 e->badges.push_back(badge->index);
1614 badge->features.Set(GetGrfSpecFeature(e->type));
1615 }
1616
1617 AddBadgeToSpecs(file.stations, GrfSpecFeature::Stations, *badge);
1618 AddBadgeToSpecs(file.housespec, GrfSpecFeature::Houses, *badge);
1619 AddBadgeToSpecs(file.industryspec, GrfSpecFeature::Industries, *badge);
1620 AddBadgeToSpecs(file.indtspec, GrfSpecFeature::IndustryTiles, *badge);
1621 AddBadgeToSpecs(file.objectspec, GrfSpecFeature::Objects, *badge);
1622 AddBadgeToSpecs(file.airportspec, GrfSpecFeature::Airports, *badge);
1623 AddBadgeToSpecs(file.airtspec, GrfSpecFeature::AirportTiles, *badge);
1624 AddBadgeToSpecs(file.roadstops, GrfSpecFeature::RoadStops, *badge);
1625 }
1626
1629}
1630
1631extern void InitGRFTownGeneratorNames();
1632
1634static void AfterLoadGRFs()
1635{
1636 /* Cached callback groups are no longer needed. */
1637 ResetCallbacks(true);
1638
1640
1641 /* Clear the action 6 override sprites. */
1642 _grf_line_to_action6_sprite_override.clear();
1643
1645
1646 /* Polish cargoes */
1648
1649 /* Pre-calculate all refit masks after loading GRF files. */
1651
1652 /* Polish engines */
1654
1655 /* Set the actually used Canal properties */
1657
1658 /* Add all new houses to the house array. */
1660
1661 /* Add all new industries to the industry array. */
1663
1664 /* Add all new objects to the object array. */
1666
1668
1669 /* Sort the list of industry types. */
1671
1672 /* Create dynamic list of industry legends for smallmap_gui.cpp */
1674
1675 /* Build the routemap legend, based on the available cargos */
1677
1678 /* Add all new airports to the airports array. */
1681
1682 /* Update the townname generators list */
1684
1685 /* Run all queued vehicle list order changes */
1687
1688 /* Load old shore sprites in new position, if they were replaced by ActionA */
1690
1691 /* Load old tram depot sprites in new position, if no new ones are present */
1693
1694 /* Set up custom rail types */
1695 InitRailTypes();
1696 InitRoadTypes();
1697
1699 if (_gted[e->index].rv_max_speed != 0) {
1700 /* Set RV maximum speed from the mph/0.8 unit value */
1701 e->VehInfo<RoadVehicleInfo>().max_speed = _gted[e->index].rv_max_speed * 4;
1702 }
1703
1705
1706 const GRFFile *file = e->GetGRF();
1707 if (file == nullptr || _gted[e->index].roadtramtype == 0) {
1708 e->VehInfo<RoadVehicleInfo>().roadtype = (rtt == RoadTramType::Tram) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
1709 continue;
1710 }
1711
1712 /* Remove +1 offset. */
1713 _gted[e->index].roadtramtype--;
1714
1715 const std::vector<RoadTypeLabel> *list = (rtt == RoadTramType::Tram) ? &file->tramtype_list : &file->roadtype_list;
1716 if (_gted[e->index].roadtramtype < list->size())
1717 {
1718 RoadTypeLabel rtl = (*list)[_gted[e->index].roadtramtype];
1719 RoadType rt = GetRoadTypeByLabel(rtl);
1720 if (rt != INVALID_ROADTYPE && GetRoadTramType(rt) == rtt) {
1721 e->VehInfo<RoadVehicleInfo>().roadtype = rt;
1722 continue;
1723 }
1724 }
1725
1726 /* Road type is not available, so disable this engine */
1727 e->info.climates = {};
1728 }
1729
1731 RailTypes railtypes{};
1732 for (RailTypeLabel label : _gted[e->index].railtypelabels) {
1733 auto rt = GetRailTypeByLabel(label);
1734 if (rt != INVALID_RAILTYPE) railtypes.Set(rt);
1735 }
1736
1737 if (railtypes.Any()) {
1738 e->VehInfo<RailVehicleInfo>().railtypes = railtypes;
1739 e->VehInfo<RailVehicleInfo>().intended_railtypes = railtypes;
1740 } else {
1741 /* Rail type is not available, so disable this engine */
1742 e->info.climates = {};
1743 }
1744 }
1745
1747
1749
1750 /* Deallocate temporary loading data */
1751 _gted.clear();
1752 _grm_sprites.clear();
1753}
1754
1760void LoadNewGRF(SpriteID load_index, uint num_baseset)
1761{
1762 /* In case of networking we need to "sync" the start values
1763 * so all NewGRFs are loaded equally. For this we use the
1764 * start date of the game and we set the counters, etc. to
1765 * 0 so they're the same too. */
1769
1770 AutoRestoreBackup backup_economy_date{TimerGameEconomy::date};
1771 AutoRestoreBackup backup_economy_year{TimerGameEconomy::year};
1772 AutoRestoreBackup backup_economy_date_fract{TimerGameEconomy::date_fract};
1773
1774 AutoRestoreBackup backup_tick_counter{TimerGameTick::counter};
1775 AutoRestoreBackup backup_display_opt{_display_opt};
1776
1777 if (_networking) {
1778 TimerGameCalendar::year = _settings_game.game_creation.starting_year;
1781
1782 TimerGameEconomy::year = TimerGameEconomy::Year{_settings_game.game_creation.starting_year.base()};
1785
1787 _display_opt.Reset();
1788 }
1789
1791
1793
1794 /*
1795 * Reset the status of all files, so we can 'retry' to load them.
1796 * This is needed when one for example rearranges the NewGRFs in-game
1797 * and a previously disabled NewGRF becomes usable. If it would not
1798 * be reset, the NewGRF would remain disabled even though it should
1799 * have been enabled.
1800 */
1801 for (const auto &c : _grfconfig) {
1802 if (c->status != GRFStatus::NotFound) c->status = GRFStatus::Unknown;
1803 }
1804
1805 _cur_gps.spriteid = load_index;
1806
1807 /* Load newgrf sprites
1808 * in each loading stage, (try to) open each file specified in the config
1809 * and load information from it. */
1811 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
1812 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
1813 for (const auto &c : _grfconfig) {
1814 if (c->status == GRFStatus::Activated) c->status = GRFStatus::Initialised;
1815 }
1816
1817 if (stage == GrfLoadingStage::Reserve) {
1818 static const std::pair<GrfID, GrfID> default_grf_overrides[] = {
1819 { GrfID{"\x44\x44\x22\x02"}, GrfID{"\x44\x44\x01\x11"} }, // UKRS addons modifies UKRS
1820 { GrfID{"\x6D\x62\x04\x02"}, GrfID{"\x6D\x62\x04\x01"} }, // DBSetXL ECS extension modifies DBSetXL
1821 { GrfID{"\x4D\x65\x6f\x20"}, GrfID{"\x4D\x65\x6F\x17"} }, // LV4cut modifies LV4
1822 };
1823 for (const auto &grf_override : default_grf_overrides) {
1824 SetNewGRFOverride(grf_override.first, grf_override.second);
1825 }
1826 }
1827
1828 uint num_grfs = 0;
1829 uint num_non_static = 0;
1830
1831 _cur_gps.stage = stage;
1832 for (const auto &c : _grfconfig) {
1833 if (c->status == GRFStatus::Disabled || c->status == GRFStatus::NotFound) continue;
1834 if (stage > GrfLoadingStage::Init && c->flags.Test(GRFConfigFlag::InitOnly)) continue;
1835
1836 Subdirectory subdir = num_grfs < num_baseset ? Subdirectory::Baseset : Subdirectory::NewGrf;
1837 if (!FioCheckFileExists(c->filename, subdir)) {
1838 Debug(grf, 0, "NewGRF file is missing '{}'; disabling", c->filename);
1839 c->status = GRFStatus::NotFound;
1840 continue;
1841 }
1842
1844
1845 if (!c->flags.Test(GRFConfigFlag::Static) && !c->flags.Test(GRFConfigFlag::System)) {
1846 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
1847 Debug(grf, 0, "'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
1848 c->status = GRFStatus::Disabled;
1849 c->errors.emplace_back(STR_NEWGRF_ERROR_MSG_FATAL, 0, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
1850 continue;
1851 }
1852 num_non_static++;
1853 }
1854
1855 num_grfs++;
1856
1857 LoadNewGRFFile(*c, stage, subdir, false);
1858 if (stage == GrfLoadingStage::Reserve) {
1859 c->flags.Set(GRFConfigFlag::Reserved);
1860 } else if (stage == GrfLoadingStage::Activation) {
1861 c->flags.Reset(GRFConfigFlag::Reserved);
1862 assert(GetFileByGRFID(c->ident.grfid) == _cur_gps.grffile);
1863 ClearTemporaryNewGRFData(_cur_gps.grffile);
1865 Debug(sprite, 2, "LoadNewGRF: Currently {} sprites are loaded", _cur_gps.spriteid);
1866 } else if (stage == GrfLoadingStage::Init && c->flags.Test(GRFConfigFlag::InitOnly)) {
1867 /* We're not going to activate this, so free whatever data we allocated */
1868 ClearTemporaryNewGRFData(_cur_gps.grffile);
1869 }
1870 }
1871 }
1872
1873 /* We've finished reading files. */
1874 _cur_gps.grfconfig = nullptr;
1875 _cur_gps.grffile = nullptr;
1876
1877 /* Pseudo sprite processing is finished; free temporary stuff */
1878 _cur_gps.ClearDataForNextFile();
1879
1880 /* Call any functions that should be run after GRFs have been loaded. */
1881 AfterLoadGRFs();
1882}
1883
1899
1906{
1907 switch (feature) {
1912 default: return VehicleType::Invalid;
1913 }
1914}
Class for backupping variables and making sure they are restored later.
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
Label< struct CargoLabelTag > CargoLabel
Globally unique label of a cargo type.
Definition cargo_type.h:17
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
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:73
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:729
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:29
@ IsFolded
Set if display of variants should be folded (hidden).
Definition engine_base.h:30
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:1169
static void FinalisePriceBaseMultipliers()
Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them...
Definition newgrf.cpp:1482
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:1115
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:65
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:1191
static GRFFile * GetFileByFilename(const std::string &filename)
Obtain a NewGRF file by its filename.
Definition newgrf.cpp:118
GRFFile * GetCurrentGRFOverride()
Get overridden GRF for current GRF if present.
Definition newgrf.cpp:201
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:339
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:219
static void ActivateOldShore()
Relocates the old shore sprites at new positions.
Definition newgrf.cpp:1430
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:1016
TypedIndexContainer< std::vector< GRFTempEngineData >, EngineID > _gted
Temporary engine data used during NewGRF loading.
Definition newgrf.cpp:80
static void FinaliseEngineArray()
Check for invalid engines.
Definition newgrf.cpp:855
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:1298
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition newgrf.cpp:76
void LoadNewGRF(SpriteID load_index, uint num_baseset)
Load all the NewGRFs.
Definition newgrf.cpp:1760
static void ClearTemporaryNewGRFData(GRFFile *gf)
Reset all NewGRFData that was used only while processing data.
Definition newgrf.cpp:129
void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig &c)
Disable a static NewGRF when it is influencing another (non-static) NewGRF as this could cause desync...
Definition newgrf.cpp:173
static void FinaliseCanals()
Set to use the correct action0 properties for each canal feature.
Definition newgrf.cpp:844
void ResetNewGRFData()
Reset all NewGRF loaded data.
Definition newgrf.cpp: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:938
GrfSpecFeature GetGrfSpecFeature(VehicleType type)
Get the GrfSpecFeature associated with a VehicleType.
Definition newgrf.cpp:1889
static void BuildCargoTranslationMap()
Construct the Cargo Mapping.
Definition newgrf.cpp:543
GRFFile * GetFileByGRFID(GrfID grfid)
Obtain a NewGRF file by its grfID.
Definition newgrf.cpp:106
void SetNewGRFOverride(GrfID source_grfid, GrfID target_grfid)
Set the override for a NewGRF.
Definition newgrf.cpp:186
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:92
EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal_id)
Return the ID of a new engine.
Definition newgrf.cpp:301
GrfMiscBits _misc_grf_features
Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E.
Definition newgrf.cpp:73
static void FinaliseHouseArray()
Add all new houses to the house array.
Definition newgrf.cpp:1041
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:1467
void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
Load a particular NewGRF.
Definition newgrf.cpp:1394
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:970
static void AfterLoadGRFs()
Finish loading NewGRFs and execute needed post-processing.
Definition newgrf.cpp:1634
GRFError * DisableGrf(StringID message, GRFConfig *config)
Disable a GRF.
Definition newgrf.cpp:140
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:1905
CargoTypes TranslateRefitMask(uint32_t refit_mask)
Translate the refit mask.
Definition newgrf.cpp:322
static void FinaliseBadges()
Finish up applying badges to things.
Definition newgrf.cpp:1605
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.
static const GrfID INVALID_GRFID
An invalid NewGRF.
Definition newgrf_type.h:19
Label< struct GrfIDTag > GrfID
The unique identifier of a 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:37
RailType
Enumeration for all possible railtypes.
Definition rail_type.h:26
@ RAILTYPE_MONO
Monorail.
Definition rail_type.h:30
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition rail_type.h:33
@ RAILTYPE_ELECTRIC
Electric rails.
Definition rail_type.h:29
@ RAILTYPE_RAIL
Standard non-electric rails.
Definition rail_type.h:28
@ RAILTYPE_MAGLEV
Maglev.
Definition rail_type.h:31
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:24
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:29
@ ROADTYPE_TRAM
Trams.
Definition road_type.h:27
@ ROADTYPE_ROAD
Basic road type.
Definition road_type.h:26
RoadTramType
The different types of road type.
Definition road_type.h:38
@ Tram
Tram type.
Definition road_type.h:40
@ Road
Road type.
Definition road_type.h:39
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:312
static const SpriteID SPR_TRAMWAY_DEPOT_NO_TRACK
Definition sprites.h:319
static const SpriteID SPR_ROAD_DEPOT
Definition sprites.h:665
static const SpriteID SPR_FLAT_GRASS_TILE
Definition sprites.h:676
static const SpriteID SPR_ORIGINALSHORE_START
Definition sprites.h:246
static const SpriteID SPR_SHORE_BASE
Definition sprites.h:244
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:261
std::string FormatArrayAsHex(std::span< const uint8_t > data)
Format a byte array into a continuous hex string.
Definition string.cpp:77
Functions related to low-level strings.
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...
constexpr bool Empty() const
Check whether the label is empty.
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:577
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:1215
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:364
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.