47#include "table/strings.h"
63std::span<const GRFFile> GetAllGRFFiles()
88void GrfMsgI(
int severity,
const std::string &msg)
91 Debug(grf, severity,
"{}", msg);
88void GrfMsgI(
int severity,
const std::string &msg) {
…}
104 auto it = std::ranges::find(
_grf_files, grfid, &GRFFile::grfid);
116 auto it = std::ranges::find(
_grf_files, filename, &GRFFile::filename);
136 if (config !=
nullptr) {
147 if (message == STR_NULL)
return nullptr;
149 config->
error = {STR_NEWGRF_ERROR_MSG_FATAL, message};
151 return &config->
error.value();
169static std::map<uint32_t, uint32_t> _grf_id_overrides;
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));
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));
193 auto found = _grf_id_overrides.find(_cur_gps.
grffile->grfid);
194 if (found != std::end(_grf_id_overrides)) {
196 if (grffile !=
nullptr)
return grffile;
213 uint32_t scope_grfid = INVALID_GRFID;
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;
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));
223 GrfMsg(5,
"Mapping from GRFID {:x} to {:x}", std::byteswap(file->grfid), std::byteswap(scope_grfid));
228 EngineID engine = _engine_mngr.
GetID(type, internal_id, scope_grfid);
229 if (engine != EngineID::Invalid()) {
240 if (engine != EngineID::Invalid()) {
245 GrfMsg(5,
"Replaced engine at index {} for GRFID {:x}, type {}, index {}", e->
index, std::byteswap(file->grfid), type, internal_id);
251 if (static_access)
return nullptr;
254 GrfMsg(0,
"Can't allocate any more engines");
265 _engine_mngr.SetID(type, internal_id, scope_grfid, std::min<uint8_t>(internal_id,
_engine_counts[type]), e->
index);
275 GrfMsg(5,
"Created new engine at index {} for GRFID {:x}, type {}, index {}", e->
index, std::byteswap(file->grfid), type, internal_id);
292 uint32_t scope_grfid = INVALID_GRFID;
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;
300 return _engine_mngr.
GetID(type, internal_id, scope_grfid);
311 CargoTypes result = 0;
329 if (base_pointer == 0) {
330 *index = INVALID_PRICE;
334 static const uint32_t start = 0x4B34;
335 static const uint32_t size = 6;
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);
342 *index = (
Price)((base_pointer - start) / size);
355 if (grffile ==
nullptr)
return nullptr;
358 if (it == std::end(grffile->
language_map))
return nullptr;
396extern void ResetCallbacks(
bool final);
397extern void ResetGRM();
405 CleanUpGRFTownNames();
486 _grf_id_overrides.clear();
488 InitializeSoundPool();
490 ResetCallbacks(
false);
548 if (newfile !=
nullptr) {
590 this->param = config.
param;
594GRFFile::GRFFile() =
default;
595GRFFile::GRFFile(
GRFFile &&other) =
default;
596GRFFile::~GRFFile() =
default;
606 CargoType cargo_type = GetCargoTypeByLabel(label);
607 if (cargo_type != INVALID_CARGO)
return label;
627 default: NOT_REACHED();
632 return std::visit(visitor{}, label);
640 CargoTypes original_known_cargoes = 0;
648 bool only_defaultcargo;
656 if (
_gted[engine].defaultcargo_grf ==
nullptr) {
658 if (e->type !=
VEH_TRAIN || e->u.rail.capacity != 0) {
663 static const struct DefaultRefitMasks {
668 } _default_refit_masks[] = {
690 switch (label.base()) {
694 _gted[engine].cargo_disallowed = {};
699 _gted[engine].cargo_disallowed = {};
713 e->u.ship.old_refittable =
true;
718 _gted[engine].cargo_disallowed = {};
722 for (
const auto &drm : _default_refit_masks) {
724 if (drm.cargo_label != label)
continue;
726 _gted[engine].cargo_allowed = drm.cargo_allowed;
727 _gted[engine].cargo_disallowed = drm.cargo_disallowed;
732 _gted[engine].ctt_exclude_mask = original_known_cargoes;
735 _gted[engine].UpdateRefittability(
_gted[engine].cargo_allowed.Any());
743 CargoTypes not_mask = 0;
744 CargoTypes xor_mask = ei->refit_mask;
750 if (
_gted[engine].cargo_allowed.Any()) {
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());
758 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) &
_cargo_mask;
761 ei->refit_mask |=
_gted[engine].ctt_include_mask;
762 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
766 if (file ==
nullptr) file = e->GetGRF();
769 uint8_t local_slot = file->
cargo_map[cs->Index()];
775 case 1:
SetBit(ei->refit_mask, cs->Index());
break;
776 case 2:
ClrBit(ei->refit_mask, cs->Index());
break;
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;
798 if (file ==
nullptr) file = e->GetGRF();
799 if (file !=
nullptr && file->grf_version >= 8 && !file->
cargo_list.empty()) {
801 uint8_t best_local_slot = UINT8_MAX;
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;
827 if (e->type ==
VEH_SHIP && !e->u.ship.old_refittable) {
836 for (uint i = 0; i < CF_END; i++) {
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;
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());
890 default: NOT_REACHED();
899 EngineID parent = e->info.variant_id;
900 while (parent != EngineID::Invalid()) {
902 if (parent != e->index)
continue;
905 e->info.variant_id = EngineID::Invalid();
907 GrfMsg(1,
"FinaliseEngineArray: Variant of engine {:x} in '{}' loops back on itself", e->grf_prop.local_id, e->GetGRF()->filename);
911 if (e->info.variant_id != EngineID::Invalid()) {
923 switch (cs.label.base()) {
925 case CT_MAIL.base(): cs.town_production_effect =
TPE_MAIL;
break;
926 default: cs.town_production_effect =
TPE_NONE;
break;
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;
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);
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);
974 Debug(grf, 1,
"FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs.
grf_prop.
local_id);
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);
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;
1004 if (min_year == 0)
return;
1007 if (!hs.enabled)
continue;
1008 if ((hs.building_availability & bitmask) != bitmask)
continue;
1031 if (file.housespec.empty())
continue;
1033 size_t num_houses = file.housespec.size();
1034 for (
size_t i = 0; i < num_houses; i++) {
1035 auto &hs = file.housespec[i];
1037 if (hs ==
nullptr)
continue;
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);
1049 file.housespec.clear();
1050 file.housespec.shrink_to_fit();
1104 for (
auto &indsp : file.industryspec) {
1105 if (indsp ==
nullptr || !indsp->enabled)
continue;
1110 for (
auto &indtsp : file.indtspec) {
1111 if (indtsp !=
nullptr) {
1112 _industile_mngr.SetEntitySpec(std::move(*indtsp));
1117 file.industryspec.clear();
1118 file.industryspec.shrink_to_fit();
1119 file.indtspec.clear();
1120 file.indtspec.shrink_to_fit();
1123 for (
auto &indsp : _industry_specs) {
1124 if (indsp.enabled && indsp.grf_prop.HasGrfFile()) {
1125 for (
auto &conflicting : indsp.conflicting) {
1129 if (!indsp.enabled) {
1130 indsp.name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
1134 for (
size_t i = 0; i < std::size(indsp.produced_cargo_label); ++i) {
1137 for (
size_t i = 0; i < std::size(indsp.accepts_cargo_label); ++i) {
1142 for (
auto &indtsp : _industry_tile_specs) {
1144 for (
size_t i = 0; i < std::size(indtsp.accepts_cargo_label); ++i) {
1158 for (
auto &objectspec : file.objectspec) {
1159 if (objectspec !=
nullptr && objectspec->grf_prop.HasGrfFile() && objectspec->IsEnabled()) {
1165 file.objectspec.clear();
1166 file.objectspec.shrink_to_fit();
1180 for (
auto &as : file.airportspec) {
1181 if (as !=
nullptr && as->enabled) {
1182 _airport_mngr.SetEntitySpec(std::move(*as));
1186 for (
auto &ats : file.airtspec) {
1187 if (ats !=
nullptr && ats->enabled) {
1188 _airporttile_mngr.SetEntitySpec(std::move(*ats));
1193 file.airportspec.clear();
1194 file.airportspec.shrink_to_fit();
1195 file.airtspec.clear();
1196 file.airtspec.shrink_to_fit();
1202 template <u
int8_t TAction>
1203 static void Invoke(
ByteReader &buf, GrfLoadingStage stage)
1212 default: NOT_REACHED();
1216 using Invoker = void(*)(
ByteReader &buf, GrfLoadingStage stage);
1217 static constexpr Invoker funcs[] = {
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>,
1223 static void Invoke(uint8_t action, GrfLoadingStage stage,
ByteReader &buf)
1225 Invoker func = action < std::size(funcs) ? funcs[action] :
nullptr;
1226 if (func ==
nullptr) {
1227 GrfMsg(7,
"DecodeSpecialSprite: Skipping unknown action 0x{:02X}", action);
1229 GrfMsg(7,
"DecodeSpecialSprite: Handling action 0x{:02X} in stage {}", action, stage);
1245 if (it == _grf_line_to_action6_sprite_override.end()) {
1252 buf = it->second.data();
1253 assert(it->second.size() == num);
1254 GrfMsg(7,
"DecodeSpecialSprite: Using preloaded pseudo sprite data");
1263 uint8_t action = br.ReadByte();
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");
1270 InvokeGrfActionHandler::Invoke(action, stage, br);
1273 GrfMsg(1,
"DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
1289 Debug(grf, 2,
"LoadNewGRFFile: Reading NewGRF-file '{}'", config.
filename);
1292 if (grf_container_version == 0) {
1293 Debug(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
1297 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
1303 if (grf_container_version >= 2) file.
ReadDword();
1306 if (grf_container_version >= 2) {
1308 uint8_t compression = file.
ReadByte();
1309 if (compression != 0) {
1310 Debug(grf, 7,
"LoadNewGRFFile: Unsupported compression format");
1319 if (num == 4 && file.
ReadByte() == 0xFF) {
1322 Debug(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
1330 while ((num = (grf_container_version >= 2 ? file.
ReadDword() : file.
ReadWord())) != 0) {
1337 if (num > 1024 * 1024) {
1338 GrfMsg(0,
"LoadNewGRFFile: Unexpectedly large sprite, disabling");
1339 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1343 DecodeSpecialSprite(allocator, num, stage);
1354 GrfMsg(0,
"LoadNewGRFFile: Unexpected sprite, disabling");
1355 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
1359 if (grf_container_version >= 2 && type == 0xFD) {
1382 const std::string &filename = config.
filename;
1393 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
1395 if (_cur_gps.
grffile ==
nullptr) UserError(
"File '{}' lost in cache.\n", filename);
1402 SpriteFile temporarySpriteFile(filename, subdir, needs_palette_remap);
1456 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0);
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);
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);
1472 static const uint32_t override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
1476 std::vector<int> grf_overrides(num_grfs, -1);
1477 for (
int i = 0; i < num_grfs; 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;
1483 auto dest = std::ranges::find(
_grf_files, override_grfid, &GRFFile::grfid);
1486 grf_overrides[i] =
static_cast<int>(std::ranges::distance(std::begin(
_grf_files), dest));
1487 assert(grf_overrides[i] >= 0);
1491 for (
int i = 0; i < num_grfs; i++) {
1492 if (grf_overrides[i] < 0 || grf_overrides[i] >= i)
continue;
1500 for (
Price p = PR_BEGIN; p < PR_END; p++) {
1503 Debug(grf, 3,
"'{}' overrides price base multiplier {} of '{}'", source.filename, p, dest.filename);
1509 for (
int i = num_grfs - 1; i >= 0; i--) {
1510 if (grf_overrides[i] < 0 || grf_overrides[i] <= i)
continue;
1518 for (
Price p = PR_BEGIN; p < PR_END; p++) {
1521 Debug(grf, 3,
"Price base multiplier {} from '{}' propagated to '{}'", p, source.filename, dest.filename);
1527 for (
int i = 0; i < num_grfs; i++) {
1528 if (grf_overrides[i] < 0)
continue;
1536 for (
Price p = PR_BEGIN; p < PR_END; p++) {
1537 if (!
HasBit(features, _price_base_specs[p].grf_feature))
continue;
1539 Debug(grf, 3,
"Price base multiplier {} from '{}' propagated to '{}'", p, dest.filename, source.filename);
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++) {
1551 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
1554 price_base_multipliers[p] = price_base_multipliers[fallback_price];
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) {
1565 price_base_multipliers[p] = 0;
1570 Debug(grf, 3,
"'{}' sets global price base multiplier {}", file.filename, p);
1572 price_base_multipliers[p] = 0;
1574 Debug(grf, 3,
"'{}' sets local price base multiplier {}", file.filename, p);
1581template <
typename T>
1584 for (
auto &spec : specs) {
1585 if (spec ==
nullptr)
continue;
1586 spec->badges.push_back(badge.
index);
1596 if (badge ==
nullptr)
continue;
1599 if (e->grf_prop.grffile != &file)
continue;
1600 e->badges.push_back(badge->
index);
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);
1623 ResetCallbacks(
true);
1628 _grf_line_to_action6_sprite_override.clear();
1685 if (
_gted[e->index].rv_max_speed != 0) {
1687 e->u.road.max_speed =
_gted[e->index].rv_max_speed * 4;
1692 const GRFFile *file = e->GetGRF();
1693 if (file ==
nullptr ||
_gted[e->index].roadtramtype == 0) {
1699 _gted[e->index].roadtramtype--;
1702 if (
_gted[e->index].roadtramtype < list->size())
1704 RoadTypeLabel rtl = (*list)[
_gted[e->index].roadtramtype];
1707 e->u.road.roadtype = rt;
1713 e->info.climates = {};
1720 e->info.climates = {};
1722 e->u.rail.railtype = railtype;
1723 e->u.rail.intended_railtype = railtype;
1733 _grm_sprites.clear();
1791 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
1798 if (stage == GLS_RESERVE) {
1799 static const std::pair<uint32_t, uint32_t> default_grf_overrides[] = {
1800 { std::byteswap(0x44442202), std::byteswap(0x44440111) },
1801 { std::byteswap(0x6D620402), std::byteswap(0x6D620401) },
1802 { std::byteswap(0x4D656f20), std::byteswap(0x4D656F17) },
1804 for (
const auto &grf_override : default_grf_overrides) {
1810 uint num_non_static = 0;
1812 _cur_gps.
stage = stage;
1819 Debug(grf, 0,
"NewGRF file is missing '{}'; disabling", c->filename);
1828 Debug(grf, 0,
"'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
1830 c->error = {STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED};
1839 if (stage == GLS_RESERVE) {
1841 }
else if (stage == GLS_ACTIVATION) {
1846 Debug(sprite, 2,
"LoadNewGRF: Currently {} sprites are loaded", _cur_gps.
spriteid);
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.
void ResetBridges()
Reset the data been eventually changed by the grf loaded.
static constexpr CargoLabel CT_INVALID
Invalid cargo type.
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
MixedCargoType
Mixed cargo types for definitions with cargo that can vary depending on climate.
@ MCT_GRAIN_WHEAT_MAIZE
Cargo can be grain, wheat or maize.
@ MCT_LIVESTOCK_FRUIT
Cargo can be livestock or fruit.
@ MCT_VALUABLES_GOLD_DIAMONDS
Cargo can be valuables, gold or diamonds.
static constexpr CargoLabel CT_PASSENGERS
Available types of cargo Labels may be re-used between different climates.
static const CargoType NUM_CARGO
Maximum number of cargo types in a game.
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.
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.
void InitializeSortedCargoSpecs()
Initialize the list of sorted cargo specifications.
CargoTypes _cargo_mask
Bitmask of cargo types available.
@ Bulk
Bulk cargo (Coal, Grain etc., Ores, Fruit)
@ Liquid
Liquids (Oil, Water, Rubber)
@ 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.
@ TPE_NONE
Town will not produce this cargo type.
@ TPE_PASSENGERS
Cargo behaves passenger-like for production.
@ TPE_MAIL
Cargo behaves mail-like for production.
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.
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.
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.
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...
Functions to handle different currencies.
Functions related to debugging.
#define Debug(category, level, format_string,...)
Output a line of debugging information.
void SetPriceBaseMultiplier(Price price, int factor)
Change a price base by the given factor.
void ResetPriceBaseMultipliers()
Reset changes to the price base multipliers.
Price
Enumeration of all base prices for use with Prices.
void SetYearEngineAgingStops()
Compute the value for _year_engine_aging_stops.
const uint8_t _engine_counts[4]
Number of engines of each vehicle type in original engine data.
void SetupEngines()
Initialise the engine pool with the data from the original vehicles.
@ 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
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Error reporting related functions.
bool FioCheckFileExists(std::string_view filename, Subdirectory subdir)
Check whether the given file exists.
Functions for Standard In/Out file operations.
Subdirectory
The different kinds of subdirectories OpenTTD uses.
@ NEWGRF_DIR
Subdirectory for all NewGRFs.
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
Functions related to world/map generation.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
void ClearSnowLine()
Clear the variable snow line table and free the memory.
static const HouseID NUM_HOUSES
Total number of houses.
@ HZ_ZONALL
1F This is just to englobe all above types at once
@ HZ_CLIMALL
Bitmask of all climate bits.
@ HZ_SUBARTC_ABOVE
11 800 can appear in sub-arctic climate above the snow line
@ HZ_ZON1
0..4 1,2,4,8,10 which town zones the building can be built in, Zone1 been the further suburb
void ResetIndustries()
This function initialize the spec arrays of both industry and industry tiles.
void SortIndustryTypes()
Initialize the list of sorted industry types.
Functions related to OTTD's landscape.
LandscapeType
Landscape types.
LiveryScheme
List of different livery schemes.
bool _networking
are we in networking mode?
static void FinaliseObjectsArray()
Add all new objects to the object array.
static void FinalisePriceBaseMultipliers()
Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them...
static CargoLabel GetActiveCargoLabel(const std::initializer_list< CargoLabel > &labels)
Find first cargo label that exists and is active from a list of cargo labels.
static void FinaliseIndustriesArray()
Add all new industries to the industry array.
std::span< const CargoLabel > GetCargoTranslationTable(const GRFFile &grffile)
Get the cargo translation table to use for the given GRF file.
static std::vector< GRFFile > _grf_files
List of all loaded GRF files.
void ResetPersistentNewGRFData()
Reset NewGRF data which is stored persistently in savegames.
static void FinaliseAirportsArray()
Add all new airports to the airport array.
static GRFFile * GetFileByFilename(const std::string &filename)
Obtain a NewGRF file by its filename.
GRFFile * GetCurrentGRFOverride()
Get overridden GRF for current GRF if present.
void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
Set the override for a NewGRF.
void GRFUnsafe(ByteReader &)
Set the current NewGRF as unsafe for static use.
Engine * GetNewEngine(const GRFFile *file, VehicleType type, uint16_t internal_id, bool static_access)
Returns the engine associated to a certain internal_id, resp.
static void ActivateOldShore()
Relocates the old shore sprites at new positions.
static void EnsureEarlyHouse(HouseZones bitmask)
Make sure there is at least one house available in the year 0 for the given climate / housezone combi...
static void FinaliseEngineArray()
Check for invalid engines.
ReferenceThroughBaseContainer< std::vector< GRFTempEngineData > > _gted
Temporary engine data used during NewGRF loading.
static void ResetNewGRFErrors()
Clear all NewGRF errors.
static void LoadNewGRFFileFromFile(GRFConfig &config, GrfLoadingStage stage, SpriteFile &file)
Load a particular NewGRF from a SpriteFile.
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....
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
void LoadNewGRF(SpriteID load_index, uint num_baseset)
Load all the NewGRFs.
static void ClearTemporaryNewGRFData(GRFFile *gf)
Reset all NewGRFData that was used only while processing data.
void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig &c)
Disable a static NewGRF when it is influencing another (non-static) NewGRF as this could cause desync...
static void FinaliseCanals()
Set to use the correct action0 properties for each canal feature.
void ResetNewGRFData()
Reset all NewGRF loaded data.
static void CalculateRefitMasks()
Precalculate refit masks from cargo classes for all vehicles.
void FinaliseCargoArray()
Check for invalid cargoes.
static void BuildCargoTranslationMap()
Construct the Cargo Mapping.
void GrfMsgI(int severity, const std::string &msg)
Debug() function dedicated to newGRF debugging messages Function is essentially the same as Debug(grf...
EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal_id)
Return the ID of a new engine.
GRFFile * GetFileByGRFID(uint32_t grfid)
Obtain a NewGRF file by its grfID.
GrfMiscBits _misc_grf_features
Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E.
static void FinaliseHouseArray()
Add all new houses to the house array.
static void InitNewGRFFile(const GRFConfig &config)
Prepare loading a NewGRF file with its config.
static void ActivateOldTramDepot()
Replocate the old tram depot sprites to the new position, if no new ones were loaded.
void LoadNewGRFFile(GRFConfig &config, GrfLoadingStage stage, Subdirectory subdir, bool temporary)
Load a particular NewGRF.
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.
static void AfterLoadGRFs()
Finish loading NewGRFs and execute needed post-processing.
GRFError * DisableGrf(StringID message, GRFConfig *config)
Disable a GRF.
static void ResetNewGRF()
Reset and clear all NewGRFs.
void InitGRFTownGeneratorNames()
Allocate memory for the NewGRF town names.
CargoTypes TranslateRefitMask(uint32_t refit_mask)
Translate the refit mask.
static void FinaliseBadges()
Finish up applying badges to things.
@ SHORE_REPLACE_ACTION_A
Shore sprites were replaced by ActionA (using grass tiles for the corner-shores).
@ SHORE_REPLACE_NONE
No shore sprites were replaced.
@ SHORE_REPLACE_ACTION_5
Shore sprites were replaced by Action5.
@ TRAMWAY_REPLACE_DEPOT_WITH_TRACK
Electrified depot graphics with tram track were loaded.
@ TRAMWAY_REPLACE_DEPOT_NONE
No tram depot graphics were loaded.
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.
void InitRailTypes()
Resolve sprites of custom rail types.
void ResetRailTypes()
Reset all rail type information to its default values.
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
RailType
Enumeration for all possible railtypes.
@ INVALID_RAILTYPE
Flag for invalid railtype.
@ RAILTYPE_ELECTRIC
Electric rails.
@ RAILTYPE_RAIL
Standard non-electric rails.
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
Get the road type for a given label.
void ResetRoadTypes()
Reset all road type information to its default values.
void InitRoadTypes()
Resolve sprites of custom road types.
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
RoadType
The different roadtypes we support.
@ INVALID_ROADTYPE
flag for invalid roadtype
@ ROADTYPE_ROAD
Basic road type.
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
void BuildLinkStatsLegend()
Populate legend table for the link stat view.
void BuildIndustriesLegend()
Fills an array for the industries legends.
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 of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
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.
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
static CargoSpec array[NUM_CARGO]
Array holding all CargoSpecs.
Information about a vehicle.
LandscapeTypes climates
Climates supported by the engine.
void ResetToDefaultMapping()
Initializes the EngineOverrideManager with the default engines.
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.
EngineID GetID(VehicleType type, uint16_t grf_local_id, uint32_t grfid)
Looks up an EngineID in the EngineOverrideManager.
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.
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.
std::array< uint8_t, NUM_CARGO > cargo_map
Inverse cargo translation table (CargoType -> local ID)
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road)
uint32_t grf_features
Bitset of GrfSpecFeature the grf uses.
std::vector< RoadTypeLabel > tramtype_list
Roadtype translation table (tram)
std::vector< CargoLabel > cargo_list
Cargo translation table (local ID -> label)
uint traininfo_vehicle_width
Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details.
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
std::unordered_map< uint8_t, LanguageMap > language_map
Mappings related to the languages.
std::vector< GRFLabel > labels
List of labels.
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
uint32_t grfid
GRF ID (defined by Action 0x08)
bool has_2CC
Set if any vehicle is loaded which uses 2cc (two company colours).
ShoreReplacement shore
In which way shore sprites were replaced.
uint64_t used_liveries
Bitmask of LiveryScheme used by the defined engines.
TramReplacement tram
In which way tram depots were replaced.
@ 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
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
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
CargoLabel accepts_cargo_label[HOUSE_ORIGINAL_NUM_ACCEPTS]
input landscape cargo slots
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...)
uint8_t population
population (Zero on other tiles in multi tile house.)
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
GRFFileProps grf_prop
Properties related the the grf file.
HouseZones building_availability
where can it be built (climates, zones)
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Helper class to invoke a GrfActionHandler.
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.
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.
Iterable ensemble of each set bit in a value.
bool dynamic_engines
enable dynamic allocation of engine data
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.
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.