46 if (ctype >= cargo_list.size()) {
47 GrfMsg(1,
"TranslateCargo: Cargo type {} out of range (max {}), skipping.", ctype, (
unsigned int)_cur_gps.grffile->cargo_list.size() - 1);
54 GrfMsg(5,
"TranslateCargo: Cargo type {} not available in this climate, skipping.", ctype);
58 CargoType cargo_type = GetCargoTypeByLabel(cl);
60 GrfMsg(5,
"TranslateCargo: Cargo '{:c}{:c}{:c}{:c}' unsupported, skipping.",
GB(cl.base(), 24, 8),
GB(cl.base(), 16, 8),
GB(cl.base(), 8, 8),
GB(cl.base(), 0, 8));
64 GrfMsg(6,
"TranslateCargo: Cargo '{:c}{:c}{:c}{:c}' mapped to cargo type {}.",
GB(cl.base(), 24, 8),
GB(cl.base(), 16, 8),
GB(cl.base(), 8, 8),
GB(cl.base(), 0, 8), cargo_type);
69static bool IsValidGroupID(uint16_t groupid, std::string_view function)
71 if (groupid >
MAX_SPRITEGROUP || _cur_gps.spritegroups[groupid] ==
nullptr) {
72 GrfMsg(1,
"{}: Spritegroup 0x{:04X} out of range or empty, skipping.", function, groupid);
81 static std::vector<EngineID> last_engines;
88 idcount =
GB(idcount, 0, 7);
90 if (last_engines.empty()) {
91 GrfMsg(0,
"VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
95 GrfMsg(6,
"VehicleMapSpriteGroup: WagonOverride: {} engines, {} wagons", last_engines.size(), idcount);
97 last_engines.resize(idcount);
100 std::vector<EngineID> engines;
101 engines.reserve(idcount);
102 for (uint i = 0; i < idcount; i++) {
112 engines.push_back(e->index);
113 if (!wagover) last_engines[i] = engines[i];
117 for (uint c = 0; c < cidcount; c++) {
120 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
continue;
122 GrfMsg(8,
"VehicleMapSpriteGroup: * [{}] Cargo type 0x{:X}, group id 0x{:02X}", c, ctype, groupid);
124 CargoType cargo_type = TranslateCargo(feature, ctype);
127 for (uint i = 0; i < idcount; i++) {
130 GrfMsg(7,
"VehicleMapSpriteGroup: [{}] Engine {}...", i, engine);
133 SetWagonOverrideSprites(engine, cargo_type, _cur_gps.spritegroups[groupid], last_engines);
135 SetCustomEngineSprites(engine, cargo_type, _cur_gps.spritegroups[groupid]);
141 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
return;
143 GrfMsg(8,
"-- Default group id 0x{:04X}", groupid);
145 for (uint i = 0; i < idcount; i++) {
192 GrfMsg(1,
"MapSpriteGroup: Invalid cargo bitnum {}, skipping.", cid);
193 }
else if (
T *spec =
GetSpec<T>(_cur_gps.grffile, local_id); spec ==
nullptr) {
194 GrfMsg(1,
"MapSpriteGroup: {} undefined, skipping.", local_id);
202 if (
T *spec =
GetSpec<T>(_cur_gps.grffile, local_id); spec ==
nullptr) {
203 GrfMsg(1,
"MapSpriteGroup: {} undefined, skipping.", local_id);
206 spec->grf_prop.SetGRFFile(_cur_gps.grffile);
207 spec->grf_prop.local_id = local_id;
213template <
typename T,
typename T
class>
220 if (
T *spec =
GetSpec<T>(_cur_gps.grffile, local_id); spec ==
nullptr) {
221 GrfMsg(1,
"MapSpriteGroup: {} undefined, skipping", local_id);
223 spec->grf_prop.SetSpriteGroup(cargo_type, group);
229 if (
T *spec =
GetSpec<T>(_cur_gps.grffile, local_id); spec ==
nullptr) {
230 GrfMsg(1,
"MapSpriteGroup: {} undefined, skipping", local_id);
231 }
else if (spec->grf_prop.HasGrfFile()) {
232 GrfMsg(1,
"MapSpriteGroup: {} mapped multiple times, skipping", local_id);
235 spec->grf_prop.SetGRFFile(_cur_gps.grffile);
236 spec->grf_prop.local_id = local_id;
237 Tclass::Assign(spec);
247 if (local_id >= CF_END) {
248 GrfMsg(1,
"CanalMapSpriteGroup: Canal subset {} out of range, skipping", local_id);
256template <>
auto *
GetSpec<StationSpec>(
GRFFile *grffile, uint16_t local_id) {
return local_id < grffile->stations.size() ? grffile->stations[local_id].get() :
nullptr; }
259template <>
auto *
GetSpec<HouseSpec>(
GRFFile *grffile, uint16_t local_id) {
return local_id < grffile->housespec.size() ? grffile->housespec[local_id].get() :
nullptr; }
262template <>
auto *
GetSpec<IndustrySpec>(
GRFFile *grffile, uint16_t local_id) {
return local_id < grffile->industryspec.size() ? grffile->industryspec[local_id].get() :
nullptr; }
265template <>
auto *
GetSpec<IndustryTileSpec>(
GRFFile *grffile, uint16_t local_id) {
return local_id < grffile->indtspec.size() ? grffile->indtspec[local_id].get() :
nullptr; }
274 GrfMsg(1,
"CargoMapSpriteGroup: Cargo type {} out of range, skipping", local_id);
277 cs->
grffile = _cur_gps.grffile;
283template <>
auto *
GetSpec<ObjectSpec>(
GRFFile *grffile, uint16_t local_id) {
return local_id < grffile->objectspec.size() ? grffile->objectspec[local_id].get() :
nullptr; }
292 const auto &type_map = _cur_gps.grffile->railtype_map;
298 rti.
grffile[rst] = _cur_gps.grffile;
299 rti.
group[rst] = group;
305template <RoadTramType TRoadTramType>
312 const auto &type_map = (TRoadTramType ==
RoadTramType::Tram) ? _cur_gps.grffile->tramtype_map : _cur_gps.grffile->roadtype_map;
318 rti.
grffile[rst] = _cur_gps.grffile;
319 rti.
group[rst] = group;
325template <>
auto *
GetSpec<AirportSpec>(
GRFFile *grffile, uint16_t local_id) {
return local_id < grffile->airportspec.size() ? grffile->airportspec[local_id].get() :
nullptr; }
328template <>
auto *
GetSpec<AirportTileSpec>(
GRFFile *grffile, uint16_t local_id) {
return local_id < grffile->airtspec.size() ? grffile->airtspec[local_id].get() :
nullptr; }
331template <>
auto *
GetSpec<RoadStopSpec>(
GRFFile *grffile, uint16_t local_id) {
return local_id < grffile->roadstops.size() ? grffile->roadstops[local_id].get() :
nullptr; }
339 auto found = _cur_gps.grffile->badge_map.find(local_id);
340 if (found == std::end(_cur_gps.grffile->badge_map)) {
341 GrfMsg(1,
"BadgeMapSpriteGroup: Badge {} undefined, skipping", local_id);
343 auto &badge = *
GetBadge(found->second);
344 badge.grf_prop.SetSpriteGroup(
static_cast<GrfSpecFeature>(cid), group);
350 auto found = _cur_gps.grffile->badge_map.find(local_id);
351 if (found == std::end(_cur_gps.grffile->badge_map)) {
352 GrfMsg(1,
"BadgeMapSpriteGroup: Badge {} undefined, skipping", local_id);
354 auto &badge = *
GetBadge(found->second);
356 badge.grf_prop.SetGRFFile(_cur_gps.grffile);
357 badge.grf_prop.local_id = local_id;
365 std::array<uint16_t, 256> local_ids_buffer;
366 for (uint i = 0; i != idcount; ++i) {
369 std::span<const uint16_t> local_ids{local_ids_buffer.begin(), idcount};
373 for (uint c = 0; c != cidcount; ++c) {
376 if (!IsValidGroupID(groupid,
"MapSpriteGroup"))
continue;
377 for (uint16_t local_id : local_ids) {
378 handler.MapSpecific(local_id, cid, _cur_gps.spritegroups[groupid]);
384 if (!IsValidGroupID(groupid,
"MapSpriteGroup"))
return;
385 for (uint16_t local_id : local_ids) {
386 handler.MapDefault(local_id, _cur_gps.spritegroups[groupid]);
391static void FeatureMapSpriteGroup(
ByteReader &buf)
411 GrfMsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x{:02X}, skipping", feature);
420 if (!IsValidGroupID(groupid,
"FeatureMapSpriteGroup"))
return;
422 GrfMsg(6,
"FeatureMapSpriteGroup: Adding generic feature callback for feature 0x{:02X}", feature);
429 _cur_gps.grffile->grf_features.Set(feature);
431 GrfMsg(6,
"FeatureMapSpriteGroup: Feature 0x{:02X}, {} ids", feature, idcount);
454 GrfMsg(1,
"FeatureMapSpriteGroup: Unsupported feature 0x{:02X}, skipping", feature);
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
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.
StrongType::Typedef< uint32_t, struct CargoLabelTag, StrongType::Compare > CargoLabel
Globally unique label of a cargo type.
static const CargoType NUM_CARGO
Maximum number of cargo types in a game.
Class to read from a NewGRF file.
uint16_t ReadWord()
Read a single Word (16 bits).
uint16_t ReadExtendedByte()
Read a single Extended Byte (8 or 16 bits).
uint8_t ReadByte()
Read a single byte (8 bits).
This struct contains all the info that is needed to draw and construct tracks.
EnumClassIndexContainer< std::array< const GRFFile *, to_underlying(RailSpriteType::End)>, RailSpriteType > grffile
NewGRF providing the Action3 for the railtype.
EnumClassIndexContainer< std::array< const SpriteGroup *, to_underlying(RailSpriteType::End)>, RailSpriteType > group
Sprite groups for resolving sprites.
EnumClassIndexContainer< std::array< const SpriteGroup *, to_underlying(RoadSpriteType::End)>, RoadSpriteType > group
Sprite groups for resolving sprites.
EnumClassIndexContainer< std::array< const GRFFile *, to_underlying(RoadSpriteType::End)>, RoadSpriteType > grffile
NewGRF providing the Action3 for the roadtype.
Functions related to debugging.
PoolID< uint16_t, struct EngineIDTag, 64000, 0xFFFF > EngineID
Unique identification number of an engine.
#define T
Climate temperate.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Functions related to errors.
Definition of HouseSpec and accessors.
std::span< const CargoLabel > GetCargoTranslationTable(const GRFFile &grffile)
Get the cargo translation table to use for the given GRF file.
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.
VehicleType GetVehicleType(GrfSpecFeature feature)
Get the VehicleType associated with a GrfSpecFeature.
Base for the NewGRF implementation.
@ RoadStops
Road stops feature.
@ RailTypes
Rail types feature.
@ Cargoes
Cargoes feature.
@ RoadVehicles
Road vehicles feature.
@ TramTypes
Tram types feature.
@ RoadTypes
Road types feature.
@ Default
Unspecified feature, default badge.
@ Stations
Stations feature.
@ Airports
Airports feature.
@ Aircraft
Aircraft feature.
@ IndustryTiles
Industry tiles feature.
@ Objects
Objects feature.
@ AirportTiles
Airport tiles feature.
@ Industries
Industries feature.
static auto * GetSpec(GRFFile *grffile, uint16_t local_id)
Specializable function to retrieve a NewGRF spec of a particular type.
NewGRF handling of airports.
NewGRF handling of airport tiles.
Badge * GetBadge(BadgeID index)
Get a badge if it exists.
Functions related to NewGRF badges.
Types related to NewGRF badges.
NewGRF buffer reader definition.
std::array< WaterFeature, CF_END > _water_feature
Table of canal 'feature' sprite groups.
Handling of NewGRF canals.
Cargo support for NewGRFs.
@ Purchase
Used before an entity exists.
@ Default
Default type used when no more-specific group matches.
void SetEngineGRF(EngineID engine, const GRFFile *file)
Tie a GRFFile entry to an engine, to allow us to retrieve GRF parameters etc during a game.
Functions for NewGRF engines.
void AddGenericCallback(GrfSpecFeature feature, const GRFFile *file, const SpriteGroup *group)
Add a generic feature callback sprite group to the appropriate feature list.
Functions related to NewGRF houses.
NewGRF internal processing state.
@ InvalidId
Attempt to modify an invalid ID.
static constexpr uint MAX_SPRITEGROUP
Maximum GRF-local ID for a spritegroup.
NewGRF internal processing state for vehicles.
Functions related to NewGRF objects.
NewGRF definitions and structures for road stops.
Header file for NewGRF stations.
RailSpriteType
Sprite types for a railtype.
RailType
Enumeration for all possible railtypes.
@ RAILTYPE_END
Used for iterations.
@ INVALID_RAILTYPE
Flag for invalid railtype.
RoadSpriteType
Sprite types for a roadtype.
RoadType
The different roadtypes we support.
@ INVALID_ROADTYPE
flag for invalid roadtype
@ ROADTYPE_END
Used for iterations.
A number of safeguards to prevent using unsafe methods.
Definition of base types and functions in a cross-platform compatible way.
void MapDefault(uint16_t local_id, const SpriteGroup *group) override
Map default/fallback SpriteGroup to a specification.
void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
Map a SpriteGroup to specific 'cargo type' of a specification.
void MapSpecific(uint16_t, uint8_t, const SpriteGroup *) override
Map a SpriteGroup to specific 'cargo type' of a specification.
void MapDefault(uint16_t local_id, const SpriteGroup *group) override
Map default/fallback SpriteGroup to a specification.
static constexpr CargoType SG_PURCHASE
Used in purchase lists before an item exists.
static constexpr CargoType SG_DEFAULT
Default type used when no more-specific cargo matches.
static constexpr CargoType SG_DEFAULT_NA
Used only by stations and roads when no more-specific cargo matches.
void MapDefault(uint16_t local_id, const SpriteGroup *group) override
Map default/fallback SpriteGroup to a specification.
void MapSpecific(uint16_t, uint8_t, const SpriteGroup *) override
Map a SpriteGroup to specific 'cargo type' of a specification.
Specification of a cargo type.
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo type.
const struct GRFFile * grffile
NewGRF where group belongs to.
Common handler for mapping sprite groups for features which support cargo-type specific sprites.
void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
Map a SpriteGroup to specific 'cargo type' of a specification.
void MapDefault(uint16_t local_id, const SpriteGroup *group) override
Map default/fallback SpriteGroup to a specification.
Dynamic data of a loaded NewGRF.
static void FileScan(ByteReader &buf)
Implementation of the GrfLoadingStage::FileScan stage of this action.
static void SafetyScan(ByteReader &buf)
Implementation of the GrfLoadingStage::SafetyScan stage of this action.
static void Reserve(ByteReader &buf)
Implementation of the GrfLoadingStage::Reserve stage of this action.
static void Activation(ByteReader &buf)
Implementation of the GrfLoadingStage::Activation stage of this action.
static void Init(ByteReader &buf)
Implementation of the GrfLoadingStage::Init stage of this action.
static void LabelScan(ByteReader &buf)
Implementation of the GrfLoadingStage::LabelScan stage of this action.
Handler interface for mapping sprite groups to their respective feature specific specifications.
virtual void MapDefault(uint16_t local_id, const SpriteGroup *group)=0
Map default/fallback SpriteGroup to a specification.
virtual void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group)=0
Map a SpriteGroup to specific 'cargo type' of a specification.
virtual ~MapSpriteGroupHandler()=default
Ensure the destructor of the sub classes are called as well.
Common handler for mapping sprite groups for features which only support "Purchase" and "Default" spr...
void MapDefault(uint16_t local_id, const SpriteGroup *group) override
Map default/fallback SpriteGroup to a specification.
void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
Map a SpriteGroup to specific 'cargo type' of a specification.
void MapDefault(uint16_t, const SpriteGroup *) override
Map default/fallback SpriteGroup to a specification.
void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
Map a SpriteGroup to specific 'cargo type' of a specification.
void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
Map a SpriteGroup to specific 'cargo type' of a specification.
void MapDefault(uint16_t, const SpriteGroup *) override
Map default/fallback SpriteGroup to a specification.
Common wrapper for all the different sprite group types.
Base class for all vehicles.