OpenTTD Source 20250528-master-g3aca5d62a8
newgrf.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "core/backup_type.hpp"
13#include "debug.h"
14#include "fileio_func.h"
15#include "engine_func.h"
16#include "engine_base.h"
17#include "bridge.h"
18#include "town.h"
19#include "newgrf_engine.h"
20#include "newgrf_text.h"
21#include "spritecache.h"
22#include "currency.h"
23#include "landscape.h"
24#include "newgrf_badge.h"
25#include "newgrf_badge_config.h"
26#include "newgrf_cargo.h"
27#include "newgrf_sound.h"
28#include "newgrf_station.h"
29#include "industrytype.h"
30#include "newgrf_canal.h"
31#include "newgrf_townname.h"
32#include "newgrf_industries.h"
33#include "newgrf_airporttiles.h"
34#include "newgrf_airport.h"
35#include "newgrf_object.h"
36#include "network/core/config.h"
37#include "smallmap_gui.h"
38#include "genworld.h"
39#include "error_func.h"
40#include "vehicle_base.h"
41#include "road.h"
42#include "newgrf_roadstop.h"
47
48#include "table/strings.h"
49
50#include "safeguards.h"
51
52/* TTDPatch extended GRF format codec
53 * (c) Petr Baudis 2004 (GPL'd)
54 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
55 *
56 * Contains portions of documentation by TTDPatch team.
57 * Thanks especially to Josef Drexler for the documentation as well as a lot
58 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
59 * served as subject to the initial testing of this codec. */
60
62static std::vector<GRFFile> _grf_files;
63
64std::span<const GRFFile> GetAllGRFFiles()
65{
66 return _grf_files;
67}
68
71
74
75GrfProcessingState _cur_gps;
76
78
89void GrfMsgI(int severity, const std::string &msg)
90{
91 if (_cur_gps.grfconfig == nullptr) {
92 Debug(grf, severity, "{}", msg);
93 } else {
94 Debug(grf, severity, "[{}:{}] {}", _cur_gps.grfconfig->filename, _cur_gps.nfo_line, msg);
95 }
96}
97
103GRFFile *GetFileByGRFID(uint32_t grfid)
104{
105 auto it = std::ranges::find(_grf_files, grfid, &GRFFile::grfid);
106 if (it != std::end(_grf_files)) return &*it;
107 return nullptr;
108}
109
115static GRFFile *GetFileByFilename(const std::string &filename)
116{
117 auto it = std::ranges::find(_grf_files, filename, &GRFFile::filename);
118 if (it != std::end(_grf_files)) return &*it;
119 return nullptr;
120}
121
124{
125 gf->labels.clear();
126}
127
135{
136 GRFFile *file;
137 if (config != nullptr) {
138 file = GetFileByGRFID(config->ident.grfid);
139 } else {
140 config = _cur_gps.grfconfig;
141 file = _cur_gps.grffile;
142 }
143
144 config->status = GCS_DISABLED;
145 if (file != nullptr) ClearTemporaryNewGRFData(file);
146 if (config == _cur_gps.grfconfig) _cur_gps.skip_sprites = -1;
147
148 if (message == STR_NULL) return nullptr;
149
150 config->error = {STR_NEWGRF_ERROR_MSG_FATAL, message};
151 if (config == _cur_gps.grfconfig) config->error->param_value[0] = _cur_gps.nfo_line;
152 return &config->error.value();
153}
154
165{
166 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, &c);
167 error->data = _cur_gps.grfconfig->GetName();
168}
169
170static std::map<uint32_t, uint32_t> _grf_id_overrides;
171
177void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
178{
179 if (target_grfid == 0) {
180 _grf_id_overrides.erase(source_grfid);
181 GrfMsg(5, "SetNewGRFOverride: Removed override of 0x{:X}", std::byteswap(source_grfid));
182 } else {
183 _grf_id_overrides[source_grfid] = target_grfid;
184 GrfMsg(5, "SetNewGRFOverride: Added override of 0x{:X} to 0x{:X}", std::byteswap(source_grfid), std::byteswap(target_grfid));
185 }
186}
187
193{
194 auto found = _grf_id_overrides.find(_cur_gps.grffile->grfid);
195 if (found != std::end(_grf_id_overrides)) {
196 GRFFile *grffile = GetFileByGRFID(found->second);
197 if (grffile != nullptr) return grffile;
198 }
199 return nullptr;
200}
201
210Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16_t internal_id, bool static_access)
211{
212 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
213 * them use the same engine slots. */
214 uint32_t scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
216 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
217 scope_grfid = file->grfid;
218 if (auto it = _grf_id_overrides.find(file->grfid); it != std::end(_grf_id_overrides)) {
219 scope_grfid = it->second;
220 const GRFFile *grf_match = GetFileByGRFID(scope_grfid);
221 if (grf_match == nullptr) {
222 GrfMsg(5, "Tried mapping from GRFID {:x} to {:x} but target is not loaded", std::byteswap(file->grfid), std::byteswap(scope_grfid));
223 } else {
224 GrfMsg(5, "Mapping from GRFID {:x} to {:x}", std::byteswap(file->grfid), std::byteswap(scope_grfid));
225 }
226 }
227
228 /* Check if the engine is registered in the override manager */
229 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
230 if (engine != EngineID::Invalid()) {
231 Engine *e = Engine::Get(engine);
232 if (!e->grf_prop.HasGrfFile()) {
233 e->grf_prop.SetGRFFile(file);
234 }
235 return e;
236 }
237 }
238
239 /* Check if there is an unreserved slot */
240 EngineID engine = _engine_mngr.UseUnreservedID(type, internal_id, scope_grfid, static_access);
241 if (engine != EngineID::Invalid()) {
242 Engine *e = Engine::Get(engine);
243
244 if (!e->grf_prop.HasGrfFile()) {
245 e->grf_prop.SetGRFFile(file);
246 GrfMsg(5, "Replaced engine at index {} for GRFID {:x}, type {}, index {}", e->index, std::byteswap(file->grfid), type, internal_id);
247 }
248
249 return e;
250 }
251
252 if (static_access) return nullptr;
253
255 GrfMsg(0, "Can't allocate any more engines");
256 return nullptr;
257 }
258
259 size_t engine_pool_size = Engine::GetPoolSize();
260
261 /* ... it's not, so create a new one based off an existing engine */
262 Engine *e = new Engine(type, internal_id);
263 e->grf_prop.SetGRFFile(file);
264
265 /* Reserve the engine slot */
266 _engine_mngr.SetID(type, internal_id, scope_grfid, std::min<uint8_t>(internal_id, _engine_counts[type]), e->index);
267
268 if (engine_pool_size != Engine::GetPoolSize()) {
269 /* Resize temporary engine data ... */
270 _gted.resize(Engine::GetPoolSize());
271 }
272 if (type == VEH_TRAIN) {
273 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
274 }
275
276 GrfMsg(5, "Created new engine at index {} for GRFID {:x}, type {}, index {}", e->index, std::byteswap(file->grfid), type, internal_id);
277
278 return e;
279}
280
291EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal_id)
292{
293 uint32_t scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
295 scope_grfid = file->grfid;
296 if (auto it = _grf_id_overrides.find(file->grfid); it != std::end(_grf_id_overrides)) {
297 scope_grfid = it->second;
298 }
299 }
300
301 return _engine_mngr.GetID(type, internal_id, scope_grfid);
302}
303
304
305
306
310CargoTypes TranslateRefitMask(uint32_t refit_mask)
311{
312 CargoTypes result = 0;
313 for (uint8_t bit : SetBitIterator(refit_mask)) {
314 CargoType cargo = GetCargoTranslation(bit, _cur_gps.grffile, true);
315 if (IsValidCargoType(cargo)) SetBit(result, cargo);
316 }
317 return result;
318}
319
327void ConvertTTDBasePrice(uint32_t base_pointer, std::string_view error_location, Price *index)
328{
329 /* Special value for 'none' */
330 if (base_pointer == 0) {
331 *index = INVALID_PRICE;
332 return;
333 }
334
335 static const uint32_t start = 0x4B34;
336 static const uint32_t size = 6;
337
338 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
339 GrfMsg(1, "{}: Unsupported running cost base 0x{:04X}, ignoring", error_location, base_pointer);
340 return;
341 }
342
343 *index = (Price)((base_pointer - start) / size);
344}
345
352/* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32_t grfid, uint8_t language_id)
353{
354 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
355 const GRFFile *grffile = GetFileByGRFID(grfid);
356 if (grffile == nullptr) return nullptr;
357
358 auto it = grffile->language_map.find(language_id);
359 if (it == std::end(grffile->language_map)) return nullptr;
360
361 return &it->second;
362}
363
369{
371
372 /* Skip remainder of GRF */
373 _cur_gps.skip_sprites = -1;
374}
375
377static void ResetNewGRF()
378{
379 _cur_gps.grfconfig = nullptr;
380 _cur_gps.grffile = nullptr;
381 _grf_files.clear();
382
383 /* We store pointers to GRFFiles in many places, so need to ensure that the pointers do not become invalid
384 * due to vector reallocation. Should not happen due to loading taking place in multiple stages, but
385 * reserving when the size is known is good practice anyway. */
386 _grf_files.reserve(_grfconfig.size());
387}
388
390static void ResetNewGRFErrors()
391{
392 for (const auto &c : _grfconfig) {
393 c->error.reset();
394 }
395}
396
397extern void ResetCallbacks(bool final);
398extern void ResetGRM();
399
404{
406 CleanUpGRFTownNames();
407
408 ResetBadges();
409
410 /* Copy/reset original engine info data */
411 SetupEngines();
412
413 /* Copy/reset original bridge info data */
414 ResetBridges();
415
416 /* Reset rail type information */
418
419 /* Copy/reset original road type info data */
421
422 /* Allocate temporary refit/cargo class data */
423 _gted.resize(Engine::GetPoolSize());
424
425 /* Fill rail type label temporary data for default trains */
426 for (const Engine *e : Engine::IterateType(VEH_TRAIN)) {
427 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
428 }
429
430 /* Reset GRM reservations */
431 ResetGRM();
432
433 /* Reset generic feature callback lists */
435
436 /* Reset price base data */
438
439 /* Reset the curencies array */
441
442 /* Reset the house array */
443 ResetHouses();
444
445 /* Reset the industries structures*/
447
448 /* Reset the objects. */
450 ResetObjects();
451
452 /* Reset station classes */
454
455 /* Reset airport-related structures */
459
460 /* Reset road stop classes */
462
463 /* Reset canal sprite groups and flags */
464 _water_feature.fill({});
465
466 /* Reset the snowline table. */
468
469 /* Reset NewGRF files */
470 ResetNewGRF();
471
472 /* Reset NewGRF errors. */
474
475 /* Set up the default cargo types */
477
478 /* Reset misc GRF features and train list display variables */
480
482 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
485
486 /* Clear all GRF overrides */
487 _grf_id_overrides.clear();
488
489 InitializeSoundPool();
490 _spritegroup_pool.CleanPool();
491 ResetCallbacks(false);
492}
493
498{
499 /* Reset override managers */
500 _engine_mngr.ResetToDefaultMapping();
501 _house_mngr.ResetMapping();
502 _industry_mngr.ResetMapping();
503 _industile_mngr.ResetMapping();
504 _airport_mngr.ResetMapping();
505 _airporttile_mngr.ResetMapping();
506}
507
513 std::span<const CargoLabel> GetCargoTranslationTable(const GRFFile &grffile)
514 {
515 /* Always use the translation table if it's installed. */
516 if (!grffile.cargo_list.empty()) return grffile.cargo_list;
517
518 /* Pre-v7 use climate-dependent "slot" table. */
519 if (grffile.grf_version < 7) return GetClimateDependentCargoTranslationTable();
520
521 /* Otherwise use climate-independent "bitnum" table. */
523 }
524
530{
531 _cur_gps.grffile->cargo_map.fill(UINT8_MAX);
532
533 auto cargo_list = GetCargoTranslationTable(*_cur_gps.grffile);
534
535 for (const CargoSpec *cs : CargoSpec::Iterate()) {
536 /* Check the translation table for this cargo's label */
537 int idx = find_index(cargo_list, cs->label);
538 if (idx >= 0) _cur_gps.grffile->cargo_map[cs->Index()] = idx;
539 }
540}
541
546static void InitNewGRFFile(const GRFConfig &config)
547{
548 GRFFile *newfile = GetFileByFilename(config.filename);
549 if (newfile != nullptr) {
550 /* We already loaded it once. */
551 _cur_gps.grffile = newfile;
552 return;
553 }
554
555 assert(_grf_files.size() < _grf_files.capacity()); // We must not invalidate pointers.
556 _cur_gps.grffile = &_grf_files.emplace_back(config);
557}
558
563GRFFile::GRFFile(const GRFConfig &config)
564{
565 this->filename = config.filename;
566 this->grfid = config.ident.grfid;
567
568 /* Initialise local settings to defaults */
569 this->traininfo_vehicle_pitch = 0;
570 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
571
572 /* Mark price_base_multipliers as 'not set' */
573 this->price_base_multipliers.fill(INVALID_PRICE_MODIFIER);
574
575 /* Initialise rail type map with default rail types */
576 this->railtype_map.fill(INVALID_RAILTYPE);
577 this->railtype_map[0] = RAILTYPE_RAIL;
578 this->railtype_map[1] = RAILTYPE_ELECTRIC;
579 this->railtype_map[2] = RAILTYPE_MONO;
580 this->railtype_map[3] = RAILTYPE_MAGLEV;
581
582 /* Initialise road type map with default road types */
583 this->roadtype_map.fill(INVALID_ROADTYPE);
584 this->roadtype_map[0] = ROADTYPE_ROAD;
585
586 /* Initialise tram type map with default tram types */
587 this->tramtype_map.fill(INVALID_ROADTYPE);
588 this->tramtype_map[0] = ROADTYPE_TRAM;
589
590 /* Copy the initial parameter list */
591 this->param = config.param;
592}
593
594/* Some compilers get confused about vectors of unique_ptrs. */
595GRFFile::GRFFile() = default;
596GRFFile::GRFFile(GRFFile &&other) = default;
597GRFFile::~GRFFile() = default;
598
604static CargoLabel GetActiveCargoLabel(const std::initializer_list<CargoLabel> &labels)
605{
606 for (const CargoLabel &label : labels) {
607 CargoType cargo_type = GetCargoTypeByLabel(label);
608 if (cargo_type != INVALID_CARGO) return label;
609 }
610 return CT_INVALID;
611}
612
618static CargoLabel GetActiveCargoLabel(const std::variant<CargoLabel, MixedCargoType> &label)
619{
620 struct visitor {
621 CargoLabel operator()(const CargoLabel &label) { return label; }
622 CargoLabel operator()(const MixedCargoType &mixed)
623 {
624 switch (mixed) {
625 case MCT_LIVESTOCK_FRUIT: return GetActiveCargoLabel({CT_LIVESTOCK, CT_FRUIT});
626 case MCT_GRAIN_WHEAT_MAIZE: return GetActiveCargoLabel({CT_GRAIN, CT_WHEAT, CT_MAIZE});
627 case MCT_VALUABLES_GOLD_DIAMONDS: return GetActiveCargoLabel({CT_VALUABLES, CT_GOLD, CT_DIAMONDS});
628 default: NOT_REACHED();
629 }
630 }
631 };
632
633 return std::visit(visitor{}, label);
634}
635
640{
641 CargoTypes original_known_cargoes = 0;
642 for (CargoType cargo_type = 0; cargo_type != NUM_CARGO; ++cargo_type) {
643 if (IsDefaultCargo(cargo_type)) SetBit(original_known_cargoes, cargo_type);
644 }
645
646 for (Engine *e : Engine::Iterate()) {
647 EngineID engine = e->index;
648 EngineInfo *ei = &e->info;
649 bool only_defaultcargo;
650
651 /* Apply default cargo translation map if cargo type hasn't been set, either explicitly or by aircraft cargo handling. */
652 if (!IsValidCargoType(e->info.cargo_type)) {
653 e->info.cargo_type = GetCargoTypeByLabel(GetActiveCargoLabel(e->info.cargo_label));
654 }
655
656 /* If the NewGRF did not set any cargo properties, we apply default values. */
657 if (_gted[engine].defaultcargo_grf == nullptr) {
658 /* If the vehicle has any capacity, apply the default refit masks */
659 if (e->type != VEH_TRAIN || e->u.rail.capacity != 0) {
660 static constexpr LandscapeType T = LandscapeType::Temperate;
661 static constexpr LandscapeType A = LandscapeType::Arctic;
662 static constexpr LandscapeType S = LandscapeType::Tropic;
663 static constexpr LandscapeType Y = LandscapeType::Toyland;
664 static const struct DefaultRefitMasks {
665 LandscapeTypes climate;
666 CargoLabel cargo_label;
667 CargoClasses cargo_allowed;
668 CargoClasses cargo_disallowed;
669 } _default_refit_masks[] = {
670 {{T, A, S, Y}, CT_PASSENGERS, {CargoClass::Passengers}, {}},
671 {{T, A, S }, CT_MAIL, {CargoClass::Mail}, {}},
672 {{T, A, S }, CT_VALUABLES, {CargoClass::Armoured}, {CargoClass::Liquid}},
674 {{T, A }, CT_COAL, {CargoClass::Bulk}, {}},
675 {{ S }, CT_COPPER_ORE, {CargoClass::Bulk}, {}},
676 {{ Y}, CT_SUGAR, {CargoClass::Bulk}, {}},
677 {{T, A, S }, CT_OIL, {CargoClass::Liquid}, {}},
678 {{ Y}, CT_COLA, {CargoClass::Liquid}, {}},
681 {{ A, S }, CT_FOOD, {CargoClass::Refrigerated}, {}},
683 };
684
685 if (e->type == VEH_AIRCRAFT) {
686 /* Aircraft default to "light" cargoes */
688 _gted[engine].cargo_disallowed = {CargoClass::Liquid};
689 } else if (e->type == VEH_SHIP) {
690 CargoLabel label = GetActiveCargoLabel(ei->cargo_label);
691 switch (label.base()) {
692 case CT_PASSENGERS.base():
693 /* Ferries */
694 _gted[engine].cargo_allowed = {CargoClass::Passengers};
695 _gted[engine].cargo_disallowed = {};
696 break;
697 case CT_OIL.base():
698 /* Tankers */
699 _gted[engine].cargo_allowed = {CargoClass::Liquid};
700 _gted[engine].cargo_disallowed = {};
701 break;
702 default:
703 /* Cargo ships */
704 if (_settings_game.game_creation.landscape == LandscapeType::Toyland) {
705 /* No tanker in toyland :( */
707 _gted[engine].cargo_disallowed = {CargoClass::Passengers};
708 } else {
710 _gted[engine].cargo_disallowed = {CargoClass::Liquid, CargoClass::Passengers};
711 }
712 break;
713 }
714 e->u.ship.old_refittable = true;
715 } else if (e->type == VEH_TRAIN && e->u.rail.railveh_type != RAILVEH_WAGON) {
716 /* Train engines default to all cargoes, so you can build single-cargo consists with fast engines.
717 * Trains loading multiple cargoes may start stations accepting unwanted cargoes. */
719 _gted[engine].cargo_disallowed = {};
720 } else {
721 /* Train wagons and road vehicles are classified by their default cargo type */
722 CargoLabel label = GetActiveCargoLabel(ei->cargo_label);
723 for (const auto &drm : _default_refit_masks) {
724 if (!drm.climate.Test(_settings_game.game_creation.landscape)) continue;
725 if (drm.cargo_label != label) continue;
726
727 _gted[engine].cargo_allowed = drm.cargo_allowed;
728 _gted[engine].cargo_disallowed = drm.cargo_disallowed;
729 break;
730 }
731
732 /* All original cargoes have specialised vehicles, so exclude them */
733 _gted[engine].ctt_exclude_mask = original_known_cargoes;
734 }
735 }
736 _gted[engine].UpdateRefittability(_gted[engine].cargo_allowed.Any());
737
738 if (IsValidCargoType(ei->cargo_type)) ClrBit(_gted[engine].ctt_exclude_mask, ei->cargo_type);
739 }
740
741 /* Compute refittability */
742 {
743 CargoTypes mask = 0;
744 CargoTypes not_mask = 0;
745 CargoTypes xor_mask = ei->refit_mask;
746
747 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
748 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
749 only_defaultcargo = _gted[engine].refittability != GRFTempEngineData::NONEMPTY;
750
751 if (_gted[engine].cargo_allowed.Any()) {
752 /* Build up the list of cargo types from the set cargo classes. */
753 for (const CargoSpec *cs : CargoSpec::Iterate()) {
754 if (cs->classes.Any(_gted[engine].cargo_allowed) && cs->classes.All(_gted[engine].cargo_allowed_required)) SetBit(mask, cs->Index());
755 if (cs->classes.Any(_gted[engine].cargo_disallowed)) SetBit(not_mask, cs->Index());
756 }
757 }
758
759 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
760
761 /* Apply explicit refit includes/excludes. */
762 ei->refit_mask |= _gted[engine].ctt_include_mask;
763 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
764
765 /* Custom refit mask callback. */
766 const GRFFile *file = _gted[e->index].defaultcargo_grf;
767 if (file == nullptr) file = e->GetGRF();
768 if (file != nullptr && e->info.callback_mask.Test(VehicleCallbackMask::CustomRefit)) {
769 for (const CargoSpec *cs : CargoSpec::Iterate()) {
770 uint8_t local_slot = file->cargo_map[cs->Index()];
771 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_CUSTOM_REFIT, cs->classes.base(), local_slot, engine, nullptr);
772 switch (callback) {
773 case CALLBACK_FAILED:
774 case 0:
775 break; // Do nothing.
776 case 1: SetBit(ei->refit_mask, cs->Index()); break;
777 case 2: ClrBit(ei->refit_mask, cs->Index()); break;
778
779 default: ErrorUnknownCallbackResult(file->grfid, CBID_VEHICLE_CUSTOM_REFIT, callback);
780 }
781 }
782 }
783 }
784
785 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
786 if (IsValidCargoType(ei->cargo_type) && !HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = INVALID_CARGO;
787
788 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
789 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
790 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && IsValidCargoType(ei->cargo_type) && !HasBit(ei->refit_mask, ei->cargo_type)) {
791 ei->cargo_type = INVALID_CARGO;
792 }
793
794 /* Check if this engine's cargo type is valid. If not, set to the first refittable
795 * cargo type. Finally disable the vehicle, if there is still no cargo. */
796 if (!IsValidCargoType(ei->cargo_type) && ei->refit_mask != 0) {
797 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
798 const GRFFile *file = _gted[engine].defaultcargo_grf;
799 if (file == nullptr) file = e->GetGRF();
800 if (file != nullptr && file->grf_version >= 8 && !file->cargo_list.empty()) {
801 /* Use first refittable cargo from cargo translation table */
802 uint8_t best_local_slot = UINT8_MAX;
803 for (CargoType cargo_type : SetCargoBitIterator(ei->refit_mask)) {
804 uint8_t local_slot = file->cargo_map[cargo_type];
805 if (local_slot < best_local_slot) {
806 best_local_slot = local_slot;
807 ei->cargo_type = cargo_type;
808 }
809 }
810 }
811
812 if (!IsValidCargoType(ei->cargo_type)) {
813 /* Use first refittable cargo slot */
814 ei->cargo_type = (CargoType)FindFirstBit(ei->refit_mask);
815 }
816 }
817 if (!IsValidCargoType(ei->cargo_type) && e->type == VEH_TRAIN && e->u.rail.railveh_type != RAILVEH_WAGON && e->u.rail.capacity == 0) {
818 /* For train engines which do not carry cargo it does not matter if their cargo type is invalid.
819 * Fallback to the first available instead, if the cargo type has not been changed (as indicated by
820 * cargo_label not being CT_INVALID). */
821 if (GetActiveCargoLabel(ei->cargo_label) != CT_INVALID) {
822 ei->cargo_type = static_cast<CargoType>(FindFirstBit(_standard_cargo_mask));
823 }
824 }
825 if (!IsValidCargoType(ei->cargo_type)) ei->climates = {};
826
827 /* Clear refit_mask for not refittable ships */
828 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
829 ei->refit_mask = 0;
830 }
831 }
832}
833
835static void FinaliseCanals()
836{
837 for (uint i = 0; i < CF_END; i++) {
838 if (_water_feature[i].grffile != nullptr) {
839 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
840 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
841 }
842 }
843}
844
847{
848 for (Engine *e : Engine::Iterate()) {
849 if (e->GetGRF() == nullptr) {
850 auto found = std::ranges::find(_engine_mngr.mappings[e->type], e->index, &EngineIDMapping::engine);
851 if (found == std::end(_engine_mngr.mappings[e->type]) || found->grfid != INVALID_GRFID || found->internal_id != found->substitute_id) {
852 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
853 }
854 }
855
856 /* Do final mapping on variant engine ID. */
857 if (e->info.variant_id != EngineID::Invalid()) {
858 e->info.variant_id = GetNewEngineID(e->grf_prop.grffile, e->type, e->info.variant_id.base());
859 }
860
861 if (!e->info.climates.Test(_settings_game.game_creation.landscape)) continue;
862
863 switch (e->type) {
864 case VEH_TRAIN: AppendCopyableBadgeList(e->badges, GetRailTypeInfo(e->u.rail.railtype)->badges, GSF_TRAINS); break;
865 case VEH_ROAD: AppendCopyableBadgeList(e->badges, GetRoadTypeInfo(e->u.road.roadtype)->badges, GSF_ROADVEHICLES); break;
866 default: break;
867 }
868
869 /* Skip wagons, there livery is defined via the engine */
870 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
871 LiveryScheme ls = GetEngineLiveryScheme(e->index, EngineID::Invalid(), nullptr);
873 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
874
875 if (e->type == VEH_TRAIN) {
877 switch (ls) {
878 case LS_STEAM:
879 case LS_DIESEL:
880 case LS_ELECTRIC:
881 case LS_MONORAIL:
882 case LS_MAGLEV:
883 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
884 break;
885
886 case LS_DMU:
887 case LS_EMU:
888 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
889 break;
890
891 default: NOT_REACHED();
892 }
893 }
894 }
895 }
896
897 /* Check engine variants don't point back on themselves (either directly or via a loop) then set appropriate flags
898 * on variant engine. This is performed separately as all variant engines need to have been resolved. */
899 for (Engine *e : Engine::Iterate()) {
900 EngineID parent = e->info.variant_id;
901 while (parent != EngineID::Invalid()) {
902 parent = Engine::Get(parent)->info.variant_id;
903 if (parent != e->index) continue;
904
905 /* Engine looped back on itself, so clear the variant. */
906 e->info.variant_id = EngineID::Invalid();
907
908 GrfMsg(1, "FinaliseEngineArray: Variant of engine {:x} in '{}' loops back on itself", e->grf_prop.local_id, e->GetGRF()->filename);
909 break;
910 }
911
912 if (e->info.variant_id != EngineID::Invalid()) {
913 Engine::Get(e->info.variant_id)->display_flags.Set({EngineDisplayFlag::HasVariants, EngineDisplayFlag::IsFolded});
914 }
915 }
916}
917
920{
921 for (CargoSpec &cs : CargoSpec::array) {
922 if (cs.town_production_effect == INVALID_TPE) {
923 /* Set default town production effect by cargo label. */
924 switch (cs.label.base()) {
925 case CT_PASSENGERS.base(): cs.town_production_effect = TPE_PASSENGERS; break;
926 case CT_MAIL.base(): cs.town_production_effect = TPE_MAIL; break;
927 default: cs.town_production_effect = TPE_NONE; break;
928 }
929 }
930 if (!cs.IsValid()) {
931 cs.name = cs.name_single = cs.units_volume = STR_NEWGRF_INVALID_CARGO;
932 cs.quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
933 cs.abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
934 }
935 }
936}
937
949static bool IsHouseSpecValid(HouseSpec &hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const std::string &filename)
950{
951 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) &&
952 (next1 == nullptr || !next1->enabled || next1->building_flags.Any(BUILDING_HAS_1_TILE))) ||
953 (hs.building_flags.Any(BUILDING_HAS_4_TILES) &&
954 (next2 == nullptr || !next2->enabled || next2->building_flags.Any(BUILDING_HAS_1_TILE) ||
955 next3 == nullptr || !next3->enabled || next3->building_flags.Any(BUILDING_HAS_1_TILE)))) {
956 hs.enabled = false;
957 if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs.grf_prop.local_id);
958 return false;
959 }
960
961 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
962 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
963 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
964 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) && next1->population != 0) ||
965 (hs.building_flags.Any(BUILDING_HAS_4_TILES) && (next2->population != 0 || next3->population != 0))) {
966 hs.enabled = false;
967 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);
968 return false;
969 }
970
971 /* Substitute type is also used for override, and having an override with a different size causes crashes.
972 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
973 if (!filename.empty() && (hs.building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs.grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
974 hs.enabled = false;
975 Debug(grf, 1, "FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs.grf_prop.local_id);
976 return false;
977 }
978
979 /* Make sure that additional parts of multitile houses are not available. */
980 if (!hs.building_flags.Any(BUILDING_HAS_1_TILE) && hs.building_availability.Any(HZ_ZONE_ALL) && hs.building_availability.Any(HZ_CLIMATE_ALL)) {
981 hs.enabled = false;
982 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);
983 return false;
984 }
985
986 return true;
987}
988
995static void EnsureEarlyHouse(HouseZones bitmask)
996{
998
999 for (const auto &hs : HouseSpec::Specs()) {
1000 if (!hs.enabled) continue;
1001 if (!hs.building_availability.All(bitmask)) continue;
1002 if (hs.min_year < min_year) min_year = hs.min_year;
1003 }
1004
1005 if (min_year == 0) return;
1006
1007 for (auto &hs : HouseSpec::Specs()) {
1008 if (!hs.enabled) continue;
1009 if (!hs.building_availability.All(bitmask)) continue;
1010 if (hs.min_year == min_year) hs.min_year = CalendarTime::MIN_YEAR;
1011 }
1012}
1013
1021{
1022 /* If there are no houses with start dates before 1930, then all houses
1023 * with start dates of 1930 have them reset to 0. This is in order to be
1024 * compatible with TTDPatch, where if no houses have start dates before
1025 * 1930 and the date is before 1930, the game pretends that this is 1930.
1026 * If there have been any houses defined with start dates before 1930 then
1027 * the dates are left alone.
1028 * On the other hand, why 1930? Just 'fix' the houses with the lowest
1029 * minimum introduction date to 0.
1030 */
1031 for (auto &file : _grf_files) {
1032 if (file.housespec.empty()) continue;
1033
1034 size_t num_houses = file.housespec.size();
1035 for (size_t i = 0; i < num_houses; i++) {
1036 auto &hs = file.housespec[i];
1037
1038 if (hs == nullptr) continue;
1039
1040 const HouseSpec *next1 = (i + 1 < num_houses ? file.housespec[i + 1].get() : nullptr);
1041 const HouseSpec *next2 = (i + 2 < num_houses ? file.housespec[i + 2].get() : nullptr);
1042 const HouseSpec *next3 = (i + 3 < num_houses ? file.housespec[i + 3].get() : nullptr);
1043
1044 if (!IsHouseSpecValid(*hs, next1, next2, next3, file.filename)) continue;
1045
1046 _house_mngr.SetEntitySpec(std::move(*hs));
1047 }
1048
1049 /* Won't be used again */
1050 file.housespec.clear();
1051 file.housespec.shrink_to_fit();
1052 }
1053
1054 for (size_t i = 0; i < HouseSpec::Specs().size(); i++) {
1055 HouseSpec *hs = HouseSpec::Get(i);
1056 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr);
1057 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr);
1058 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : nullptr);
1059
1060 /* We need to check all houses again to we are sure that multitile houses
1061 * did get consecutive IDs and none of the parts are missing. */
1062 if (!IsHouseSpecValid(*hs, next1, next2, next3, std::string{})) {
1063 /* GetHouseNorthPart checks 3 houses that are directly before
1064 * it in the house pool. If any of those houses have multi-tile
1065 * flags set it assumes it's part of a multitile house. Since
1066 * we can have invalid houses in the pool marked as disabled, we
1067 * don't want to have them influencing valid tiles. As such set
1068 * building_flags to zero here to make sure any house following
1069 * this one in the pool is properly handled as 1x1 house. */
1070 hs->building_flags = {};
1071 }
1072
1073 /* Apply default cargo translation map for unset cargo slots */
1074 for (uint i = 0; i < lengthof(hs->accepts_cargo_label); ++i) {
1075 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->accepts_cargo[i] = GetCargoTypeByLabel(hs->accepts_cargo_label[i]);
1076 /* Disable acceptance if cargo type is invalid. */
1077 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->cargo_acceptance[i] = 0;
1078 }
1079 }
1080
1081 HouseZones climate_mask = GetClimateMaskForLandscape();
1082 for (HouseZone climate : climate_mask) {
1083 for (HouseZone zone : HZ_ZONE_ALL) {
1084 EnsureEarlyHouse({climate, zone});
1085 }
1086 }
1087}
1088
1095{
1096 for (auto &file : _grf_files) {
1097 for (auto &indsp : file.industryspec) {
1098 if (indsp == nullptr || !indsp->enabled) continue;
1099
1100 _industry_mngr.SetEntitySpec(std::move(*indsp));
1101 }
1102
1103 for (auto &indtsp : file.indtspec) {
1104 if (indtsp != nullptr) {
1105 _industile_mngr.SetEntitySpec(std::move(*indtsp));
1106 }
1107 }
1108
1109 /* Won't be used again */
1110 file.industryspec.clear();
1111 file.industryspec.shrink_to_fit();
1112 file.indtspec.clear();
1113 file.indtspec.shrink_to_fit();
1114 }
1115
1116 for (auto &indsp : _industry_specs) {
1117 if (indsp.enabled && indsp.grf_prop.HasGrfFile()) {
1118 for (auto &conflicting : indsp.conflicting) {
1119 conflicting = MapNewGRFIndustryType(conflicting, indsp.grf_prop.grfid);
1120 }
1121 }
1122 if (!indsp.enabled) {
1123 indsp.name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
1124 }
1125
1126 /* Apply default cargo translation map for unset cargo slots */
1127 for (size_t i = 0; i < std::size(indsp.produced_cargo_label); ++i) {
1128 if (!IsValidCargoType(indsp.produced_cargo[i])) indsp.produced_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.produced_cargo_label[i]));
1129 }
1130 for (size_t i = 0; i < std::size(indsp.accepts_cargo_label); ++i) {
1131 if (!IsValidCargoType(indsp.accepts_cargo[i])) indsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.accepts_cargo_label[i]));
1132 }
1133 }
1134
1135 for (auto &indtsp : _industry_tile_specs) {
1136 /* Apply default cargo translation map for unset cargo slots */
1137 for (size_t i = 0; i < std::size(indtsp.accepts_cargo_label); ++i) {
1138 if (!IsValidCargoType(indtsp.accepts_cargo[i])) indtsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indtsp.accepts_cargo_label[i]));
1139 }
1140 }
1141}
1142
1149{
1150 for (auto &file : _grf_files) {
1151 for (auto &objectspec : file.objectspec) {
1152 if (objectspec != nullptr && objectspec->grf_prop.HasGrfFile() && objectspec->IsEnabled()) {
1153 _object_mngr.SetEntitySpec(std::move(*objectspec));
1154 }
1155 }
1156
1157 /* Won't be used again */
1158 file.objectspec.clear();
1159 file.objectspec.shrink_to_fit();
1160 }
1161
1163}
1164
1171{
1172 for (auto &file : _grf_files) {
1173 for (auto &as : file.airportspec) {
1174 if (as != nullptr && as->enabled) {
1175 _airport_mngr.SetEntitySpec(std::move(*as));
1176 }
1177 }
1178
1179 for (auto &ats : file.airtspec) {
1180 if (ats != nullptr && ats->enabled) {
1181 _airporttile_mngr.SetEntitySpec(std::move(*ats));
1182 }
1183 }
1184
1185 /* Won't be used again */
1186 file.airportspec.clear();
1187 file.airportspec.shrink_to_fit();
1188 file.airtspec.clear();
1189 file.airtspec.shrink_to_fit();
1190 }
1191}
1192
1195 template <uint8_t TAction>
1196 static void Invoke(ByteReader &buf, GrfLoadingStage stage)
1197 {
1198 switch (stage) {
1199 case GLS_FILESCAN: GrfActionHandler<TAction>::FileScan(buf); break;
1200 case GLS_SAFETYSCAN: GrfActionHandler<TAction>::SafetyScan(buf); break;
1201 case GLS_LABELSCAN: GrfActionHandler<TAction>::LabelScan(buf); break;
1202 case GLS_INIT: GrfActionHandler<TAction>::Init(buf); break;
1203 case GLS_RESERVE: GrfActionHandler<TAction>::Reserve(buf); break;
1204 case GLS_ACTIVATION: GrfActionHandler<TAction>::Activation(buf); break;
1205 default: NOT_REACHED();
1206 }
1207 }
1208
1209 using Invoker = void(*)(ByteReader &buf, GrfLoadingStage stage);
1210 static constexpr Invoker funcs[] = { // Must be listed in action order.
1211 Invoke<0x00>, Invoke<0x01>, Invoke<0x02>, Invoke<0x03>, Invoke<0x04>, Invoke<0x05>, Invoke<0x06>, Invoke<0x07>,
1212 Invoke<0x08>, Invoke<0x09>, Invoke<0x0A>, Invoke<0x0B>, Invoke<0x0C>, Invoke<0x0D>, Invoke<0x0E>, Invoke<0x0F>,
1213 Invoke<0x10>, Invoke<0x11>, Invoke<0x12>, Invoke<0x13>, Invoke<0x14>,
1214 };
1215
1216 static void Invoke(uint8_t action, GrfLoadingStage stage, ByteReader &buf)
1217 {
1218 Invoker func = action < std::size(funcs) ? funcs[action] : nullptr;
1219 if (func == nullptr) {
1220 GrfMsg(7, "DecodeSpecialSprite: Skipping unknown action 0x{:02X}", action);
1221 } else {
1222 GrfMsg(7, "DecodeSpecialSprite: Handling action 0x{:02X} in stage {}", action, stage);
1223 func(buf, stage);
1224 }
1225 }
1226};
1227
1228/* Here we perform initial decoding of some special sprites (as are they
1229 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
1230 * partial implementation yet).
1231 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
1232 * a crafted invalid GRF file. We should tell that to the user somehow, or
1233 * better make this more robust in the future. */
1234static void DecodeSpecialSprite(ReusableBuffer<uint8_t> &allocator, uint num, GrfLoadingStage stage)
1235{
1236 uint8_t *buf;
1237 auto it = _grf_line_to_action6_sprite_override.find({_cur_gps.grfconfig->ident.grfid, _cur_gps.nfo_line});
1238 if (it == _grf_line_to_action6_sprite_override.end()) {
1239 /* No preloaded sprite to work with; read the
1240 * pseudo sprite content. */
1241 buf = allocator.Allocate(num);
1242 _cur_gps.file->ReadBlock(buf, num);
1243 } else {
1244 /* Use the preloaded sprite data. */
1245 buf = it->second.data();
1246 assert(it->second.size() == num);
1247 GrfMsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
1248
1249 /* Skip the real (original) content of this action. */
1250 _cur_gps.file->SeekTo(num, SEEK_CUR);
1251 }
1252
1253 ByteReader br(buf, num);
1254
1255 try {
1256 uint8_t action = br.ReadByte();
1257
1258 if (action == 0xFF) {
1259 GrfMsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
1260 } else if (action == 0xFE) {
1261 GrfMsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
1262 } else {
1263 InvokeGrfActionHandler::Invoke(action, stage, br);
1264 }
1265 } catch (...) {
1266 GrfMsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
1267 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
1268 }
1269}
1270
1277static void LoadNewGRFFileFromFile(GRFConfig &config, GrfLoadingStage stage, SpriteFile &file)
1278{
1279 AutoRestoreBackup cur_file(_cur_gps.file, &file);
1280 AutoRestoreBackup cur_config(_cur_gps.grfconfig, &config);
1281
1282 Debug(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '{}'", config.filename);
1283
1284 uint8_t grf_container_version = file.GetContainerVersion();
1285 if (grf_container_version == 0) {
1286 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1287 return;
1288 }
1289
1290 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
1291 /* We need the sprite offsets in the init stage for NewGRF sounds
1292 * and in the activation stage for real sprites. */
1294 } else {
1295 /* Skip sprite section offset if present. */
1296 if (grf_container_version >= 2) file.ReadDword();
1297 }
1298
1299 if (grf_container_version >= 2) {
1300 /* Read compression value. */
1301 uint8_t compression = file.ReadByte();
1302 if (compression != 0) {
1303 Debug(grf, 7, "LoadNewGRFFile: Unsupported compression format");
1304 return;
1305 }
1306 }
1307
1308 /* Skip the first sprite; we don't care about how many sprites this
1309 * does contain; newest TTDPatches and George's longvehicles don't
1310 * neither, apparently. */
1311 uint32_t num = grf_container_version >= 2 ? file.ReadDword() : file.ReadWord();
1312 if (num == 4 && file.ReadByte() == 0xFF) {
1313 file.ReadDword();
1314 } else {
1315 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1316 return;
1317 }
1318
1319 _cur_gps.ClearDataForNextFile();
1320
1321 ReusableBuffer<uint8_t> allocator;
1322
1323 while ((num = (grf_container_version >= 2 ? file.ReadDword() : file.ReadWord())) != 0) {
1324 uint8_t type = file.ReadByte();
1325 _cur_gps.nfo_line++;
1326
1327 if (type == 0xFF) {
1328 if (_cur_gps.skip_sprites == 0) {
1329 /* Limit the special sprites to 1 MiB. */
1330 if (num > 1024 * 1024) {
1331 GrfMsg(0, "LoadNewGRFFile: Unexpectedly large sprite, disabling");
1332 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1333 break;
1334 }
1335
1336 DecodeSpecialSprite(allocator, num, stage);
1337
1338 /* Stop all processing if we are to skip the remaining sprites */
1339 if (_cur_gps.skip_sprites == -1) break;
1340
1341 continue;
1342 } else {
1343 file.SkipBytes(num);
1344 }
1345 } else {
1346 if (_cur_gps.skip_sprites == 0) {
1347 GrfMsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
1348 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1349 break;
1350 }
1351
1352 if (grf_container_version >= 2 && type == 0xFD) {
1353 /* Reference to data section. Container version >= 2 only. */
1354 file.SkipBytes(num);
1355 } else {
1356 file.SkipBytes(7);
1357 SkipSpriteData(file, type, num - 8);
1358 }
1359 }
1360
1361 if (_cur_gps.skip_sprites > 0) _cur_gps.skip_sprites--;
1362 }
1363}
1364
1373void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
1374{
1375 const std::string &filename = config.filename;
1376
1377 /* A .grf file is activated only if it was active when the game was
1378 * started. If a game is loaded, only its active .grfs will be
1379 * reactivated, unless "loadallgraphics on" is used. A .grf file is
1380 * considered active if its action 8 has been processed, i.e. its
1381 * action 8 hasn't been skipped using an action 7.
1382 *
1383 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
1384 * carried out. All others are ignored, because they only need to be
1385 * processed once at initialization. */
1386 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
1387 _cur_gps.grffile = GetFileByFilename(filename);
1388 if (_cur_gps.grffile == nullptr) UserError("File '{}' lost in cache.\n", filename);
1389 if (stage == GLS_RESERVE && config.status != GCS_INITIALISED) return;
1390 if (stage == GLS_ACTIVATION && !config.flags.Test(GRFConfigFlag::Reserved)) return;
1391 }
1392
1393 bool needs_palette_remap = config.palette & GRFP_USE_MASK;
1394 if (temporary) {
1395 SpriteFile temporarySpriteFile(filename, subdir, needs_palette_remap);
1396 LoadNewGRFFileFromFile(config, stage, temporarySpriteFile);
1397 } else {
1398 LoadNewGRFFileFromFile(config, stage, OpenCachedSpriteFile(filename, subdir, needs_palette_remap));
1399 }
1400}
1401
1409static void ActivateOldShore()
1410{
1411 /* Use default graphics, if no shore sprites were loaded.
1412 * Should not happen, as the base set's extra grf should include some. */
1414
1416 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
1417 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
1418 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
1419 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
1420 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
1421 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
1422 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
1423 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
1424 }
1425
1427 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
1428 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
1429 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
1430 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
1431 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
1432 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
1433 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
1434 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
1435
1436 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
1437 * If they would be used somewhen, then these grass tiles will most like not look as needed */
1438 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
1439 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
1440 }
1441}
1442
1447{
1449 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0); // use road depot graphics for "no tracks"
1450 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
1451 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2); // use road depot graphics for "no tracks"
1452 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
1453 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
1454 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
1455 }
1456}
1457
1462{
1463 extern const PriceBaseSpec _price_base_specs[];
1465 static constexpr GrfSpecFeatures override_features{GSF_TRAINS, GSF_ROADVEHICLES, GSF_SHIPS, GSF_AIRCRAFT};
1466
1467 /* Evaluate grf overrides */
1468 int num_grfs = (uint)_grf_files.size();
1469 std::vector<int> grf_overrides(num_grfs, -1);
1470 for (int i = 0; i < num_grfs; i++) {
1471 GRFFile &source = _grf_files[i];
1472 auto it = _grf_id_overrides.find(source.grfid);
1473 if (it == std::end(_grf_id_overrides)) continue;
1474 uint32_t override_grfid = it->second;
1475
1476 auto dest = std::ranges::find(_grf_files, override_grfid, &GRFFile::grfid);
1477 if (dest == std::end(_grf_files)) continue;
1478
1479 grf_overrides[i] = static_cast<int>(std::ranges::distance(std::begin(_grf_files), dest));
1480 assert(grf_overrides[i] >= 0);
1481 }
1482
1483 /* Override features and price base multipliers of earlier loaded grfs */
1484 for (int i = 0; i < num_grfs; i++) {
1485 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
1486 GRFFile &source = _grf_files[i];
1487 GRFFile &dest = _grf_files[grf_overrides[i]];
1488
1489 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1490 source.grf_features.Set(features);
1491 dest.grf_features.Set(features);
1492
1493 for (Price p = PR_BEGIN; p < PR_END; p++) {
1494 /* No price defined -> nothing to do */
1495 if (!features.Test(_price_base_specs[p].grf_feature) || source.price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
1496 Debug(grf, 3, "'{}' overrides price base multiplier {} of '{}'", source.filename, p, dest.filename);
1498 }
1499 }
1500
1501 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
1502 for (int i = num_grfs - 1; i >= 0; i--) {
1503 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
1504 GRFFile &source = _grf_files[i];
1505 GRFFile &dest = _grf_files[grf_overrides[i]];
1506
1507 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1508 source.grf_features.Set(features);
1509 dest.grf_features.Set(features);
1510
1511 for (Price p = PR_BEGIN; p < PR_END; p++) {
1512 /* Already a price defined -> nothing to do */
1513 if (!features.Test(_price_base_specs[p].grf_feature) || dest.price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
1514 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, source.filename, dest.filename);
1516 }
1517 }
1518
1519 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
1520 for (int i = 0; i < num_grfs; i++) {
1521 if (grf_overrides[i] < 0) continue;
1522 GRFFile &source = _grf_files[i];
1523 GRFFile &dest = _grf_files[grf_overrides[i]];
1524
1525 GrfSpecFeatures features = (source.grf_features | dest.grf_features) & override_features;
1526 source.grf_features.Set(features);
1527 dest.grf_features.Set(features);
1528
1529 for (Price p = PR_BEGIN; p < PR_END; p++) {
1530 if (!features.Test(_price_base_specs[p].grf_feature)) continue;
1531 if (source.price_base_multipliers[p] != dest.price_base_multipliers[p]) {
1532 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, dest.filename, source.filename);
1533 }
1535 }
1536 }
1537
1538 /* Apply fallback prices for grf version < 8 */
1539 for (auto &file : _grf_files) {
1540 if (file.grf_version >= 8) continue;
1541 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1542 for (Price p = PR_BEGIN; p < PR_END; p++) {
1543 Price fallback_price = _price_base_specs[p].fallback_price;
1544 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1545 /* No price multiplier has been set.
1546 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
1547 price_base_multipliers[p] = price_base_multipliers[fallback_price];
1548 }
1549 }
1550 }
1551
1552 /* Decide local/global scope of price base multipliers */
1553 for (auto &file : _grf_files) {
1554 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1555 for (Price p = PR_BEGIN; p < PR_END; p++) {
1556 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1557 /* No multiplier was set; set it to a neutral value */
1558 price_base_multipliers[p] = 0;
1559 } else {
1560 if (!file.grf_features.Test(_price_base_specs[p].grf_feature)) {
1561 /* The grf does not define any objects of the feature,
1562 * so it must be a difficulty setting. Apply it globally */
1563 Debug(grf, 3, "'{}' sets global price base multiplier {}", file.filename, p);
1564 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
1565 price_base_multipliers[p] = 0;
1566 } else {
1567 Debug(grf, 3, "'{}' sets local price base multiplier {}", file.filename, p);
1568 }
1569 }
1570 }
1571 }
1572}
1573
1574template <typename T>
1575void AddBadgeToSpecs(T &specs, GrfSpecFeature feature, Badge &badge)
1576{
1577 for (auto &spec : specs) {
1578 if (spec == nullptr) continue;
1579 spec->badges.push_back(badge.index);
1580 badge.features.Set(feature);
1581 }
1582}
1583
1585static void FinaliseBadges()
1586{
1587 for (const auto &file : _grf_files) {
1588 Badge *badge = GetBadgeByLabel(fmt::format("newgrf/{:08x}", std::byteswap(file.grfid)));
1589 if (badge == nullptr) continue;
1590
1591 for (Engine *e : Engine::Iterate()) {
1592 if (e->grf_prop.grffile != &file) continue;
1593 e->badges.push_back(badge->index);
1594 badge->features.Set(static_cast<GrfSpecFeature>(GSF_TRAINS + e->type));
1595 }
1596
1597 AddBadgeToSpecs(file.stations, GSF_STATIONS, *badge);
1598 AddBadgeToSpecs(file.housespec, GSF_HOUSES, *badge);
1599 AddBadgeToSpecs(file.industryspec, GSF_INDUSTRIES, *badge);
1600 AddBadgeToSpecs(file.indtspec, GSF_INDUSTRYTILES, *badge);
1601 AddBadgeToSpecs(file.objectspec, GSF_OBJECTS, *badge);
1602 AddBadgeToSpecs(file.airportspec, GSF_AIRPORTS, *badge);
1603 AddBadgeToSpecs(file.airtspec, GSF_AIRPORTTILES, *badge);
1604 AddBadgeToSpecs(file.roadstops, GSF_ROADSTOPS, *badge);
1605 }
1606
1609}
1610
1611extern void InitGRFTownGeneratorNames();
1612
1614static void AfterLoadGRFs()
1615{
1616 /* Cached callback groups are no longer needed. */
1617 ResetCallbacks(true);
1618
1620
1621 /* Clear the action 6 override sprites. */
1622 _grf_line_to_action6_sprite_override.clear();
1623
1625
1626 /* Polish cargoes */
1628
1629 /* Pre-calculate all refit masks after loading GRF files. */
1631
1632 /* Polish engines */
1634
1635 /* Set the actually used Canal properties */
1637
1638 /* Add all new houses to the house array. */
1640
1641 /* Add all new industries to the industry array. */
1643
1644 /* Add all new objects to the object array. */
1646
1648
1649 /* Sort the list of industry types. */
1651
1652 /* Create dynamic list of industry legends for smallmap_gui.cpp */
1654
1655 /* Build the routemap legend, based on the available cargos */
1657
1658 /* Add all new airports to the airports array. */
1661
1662 /* Update the townname generators list */
1664
1665 /* Run all queued vehicle list order changes */
1667
1668 /* Load old shore sprites in new position, if they were replaced by ActionA */
1670
1671 /* Load old tram depot sprites in new position, if no new ones are present */
1673
1674 /* Set up custom rail types */
1675 InitRailTypes();
1676 InitRoadTypes();
1677
1678 for (Engine *e : Engine::IterateType(VEH_ROAD)) {
1679 if (_gted[e->index].rv_max_speed != 0) {
1680 /* Set RV maximum speed from the mph/0.8 unit value */
1681 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
1682 }
1683
1684 RoadTramType rtt = e->info.misc_flags.Test(EngineMiscFlag::RoadIsTram) ? RTT_TRAM : RTT_ROAD;
1685
1686 const GRFFile *file = e->GetGRF();
1687 if (file == nullptr || _gted[e->index].roadtramtype == 0) {
1688 e->u.road.roadtype = (rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
1689 continue;
1690 }
1691
1692 /* Remove +1 offset. */
1693 _gted[e->index].roadtramtype--;
1694
1695 const std::vector<RoadTypeLabel> *list = (rtt == RTT_TRAM) ? &file->tramtype_list : &file->roadtype_list;
1696 if (_gted[e->index].roadtramtype < list->size())
1697 {
1698 RoadTypeLabel rtl = (*list)[_gted[e->index].roadtramtype];
1699 RoadType rt = GetRoadTypeByLabel(rtl);
1700 if (rt != INVALID_ROADTYPE && GetRoadTramType(rt) == rtt) {
1701 e->u.road.roadtype = rt;
1702 continue;
1703 }
1704 }
1705
1706 /* Road type is not available, so disable this engine */
1707 e->info.climates = {};
1708 }
1709
1711 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
1712 if (railtype == INVALID_RAILTYPE) {
1713 /* Rail type is not available, so disable this engine */
1714 e->info.climates = {};
1715 } else {
1716 e->u.rail.railtype = railtype;
1717 e->u.rail.intended_railtype = railtype;
1718 }
1719 }
1720
1722
1724
1725 /* Deallocate temporary loading data */
1726 _gted.clear();
1727 _grm_sprites.clear();
1728}
1729
1735void LoadNewGRF(SpriteID load_index, uint num_baseset)
1736{
1737 /* In case of networking we need to "sync" the start values
1738 * so all NewGRFs are loaded equally. For this we use the
1739 * start date of the game and we set the counters, etc. to
1740 * 0 so they're the same too. */
1744
1748
1749 uint64_t tick_counter = TimerGameTick::counter;
1750 uint8_t display_opt = _display_opt;
1751
1752 if (_networking) {
1756
1760
1762 _display_opt = 0;
1763 }
1764
1766
1768
1769 /*
1770 * Reset the status of all files, so we can 'retry' to load them.
1771 * This is needed when one for example rearranges the NewGRFs in-game
1772 * and a previously disabled NewGRF becomes usable. If it would not
1773 * be reset, the NewGRF would remain disabled even though it should
1774 * have been enabled.
1775 */
1776 for (const auto &c : _grfconfig) {
1777 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
1778 }
1779
1780 _cur_gps.spriteid = load_index;
1781
1782 /* Load newgrf sprites
1783 * in each loading stage, (try to) open each file specified in the config
1784 * and load information from it. */
1785 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
1786 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
1787 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
1788 for (const auto &c : _grfconfig) {
1789 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
1790 }
1791
1792 if (stage == GLS_RESERVE) {
1793 static const std::pair<uint32_t, uint32_t> default_grf_overrides[] = {
1794 { std::byteswap(0x44442202), std::byteswap(0x44440111) }, // UKRS addons modifies UKRS
1795 { std::byteswap(0x6D620402), std::byteswap(0x6D620401) }, // DBSetXL ECS extension modifies DBSetXL
1796 { std::byteswap(0x4D656f20), std::byteswap(0x4D656F17) }, // LV4cut modifies LV4
1797 };
1798 for (const auto &grf_override : default_grf_overrides) {
1799 SetNewGRFOverride(grf_override.first, grf_override.second);
1800 }
1801 }
1802
1803 uint num_grfs = 0;
1804 uint num_non_static = 0;
1805
1806 _cur_gps.stage = stage;
1807 for (const auto &c : _grfconfig) {
1808 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
1809 if (stage > GLS_INIT && c->flags.Test(GRFConfigFlag::InitOnly)) continue;
1810
1811 Subdirectory subdir = num_grfs < num_baseset ? BASESET_DIR : NEWGRF_DIR;
1812 if (!FioCheckFileExists(c->filename, subdir)) {
1813 Debug(grf, 0, "NewGRF file is missing '{}'; disabling", c->filename);
1814 c->status = GCS_NOT_FOUND;
1815 continue;
1816 }
1817
1818 if (stage == GLS_LABELSCAN) InitNewGRFFile(*c);
1819
1820 if (!c->flags.Test(GRFConfigFlag::Static) && !c->flags.Test(GRFConfigFlag::System)) {
1821 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
1822 Debug(grf, 0, "'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
1823 c->status = GCS_DISABLED;
1824 c->error = {STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED};
1825 continue;
1826 }
1827 num_non_static++;
1828 }
1829
1830 num_grfs++;
1831
1832 LoadNewGRFFile(*c, stage, subdir, false);
1833 if (stage == GLS_RESERVE) {
1834 c->flags.Set(GRFConfigFlag::Reserved);
1835 } else if (stage == GLS_ACTIVATION) {
1836 c->flags.Reset(GRFConfigFlag::Reserved);
1837 assert(GetFileByGRFID(c->ident.grfid) == _cur_gps.grffile);
1840 Debug(sprite, 2, "LoadNewGRF: Currently {} sprites are loaded", _cur_gps.spriteid);
1841 } else if (stage == GLS_INIT && c->flags.Test(GRFConfigFlag::InitOnly)) {
1842 /* We're not going to activate this, so free whatever data we allocated */
1844 }
1845 }
1846 }
1847
1848 /* We've finished reading files. */
1849 _cur_gps.grfconfig = nullptr;
1850 _cur_gps.grffile = nullptr;
1851
1852 /* Pseudo sprite processing is finished; free temporary stuff */
1853 _cur_gps.ClearDataForNextFile();
1854
1855 /* Call any functions that should be run after GRFs have been loaded. */
1856 AfterLoadGRFs();
1857
1858 /* Now revert back to the original situation */
1861 TimerGameCalendar::date_fract = date_fract;
1862
1863 TimerGameEconomy::year = economy_year;
1864 TimerGameEconomy::date = economy_date;
1865 TimerGameEconomy::date_fract = economy_date_fract;
1866
1867 TimerGameTick::counter = tick_counter;
1868 _display_opt = display_opt;
1869}
Class for backupping variables and making sure they are restored later.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr uint8_t FindFirstBit(T x)
Search the first set bit in a value.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
Header file for bridges.
void ResetBridges()
Reset the data been eventually changed by the grf loaded.
static constexpr CargoLabel CT_INVALID
Invalid cargo type.
Definition cargo_type.h:72
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:23
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:106
MixedCargoType
Mixed cargo types for definitions with cargo that can vary depending on climate.
Definition cargo_type.h:84
@ MCT_GRAIN_WHEAT_MAIZE
Cargo can be grain, wheat or maize.
Definition cargo_type.h:86
@ MCT_LIVESTOCK_FRUIT
Cargo can be livestock or fruit.
Definition cargo_type.h:85
@ MCT_VALUABLES_GOLD_DIAMONDS
Cargo can be valuables, gold or diamonds.
Definition cargo_type.h:87
static constexpr CargoLabel CT_PASSENGERS
Available types of cargo Labels may be re-used between different climates.
Definition cargo_type.h:31
static const CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:75
std::span< const CargoLabel > GetClimateDependentCargoTranslationTable()
Get default climate-dependent cargo translation table for a NewGRF, used if the NewGRF does not provi...
bool IsDefaultCargo(CargoType cargo_type)
Test if a cargo is a default cargo type.
CargoTypes _standard_cargo_mask
Bitmask of real cargo types available.
Definition cargotype.cpp:36
std::span< const CargoLabel > GetClimateIndependentCargoTranslationTable()
Get default climate-independent cargo translation table for a NewGRF, used if the NewGRF does not pro...
void SetupCargoForClimate(LandscapeType l)
Set up the default cargo types for the given landscape type.
Definition cargotype.cpp:62
void InitializeSortedCargoSpecs()
Initialize the list of sorted cargo specifications.
CargoTypes _cargo_mask
Bitmask of cargo types available.
Definition cargotype.cpp:31
@ Bulk
Bulk cargo (Coal, Grain etc., Ores, Fruit)
@ Mail
Mail.
@ Liquid
Liquids (Oil, Water, Rubber)
@ Passengers
Passengers.
@ Armoured
Armoured cargo (Valuables, Gold, Diamonds)
@ Refrigerated
Refrigerated cargo (Food, Fruit)
@ Express
Express cargo (Goods, Food, Candy, but also possible for passengers)
@ PieceGoods
Piece goods (Livestock, Wood, Steel, Paper)
@ INVALID_TPE
Invalid town production effect.
Definition cargotype.h:45
@ TPE_NONE
Town will not produce this cargo type.
Definition cargotype.h:36
@ TPE_PASSENGERS
Cargo behaves passenger-like for production.
Definition cargotype.h:37
@ TPE_MAIL
Cargo behaves mail-like for production.
Definition cargotype.h:38
BadgeID index
Index assigned to badge.
GrfSpecFeatures features
Bitmask of which features use this badge.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Timpl & Set()
Set all bits.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Class to read from a NewGRF file.
Enum-as-bit-set wrapper.
void SetEntitySpec(HouseSpec &&hs)
Install the specs into the HouseSpecs array It will find itself the proper slot on which it will go.
void SetEntitySpec(IndustrySpec &&inds)
Method to install the new industry data in its proper slot The slot assignment is internal of this me...
static void Reset()
Reset the classes, i.e.
void SetEntitySpec(ObjectSpec &&spec)
Method to install the new object data in its proper slot The slot assignment is internal of this meth...
void ResetMapping()
Resets the mapping, which is used while initializing game.
RailTypeLabel label
Unique 32 bit rail type identifier.
Definition rail.h:227
void ReadBlock(void *ptr, size_t size)
Read a block.
void SeekTo(size_t pos, int mode)
Seek in the current file.
uint8_t ReadByte()
Read a byte from the file.
uint32_t ReadDword()
Read a double word (32 bits) from the file (in low endian format).
void SkipBytes(size_t n)
Skip n bytes ahead in the file.
uint16_t ReadWord()
Read a word (16 bits) from the file (in low endian format).
A sort-of mixin that adds 'at(pos)' and 'operator[](pos)' implementations for 'ConvertibleThroughBase...
A reusable buffer that can be used for places that temporary allocate a bit of memory and do that ver...
T * Allocate(size_t count)
Get buffer of at least count times T.
RandomAccessFile with some extra information specific for sprite files.
uint8_t GetContainerVersion() const
Get the version number of container type used by the file.
static Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
static Date date
Current date in days (day counter).
static Year year
Current year, starting at 0.
static DateFract date_fract
Fractional part of the day.
static constexpr TimerGame< struct Calendar >::Year MIN_YEAR
The absolute minimum year in OTTD.
static constexpr TimerGame< struct Calendar >::Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date,...
static Date date
Current date in days (day counter).
static Year year
Current year, starting at 0.
static DateFract date_fract
Fractional part of the day.
static Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
static TickCounter counter
Monotonic counter, in ticks, since start of game.
uint16_t DateFract
The fraction of a date we're in, i.e.
Configuration options of the network stuff.
static const uint NETWORK_MAX_GRF_COUNT
Maximum number of GRFs that can be sent.
Definition config.h:90
Some simple functions to help with accessing containers.
int find_index(Container const &container, typename Container::const_reference item)
Helper function to get the index of an item Consider using std::set, std::unordered_set or std::flat_...
void ResetCurrencies(bool preserve_custom)
Will fill _currency_specs array with default values from origin_currency_specs Called only from newgr...
Definition currency.cpp:162
Functions to handle different currencies.
Functions related to debugging.
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
void SetPriceBaseMultiplier(Price price, int factor)
Change a price base by the given factor.
Definition economy.cpp:885
void ResetPriceBaseMultipliers()
Reset changes to the price base multipliers.
Definition economy.cpp:873
Price
Enumeration of all base prices for use with Prices.
void SetYearEngineAgingStops()
Compute the value for _year_engine_aging_stops.
Definition engine.cpp:693
const uint8_t _engine_counts[4]
Number of engines of each vehicle type in original engine data.
Definition engine.cpp:54
void SetupEngines()
Initialise the engine pool with the data from the original vehicles.
Definition engine.cpp:601
Base class for engines.
@ HasVariants
Set if engine has variants.
@ IsFolded
Set if display of variants should be folded (hidden).
Functions related to engines.
@ RoadIsTram
Road vehicle is a tram/light rail vehicle.
@ RAILVEH_WAGON
simple wagon, not motorized
Definition engine_type.h:34
Error reporting related functions.
bool FioCheckFileExists(std::string_view filename, Subdirectory subdir)
Check whether the given file exists.
Definition fileio.cpp:121
Functions for Standard In/Out file operations.
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition fileio_type.h:87
@ NEWGRF_DIR
Subdirectory for all NewGRFs.
Definition fileio_type.h:96
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
Definition fileio_type.h:95
Functions related to world/map generation.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
void ClearSnowLine()
Clear the variable snow line table and free the memory.
HouseZones GetClimateMaskForLandscape()
Get the HouseZones climate mask for the current landscape type.
static const HouseID NUM_HOUSES
Total number of houses.
Definition house.h:29
HouseZone
Definition house.h:55
void ResetIndustries()
This function initialize the spec arrays of both industry and industry tiles.
void SortIndustryTypes()
Initialize the list of sorted industry types.
Industry type specs.
Functions related to OTTD's landscape.
LandscapeType
Landscape types.
LiveryScheme
List of different livery schemes.
Definition livery.h:21
bool _networking
are we in networking mode?
Definition network.cpp:67
static void FinaliseObjectsArray()
Add all new objects to the object array.
Definition newgrf.cpp:1148
static void FinalisePriceBaseMultipliers()
Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them...
Definition newgrf.cpp:1461
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:604
static void FinaliseIndustriesArray()
Add all new industries to the industry array.
Definition newgrf.cpp:1094
std::span< const CargoLabel > GetCargoTranslationTable(const GRFFile &grffile)
Get the cargo translation table to use for the given GRF file.
Definition newgrf.cpp:513
static std::vector< GRFFile > _grf_files
List of all loaded GRF files.
Definition newgrf.cpp:62
void ResetPersistentNewGRFData()
Reset NewGRF data which is stored persistently in savegames.
Definition newgrf.cpp:497
static void FinaliseAirportsArray()
Add all new airports to the airport array.
Definition newgrf.cpp:1170
static GRFFile * GetFileByFilename(const std::string &filename)
Obtain a NewGRF file by its filename.
Definition newgrf.cpp:115
GRFFile * GetCurrentGRFOverride()
Get overridden GRF for current GRF if present.
Definition newgrf.cpp:192
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:327
void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
Set the override for a NewGRF.
Definition newgrf.cpp:177
void GRFUnsafe(ByteReader &)
Set the current NewGRF as unsafe for static use.
Definition newgrf.cpp:368
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:210
static void ActivateOldShore()
Relocates the old shore sprites at new positions.
Definition newgrf.cpp:1409
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:995
static void FinaliseEngineArray()
Check for invalid engines.
Definition newgrf.cpp:846
ReferenceThroughBaseContainer< std::vector< GRFTempEngineData > > _gted
Temporary engine data used during NewGRF loading.
Definition newgrf.cpp:77
static void ResetNewGRFErrors()
Clear all NewGRF errors.
Definition newgrf.cpp:390
static void LoadNewGRFFileFromFile(GRFConfig &config, GrfLoadingStage stage, SpriteFile &file)
Load a particular NewGRF from a SpriteFile.
Definition newgrf.cpp:1277
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition newgrf.cpp:73
void LoadNewGRF(SpriteID load_index, uint num_baseset)
Load all the NewGRFs.
Definition newgrf.cpp:1735
static void ClearTemporaryNewGRFData(GRFFile *gf)
Reset all NewGRFData that was used only while processing data.
Definition newgrf.cpp:123
void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig &c)
Disable a static NewGRF when it is influencing another (non-static) NewGRF as this could cause desync...
Definition newgrf.cpp:164
static void FinaliseCanals()
Set to use the correct action0 properties for each canal feature.
Definition newgrf.cpp:835
void ResetNewGRFData()
Reset all NewGRF loaded data.
Definition newgrf.cpp:403
static void CalculateRefitMasks()
Precalculate refit masks from cargo classes for all vehicles.
Definition newgrf.cpp:639
void FinaliseCargoArray()
Check for invalid cargoes.
Definition newgrf.cpp:919
static void BuildCargoTranslationMap()
Construct the Cargo Mapping.
Definition newgrf.cpp:529
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:89
EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal_id)
Return the ID of a new engine.
Definition newgrf.cpp:291
GRFFile * GetFileByGRFID(uint32_t grfid)
Obtain a NewGRF file by its grfID.
Definition newgrf.cpp:103
GrfMiscBits _misc_grf_features
Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E.
Definition newgrf.cpp:70
static void FinaliseHouseArray()
Add all new houses to the house array.
Definition newgrf.cpp:1020
static void InitNewGRFFile(const GRFConfig &config)
Prepare loading a NewGRF file with its config.
Definition newgrf.cpp:546
static void ActivateOldTramDepot()
Replocate the old tram depot sprites to the new position, if no new ones were loaded.
Definition newgrf.cpp:1446
void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
Load a particular NewGRF.
Definition newgrf.cpp:1373
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:949
static void AfterLoadGRFs()
Finish loading NewGRFs and execute needed post-processing.
Definition newgrf.cpp:1614
GRFError * DisableGrf(StringID message, GRFConfig *config)
Disable a GRF.
Definition newgrf.cpp:134
static void ResetNewGRF()
Reset and clear all NewGRFs.
Definition newgrf.cpp:377
void InitGRFTownGeneratorNames()
Allocate memory for the NewGRF town names.
CargoTypes TranslateRefitMask(uint32_t refit_mask)
Translate the refit mask.
Definition newgrf.cpp:310
static void FinaliseBadges()
Finish up applying badges to things.
Definition newgrf.cpp:1585
@ SHORE_REPLACE_ACTION_A
Shore sprites were replaced by ActionA (using grass tiles for the corner-shores).
Definition newgrf.h:178
@ SHORE_REPLACE_NONE
No shore sprites were replaced.
Definition newgrf.h:176
@ SHORE_REPLACE_ACTION_5
Shore sprites were replaced by Action5.
Definition newgrf.h:177
@ TRAMWAY_REPLACE_DEPOT_WITH_TRACK
Electrified depot graphics with tram track were loaded.
Definition newgrf.h:184
@ TRAMWAY_REPLACE_DEPOT_NONE
No tram depot graphics were loaded.
Definition newgrf.h:183
GrfSpecFeature
Definition newgrf.h:69
void InitializePatchFlags()
Initialize the TTDPatch flags.
void BindAirportSpecs()
Tie all airportspecs to their class.
NewGRF handling of airports.
NewGRF handling of airport tiles.
void ApplyBadgeFeaturesToClassBadges()
Apply features from all badges to their badge classes.
void AppendCopyableBadgeList(std::vector< BadgeID > &dst, std::span< const BadgeID > src, GrfSpecFeature feature)
Append copyable badges from a list onto another.
Badge * GetBadgeByLabel(std::string_view label)
Get a badge by label if it exists.
void ResetBadges()
Reset badges to the default state.
Functions related to NewGRF badges.
void AddBadgeClassesToConfiguration()
Add current badge classes to user configuration.
Functions related to NewGRF badge configuration.
NewGRF buffer reader definition.
@ CustomRefit
Custom refit mask.
@ CBID_VEHICLE_CUSTOM_REFIT
Called to get custom engine refit mask.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
std::array< WaterFeature, CF_END > _water_feature
Table of canal 'feature' sprite groups.
Handling of NewGRF canals.
CargoType GetCargoTranslation(uint8_t cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoType.
Cargo support for NewGRFs.
void ErrorUnknownCallbackResult(uint32_t grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
GRFConfigList _grfconfig
First item in list of current GRF set up.
@ GCS_INITIALISED
GRF file has been initialised.
@ GCS_DISABLED
GRF file is disabled.
@ GCS_NOT_FOUND
GRF file was not found in the local cache.
@ GCS_UNKNOWN
The status of this grf file is unknown.
@ GCS_ACTIVATED
GRF file has been activated.
@ InitOnly
GRF file is processed up to GLS_INIT.
@ Reserved
GRF file passed GLS_RESERVE stage.
@ System
GRF file is an openttd-internal system grf.
@ Static
GRF file is used statically (can be used in any MP game)
@ Unsafe
GRF file is unsafe for static usage.
@ GRFP_USE_MASK
Bitmask to get only the use palette use states.
uint16_t GetVehicleCallback(CallbackID callback, uint32_t param1, uint32_t param2, EngineID engine, const Vehicle *v, std::span< int32_t > regs100)
Evaluate a newgrf callback for vehicles.
void CommitVehicleListOrderChanges()
Determine default engine sorting and execute recorded ListOrderChanges from AlterVehicleListOrder.
Functions for NewGRF engines.
void ResetGenericCallbacks()
Reset all generic feature callback sprite groups.
IndustryType MapNewGRFIndustryType(IndustryType grf_type, uint32_t grf_id)
Map the GRF local type to an industry type.
Functions for NewGRF industries.
NewGRF internal processing state.
NewGRF internal processing state for vehicles.
void ResetObjects()
This function initialize the spec arrays of objects.
Functions related to NewGRF objects.
NewGRF definitions and structures for road stops.
Functions related to NewGRF provided sounds.
Header file for NewGRF stations.
void FinaliseStringMapping()
Finalise all string mappings.
NewGRF string mapping definition.
void CleanUpStrings()
House cleaning.
Header of Action 04 "universal holder" structure and functions.
Header of Action 0F "universal holder" structure and functions.
RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels)
Get the rail type for a given label.
Definition rail.cpp:313
void InitRailTypes()
Resolve sprites of custom rail types.
Definition rail_cmd.cpp:130
void ResetRailTypes()
Reset all rail type information to its default values.
Definition rail_cmd.cpp:65
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition rail.h:300
RailType
Enumeration for all possible railtypes.
Definition rail_type.h:25
@ RAILTYPE_MONO
Monorail.
Definition rail_type.h:29
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition rail_type.h:32
@ RAILTYPE_ELECTRIC
Electric rails.
Definition rail_type.h:28
@ RAILTYPE_RAIL
Standard non-electric rails.
Definition rail_type.h:27
@ RAILTYPE_MAGLEV
Maglev.
Definition rail_type.h:30
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
Get the road type for a given label.
Definition road.cpp:253
Road specific functions.
void ResetRoadTypes()
Reset all road type information to its default values.
Definition road_cmd.cpp:63
void InitRoadTypes()
Resolve sprites of custom road types.
Definition road_cmd.cpp:111
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:230
RoadType
The different roadtypes we support.
Definition road_type.h:23
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
@ ROADTYPE_TRAM
Trams.
Definition road_type.h:26
@ ROADTYPE_ROAD
Basic road type.
Definition road_type.h:25
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
void BuildLinkStatsLegend()
Populate legend table for the link stat view.
void BuildIndustriesLegend()
Fills an array for the industries legends.
Smallmap GUI functions.
SpriteFile & OpenCachedSpriteFile(const std::string &filename, Subdirectory subdir, bool palette_remap)
Open/get the SpriteFile that is cached for use in the sprite cache.
bool SkipSpriteData(SpriteFile &file, uint8_t type, uint16_t num)
Skip the given amount of sprite graphics data.
void ReadGRFSpriteOffsets(SpriteFile &file)
Parse the sprite section of GRFs.
Functions to cache sprites in memory.
static const SpriteID SPR_SHORE_BASE
shore tiles - action 05-0D
Definition sprites.h:226
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static void ResetAirports()
This function initializes the airportspec array.
static void ResetAirportTiles()
This function initializes the tile array of AirportTileSpec.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Specification of a cargo type.
Definition cargotype.h:74
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:192
static CargoSpec array[NUM_CARGO]
Array holding all CargoSpecs.
Definition cargotype.h:198
Information about a vehicle.
LandscapeTypes climates
Climates supported by the engine.
void ResetToDefaultMapping()
Initializes the EngineOverrideManager with the default engines.
Definition engine.cpp:509
EngineID UseUnreservedID(VehicleType type, uint16_t grf_local_id, uint32_t grfid, bool static_access)
Look for an unreserved EngineID matching the local id, and reserve it if found.
Definition engine.cpp:549
EngineID GetID(VehicleType type, uint16_t grf_local_id, uint32_t grfid)
Looks up an EngineID in the EngineOverrideManager.
Definition engine.cpp:530
static Pool::IterateWrapperFiltered< Engine, EngineTypeFilter > IterateType(VehicleType vt, size_t from=0)
Returns an iterable ensemble of all valid engines of the given type.
CargoGRFFileProps grf_prop
Link to NewGRF.
Definition engine_base.h:77
Information about GRF, used in the game and (part of it) in savegames.
uint8_t palette
GRFPalette, bitset.
std::vector< uint32_t > param
GRF parameters.
GRFStatus status
NOSAVE: GRFStatus, enum.
std::optional< GRFError > error
NOSAVE: Error/Warning during GRF loading (Action 0x0B)
GRFConfigFlags flags
NOSAVE: GCF_Flags, bitset.
std::string filename
Filename - either with or without full path.
GRFIdentifier ident
grfid and md5sum to uniquely identify newgrfs
std::string GetName() const
Get the name of this grf.
Information about why GRF had problems during initialisation.
std::string data
Additional data for message and custom_message.
uint16_t local_id
id defined by the grf file for this entity
void SetGRFFile(const struct GRFFile *grffile)
Set the NewGRF file, and its grfid, associated with grf props.
bool HasGrfFile() const
Test if this entity was introduced by NewGRF.
Dynamic data of a loaded NewGRF.
Definition newgrf.h:115
std::array< uint8_t, NUM_CARGO > cargo_map
Inverse cargo translation table (CargoType -> local ID)
Definition newgrf.h:137
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road)
Definition newgrf.h:145
std::vector< RoadTypeLabel > tramtype_list
Roadtype translation table (tram)
Definition newgrf.h:148
std::vector< CargoLabel > cargo_list
Cargo translation table (local ID -> label)
Definition newgrf.h:136
uint traininfo_vehicle_width
Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details.
Definition newgrf.h:156
GrfSpecFeatures grf_features
Bitset of GrfSpecFeature the grf uses.
Definition newgrf.h:158
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
Definition newgrf.h:155
std::unordered_map< uint8_t, LanguageMap > language_map
Mappings related to the languages.
Definition newgrf.h:153
std::vector< GRFLabel > labels
List of labels.
Definition newgrf.h:134
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition newgrf.h:159
uint32_t grfid
GRF ID (defined by Action 0x08)
bool has_2CC
Set if any vehicle is loaded which uses 2cc (two company colours).
Definition newgrf.h:189
ShoreReplacement shore
In which way shore sprites were replaced.
Definition newgrf.h:191
uint64_t used_liveries
Bitmask of LiveryScheme used by the defined engines.
Definition newgrf.h:190
TramReplacement tram
In which way tram depots were replaced.
Definition newgrf.h:192
@ NONEMPTY
GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not av...
LandscapeType landscape
the landscape we're currently in
TimerGameCalendar::Year starting_year
starting date
GameCreationSettings game_creation
settings used during the creation of a game (map)
VehicleSettings vehicle
options for vehicles
GRF action handler.
Temporary data during loading of GRFs.
SpriteFile * file
File of currently processed GRF file.
GRFFile * grffile
Currently processed GRF file.
uint32_t nfo_line
Currently processed pseudo sprite number in the GRF.
SpriteID spriteid
First available SpriteID for loading realsprites.
GRFConfig * grfconfig
Config of the currently processed GRF file.
void ClearDataForNextFile()
Clear temporary data before processing the next file in the current loading stage.
GrfLoadingStage stage
Current loading stage.
int skip_sprites
Number of pseudo sprites to skip before processing the next one. (-1 to skip to end of file)
CargoType accepts_cargo[HOUSE_NUM_ACCEPTS]
input cargo slots
Definition house.h:108
SubstituteGRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:114
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:111
CargoLabel accepts_cargo_label[HOUSE_ORIGINAL_NUM_ACCEPTS]
input landscape cargo slots
Definition house.h:126
static HouseSpec * Get(size_t house_id)
Get the spec for a house ID.
BuildingFlags building_flags
some flags that describe the house (size, stadium etc...)
Definition house.h:109
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:102
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:107
HouseZones building_availability
where can it be built (climates, zones)
Definition house.h:110
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Helper class to invoke a GrfActionHandler.
Definition newgrf.cpp:1194
Mapping of language data between a NewGRF and OpenTTD.
static const LanguageMap * GetLanguageMap(uint32_t grfid, uint8_t language_id)
Get the language map associated with a given NewGRF and language.
Definition newgrf.cpp:352
static void BindToClasses()
Tie all ObjectSpecs to their class.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static size_t GetPoolSize()
Returns first unused index.
static Titem * Get(auto index)
Returns Titem with given index.
Tindex index
Index of this pool item.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
void CleanPool() override
Virtual method that deletes all items in the pool.
Describes properties of price bases.
Definition newgrf.h:198
Price fallback_price
Fallback price multiplier for new prices but old grfs.
Definition newgrf.h:202
GrfSpecFeature grf_feature
GRF Feature that decides whether price multipliers apply locally or globally, GSF_END if none.
Definition newgrf.h:201
RailType railtype
Railtype, mangled if elrail is disabled.
Definition engine_type.h:51
Iterable ensemble of each set bit in a value.
bool dynamic_engines
enable dynamic allocation of engine data
Base of the town class.
uint8_t _display_opt
What do we want to draw/do?
LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
Determines the LiveryScheme for a vehicle.
Definition vehicle.cpp:1940
Base class for all vehicles.
VehicleType
Available vehicle types.
@ VEH_ROAD
Road vehicle type.
@ VEH_AIRCRAFT
Aircraft vehicle type.
@ VEH_SHIP
Ship vehicle type.
@ VEH_TRAIN
Train vehicle type.