diff --git a/src/engine_base.h b/src/engine_base.h index ab7862e9f5..edeb45d2ff 100644 --- a/src/engine_base.h +++ b/src/engine_base.h @@ -74,13 +74,7 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> { uint16_t list_position = 0; /* NewGRF related data */ - /** - * Properties related the the grf file. - * NUM_CARGO real cargo plus two pseudo cargo sprite groups. - * Used for obtaining the sprite offset of custom sprites, and for - * evaluating callbacks. - */ - VariableGRFFileProps grf_prop{}; + CargoGRFFileProps grf_prop{}; ///< Link to NewGRF std::vector overrides{}; std::vector badges{}; diff --git a/src/newgrf/newgrf_act3.cpp b/src/newgrf/newgrf_act3.cpp index c68cba4dc1..34fc0e62f9 100644 --- a/src/newgrf/newgrf_act3.cpp +++ b/src/newgrf/newgrf_act3.cpp @@ -36,8 +36,8 @@ static CargoType TranslateCargo(uint8_t feature, uint8_t ctype) { /* Special cargo types for purchase list and stations */ - if ((feature == GSF_STATIONS || feature == GSF_ROADSTOPS) && ctype == 0xFE) return SpriteGroupCargo::SG_DEFAULT_NA; - if (ctype == 0xFF) return SpriteGroupCargo::SG_PURCHASE; + if ((feature == GSF_STATIONS || feature == GSF_ROADSTOPS) && ctype == 0xFE) return CargoGRFFileProps::SG_DEFAULT_NA; + if (ctype == 0xFF) return CargoGRFFileProps::SG_PURCHASE; auto cargo_list = GetCargoTranslationTable(*_cur_gps.grffile); @@ -145,9 +145,9 @@ static void VehicleMapSpriteGroup(ByteReader &buf, uint8_t feature, uint8_t idco EngineID engine = engines[i]; if (wagover) { - SetWagonOverrideSprites(engine, SpriteGroupCargo::SG_DEFAULT, _cur_gps.spritegroups[groupid], last_engines); + SetWagonOverrideSprites(engine, CargoGRFFileProps::SG_DEFAULT, _cur_gps.spritegroups[groupid], last_engines); } else { - SetCustomEngineSprites(engine, SpriteGroupCargo::SG_DEFAULT, _cur_gps.spritegroups[groupid]); + SetCustomEngineSprites(engine, CargoGRFFileProps::SG_DEFAULT, _cur_gps.spritegroups[groupid]); SetEngineGRF(engine, _cur_gps.grffile); } } @@ -199,8 +199,8 @@ static void StationMapSpriteGroup(ByteReader &buf, uint8_t idcount) uint16_t groupid = buf.ReadWord(); if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue; - ctype = TranslateCargo(GSF_STATIONS, ctype); - if (!IsValidCargoType(ctype)) continue; + CargoType cargo_type = TranslateCargo(GSF_STATIONS, ctype); + if (!IsValidCargoType(cargo_type)) continue; for (auto &station : stations) { StationSpec *statspec = station >= _cur_gps.grffile->stations.size() ? nullptr : _cur_gps.grffile->stations[station].get(); @@ -210,7 +210,7 @@ static void StationMapSpriteGroup(ByteReader &buf, uint8_t idcount) continue; } - statspec->grf_prop.SetSpriteGroup(ctype, _cur_gps.spritegroups[groupid]); + statspec->grf_prop.SetSpriteGroup(cargo_type, _cur_gps.spritegroups[groupid]); } } @@ -230,7 +230,7 @@ static void StationMapSpriteGroup(ByteReader &buf, uint8_t idcount) continue; } - statspec->grf_prop.SetSpriteGroup(SpriteGroupCargo::SG_DEFAULT, _cur_gps.spritegroups[groupid]); + statspec->grf_prop.SetSpriteGroup(CargoGRFFileProps::SG_DEFAULT, _cur_gps.spritegroups[groupid]); statspec->grf_prop.SetGRFFile(_cur_gps.grffile); statspec->grf_prop.local_id = station; StationClass::Assign(statspec); @@ -569,8 +569,8 @@ static void RoadStopMapSpriteGroup(ByteReader &buf, uint8_t idcount) uint16_t groupid = buf.ReadWord(); if (!IsValidGroupID(groupid, "RoadStopMapSpriteGroup")) continue; - ctype = TranslateCargo(GSF_ROADSTOPS, ctype); - if (!IsValidCargoType(ctype)) continue; + CargoType cargo_type = TranslateCargo(GSF_ROADSTOPS, ctype); + if (!IsValidCargoType(cargo_type)) continue; for (auto &roadstop : roadstops) { RoadStopSpec *roadstopspec = roadstop >= _cur_gps.grffile->roadstops.size() ? nullptr : _cur_gps.grffile->roadstops[roadstop].get(); @@ -580,7 +580,7 @@ static void RoadStopMapSpriteGroup(ByteReader &buf, uint8_t idcount) continue; } - roadstopspec->grf_prop.SetSpriteGroup(ctype, _cur_gps.spritegroups[groupid]); + roadstopspec->grf_prop.SetSpriteGroup(cargo_type, _cur_gps.spritegroups[groupid]); } } @@ -600,7 +600,7 @@ static void RoadStopMapSpriteGroup(ByteReader &buf, uint8_t idcount) continue; } - roadstopspec->grf_prop.SetSpriteGroup(SpriteGroupCargo::SG_DEFAULT, _cur_gps.spritegroups[groupid]); + roadstopspec->grf_prop.SetSpriteGroup(CargoGRFFileProps::SG_DEFAULT, _cur_gps.spritegroups[groupid]); roadstopspec->grf_prop.SetGRFFile(_cur_gps.grffile); roadstopspec->grf_prop.local_id = roadstop; RoadStopClass::Assign(roadstopspec); @@ -636,7 +636,7 @@ static void BadgeMapSpriteGroup(ByteReader &buf, uint8_t idcount) } auto &badge = *GetBadge(found->second); - badge.grf_prop.SetSpriteGroup(ctype, _cur_gps.spritegroups[groupid]); + badge.grf_prop.SetSpriteGroup(static_cast(ctype), _cur_gps.spritegroups[groupid]); } } diff --git a/src/newgrf_badge.h b/src/newgrf_badge.h index 4b08d31618..dca2bd6995 100644 --- a/src/newgrf_badge.h +++ b/src/newgrf_badge.h @@ -24,7 +24,7 @@ public: BadgeFlags flags = {}; ///< Display flags StringID name = 0; ///< Short name. GrfSpecFeatures features{}; ///< Bitmask of which features use this badge. - VariableGRFFileProps grf_prop; ///< Sprite information. + VariableGRFFileProps grf_prop; ///< Sprite information. Badge(std::string_view label, BadgeID index, BadgeClassID class_index) : label(label), index(index), class_index(class_index) {} }; diff --git a/src/newgrf_cargo.h b/src/newgrf_cargo.h index 649c9ee420..544a58f576 100644 --- a/src/newgrf_cargo.h +++ b/src/newgrf_cargo.h @@ -14,17 +14,6 @@ #include "cargo_type.h" #include "gfx_type.h" -/** - * Sprite Group Cargo types. - * These special cargo types are used when resolving sprite groups when non-cargo-specific sprites or callbacks are needed, - * e.g. in purchase lists, or if no specific cargo type sprite group is supplied. - */ -namespace SpriteGroupCargo { - static constexpr CargoType SG_DEFAULT = NUM_CARGO; ///< Default type used when no more-specific cargo matches. - static constexpr CargoType SG_PURCHASE = NUM_CARGO + 1; ///< Used in purchase lists before an item exists. - static constexpr CargoType SG_DEFAULT_NA = NUM_CARGO + 2; ///< Used only by stations and roads when no more-specific cargo matches. -}; - /* Forward declarations of structs used */ struct CargoSpec; struct GRFFile; diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp index 3b03f253ff..6ad066bf64 100644 --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -740,30 +740,3 @@ void GRFFilePropsBase::SetGRFFile(const struct GRFFile *grffile) this->grffile = grffile; this->grfid = grffile == nullptr ? 0 : grffile->grfid; } - -/** - * Get the SpriteGroup at the specified index. - * @param index Index to get. - * @returns SpriteGroup at index, or nullptr if not present. - */ -const SpriteGroup *VariableGRFFileProps::GetSpriteGroup(size_t index) const -{ - auto it = std::ranges::lower_bound(this->spritegroups, index, std::less{}, &CargoSpriteGroup::first); - if (it == std::end(this->spritegroups) || it->first != index) return nullptr; - return it->second; -} - -/** - * Set the SpriteGroup at the specified index. - * @param index Index to set. - * @param spritegroup SpriteGroup to set. - */ -void VariableGRFFileProps::SetSpriteGroup(size_t index, const SpriteGroup *spritegroup) -{ - auto it = std::ranges::lower_bound(this->spritegroups, index, std::less{}, &CargoSpriteGroup::first); - if (it == std::end(this->spritegroups) || it->first != index) { - this->spritegroups.emplace(it, index, spritegroup); - } else { - it->second = spritegroup; - } -} diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index d553bd6e49..538014173a 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -18,6 +18,7 @@ #include "command_type.h" #include "direction_type.h" #include "company_type.h" +#include "cargo_type.h" /** Context for tile accesses */ enum TileContext : uint8_t { @@ -328,13 +329,48 @@ struct FixedGRFFileProps : GRFFilePropsBase { /** * Variable-length list of sprite groups for an entity. + * @tparam Tkey Key for indexing spritegroups */ +template struct VariableGRFFileProps : GRFFilePropsBase { - using CargoSpriteGroup = std::pair; - std::vector spritegroups; ///< pointers to the different sprite groups of the entity + using ValueType = std::pair; + std::vector spritegroups; ///< pointers to the different sprite groups of the entity - const struct SpriteGroup *GetSpriteGroup(size_t index) const; - void SetSpriteGroup(size_t index, const struct SpriteGroup *spritegroup); + /** + * Get the SpriteGroup at the specified index. + * @param index Index to get. + * @returns SpriteGroup at index, or nullptr if not present. + */ + const SpriteGroup *GetSpriteGroup(Tkey index) const + { + auto it = std::ranges::lower_bound(this->spritegroups, index, std::less{}, &ValueType::first); + if (it == std::end(this->spritegroups) || it->first != index) return nullptr; + return it->second; + } + + /** + * Set the SpriteGroup at the specified index. + * @param index Index to set. + * @param spritegroup SpriteGroup to set. + */ + void SetSpriteGroup(Tkey index, const SpriteGroup *spritegroup) + { + auto it = std::ranges::lower_bound(this->spritegroups, index, std::less{}, &ValueType::first); + if (it == std::end(this->spritegroups) || it->first != index) { + this->spritegroups.emplace(it, index, spritegroup); + } else { + it->second = spritegroup; + } + } +}; + +/** + * Sprite groups indexed by CargoType. + */ +struct CargoGRFFileProps : VariableGRFFileProps { + static constexpr CargoType SG_DEFAULT = NUM_CARGO; ///< Default type used when no more-specific cargo matches. + static constexpr CargoType SG_PURCHASE = NUM_CARGO + 1; ///< Used in purchase lists before an item exists. + static constexpr CargoType SG_DEFAULT_NA = NUM_CARGO + 2; ///< Used only by stations and roads when no more-specific cargo matches. }; /** Data related to the handling of grf files. */ diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 5bb85806bb..1f9c55fa30 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -45,7 +45,7 @@ const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoType cargo, E const Engine *e = Engine::Get(engine); for (const WagonOverride &wo : e->overrides) { - if (wo.cargo != cargo && wo.cargo != SpriteGroupCargo::SG_DEFAULT) continue; + if (wo.cargo != cargo && wo.cargo != CargoGRFFileProps::SG_DEFAULT) continue; if (std::ranges::find(wo.engines, overriding_engine) != wo.engines.end()) return wo.group; } return nullptr; @@ -1068,7 +1068,7 @@ VehicleResolverObject::VehicleResolverObject(EngineID engine_type, const Vehicle cached_relative_count(0) { if (wagon_override == WO_SELF) { - this->root_spritegroup = GetWagonOverrideSpriteSet(engine_type, SpriteGroupCargo::SG_DEFAULT, engine_type); + this->root_spritegroup = GetWagonOverrideSpriteSet(engine_type, CargoGRFFileProps::SG_DEFAULT, engine_type); } else { if (wagon_override != WO_NONE && v != nullptr && v->IsGroundVehicle()) { assert(v->engine_type == engine_type); // overrides make little sense with fake scopes @@ -1085,9 +1085,9 @@ VehicleResolverObject::VehicleResolverObject(EngineID engine_type, const Vehicle if (this->root_spritegroup == nullptr) { const Engine *e = Engine::Get(engine_type); - CargoType cargo = v != nullptr ? v->cargo_type : SpriteGroupCargo::SG_PURCHASE; + CargoType cargo = v != nullptr ? v->cargo_type : CargoGRFFileProps::SG_PURCHASE; this->root_spritegroup = e->grf_prop.GetSpriteGroup(cargo); - if (this->root_spritegroup == nullptr) this->root_spritegroup = e->grf_prop.GetSpriteGroup(SpriteGroupCargo::SG_DEFAULT); + if (this->root_spritegroup == nullptr) this->root_spritegroup = e->grf_prop.GetSpriteGroup(CargoGRFFileProps::SG_DEFAULT); } } } diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp index f0700b1ebb..57ce2828c3 100644 --- a/src/newgrf_roadstop.cpp +++ b/src/newgrf_roadstop.cpp @@ -229,11 +229,11 @@ RoadStopResolverObject::RoadStopResolverObject(const RoadStopSpec *roadstopspec, CallbackID callback, uint32_t param1, uint32_t param2) : SpecializedResolverObject(roadstopspec->grf_prop.grffile, callback, param1, param2), roadstop_scope(*this, st, roadstopspec, tile, roadtype, type, view) { - CargoType ctype = SpriteGroupCargo::SG_DEFAULT_NA; + CargoType ctype = CargoGRFFileProps::SG_DEFAULT_NA; if (st == nullptr) { /* No station, so we are in a purchase list */ - ctype = SpriteGroupCargo::SG_PURCHASE; + ctype = CargoGRFFileProps::SG_PURCHASE; this->root_spritegroup = roadstopspec->grf_prop.GetSpriteGroup(ctype); } else if (Station::IsExpected(st)) { const Station *station = Station::From(st); @@ -247,13 +247,13 @@ RoadStopResolverObject::RoadStopResolverObject(const RoadStopSpec *roadstopspec, } if (this->root_spritegroup == nullptr) { - ctype = SpriteGroupCargo::SG_DEFAULT_NA; + ctype = CargoGRFFileProps::SG_DEFAULT_NA; this->root_spritegroup = roadstopspec->grf_prop.GetSpriteGroup(ctype); } } if (this->root_spritegroup == nullptr) { - ctype = SpriteGroupCargo::SG_DEFAULT; + ctype = CargoGRFFileProps::SG_DEFAULT; this->root_spritegroup = roadstopspec->grf_prop.GetSpriteGroup(ctype); } diff --git a/src/newgrf_roadstop.h b/src/newgrf_roadstop.h index f7b61e7e1b..3d89ccb6bc 100644 --- a/src/newgrf_roadstop.h +++ b/src/newgrf_roadstop.h @@ -128,13 +128,7 @@ struct RoadStopResolverObject : public SpecializedResolverObject { - /** - * Properties related the the grf file. - * NUM_CARGO real cargo plus three pseudo cargo sprite groups. - * Used for obtaining the sprite offset of custom sprites, and for - * evaluating callbacks. - */ - VariableGRFFileProps grf_prop; + CargoGRFFileProps grf_prop; ///< Link to NewGRF StringID name; ///< Name of this stop RoadStopAvailabilityType stop_type = ROADSTOPTYPE_ALL; diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 9b5c3e9f81..28e81f7ee8 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -530,12 +530,12 @@ uint32_t Waypoint::GetNewGRFVariable(const ResolverObject &, uint8_t variable, [ switch (this->station_scope.cargo_type) { case INVALID_CARGO: - case SpriteGroupCargo::SG_DEFAULT_NA: - case SpriteGroupCargo::SG_PURCHASE: + case CargoGRFFileProps::SG_DEFAULT_NA: + case CargoGRFFileProps::SG_PURCHASE: cargo = 0; break; - case SpriteGroupCargo::SG_DEFAULT: + case CargoGRFFileProps::SG_DEFAULT: for (const GoodsEntry &ge : st->goods) { if (!ge.HasData()) continue; cargo += ge.GetData().cargo.TotalCount(); @@ -594,11 +594,11 @@ StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseSt /* Invalidate all cached vars */ _svc.valid = 0; - CargoType ctype = SpriteGroupCargo::SG_DEFAULT_NA; + CargoType ctype = CargoGRFFileProps::SG_DEFAULT_NA; if (this->station_scope.st == nullptr) { /* No station, so we are in a purchase list */ - ctype = SpriteGroupCargo::SG_PURCHASE; + ctype = CargoGRFFileProps::SG_PURCHASE; this->root_spritegroup = statspec->grf_prop.GetSpriteGroup(ctype); } else if (Station::IsExpected(this->station_scope.st)) { const Station *st = Station::From(this->station_scope.st); @@ -612,14 +612,14 @@ StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseSt } if (this->root_spritegroup == nullptr) { - ctype = SpriteGroupCargo::SG_DEFAULT_NA; + ctype = CargoGRFFileProps::SG_DEFAULT_NA; this->root_spritegroup = statspec->grf_prop.GetSpriteGroup(ctype); } } if (this->root_spritegroup == nullptr) { - ctype = SpriteGroupCargo::SG_DEFAULT; + ctype = CargoGRFFileProps::SG_DEFAULT; this->root_spritegroup = statspec->grf_prop.GetSpriteGroup(ctype); } diff --git a/src/newgrf_station.h b/src/newgrf_station.h index ef3bcbee01..2be7947e43 100644 --- a/src/newgrf_station.h +++ b/src/newgrf_station.h @@ -110,13 +110,8 @@ struct StationSpec : NewGRFSpecBase { cargo_threshold(0), cargo_triggers(0), callback_mask(0), flags(0) {} - /** - * Properties related the the grf file. - * NUM_CARGO real cargo plus three pseudo cargo sprite groups. - * Used for obtaining the sprite offset of custom sprites, and for - * evaluating callbacks. - */ - VariableGRFFileProps grf_prop; + + CargoGRFFileProps grf_prop; ///< Link to NewGRF StringID name; ///< Name of this station. /**