OpenTTD Source 20250426-master-gbb1d561369
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_cargo.h"
26#include "newgrf_sound.h"
27#include "newgrf_station.h"
28#include "industrytype.h"
29#include "newgrf_canal.h"
30#include "newgrf_townname.h"
31#include "newgrf_industries.h"
32#include "newgrf_airporttiles.h"
33#include "newgrf_airport.h"
34#include "newgrf_object.h"
35#include "network/core/config.h"
36#include "smallmap_gui.h"
37#include "genworld.h"
38#include "error_func.h"
39#include "vehicle_base.h"
40#include "road.h"
41#include "newgrf_roadstop.h"
46
47#include "table/strings.h"
48
49#include "safeguards.h"
50
51/* TTDPatch extended GRF format codec
52 * (c) Petr Baudis 2004 (GPL'd)
53 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
54 *
55 * Contains portions of documentation by TTDPatch team.
56 * Thanks especially to Josef Drexler for the documentation as well as a lot
57 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
58 * served as subject to the initial testing of this codec. */
59
61static std::vector<GRFFile> _grf_files;
62
63std::span<const GRFFile> GetAllGRFFiles()
64{
65 return _grf_files;
66}
67
70
73
74GrfProcessingState _cur_gps;
75
77
88void GrfMsgI(int severity, const std::string &msg)
89{
90 if (_cur_gps.grfconfig == nullptr) {
91 Debug(grf, severity, "{}", msg);
92 } else {
93 Debug(grf, severity, "[{}:{}] {}", _cur_gps.grfconfig->filename, _cur_gps.nfo_line, msg);
94 }
95}
96
102GRFFile *GetFileByGRFID(uint32_t grfid)
103{
104 auto it = std::ranges::find(_grf_files, grfid, &GRFFile::grfid);
105 if (it != std::end(_grf_files)) return &*it;
106 return nullptr;
107}
108
114static GRFFile *GetFileByFilename(const std::string &filename)
115{
116 auto it = std::ranges::find(_grf_files, filename, &GRFFile::filename);
117 if (it != std::end(_grf_files)) return &*it;
118 return nullptr;
119}
120
123{
124 gf->labels.clear();
125}
126
134{
135 GRFFile *file;
136 if (config != nullptr) {
137 file = GetFileByGRFID(config->ident.grfid);
138 } else {
139 config = _cur_gps.grfconfig;
140 file = _cur_gps.grffile;
141 }
142
143 config->status = GCS_DISABLED;
144 if (file != nullptr) ClearTemporaryNewGRFData(file);
145 if (config == _cur_gps.grfconfig) _cur_gps.skip_sprites = -1;
146
147 if (message == STR_NULL) return nullptr;
148
149 config->error = {STR_NEWGRF_ERROR_MSG_FATAL, message};
150 if (config == _cur_gps.grfconfig) config->error->param_value[0] = _cur_gps.nfo_line;
151 return &config->error.value();
152}
153
164{
165 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, &c);
166 error->data = _cur_gps.grfconfig->GetName();
167}
168
169static std::map<uint32_t, uint32_t> _grf_id_overrides;
170
176void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
177{
178 if (target_grfid == 0) {
179 _grf_id_overrides.erase(source_grfid);
180 GrfMsg(5, "SetNewGRFOverride: Removed override of 0x{:X}", std::byteswap(source_grfid));
181 } else {
182 _grf_id_overrides[source_grfid] = target_grfid;
183 GrfMsg(5, "SetNewGRFOverride: Added override of 0x{:X} to 0x{:X}", std::byteswap(source_grfid), std::byteswap(target_grfid));
184 }
185}
186
192{
193 auto found = _grf_id_overrides.find(_cur_gps.grffile->grfid);
194 if (found != std::end(_grf_id_overrides)) {
195 GRFFile *grffile = GetFileByGRFID(found->second);
196 if (grffile != nullptr) return grffile;
197 }
198 return nullptr;
199}
200
209Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16_t internal_id, bool static_access)
210{
211 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
212 * them use the same engine slots. */
213 uint32_t scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
215 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
216 scope_grfid = file->grfid;
217 if (auto it = _grf_id_overrides.find(file->grfid); it != std::end(_grf_id_overrides)) {
218 scope_grfid = it->second;
219 const GRFFile *grf_match = GetFileByGRFID(scope_grfid);
220 if (grf_match == nullptr) {
221 GrfMsg(5, "Tried mapping from GRFID {:x} to {:x} but target is not loaded", std::byteswap(file->grfid), std::byteswap(scope_grfid));
222 } else {
223 GrfMsg(5, "Mapping from GRFID {:x} to {:x}", std::byteswap(file->grfid), std::byteswap(scope_grfid));
224 }
225 }
226
227 /* Check if the engine is registered in the override manager */
228 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
229 if (engine != EngineID::Invalid()) {
230 Engine *e = Engine::Get(engine);
231 if (!e->grf_prop.HasGrfFile()) {
232 e->grf_prop.SetGRFFile(file);
233 }
234 return e;
235 }
236 }
237
238 /* Check if there is an unreserved slot */
239 EngineID engine = _engine_mngr.UseUnreservedID(type, internal_id, scope_grfid, static_access);
240 if (engine != EngineID::Invalid()) {
241 Engine *e = Engine::Get(engine);
242
243 if (!e->grf_prop.HasGrfFile()) {
244 e->grf_prop.SetGRFFile(file);
245 GrfMsg(5, "Replaced engine at index {} for GRFID {:x}, type {}, index {}", e->index, std::byteswap(file->grfid), type, internal_id);
246 }
247
248 return e;
249 }
250
251 if (static_access) return nullptr;
252
254 GrfMsg(0, "Can't allocate any more engines");
255 return nullptr;
256 }
257
258 size_t engine_pool_size = Engine::GetPoolSize();
259
260 /* ... it's not, so create a new one based off an existing engine */
261 Engine *e = new Engine(type, internal_id);
262 e->grf_prop.SetGRFFile(file);
263
264 /* Reserve the engine slot */
265 _engine_mngr.SetID(type, internal_id, scope_grfid, std::min<uint8_t>(internal_id, _engine_counts[type]), e->index);
266
267 if (engine_pool_size != Engine::GetPoolSize()) {
268 /* Resize temporary engine data ... */
269 _gted.resize(Engine::GetPoolSize());
270 }
271 if (type == VEH_TRAIN) {
272 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
273 }
274
275 GrfMsg(5, "Created new engine at index {} for GRFID {:x}, type {}, index {}", e->index, std::byteswap(file->grfid), type, internal_id);
276
277 return e;
278}
279
290EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal_id)
291{
292 uint32_t scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
294 scope_grfid = file->grfid;
295 if (auto it = _grf_id_overrides.find(file->grfid); it != std::end(_grf_id_overrides)) {
296 scope_grfid = it->second;
297 }
298 }
299
300 return _engine_mngr.GetID(type, internal_id, scope_grfid);
301}
302
303
304
305
309CargoTypes TranslateRefitMask(uint32_t refit_mask)
310{
311 CargoTypes result = 0;
312 for (uint8_t bit : SetBitIterator(refit_mask)) {
313 CargoType cargo = GetCargoTranslation(bit, _cur_gps.grffile, true);
314 if (IsValidCargoType(cargo)) SetBit(result, cargo);
315 }
316 return result;
317}
318
326void ConvertTTDBasePrice(uint32_t base_pointer, const char *error_location, Price *index)
327{
328 /* Special value for 'none' */
329 if (base_pointer == 0) {
330 *index = INVALID_PRICE;
331 return;
332 }
333
334 static const uint32_t start = 0x4B34;
335 static const uint32_t size = 6;
336
337 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
338 GrfMsg(1, "{}: Unsupported running cost base 0x{:04X}, ignoring", error_location, base_pointer);
339 return;
340 }
341
342 *index = (Price)((base_pointer - start) / size);
343}
344
351/* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32_t grfid, uint8_t language_id)
352{
353 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
354 const GRFFile *grffile = GetFileByGRFID(grfid);
355 if (grffile == nullptr) return nullptr;
356
357 auto it = grffile->language_map.find(language_id);
358 if (it == std::end(grffile->language_map)) return nullptr;
359
360 return &it->second;
361}
362
368{
370
371 /* Skip remainder of GRF */
372 _cur_gps.skip_sprites = -1;
373}
374
376static void ResetNewGRF()
377{
378 _cur_gps.grfconfig = nullptr;
379 _cur_gps.grffile = nullptr;
380 _grf_files.clear();
381
382 /* We store pointers to GRFFiles in many places, so need to ensure that the pointers do not become invalid
383 * due to vector reallocation. Should not happen due to loading taking place in multiple stages, but
384 * reserving when the size is known is good practice anyway. */
385 _grf_files.reserve(_grfconfig.size());
386}
387
389static void ResetNewGRFErrors()
390{
391 for (const auto &c : _grfconfig) {
392 c->error.reset();
393 }
394}
395
396extern void ResetCallbacks(bool final);
397extern void ResetGRM();
398
403{
405 CleanUpGRFTownNames();
406
407 ResetBadges();
408
409 /* Copy/reset original engine info data */
410 SetupEngines();
411
412 /* Copy/reset original bridge info data */
413 ResetBridges();
414
415 /* Reset rail type information */
417
418 /* Copy/reset original road type info data */
420
421 /* Allocate temporary refit/cargo class data */
422 _gted.resize(Engine::GetPoolSize());
423
424 /* Fill rail type label temporary data for default trains */
425 for (const Engine *e : Engine::IterateType(VEH_TRAIN)) {
426 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
427 }
428
429 /* Reset GRM reservations */
430 ResetGRM();
431
432 /* Reset generic feature callback lists */
434
435 /* Reset price base data */
437
438 /* Reset the curencies array */
440
441 /* Reset the house array */
442 ResetHouses();
443
444 /* Reset the industries structures*/
446
447 /* Reset the objects. */
449 ResetObjects();
450
451 /* Reset station classes */
453
454 /* Reset airport-related structures */
458
459 /* Reset road stop classes */
461
462 /* Reset canal sprite groups and flags */
463 _water_feature.fill({});
464
465 /* Reset the snowline table. */
467
468 /* Reset NewGRF files */
469 ResetNewGRF();
470
471 /* Reset NewGRF errors. */
473
474 /* Set up the default cargo types */
476
477 /* Reset misc GRF features and train list display variables */
479
481 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
484
485 /* Clear all GRF overrides */
486 _grf_id_overrides.clear();
487
488 InitializeSoundPool();
489 _spritegroup_pool.CleanPool();
490 ResetCallbacks(false);
491}
492
497{
498 /* Reset override managers */
499 _engine_mngr.ResetToDefaultMapping();
500 _house_mngr.ResetMapping();
501 _industry_mngr.ResetMapping();
502 _industile_mngr.ResetMapping();
503 _airport_mngr.ResetMapping();
504 _airporttile_mngr.ResetMapping();
505}
506
512 std::span<const CargoLabel> GetCargoTranslationTable(const GRFFile &grffile)
513 {
514 /* Always use the translation table if it's installed. */
515 if (!grffile.cargo_list.empty()) return grffile.cargo_list;
516
517 /* Pre-v7 use climate-dependent "slot" table. */
518 if (grffile.grf_version < 7) return GetClimateDependentCargoTranslationTable();
519
520 /* Otherwise use climate-independent "bitnum" table. */
522 }
523
529{
530 _cur_gps.grffile->cargo_map.fill(UINT8_MAX);
531
532 auto cargo_list = GetCargoTranslationTable(*_cur_gps.grffile);
533
534 for (const CargoSpec *cs : CargoSpec::Iterate()) {
535 /* Check the translation table for this cargo's label */
536 int idx = find_index(cargo_list, cs->label);
537 if (idx >= 0) _cur_gps.grffile->cargo_map[cs->Index()] = idx;
538 }
539}
540
545static void InitNewGRFFile(const GRFConfig &config)
546{
547 GRFFile *newfile = GetFileByFilename(config.filename);
548 if (newfile != nullptr) {
549 /* We already loaded it once. */
550 _cur_gps.grffile = newfile;
551 return;
552 }
553
554 assert(_grf_files.size() < _grf_files.capacity()); // We must not invalidate pointers.
555 _cur_gps.grffile = &_grf_files.emplace_back(config);
556}
557
562GRFFile::GRFFile(const GRFConfig &config)
563{
564 this->filename = config.filename;
565 this->grfid = config.ident.grfid;
566
567 /* Initialise local settings to defaults */
568 this->traininfo_vehicle_pitch = 0;
569 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
570
571 /* Mark price_base_multipliers as 'not set' */
572 this->price_base_multipliers.fill(INVALID_PRICE_MODIFIER);
573
574 /* Initialise rail type map with default rail types */
575 this->railtype_map.fill(INVALID_RAILTYPE);
576 this->railtype_map[0] = RAILTYPE_RAIL;
577 this->railtype_map[1] = RAILTYPE_ELECTRIC;
578 this->railtype_map[2] = RAILTYPE_MONO;
579 this->railtype_map[3] = RAILTYPE_MAGLEV;
580
581 /* Initialise road type map with default road types */
582 this->roadtype_map.fill(INVALID_ROADTYPE);
583 this->roadtype_map[0] = ROADTYPE_ROAD;
584
585 /* Initialise tram type map with default tram types */
586 this->tramtype_map.fill(INVALID_ROADTYPE);
587 this->tramtype_map[0] = ROADTYPE_TRAM;
588
589 /* Copy the initial parameter list */
590 this->param = config.param;
591}
592
593/* Some compilers get confused about vectors of unique_ptrs. */
594GRFFile::GRFFile() = default;
595GRFFile::GRFFile(GRFFile &&other) = default;
596GRFFile::~GRFFile() = default;
597
603static CargoLabel GetActiveCargoLabel(const std::initializer_list<CargoLabel> &labels)
604{
605 for (const CargoLabel &label : labels) {
606 CargoType cargo_type = GetCargoTypeByLabel(label);
607 if (cargo_type != INVALID_CARGO) return label;
608 }
609 return CT_INVALID;
610}
611
617static CargoLabel GetActiveCargoLabel(const std::variant<CargoLabel, MixedCargoType> &label)
618{
619 struct visitor {
620 CargoLabel operator()(const CargoLabel &label) { return label; }
621 CargoLabel operator()(const MixedCargoType &mixed)
622 {
623 switch (mixed) {
624 case MCT_LIVESTOCK_FRUIT: return GetActiveCargoLabel({CT_LIVESTOCK, CT_FRUIT});
625 case MCT_GRAIN_WHEAT_MAIZE: return GetActiveCargoLabel({CT_GRAIN, CT_WHEAT, CT_MAIZE});
626 case MCT_VALUABLES_GOLD_DIAMONDS: return GetActiveCargoLabel({CT_VALUABLES, CT_GOLD, CT_DIAMONDS});
627 default: NOT_REACHED();
628 }
629 }
630 };
631
632 return std::visit(visitor{}, label);
633}
634
639{
640 CargoTypes original_known_cargoes = 0;
641 for (CargoType cargo_type = 0; cargo_type != NUM_CARGO; ++cargo_type) {
642 if (IsDefaultCargo(cargo_type)) SetBit(original_known_cargoes, cargo_type);
643 }
644
645 for (Engine *e : Engine::Iterate()) {
646 EngineID engine = e->index;
647 EngineInfo *ei = &e->info;
648 bool only_defaultcargo;
649
650 /* Apply default cargo translation map if cargo type hasn't been set, either explicitly or by aircraft cargo handling. */
651 if (!IsValidCargoType(e->info.cargo_type)) {
652 e->info.cargo_type = GetCargoTypeByLabel(GetActiveCargoLabel(e->info.cargo_label));
653 }
654
655 /* If the NewGRF did not set any cargo properties, we apply default values. */
656 if (_gted[engine].defaultcargo_grf == nullptr) {
657 /* If the vehicle has any capacity, apply the default refit masks */
658 if (e->type != VEH_TRAIN || e->u.rail.capacity != 0) {
659 static constexpr LandscapeType T = LandscapeType::Temperate;
660 static constexpr LandscapeType A = LandscapeType::Arctic;
661 static constexpr LandscapeType S = LandscapeType::Tropic;
662 static constexpr LandscapeType Y = LandscapeType::Toyland;
663 static const struct DefaultRefitMasks {
664 LandscapeTypes climate;
665 CargoLabel cargo_label;
666 CargoClasses cargo_allowed;
667 CargoClasses cargo_disallowed;
668 } _default_refit_masks[] = {
669 {{T, A, S, Y}, CT_PASSENGERS, {CargoClass::Passengers}, {}},
670 {{T, A, S }, CT_MAIL, {CargoClass::Mail}, {}},
671 {{T, A, S }, CT_VALUABLES, {CargoClass::Armoured}, {CargoClass::Liquid}},
673 {{T, A }, CT_COAL, {CargoClass::Bulk}, {}},
674 {{ S }, CT_COPPER_ORE, {CargoClass::Bulk}, {}},
675 {{ Y}, CT_SUGAR, {CargoClass::Bulk}, {}},
676 {{T, A, S }, CT_OIL, {CargoClass::Liquid}, {}},
677 {{ Y}, CT_COLA, {CargoClass::Liquid}, {}},
680 {{ A, S }, CT_FOOD, {CargoClass::Refrigerated}, {}},
682 };
683
684 if (e->type == VEH_AIRCRAFT) {
685 /* Aircraft default to "light" cargoes */
687 _gted[engine].cargo_disallowed = {CargoClass::Liquid};
688 } else if (e->type == VEH_SHIP) {
689 CargoLabel label = GetActiveCargoLabel(ei->cargo_label);
690 switch (label.base()) {
691 case CT_PASSENGERS.base():
692 /* Ferries */
693 _gted[engine].cargo_allowed = {CargoClass::Passengers};
694 _gted[engine].cargo_disallowed = {};
695 break;
696 case CT_OIL.base():
697 /* Tankers */
698 _gted[engine].cargo_allowed = {CargoClass::Liquid};
699 _gted[engine].cargo_disallowed = {};
700 break;
701 default:
702 /* Cargo ships */
703 if (_settings_game.game_creation.landscape == LandscapeType::Toyland) {
704 /* No tanker in toyland :( */
706 _gted[engine].cargo_disallowed = {CargoClass::Passengers};
707 } else {
709 _gted[engine].cargo_disallowed = {CargoClass::Liquid, CargoClass::Passengers};
710 }
711 break;
712 }
713 e->u.ship.old_refittable = true;
714 } else if (e->type == VEH_TRAIN && e->u.rail.railveh_type != RAILVEH_WAGON) {
715 /* Train engines default to all cargoes, so you can build single-cargo consists with fast engines.
716 * Trains loading multiple cargoes may start stations accepting unwanted cargoes. */
718 _gted[engine].cargo_disallowed = {};
719 } else {
720 /* Train wagons and road vehicles are classified by their default cargo type */
721 CargoLabel label = GetActiveCargoLabel(ei->cargo_label);
722 for (const auto &drm : _default_refit_masks) {
723 if (!drm.climate.Test(_settings_game.game_creation.landscape)) continue;
724 if (drm.cargo_label != label) continue;
725
726 _gted[engine].cargo_allowed = drm.cargo_allowed;
727 _gted[engine].cargo_disallowed = drm.cargo_disallowed;
728 break;
729 }
730
731 /* All original cargoes have specialised vehicles, so exclude them */
732 _gted[engine].ctt_exclude_mask = original_known_cargoes;
733 }
734 }
735 _gted[engine].UpdateRefittability(_gted[engine].cargo_allowed.Any());
736
737 if (IsValidCargoType(ei->cargo_type)) ClrBit(_gted[engine].ctt_exclude_mask, ei->cargo_type);
738 }
739
740 /* Compute refittability */
741 {
742 CargoTypes mask = 0;
743 CargoTypes not_mask = 0;
744 CargoTypes xor_mask = ei->refit_mask;
745
746 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
747 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
748 only_defaultcargo = _gted[engine].refittability != GRFTempEngineData::NONEMPTY;
749
750 if (_gted[engine].cargo_allowed.Any()) {
751 /* Build up the list of cargo types from the set cargo classes. */
752 for (const CargoSpec *cs : CargoSpec::Iterate()) {
753 if (cs->classes.Any(_gted[engine].cargo_allowed) && cs->classes.All(_gted[engine].cargo_allowed_required)) SetBit(mask, cs->Index());
754 if (cs->classes.Any(_gted[engine].cargo_disallowed)) SetBit(not_mask, cs->Index());
755 }
756 }
757
758 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
759
760 /* Apply explicit refit includes/excludes. */
761 ei->refit_mask |= _gted[engine].ctt_include_mask;
762 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
763
764 /* Custom refit mask callback. */
765 const GRFFile *file = _gted[e->index].defaultcargo_grf;
766 if (file == nullptr) file = e->GetGRF();
767 if (file != nullptr && e->info.callback_mask.Test(VehicleCallbackMask::CustomRefit)) {
768 for (const CargoSpec *cs : CargoSpec::Iterate()) {
769 uint8_t local_slot = file->cargo_map[cs->Index()];
770 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_CUSTOM_REFIT, cs->classes.base(), local_slot, engine, nullptr);
771 switch (callback) {
772 case CALLBACK_FAILED:
773 case 0:
774 break; // Do nothing.
775 case 1: SetBit(ei->refit_mask, cs->Index()); break;
776 case 2: ClrBit(ei->refit_mask, cs->Index()); break;
777
778 default: ErrorUnknownCallbackResult(file->grfid, CBID_VEHICLE_CUSTOM_REFIT, callback);
779 }
780 }
781 }
782 }
783
784 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
785 if (IsValidCargoType(ei->cargo_type) && !HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = INVALID_CARGO;
786
787 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
788 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
789 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && IsValidCargoType(ei->cargo_type) && !HasBit(ei->refit_mask, ei->cargo_type)) {
790 ei->cargo_type = INVALID_CARGO;
791 }
792
793 /* Check if this engine's cargo type is valid. If not, set to the first refittable
794 * cargo type. Finally disable the vehicle, if there is still no cargo. */
795 if (!IsValidCargoType(ei->cargo_type) && ei->refit_mask != 0) {
796 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
797 const GRFFile *file = _gted[engine].defaultcargo_grf;
798 if (file == nullptr) file = e->GetGRF();
799 if (file != nullptr && file->grf_version >= 8 && !file->cargo_list.empty()) {
800 /* Use first refittable cargo from cargo translation table */
801 uint8_t best_local_slot = UINT8_MAX;
802 for (CargoType cargo_type : SetCargoBitIterator(ei->refit_mask)) {
803 uint8_t local_slot = file->cargo_map[cargo_type];
804 if (local_slot < best_local_slot) {
805 best_local_slot = local_slot;
806 ei->cargo_type = cargo_type;
807 }
808 }
809 }
810
811 if (!IsValidCargoType(ei->cargo_type)) {
812 /* Use first refittable cargo slot */
813 ei->cargo_type = (CargoType)FindFirstBit(ei->refit_mask);
814 }
815 }
816 if (!IsValidCargoType(ei->cargo_type) && e->type == VEH_TRAIN && e->u.rail.railveh_type != RAILVEH_WAGON && e->u.rail.capacity == 0) {
817 /* For train engines which do not carry cargo it does not matter if their cargo type is invalid.
818 * Fallback to the first available instead, if the cargo type has not been changed (as indicated by
819 * cargo_label not being CT_INVALID). */
820 if (GetActiveCargoLabel(ei->cargo_label) != CT_INVALID) {
821 ei->cargo_type = static_cast<CargoType>(FindFirstBit(_standard_cargo_mask));
822 }
823 }
824 if (!IsValidCargoType(ei->cargo_type)) ei->climates = {};
825
826 /* Clear refit_mask for not refittable ships */
827 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
828 ei->refit_mask = 0;
829 }
830 }
831}
832
834static void FinaliseCanals()
835{
836 for (uint i = 0; i < CF_END; i++) {
837 if (_water_feature[i].grffile != nullptr) {
838 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
839 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
840 }
841 }
842}
843
846{
847 for (Engine *e : Engine::Iterate()) {
848 if (e->GetGRF() == nullptr) {
849 auto found = std::ranges::find(_engine_mngr.mappings[e->type], e->index, &EngineIDMapping::engine);
850 if (found == std::end(_engine_mngr.mappings[e->type]) || found->grfid != INVALID_GRFID || found->internal_id != found->substitute_id) {
851 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
852 }
853 }
854
855 /* Do final mapping on variant engine ID. */
856 if (e->info.variant_id != EngineID::Invalid()) {
857 e->info.variant_id = GetNewEngineID(e->grf_prop.grffile, e->type, e->info.variant_id.base());
858 }
859
860 if (!e->info.climates.Test(_settings_game.game_creation.landscape)) continue;
861
862 switch (e->type) {
863 case VEH_TRAIN: AppendCopyableBadgeList(e->badges, GetRailTypeInfo(e->u.rail.railtype)->badges, GSF_TRAINS); break;
864 case VEH_ROAD: AppendCopyableBadgeList(e->badges, GetRoadTypeInfo(e->u.road.roadtype)->badges, GSF_ROADVEHICLES); break;
865 default: break;
866 }
867
868 /* Skip wagons, there livery is defined via the engine */
869 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
870 LiveryScheme ls = GetEngineLiveryScheme(e->index, EngineID::Invalid(), nullptr);
872 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
873
874 if (e->type == VEH_TRAIN) {
876 switch (ls) {
877 case LS_STEAM:
878 case LS_DIESEL:
879 case LS_ELECTRIC:
880 case LS_MONORAIL:
881 case LS_MAGLEV:
882 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
883 break;
884
885 case LS_DMU:
886 case LS_EMU:
887 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
888 break;
889
890 default: NOT_REACHED();
891 }
892 }
893 }
894 }
895
896 /* Check engine variants don't point back on themselves (either directly or via a loop) then set appropriate flags
897 * on variant engine. This is performed separately as all variant engines need to have been resolved. */
898 for (Engine *e : Engine::Iterate()) {
899 EngineID parent = e->info.variant_id;
900 while (parent != EngineID::Invalid()) {
901 parent = Engine::Get(parent)->info.variant_id;
902 if (parent != e->index) continue;
903
904 /* Engine looped back on itself, so clear the variant. */
905 e->info.variant_id = EngineID::Invalid();
906
907 GrfMsg(1, "FinaliseEngineArray: Variant of engine {:x} in '{}' loops back on itself", e->grf_prop.local_id, e->GetGRF()->filename);
908 break;
909 }
910
911 if (e->info.variant_id != EngineID::Invalid()) {
912 Engine::Get(e->info.variant_id)->display_flags.Set({EngineDisplayFlag::HasVariants, EngineDisplayFlag::IsFolded});
913 }
914 }
915}
916
919{
920 for (CargoSpec &cs : CargoSpec::array) {
921 if (cs.town_production_effect == INVALID_TPE) {
922 /* Set default town production effect by cargo label. */
923 switch (cs.label.base()) {
924 case CT_PASSENGERS.base(): cs.town_production_effect = TPE_PASSENGERS; break;
925 case CT_MAIL.base(): cs.town_production_effect = TPE_MAIL; break;
926 default: cs.town_production_effect = TPE_NONE; break;
927 }
928 }
929 if (!cs.IsValid()) {
930 cs.name = cs.name_single = cs.units_volume = STR_NEWGRF_INVALID_CARGO;
931 cs.quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
932 cs.abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
933 }
934 }
935}
936
948static bool IsHouseSpecValid(HouseSpec &hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const std::string &filename)
949{
950 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) &&
951 (next1 == nullptr || !next1->enabled || next1->building_flags.Any(BUILDING_HAS_1_TILE))) ||
952 (hs.building_flags.Any(BUILDING_HAS_4_TILES) &&
953 (next2 == nullptr || !next2->enabled || next2->building_flags.Any(BUILDING_HAS_1_TILE) ||
954 next3 == nullptr || !next3->enabled || next3->building_flags.Any(BUILDING_HAS_1_TILE)))) {
955 hs.enabled = false;
956 if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs.grf_prop.local_id);
957 return false;
958 }
959
960 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
961 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
962 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
963 if ((hs.building_flags.Any(BUILDING_HAS_2_TILES) && next1->population != 0) ||
964 (hs.building_flags.Any(BUILDING_HAS_4_TILES) && (next2->population != 0 || next3->population != 0))) {
965 hs.enabled = false;
966 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);
967 return false;
968 }
969
970 /* Substitute type is also used for override, and having an override with a different size causes crashes.
971 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
972 if (!filename.empty() && (hs.building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs.grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
973 hs.enabled = false;
974 Debug(grf, 1, "FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs.grf_prop.local_id);
975 return false;
976 }
977
978 /* Make sure that additional parts of multitile houses are not available. */
979 if (!hs.building_flags.Any(BUILDING_HAS_1_TILE) && (hs.building_availability & HZ_ZONALL) != 0 && (hs.building_availability & HZ_CLIMALL) != 0) {
980 hs.enabled = false;
981 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);
982 return false;
983 }
984
985 return true;
986}
987
994static void EnsureEarlyHouse(HouseZones bitmask)
995{
997
998 for (const auto &hs : HouseSpec::Specs()) {
999 if (!hs.enabled) continue;
1000 if ((hs.building_availability & bitmask) != bitmask) continue;
1001 if (hs.min_year < min_year) min_year = hs.min_year;
1002 }
1003
1004 if (min_year == 0) return;
1005
1006 for (auto &hs : HouseSpec::Specs()) {
1007 if (!hs.enabled) continue;
1008 if ((hs.building_availability & bitmask) != bitmask) continue;
1009 if (hs.min_year == min_year) hs.min_year = CalendarTime::MIN_YEAR;
1010 }
1011}
1012
1020{
1021 /* If there are no houses with start dates before 1930, then all houses
1022 * with start dates of 1930 have them reset to 0. This is in order to be
1023 * compatible with TTDPatch, where if no houses have start dates before
1024 * 1930 and the date is before 1930, the game pretends that this is 1930.
1025 * If there have been any houses defined with start dates before 1930 then
1026 * the dates are left alone.
1027 * On the other hand, why 1930? Just 'fix' the houses with the lowest
1028 * minimum introduction date to 0.
1029 */
1030 for (auto &file : _grf_files) {
1031 if (file.housespec.empty()) continue;
1032
1033 size_t num_houses = file.housespec.size();
1034 for (size_t i = 0; i < num_houses; i++) {
1035 auto &hs = file.housespec[i];
1036
1037 if (hs == nullptr) continue;
1038
1039 const HouseSpec *next1 = (i + 1 < num_houses ? file.housespec[i + 1].get() : nullptr);
1040 const HouseSpec *next2 = (i + 2 < num_houses ? file.housespec[i + 2].get() : nullptr);
1041 const HouseSpec *next3 = (i + 3 < num_houses ? file.housespec[i + 3].get() : nullptr);
1042
1043 if (!IsHouseSpecValid(*hs, next1, next2, next3, file.filename)) continue;
1044
1045 _house_mngr.SetEntitySpec(std::move(*hs));
1046 }
1047
1048 /* Won't be used again */
1049 file.housespec.clear();
1050 file.housespec.shrink_to_fit();
1051 }
1052
1053 for (size_t i = 0; i < HouseSpec::Specs().size(); i++) {
1054 HouseSpec *hs = HouseSpec::Get(i);
1055 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr);
1056 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr);
1057 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : nullptr);
1058
1059 /* We need to check all houses again to we are sure that multitile houses
1060 * did get consecutive IDs and none of the parts are missing. */
1061 if (!IsHouseSpecValid(*hs, next1, next2, next3, std::string{})) {
1062 /* GetHouseNorthPart checks 3 houses that are directly before
1063 * it in the house pool. If any of those houses have multi-tile
1064 * flags set it assumes it's part of a multitile house. Since
1065 * we can have invalid houses in the pool marked as disabled, we
1066 * don't want to have them influencing valid tiles. As such set
1067 * building_flags to zero here to make sure any house following
1068 * this one in the pool is properly handled as 1x1 house. */
1069 hs->building_flags = {};
1070 }
1071
1072 /* Apply default cargo translation map for unset cargo slots */
1073 for (uint i = 0; i < lengthof(hs->accepts_cargo_label); ++i) {
1074 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->accepts_cargo[i] = GetCargoTypeByLabel(hs->accepts_cargo_label[i]);
1075 /* Disable acceptance if cargo type is invalid. */
1076 if (!IsValidCargoType(hs->accepts_cargo[i])) hs->cargo_acceptance[i] = 0;
1077 }
1078 }
1079
1081 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
1082 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
1083 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
1084 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
1085 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
1086
1087 if (_settings_game.game_creation.landscape == LandscapeType::Arctic) {
1093 }
1094}
1095
1102{
1103 for (auto &file : _grf_files) {
1104 for (auto &indsp : file.industryspec) {
1105 if (indsp == nullptr || !indsp->enabled) continue;
1106
1107 _industry_mngr.SetEntitySpec(std::move(*indsp));
1108 }
1109
1110 for (auto &indtsp : file.indtspec) {
1111 if (indtsp != nullptr) {
1112 _industile_mngr.SetEntitySpec(std::move(*indtsp));
1113 }
1114 }
1115
1116 /* Won't be used again */
1117 file.industryspec.clear();
1118 file.industryspec.shrink_to_fit();
1119 file.indtspec.clear();
1120 file.indtspec.shrink_to_fit();
1121 }
1122
1123 for (auto &indsp : _industry_specs) {
1124 if (indsp.enabled && indsp.grf_prop.HasGrfFile()) {
1125 for (auto &conflicting : indsp.conflicting) {
1126 conflicting = MapNewGRFIndustryType(conflicting, indsp.grf_prop.grfid);
1127 }
1128 }
1129 if (!indsp.enabled) {
1130 indsp.name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
1131 }
1132
1133 /* Apply default cargo translation map for unset cargo slots */
1134 for (size_t i = 0; i < std::size(indsp.produced_cargo_label); ++i) {
1135 if (!IsValidCargoType(indsp.produced_cargo[i])) indsp.produced_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.produced_cargo_label[i]));
1136 }
1137 for (size_t i = 0; i < std::size(indsp.accepts_cargo_label); ++i) {
1138 if (!IsValidCargoType(indsp.accepts_cargo[i])) indsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indsp.accepts_cargo_label[i]));
1139 }
1140 }
1141
1142 for (auto &indtsp : _industry_tile_specs) {
1143 /* Apply default cargo translation map for unset cargo slots */
1144 for (size_t i = 0; i < std::size(indtsp.accepts_cargo_label); ++i) {
1145 if (!IsValidCargoType(indtsp.accepts_cargo[i])) indtsp.accepts_cargo[i] = GetCargoTypeByLabel(GetActiveCargoLabel(indtsp.accepts_cargo_label[i]));
1146 }
1147 }
1148}
1149
1156{
1157 for (auto &file : _grf_files) {
1158 for (auto &objectspec : file.objectspec) {
1159 if (objectspec != nullptr && objectspec->grf_prop.HasGrfFile() && objectspec->IsEnabled()) {
1160 _object_mngr.SetEntitySpec(std::move(*objectspec));
1161 }
1162 }
1163
1164 /* Won't be used again */
1165 file.objectspec.clear();
1166 file.objectspec.shrink_to_fit();
1167 }
1168
1170}
1171
1178{
1179 for (auto &file : _grf_files) {
1180 for (auto &as : file.airportspec) {
1181 if (as != nullptr && as->enabled) {
1182 _airport_mngr.SetEntitySpec(std::move(*as));
1183 }
1184 }
1185
1186 for (auto &ats : file.airtspec) {
1187 if (ats != nullptr && ats->enabled) {
1188 _airporttile_mngr.SetEntitySpec(std::move(*ats));
1189 }
1190 }
1191
1192 /* Won't be used again */
1193 file.airportspec.clear();
1194 file.airportspec.shrink_to_fit();
1195 file.airtspec.clear();
1196 file.airtspec.shrink_to_fit();
1197 }
1198}
1199
1202 template <uint8_t TAction>
1203 static void Invoke(ByteReader &buf, GrfLoadingStage stage)
1204 {
1205 switch (stage) {
1206 case GLS_FILESCAN: GrfActionHandler<TAction>::FileScan(buf); break;
1207 case GLS_SAFETYSCAN: GrfActionHandler<TAction>::SafetyScan(buf); break;
1208 case GLS_LABELSCAN: GrfActionHandler<TAction>::LabelScan(buf); break;
1209 case GLS_INIT: GrfActionHandler<TAction>::Init(buf); break;
1210 case GLS_RESERVE: GrfActionHandler<TAction>::Reserve(buf); break;
1211 case GLS_ACTIVATION: GrfActionHandler<TAction>::Activation(buf); break;
1212 default: NOT_REACHED();
1213 }
1214 }
1215
1216 using Invoker = void(*)(ByteReader &buf, GrfLoadingStage stage);
1217 static constexpr Invoker funcs[] = { // Must be listed in action order.
1218 Invoke<0x00>, Invoke<0x01>, Invoke<0x02>, Invoke<0x03>, Invoke<0x04>, Invoke<0x05>, Invoke<0x06>, Invoke<0x07>,
1219 Invoke<0x08>, Invoke<0x09>, Invoke<0x0A>, Invoke<0x0B>, Invoke<0x0C>, Invoke<0x0D>, Invoke<0x0E>, Invoke<0x0F>,
1220 Invoke<0x10>, Invoke<0x11>, Invoke<0x12>, Invoke<0x13>, Invoke<0x14>,
1221 };
1222
1223 static void Invoke(uint8_t action, GrfLoadingStage stage, ByteReader &buf)
1224 {
1225 Invoker func = action < std::size(funcs) ? funcs[action] : nullptr;
1226 if (func == nullptr) {
1227 GrfMsg(7, "DecodeSpecialSprite: Skipping unknown action 0x{:02X}", action);
1228 } else {
1229 GrfMsg(7, "DecodeSpecialSprite: Handling action 0x{:02X} in stage {}", action, stage);
1230 func(buf, stage);
1231 }
1232 }
1233};
1234
1235/* Here we perform initial decoding of some special sprites (as are they
1236 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
1237 * partial implementation yet).
1238 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
1239 * a crafted invalid GRF file. We should tell that to the user somehow, or
1240 * better make this more robust in the future. */
1241static void DecodeSpecialSprite(ReusableBuffer<uint8_t> &allocator, uint num, GrfLoadingStage stage)
1242{
1243 uint8_t *buf;
1244 auto it = _grf_line_to_action6_sprite_override.find({_cur_gps.grfconfig->ident.grfid, _cur_gps.nfo_line});
1245 if (it == _grf_line_to_action6_sprite_override.end()) {
1246 /* No preloaded sprite to work with; read the
1247 * pseudo sprite content. */
1248 buf = allocator.Allocate(num);
1249 _cur_gps.file->ReadBlock(buf, num);
1250 } else {
1251 /* Use the preloaded sprite data. */
1252 buf = it->second.data();
1253 assert(it->second.size() == num);
1254 GrfMsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
1255
1256 /* Skip the real (original) content of this action. */
1257 _cur_gps.file->SeekTo(num, SEEK_CUR);
1258 }
1259
1260 ByteReader br(buf, num);
1261
1262 try {
1263 uint8_t action = br.ReadByte();
1264
1265 if (action == 0xFF) {
1266 GrfMsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
1267 } else if (action == 0xFE) {
1268 GrfMsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
1269 } else {
1270 InvokeGrfActionHandler::Invoke(action, stage, br);
1271 }
1272 } catch (...) {
1273 GrfMsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
1274 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
1275 }
1276}
1277
1284static void LoadNewGRFFileFromFile(GRFConfig &config, GrfLoadingStage stage, SpriteFile &file)
1285{
1286 AutoRestoreBackup cur_file(_cur_gps.file, &file);
1287 AutoRestoreBackup cur_config(_cur_gps.grfconfig, &config);
1288
1289 Debug(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '{}'", config.filename);
1290
1291 uint8_t grf_container_version = file.GetContainerVersion();
1292 if (grf_container_version == 0) {
1293 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1294 return;
1295 }
1296
1297 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
1298 /* We need the sprite offsets in the init stage for NewGRF sounds
1299 * and in the activation stage for real sprites. */
1301 } else {
1302 /* Skip sprite section offset if present. */
1303 if (grf_container_version >= 2) file.ReadDword();
1304 }
1305
1306 if (grf_container_version >= 2) {
1307 /* Read compression value. */
1308 uint8_t compression = file.ReadByte();
1309 if (compression != 0) {
1310 Debug(grf, 7, "LoadNewGRFFile: Unsupported compression format");
1311 return;
1312 }
1313 }
1314
1315 /* Skip the first sprite; we don't care about how many sprites this
1316 * does contain; newest TTDPatches and George's longvehicles don't
1317 * neither, apparently. */
1318 uint32_t num = grf_container_version >= 2 ? file.ReadDword() : file.ReadWord();
1319 if (num == 4 && file.ReadByte() == 0xFF) {
1320 file.ReadDword();
1321 } else {
1322 Debug(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
1323 return;
1324 }
1325
1326 _cur_gps.ClearDataForNextFile();
1327
1328 ReusableBuffer<uint8_t> allocator;
1329
1330 while ((num = (grf_container_version >= 2 ? file.ReadDword() : file.ReadWord())) != 0) {
1331 uint8_t type = file.ReadByte();
1332 _cur_gps.nfo_line++;
1333
1334 if (type == 0xFF) {
1335 if (_cur_gps.skip_sprites == 0) {
1336 /* Limit the special sprites to 1 MiB. */
1337 if (num > 1024 * 1024) {
1338 GrfMsg(0, "LoadNewGRFFile: Unexpectedly large sprite, disabling");
1339 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1340 break;
1341 }
1342
1343 DecodeSpecialSprite(allocator, num, stage);
1344
1345 /* Stop all processing if we are to skip the remaining sprites */
1346 if (_cur_gps.skip_sprites == -1) break;
1347
1348 continue;
1349 } else {
1350 file.SkipBytes(num);
1351 }
1352 } else {
1353 if (_cur_gps.skip_sprites == 0) {
1354 GrfMsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
1355 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1356 break;
1357 }
1358
1359 if (grf_container_version >= 2 && type == 0xFD) {
1360 /* Reference to data section. Container version >= 2 only. */
1361 file.SkipBytes(num);
1362 } else {
1363 file.SkipBytes(7);
1364 SkipSpriteData(file, type, num - 8);
1365 }
1366 }
1367
1368 if (_cur_gps.skip_sprites > 0) _cur_gps.skip_sprites--;
1369 }
1370}
1371
1380void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
1381{
1382 const std::string &filename = config.filename;
1383
1384 /* A .grf file is activated only if it was active when the game was
1385 * started. If a game is loaded, only its active .grfs will be
1386 * reactivated, unless "loadallgraphics on" is used. A .grf file is
1387 * considered active if its action 8 has been processed, i.e. its
1388 * action 8 hasn't been skipped using an action 7.
1389 *
1390 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
1391 * carried out. All others are ignored, because they only need to be
1392 * processed once at initialization. */
1393 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
1394 _cur_gps.grffile = GetFileByFilename(filename);
1395 if (_cur_gps.grffile == nullptr) UserError("File '{}' lost in cache.\n", filename);
1396 if (stage == GLS_RESERVE && config.status != GCS_INITIALISED) return;
1397 if (stage == GLS_ACTIVATION && !config.flags.Test(GRFConfigFlag::Reserved)) return;
1398 }
1399
1400 bool needs_palette_remap = config.palette & GRFP_USE_MASK;
1401 if (temporary) {
1402 SpriteFile temporarySpriteFile(filename, subdir, needs_palette_remap);
1403 LoadNewGRFFileFromFile(config, stage, temporarySpriteFile);
1404 } else {
1405 LoadNewGRFFileFromFile(config, stage, OpenCachedSpriteFile(filename, subdir, needs_palette_remap));
1406 }
1407}
1408
1416static void ActivateOldShore()
1417{
1418 /* Use default graphics, if no shore sprites were loaded.
1419 * Should not happen, as the base set's extra grf should include some. */
1421
1423 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
1424 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
1425 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
1426 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
1427 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
1428 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
1429 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
1430 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
1431 }
1432
1434 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
1435 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
1436 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
1437 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
1438 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
1439 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
1440 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
1441 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
1442
1443 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
1444 * If they would be used somewhen, then these grass tiles will most like not look as needed */
1445 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
1446 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
1447 }
1448}
1449
1454{
1456 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0); // use road depot graphics for "no tracks"
1457 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
1458 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2); // use road depot graphics for "no tracks"
1459 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
1460 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
1461 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
1462 }
1463}
1464
1469{
1470 extern const PriceBaseSpec _price_base_specs[];
1472 static const uint32_t override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
1473
1474 /* Evaluate grf overrides */
1475 int num_grfs = (uint)_grf_files.size();
1476 std::vector<int> grf_overrides(num_grfs, -1);
1477 for (int i = 0; i < num_grfs; i++) {
1478 GRFFile &source = _grf_files[i];
1479 auto it = _grf_id_overrides.find(source.grfid);
1480 if (it == std::end(_grf_id_overrides)) continue;
1481 uint32_t override_grfid = it->second;
1482
1483 auto dest = std::ranges::find(_grf_files, override_grfid, &GRFFile::grfid);
1484 if (dest == std::end(_grf_files)) continue;
1485
1486 grf_overrides[i] = static_cast<int>(std::ranges::distance(std::begin(_grf_files), dest));
1487 assert(grf_overrides[i] >= 0);
1488 }
1489
1490 /* Override features and price base multipliers of earlier loaded grfs */
1491 for (int i = 0; i < num_grfs; i++) {
1492 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
1493 GRFFile &source = _grf_files[i];
1494 GRFFile &dest = _grf_files[grf_overrides[i]];
1495
1496 uint32_t features = (source.grf_features | dest.grf_features) & override_features;
1497 source.grf_features |= features;
1498 dest.grf_features |= features;
1499
1500 for (Price p = PR_BEGIN; p < PR_END; p++) {
1501 /* No price defined -> nothing to do */
1502 if (!HasBit(features, _price_base_specs[p].grf_feature) || source.price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
1503 Debug(grf, 3, "'{}' overrides price base multiplier {} of '{}'", source.filename, p, dest.filename);
1505 }
1506 }
1507
1508 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
1509 for (int i = num_grfs - 1; i >= 0; i--) {
1510 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
1511 GRFFile &source = _grf_files[i];
1512 GRFFile &dest = _grf_files[grf_overrides[i]];
1513
1514 uint32_t features = (source.grf_features | dest.grf_features) & override_features;
1515 source.grf_features |= features;
1516 dest.grf_features |= features;
1517
1518 for (Price p = PR_BEGIN; p < PR_END; p++) {
1519 /* Already a price defined -> nothing to do */
1520 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest.price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
1521 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, source.filename, dest.filename);
1523 }
1524 }
1525
1526 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
1527 for (int i = 0; i < num_grfs; i++) {
1528 if (grf_overrides[i] < 0) continue;
1529 GRFFile &source = _grf_files[i];
1530 GRFFile &dest = _grf_files[grf_overrides[i]];
1531
1532 uint32_t features = (source.grf_features | dest.grf_features) & override_features;
1533 source.grf_features |= features;
1534 dest.grf_features |= features;
1535
1536 for (Price p = PR_BEGIN; p < PR_END; p++) {
1537 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
1538 if (source.price_base_multipliers[p] != dest.price_base_multipliers[p]) {
1539 Debug(grf, 3, "Price base multiplier {} from '{}' propagated to '{}'", p, dest.filename, source.filename);
1540 }
1542 }
1543 }
1544
1545 /* Apply fallback prices for grf version < 8 */
1546 for (auto &file : _grf_files) {
1547 if (file.grf_version >= 8) continue;
1548 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1549 for (Price p = PR_BEGIN; p < PR_END; p++) {
1550 Price fallback_price = _price_base_specs[p].fallback_price;
1551 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1552 /* No price multiplier has been set.
1553 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
1554 price_base_multipliers[p] = price_base_multipliers[fallback_price];
1555 }
1556 }
1557 }
1558
1559 /* Decide local/global scope of price base multipliers */
1560 for (auto &file : _grf_files) {
1561 PriceMultipliers &price_base_multipliers = file.price_base_multipliers;
1562 for (Price p = PR_BEGIN; p < PR_END; p++) {
1563 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1564 /* No multiplier was set; set it to a neutral value */
1565 price_base_multipliers[p] = 0;
1566 } else {
1567 if (!HasBit(file.grf_features, _price_base_specs[p].grf_feature)) {
1568 /* The grf does not define any objects of the feature,
1569 * so it must be a difficulty setting. Apply it globally */
1570 Debug(grf, 3, "'{}' sets global price base multiplier {}", file.filename, p);
1571 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
1572 price_base_multipliers[p] = 0;
1573 } else {
1574 Debug(grf, 3, "'{}' sets local price base multiplier {}", file.filename, p);
1575 }
1576 }
1577 }
1578 }
1579}
1580
1581template <typename T>
1582void AddBadgeToSpecs(T &specs, GrfSpecFeature feature, Badge &badge)
1583{
1584 for (auto &spec : specs) {
1585 if (spec == nullptr) continue;
1586 spec->badges.push_back(badge.index);
1587 badge.features.Set(feature);
1588 }
1589}
1590
1592static void FinaliseBadges()
1593{
1594 for (const auto &file : _grf_files) {
1595 Badge *badge = GetBadgeByLabel(fmt::format("newgrf/{:08x}", std::byteswap(file.grfid)));
1596 if (badge == nullptr) continue;
1597
1598 for (Engine *e : Engine::Iterate()) {
1599 if (e->grf_prop.grffile != &file) continue;
1600 e->badges.push_back(badge->index);
1601 badge->features.Set(static_cast<GrfSpecFeature>(GSF_TRAINS + e->type));
1602 }
1603
1604 AddBadgeToSpecs(file.stations, GSF_STATIONS, *badge);
1605 AddBadgeToSpecs(file.housespec, GSF_HOUSES, *badge);
1606 AddBadgeToSpecs(file.industryspec, GSF_INDUSTRIES, *badge);
1607 AddBadgeToSpecs(file.indtspec, GSF_INDUSTRYTILES, *badge);
1608 AddBadgeToSpecs(file.objectspec, GSF_OBJECTS, *badge);
1609 AddBadgeToSpecs(file.airportspec, GSF_AIRPORTS, *badge);
1610 AddBadgeToSpecs(file.airtspec, GSF_AIRPORTTILES, *badge);
1611 AddBadgeToSpecs(file.roadstops, GSF_ROADSTOPS, *badge);
1612 }
1613
1615}
1616
1617extern void InitGRFTownGeneratorNames();
1618
1620static void AfterLoadGRFs()
1621{
1622 /* Cached callback groups are no longer needed. */
1623 ResetCallbacks(true);
1624
1626
1627 /* Clear the action 6 override sprites. */
1628 _grf_line_to_action6_sprite_override.clear();
1629
1631
1632 /* Polish cargoes */
1634
1635 /* Pre-calculate all refit masks after loading GRF files. */
1637
1638 /* Polish engines */
1640
1641 /* Set the actually used Canal properties */
1643
1644 /* Add all new houses to the house array. */
1646
1647 /* Add all new industries to the industry array. */
1649
1650 /* Add all new objects to the object array. */
1652
1654
1655 /* Sort the list of industry types. */
1657
1658 /* Create dynamic list of industry legends for smallmap_gui.cpp */
1660
1661 /* Build the routemap legend, based on the available cargos */
1663
1664 /* Add all new airports to the airports array. */
1667
1668 /* Update the townname generators list */
1670
1671 /* Run all queued vehicle list order changes */
1673
1674 /* Load old shore sprites in new position, if they were replaced by ActionA */
1676
1677 /* Load old tram depot sprites in new position, if no new ones are present */
1679
1680 /* Set up custom rail types */
1681 InitRailTypes();
1682 InitRoadTypes();
1683
1684 for (Engine *e : Engine::IterateType(VEH_ROAD)) {
1685 if (_gted[e->index].rv_max_speed != 0) {
1686 /* Set RV maximum speed from the mph/0.8 unit value */
1687 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
1688 }
1689
1690 RoadTramType rtt = e->info.misc_flags.Test(EngineMiscFlag::RoadIsTram) ? RTT_TRAM : RTT_ROAD;
1691
1692 const GRFFile *file = e->GetGRF();
1693 if (file == nullptr || _gted[e->index].roadtramtype == 0) {
1694 e->u.road.roadtype = (rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
1695 continue;
1696 }
1697
1698 /* Remove +1 offset. */
1699 _gted[e->index].roadtramtype--;
1700
1701 const std::vector<RoadTypeLabel> *list = (rtt == RTT_TRAM) ? &file->tramtype_list : &file->roadtype_list;
1702 if (_gted[e->index].roadtramtype < list->size())
1703 {
1704 RoadTypeLabel rtl = (*list)[_gted[e->index].roadtramtype];
1705 RoadType rt = GetRoadTypeByLabel(rtl);
1706 if (rt != INVALID_ROADTYPE && GetRoadTramType(rt) == rtt) {
1707 e->u.road.roadtype = rt;
1708 continue;
1709 }
1710 }
1711
1712 /* Road type is not available, so disable this engine */
1713 e->info.climates = {};
1714 }
1715
1717 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
1718 if (railtype == INVALID_RAILTYPE) {
1719 /* Rail type is not available, so disable this engine */
1720 e->info.climates = {};
1721 } else {
1722 e->u.rail.railtype = railtype;
1723 e->u.rail.intended_railtype = railtype;
1724 }
1725 }
1726
1728
1730
1731 /* Deallocate temporary loading data */
1732 _gted.clear();
1733 _grm_sprites.clear();
1734}
1735
1741void LoadNewGRF(SpriteID load_index, uint num_baseset)
1742{
1743 /* In case of networking we need to "sync" the start values
1744 * so all NewGRFs are loaded equally. For this we use the
1745 * start date of the game and we set the counters, etc. to
1746 * 0 so they're the same too. */
1747 TimerGameCalendar::Date date = TimerGameCalendar::date;
1750
1751 TimerGameEconomy::Date economy_date = TimerGameEconomy::date;
1752 TimerGameEconomy::Year economy_year = TimerGameEconomy::year;
1754
1755 uint64_t tick_counter = TimerGameTick::counter;
1756 uint8_t display_opt = _display_opt;
1757
1758 if (_networking) {
1762
1763 TimerGameEconomy::year = TimerGameEconomy::Year{_settings_game.game_creation.starting_year.base()};
1766
1768 _display_opt = 0;
1769 }
1770
1772
1774
1775 /*
1776 * Reset the status of all files, so we can 'retry' to load them.
1777 * This is needed when one for example rearranges the NewGRFs in-game
1778 * and a previously disabled NewGRF becomes usable. If it would not
1779 * be reset, the NewGRF would remain disabled even though it should
1780 * have been enabled.
1781 */
1782 for (const auto &c : _grfconfig) {
1783 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
1784 }
1785
1786 _cur_gps.spriteid = load_index;
1787
1788 /* Load newgrf sprites
1789 * in each loading stage, (try to) open each file specified in the config
1790 * and load information from it. */
1791 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
1792 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
1793 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
1794 for (const auto &c : _grfconfig) {
1795 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
1796 }
1797
1798 if (stage == GLS_RESERVE) {
1799 static const std::pair<uint32_t, uint32_t> default_grf_overrides[] = {
1800 { std::byteswap(0x44442202), std::byteswap(0x44440111) }, // UKRS addons modifies UKRS
1801 { std::byteswap(0x6D620402), std::byteswap(0x6D620401) }, // DBSetXL ECS extension modifies DBSetXL
1802 { std::byteswap(0x4D656f20), std::byteswap(0x4D656F17) }, // LV4cut modifies LV4
1803 };
1804 for (const auto &grf_override : default_grf_overrides) {
1805 SetNewGRFOverride(grf_override.first, grf_override.second);
1806 }
1807 }
1808
1809 uint num_grfs = 0;
1810 uint num_non_static = 0;
1811
1812 _cur_gps.stage = stage;
1813 for (const auto &c : _grfconfig) {
1814 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
1815 if (stage > GLS_INIT && c->flags.Test(GRFConfigFlag::InitOnly)) continue;
1816
1817 Subdirectory subdir = num_grfs < num_baseset ? BASESET_DIR : NEWGRF_DIR;
1818 if (!FioCheckFileExists(c->filename, subdir)) {
1819 Debug(grf, 0, "NewGRF file is missing '{}'; disabling", c->filename);
1820 c->status = GCS_NOT_FOUND;
1821 continue;
1822 }
1823
1824 if (stage == GLS_LABELSCAN) InitNewGRFFile(*c);
1825
1826 if (!c->flags.Test(GRFConfigFlag::Static) && !c->flags.Test(GRFConfigFlag::System)) {
1827 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
1828 Debug(grf, 0, "'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
1829 c->status = GCS_DISABLED;
1830 c->error = {STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED};
1831 continue;
1832 }
1833 num_non_static++;
1834 }
1835
1836 num_grfs++;
1837
1838 LoadNewGRFFile(*c, stage, subdir, false);
1839 if (stage == GLS_RESERVE) {
1840 c->flags.Set(GRFConfigFlag::Reserved);
1841 } else if (stage == GLS_ACTIVATION) {
1842 c->flags.Reset(GRFConfigFlag::Reserved);
1843 assert(GetFileByGRFID(c->ident.grfid) == _cur_gps.grffile);
1846 Debug(sprite, 2, "LoadNewGRF: Currently {} sprites are loaded", _cur_gps.spriteid);
1847 } else if (stage == GLS_INIT && c->flags.Test(GRFConfigFlag::InitOnly)) {
1848 /* We're not going to activate this, so free whatever data we allocated */
1850 }
1851 }
1852 }
1853
1854 /* We've finished reading files. */
1855 _cur_gps.grfconfig = nullptr;
1856 _cur_gps.grffile = nullptr;
1857
1858 /* Pseudo sprite processing is finished; free temporary stuff */
1859 _cur_gps.ClearDataForNextFile();
1860
1861 /* Call any functions that should be run after GRFs have been loaded. */
1862 AfterLoadGRFs();
1863
1864 /* Now revert back to the original situation */
1867 TimerGameCalendar::date_fract = date_fract;
1868
1869 TimerGameEconomy::year = economy_year;
1870 TimerGameEconomy::date = economy_date;
1871 TimerGameEconomy::date_fract = economy_date_fract;
1872
1873 TimerGameTick::counter = tick_counter;
1874 _display_opt = display_opt;
1875}
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
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Definition enum_type.hpp:17
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.
static const HouseID NUM_HOUSES
Total number of houses.
Definition house.h:29
HouseZones
Definition house.h:68
@ HZ_ZONALL
1F This is just to englobe all above types at once
Definition house.h:75
@ HZ_CLIMALL
Bitmask of all climate bits.
Definition house.h:81
@ HZ_ZON5
center of town
Definition house.h:74
@ HZ_SUBARTC_ABOVE
11 800 can appear in sub-arctic climate above the snow line
Definition house.h:76
@ HZ_ZON1
0..4 1,2,4,8,10 which town zones the building can be built in, Zone1 been the further suburb
Definition house.h:70
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:66
static void FinaliseObjectsArray()
Add all new objects to the object array.
Definition newgrf.cpp:1155
static void FinalisePriceBaseMultipliers()
Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them...
Definition newgrf.cpp:1468
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:603
static void FinaliseIndustriesArray()
Add all new industries to the industry array.
Definition newgrf.cpp:1101
std::span< const CargoLabel > GetCargoTranslationTable(const GRFFile &grffile)
Get the cargo translation table to use for the given GRF file.
Definition newgrf.cpp:512
static std::vector< GRFFile > _grf_files
List of all loaded GRF files.
Definition newgrf.cpp:61
void ResetPersistentNewGRFData()
Reset NewGRF data which is stored persistently in savegames.
Definition newgrf.cpp:496
static void FinaliseAirportsArray()
Add all new airports to the airport array.
Definition newgrf.cpp:1177
static GRFFile * GetFileByFilename(const std::string &filename)
Obtain a NewGRF file by its filename.
Definition newgrf.cpp:114
GRFFile * GetCurrentGRFOverride()
Get overridden GRF for current GRF if present.
Definition newgrf.cpp:191
void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
Set the override for a NewGRF.
Definition newgrf.cpp:176
void GRFUnsafe(ByteReader &)
Set the current NewGRF as unsafe for static use.
Definition newgrf.cpp:367
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:209
static void ActivateOldShore()
Relocates the old shore sprites at new positions.
Definition newgrf.cpp:1416
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:994
static void FinaliseEngineArray()
Check for invalid engines.
Definition newgrf.cpp:845
ReferenceThroughBaseContainer< std::vector< GRFTempEngineData > > _gted
Temporary engine data used during NewGRF loading.
Definition newgrf.cpp:76
static void ResetNewGRFErrors()
Clear all NewGRF errors.
Definition newgrf.cpp:389
static void LoadNewGRFFileFromFile(GRFConfig &config, GrfLoadingStage stage, SpriteFile &file)
Load a particular NewGRF from a SpriteFile.
Definition newgrf.cpp:1284
void ConvertTTDBasePrice(uint32_t base_pointer, const char *error_location, Price *index)
Converts TTD(P) Base Price pointers into the enum used by OTTD See http://wiki.ttdpatch....
Definition newgrf.cpp:326
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition newgrf.cpp:72
void LoadNewGRF(SpriteID load_index, uint num_baseset)
Load all the NewGRFs.
Definition newgrf.cpp:1741
static void ClearTemporaryNewGRFData(GRFFile *gf)
Reset all NewGRFData that was used only while processing data.
Definition newgrf.cpp:122
void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig &c)
Disable a static NewGRF when it is influencing another (non-static) NewGRF as this could cause desync...
Definition newgrf.cpp:163
static void FinaliseCanals()
Set to use the correct action0 properties for each canal feature.
Definition newgrf.cpp:834
void ResetNewGRFData()
Reset all NewGRF loaded data.
Definition newgrf.cpp:402
static void CalculateRefitMasks()
Precalculate refit masks from cargo classes for all vehicles.
Definition newgrf.cpp:638
void FinaliseCargoArray()
Check for invalid cargoes.
Definition newgrf.cpp:918
static void BuildCargoTranslationMap()
Construct the Cargo Mapping.
Definition newgrf.cpp:528
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:88
EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal_id)
Return the ID of a new engine.
Definition newgrf.cpp:290
GRFFile * GetFileByGRFID(uint32_t grfid)
Obtain a NewGRF file by its grfID.
Definition newgrf.cpp:102
GrfMiscBits _misc_grf_features
Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E.
Definition newgrf.cpp:69
static void FinaliseHouseArray()
Add all new houses to the house array.
Definition newgrf.cpp:1019
static void InitNewGRFFile(const GRFConfig &config)
Prepare loading a NewGRF file with its config.
Definition newgrf.cpp:545
static void ActivateOldTramDepot()
Replocate the old tram depot sprites to the new position, if no new ones were loaded.
Definition newgrf.cpp:1453
void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
Load a particular NewGRF.
Definition newgrf.cpp:1380
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:948
static void AfterLoadGRFs()
Finish loading NewGRFs and execute needed post-processing.
Definition newgrf.cpp:1620
GRFError * DisableGrf(StringID message, GRFConfig *config)
Disable a GRF.
Definition newgrf.cpp:133
static void ResetNewGRF()
Reset and clear all NewGRFs.
Definition newgrf.cpp:376
void InitGRFTownGeneratorNames()
Allocate memory for the NewGRF town names.
CargoTypes TranslateRefitMask(uint32_t refit_mask)
Translate the refit mask.
Definition newgrf.cpp:309
static void FinaliseBadges()
Finish up applying badges to things.
Definition newgrf.cpp:1592
@ SHORE_REPLACE_ACTION_A
Shore sprites were replaced by ActionA (using grass tiles for the corner-shores).
Definition newgrf.h:176
@ SHORE_REPLACE_NONE
No shore sprites were replaced.
Definition newgrf.h:174
@ SHORE_REPLACE_ACTION_5
Shore sprites were replaced by Action5.
Definition newgrf.h:175
@ TRAMWAY_REPLACE_DEPOT_WITH_TRACK
Electrified depot graphics with tram track were loaded.
Definition newgrf.h:182
@ TRAMWAY_REPLACE_DEPOT_NONE
No tram depot graphics were loaded.
Definition newgrf.h:181
GrfSpecFeature
Definition newgrf.h:70
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.
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)
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:60
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:224
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.
VariableGRFFileProps grf_prop
Properties related the the grf file.
Definition engine_base.h:83
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:113
std::array< uint8_t, NUM_CARGO > cargo_map
Inverse cargo translation table (CargoType -> local ID)
Definition newgrf.h:135
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road)
Definition newgrf.h:143
uint32_t grf_features
Bitset of GrfSpecFeature the grf uses.
Definition newgrf.h:156
std::vector< RoadTypeLabel > tramtype_list
Roadtype translation table (tram)
Definition newgrf.h:146
std::vector< CargoLabel > cargo_list
Cargo translation table (local ID -> label)
Definition newgrf.h:134
uint traininfo_vehicle_width
Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details.
Definition newgrf.h:154
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
Definition newgrf.h:153
std::unordered_map< uint8_t, LanguageMap > language_map
Mappings related to the languages.
Definition newgrf.h:151
std::vector< GRFLabel > labels
List of labels.
Definition newgrf.h:132
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition newgrf.h:157
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:187
ShoreReplacement shore
In which way shore sprites were replaced.
Definition newgrf.h:189
uint64_t used_liveries
Bitmask of LiveryScheme used by the defined engines.
Definition newgrf.h:188
TramReplacement tram
In which way tram depots were replaced.
Definition newgrf.h:190
@ 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:103
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:106
CargoLabel accepts_cargo_label[HOUSE_ORIGINAL_NUM_ACCEPTS]
input landscape cargo slots
Definition house.h:121
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:104
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:97
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:102
GRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:109
HouseZones building_availability
where can it be built (climates, zones)
Definition house.h:105
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Helper class to invoke a GrfActionHandler.
Definition newgrf.cpp:1201
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:351
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.
Price fallback_price
Fallback price multiplier for new prices but old grfs.
uint grf_feature
GRF Feature that decides whether price multipliers apply locally or globally, GSF_END if none.
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:1923
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.