1
0
Fork 0

Codechange: Use proper enum type to index sprite groups in VariableGRFFileProps.

pull/14133/head
frosch 2025-04-26 18:57:03 +02:00 committed by frosch
parent 893aa0fb91
commit 41a20e512d
11 changed files with 73 additions and 92 deletions

View File

@ -74,13 +74,7 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> {
uint16_t list_position = 0; uint16_t list_position = 0;
/* NewGRF related data */ /* NewGRF related data */
/** CargoGRFFileProps grf_prop{}; ///< Link to NewGRF
* 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{};
std::vector<WagonOverride> overrides{}; std::vector<WagonOverride> overrides{};
std::vector<BadgeID> badges{}; std::vector<BadgeID> badges{};

View File

@ -36,8 +36,8 @@
static CargoType TranslateCargo(uint8_t feature, uint8_t ctype) static CargoType TranslateCargo(uint8_t feature, uint8_t ctype)
{ {
/* Special cargo types for purchase list and stations */ /* Special cargo types for purchase list and stations */
if ((feature == GSF_STATIONS || feature == GSF_ROADSTOPS) && ctype == 0xFE) return SpriteGroupCargo::SG_DEFAULT_NA; if ((feature == GSF_STATIONS || feature == GSF_ROADSTOPS) && ctype == 0xFE) return CargoGRFFileProps::SG_DEFAULT_NA;
if (ctype == 0xFF) return SpriteGroupCargo::SG_PURCHASE; if (ctype == 0xFF) return CargoGRFFileProps::SG_PURCHASE;
auto cargo_list = GetCargoTranslationTable(*_cur_gps.grffile); 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]; EngineID engine = engines[i];
if (wagover) { 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 { } else {
SetCustomEngineSprites(engine, SpriteGroupCargo::SG_DEFAULT, _cur_gps.spritegroups[groupid]); SetCustomEngineSprites(engine, CargoGRFFileProps::SG_DEFAULT, _cur_gps.spritegroups[groupid]);
SetEngineGRF(engine, _cur_gps.grffile); SetEngineGRF(engine, _cur_gps.grffile);
} }
} }
@ -199,8 +199,8 @@ static void StationMapSpriteGroup(ByteReader &buf, uint8_t idcount)
uint16_t groupid = buf.ReadWord(); uint16_t groupid = buf.ReadWord();
if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue; if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
ctype = TranslateCargo(GSF_STATIONS, ctype); CargoType cargo_type = TranslateCargo(GSF_STATIONS, ctype);
if (!IsValidCargoType(ctype)) continue; if (!IsValidCargoType(cargo_type)) continue;
for (auto &station : stations) { for (auto &station : stations) {
StationSpec *statspec = station >= _cur_gps.grffile->stations.size() ? nullptr : _cur_gps.grffile->stations[station].get(); 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; 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; 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.SetGRFFile(_cur_gps.grffile);
statspec->grf_prop.local_id = station; statspec->grf_prop.local_id = station;
StationClass::Assign(statspec); StationClass::Assign(statspec);
@ -569,8 +569,8 @@ static void RoadStopMapSpriteGroup(ByteReader &buf, uint8_t idcount)
uint16_t groupid = buf.ReadWord(); uint16_t groupid = buf.ReadWord();
if (!IsValidGroupID(groupid, "RoadStopMapSpriteGroup")) continue; if (!IsValidGroupID(groupid, "RoadStopMapSpriteGroup")) continue;
ctype = TranslateCargo(GSF_ROADSTOPS, ctype); CargoType cargo_type = TranslateCargo(GSF_ROADSTOPS, ctype);
if (!IsValidCargoType(ctype)) continue; if (!IsValidCargoType(cargo_type)) continue;
for (auto &roadstop : roadstops) { for (auto &roadstop : roadstops) {
RoadStopSpec *roadstopspec = roadstop >= _cur_gps.grffile->roadstops.size() ? nullptr : _cur_gps.grffile->roadstops[roadstop].get(); 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; 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; 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.SetGRFFile(_cur_gps.grffile);
roadstopspec->grf_prop.local_id = roadstop; roadstopspec->grf_prop.local_id = roadstop;
RoadStopClass::Assign(roadstopspec); RoadStopClass::Assign(roadstopspec);
@ -636,7 +636,7 @@ static void BadgeMapSpriteGroup(ByteReader &buf, uint8_t idcount)
} }
auto &badge = *GetBadge(found->second); auto &badge = *GetBadge(found->second);
badge.grf_prop.SetSpriteGroup(ctype, _cur_gps.spritegroups[groupid]); badge.grf_prop.SetSpriteGroup(static_cast<GrfSpecFeature>(ctype), _cur_gps.spritegroups[groupid]);
} }
} }

View File

@ -24,7 +24,7 @@ public:
BadgeFlags flags = {}; ///< Display flags BadgeFlags flags = {}; ///< Display flags
StringID name = 0; ///< Short name. StringID name = 0; ///< Short name.
GrfSpecFeatures features{}; ///< Bitmask of which features use this badge. GrfSpecFeatures features{}; ///< Bitmask of which features use this badge.
VariableGRFFileProps grf_prop; ///< Sprite information. VariableGRFFileProps<GrfSpecFeature> grf_prop; ///< Sprite information.
Badge(std::string_view label, BadgeID index, BadgeClassID class_index) : label(label), index(index), class_index(class_index) {} Badge(std::string_view label, BadgeID index, BadgeClassID class_index) : label(label), index(index), class_index(class_index) {}
}; };

View File

@ -14,17 +14,6 @@
#include "cargo_type.h" #include "cargo_type.h"
#include "gfx_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 */ /* Forward declarations of structs used */
struct CargoSpec; struct CargoSpec;
struct GRFFile; struct GRFFile;

View File

@ -740,30 +740,3 @@ void GRFFilePropsBase::SetGRFFile(const struct GRFFile *grffile)
this->grffile = grffile; this->grffile = grffile;
this->grfid = grffile == nullptr ? 0 : grffile->grfid; 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;
}
}

View File

@ -18,6 +18,7 @@
#include "command_type.h" #include "command_type.h"
#include "direction_type.h" #include "direction_type.h"
#include "company_type.h" #include "company_type.h"
#include "cargo_type.h"
/** Context for tile accesses */ /** Context for tile accesses */
enum TileContext : uint8_t { enum TileContext : uint8_t {
@ -328,13 +329,48 @@ struct FixedGRFFileProps : GRFFilePropsBase {
/** /**
* Variable-length list of sprite groups for an entity. * Variable-length list of sprite groups for an entity.
* @tparam Tkey Key for indexing spritegroups
*/ */
template <class Tkey>
struct VariableGRFFileProps : GRFFilePropsBase { struct VariableGRFFileProps : GRFFilePropsBase {
using CargoSpriteGroup = std::pair<size_t, const struct SpriteGroup *>; using ValueType = std::pair<Tkey, const struct SpriteGroup *>;
std::vector<CargoSpriteGroup> spritegroups; ///< pointers to the different sprite groups of the entity std::vector<ValueType> 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<CargoType> {
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. */ /** Data related to the handling of grf files. */

View File

@ -45,7 +45,7 @@ const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoType cargo, E
const Engine *e = Engine::Get(engine); const Engine *e = Engine::Get(engine);
for (const WagonOverride &wo : e->overrides) { 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; if (std::ranges::find(wo.engines, overriding_engine) != wo.engines.end()) return wo.group;
} }
return nullptr; return nullptr;
@ -1068,7 +1068,7 @@ VehicleResolverObject::VehicleResolverObject(EngineID engine_type, const Vehicle
cached_relative_count(0) cached_relative_count(0)
{ {
if (wagon_override == WO_SELF) { 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 { } else {
if (wagon_override != WO_NONE && v != nullptr && v->IsGroundVehicle()) { if (wagon_override != WO_NONE && v != nullptr && v->IsGroundVehicle()) {
assert(v->engine_type == engine_type); // overrides make little sense with fake scopes 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) { if (this->root_spritegroup == nullptr) {
const Engine *e = Engine::Get(engine_type); 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); 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);
} }
} }
} }

View File

@ -229,11 +229,11 @@ RoadStopResolverObject::RoadStopResolverObject(const RoadStopSpec *roadstopspec,
CallbackID callback, uint32_t param1, uint32_t param2) CallbackID callback, uint32_t param1, uint32_t param2)
: SpecializedResolverObject<StationRandomTriggers>(roadstopspec->grf_prop.grffile, callback, param1, param2), roadstop_scope(*this, st, roadstopspec, tile, roadtype, type, view) : SpecializedResolverObject<StationRandomTriggers>(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) { if (st == nullptr) {
/* No station, so we are in a purchase list */ /* 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); this->root_spritegroup = roadstopspec->grf_prop.GetSpriteGroup(ctype);
} else if (Station::IsExpected(st)) { } else if (Station::IsExpected(st)) {
const Station *station = Station::From(st); const Station *station = Station::From(st);
@ -247,13 +247,13 @@ RoadStopResolverObject::RoadStopResolverObject(const RoadStopSpec *roadstopspec,
} }
if (this->root_spritegroup == nullptr) { if (this->root_spritegroup == nullptr) {
ctype = SpriteGroupCargo::SG_DEFAULT_NA; ctype = CargoGRFFileProps::SG_DEFAULT_NA;
this->root_spritegroup = roadstopspec->grf_prop.GetSpriteGroup(ctype); this->root_spritegroup = roadstopspec->grf_prop.GetSpriteGroup(ctype);
} }
} }
if (this->root_spritegroup == nullptr) { if (this->root_spritegroup == nullptr) {
ctype = SpriteGroupCargo::SG_DEFAULT; ctype = CargoGRFFileProps::SG_DEFAULT;
this->root_spritegroup = roadstopspec->grf_prop.GetSpriteGroup(ctype); this->root_spritegroup = roadstopspec->grf_prop.GetSpriteGroup(ctype);
} }

View File

@ -128,13 +128,7 @@ struct RoadStopResolverObject : public SpecializedResolverObject<StationRandomTr
/** Road stop specification. */ /** Road stop specification. */
struct RoadStopSpec : NewGRFSpecBase<RoadStopClassID> { struct RoadStopSpec : NewGRFSpecBase<RoadStopClassID> {
/** CargoGRFFileProps grf_prop; ///< Link to NewGRF
* 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;
StringID name; ///< Name of this stop StringID name; ///< Name of this stop
RoadStopAvailabilityType stop_type = ROADSTOPTYPE_ALL; RoadStopAvailabilityType stop_type = ROADSTOPTYPE_ALL;

View File

@ -530,12 +530,12 @@ uint32_t Waypoint::GetNewGRFVariable(const ResolverObject &, uint8_t variable, [
switch (this->station_scope.cargo_type) { switch (this->station_scope.cargo_type) {
case INVALID_CARGO: case INVALID_CARGO:
case SpriteGroupCargo::SG_DEFAULT_NA: case CargoGRFFileProps::SG_DEFAULT_NA:
case SpriteGroupCargo::SG_PURCHASE: case CargoGRFFileProps::SG_PURCHASE:
cargo = 0; cargo = 0;
break; break;
case SpriteGroupCargo::SG_DEFAULT: case CargoGRFFileProps::SG_DEFAULT:
for (const GoodsEntry &ge : st->goods) { for (const GoodsEntry &ge : st->goods) {
if (!ge.HasData()) continue; if (!ge.HasData()) continue;
cargo += ge.GetData().cargo.TotalCount(); cargo += ge.GetData().cargo.TotalCount();
@ -594,11 +594,11 @@ StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseSt
/* Invalidate all cached vars */ /* Invalidate all cached vars */
_svc.valid = 0; _svc.valid = 0;
CargoType ctype = SpriteGroupCargo::SG_DEFAULT_NA; CargoType ctype = CargoGRFFileProps::SG_DEFAULT_NA;
if (this->station_scope.st == nullptr) { if (this->station_scope.st == nullptr) {
/* No station, so we are in a purchase list */ /* 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); this->root_spritegroup = statspec->grf_prop.GetSpriteGroup(ctype);
} else if (Station::IsExpected(this->station_scope.st)) { } else if (Station::IsExpected(this->station_scope.st)) {
const Station *st = Station::From(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) { if (this->root_spritegroup == nullptr) {
ctype = SpriteGroupCargo::SG_DEFAULT_NA; ctype = CargoGRFFileProps::SG_DEFAULT_NA;
this->root_spritegroup = statspec->grf_prop.GetSpriteGroup(ctype); this->root_spritegroup = statspec->grf_prop.GetSpriteGroup(ctype);
} }
} }
if (this->root_spritegroup == nullptr) { if (this->root_spritegroup == nullptr) {
ctype = SpriteGroupCargo::SG_DEFAULT; ctype = CargoGRFFileProps::SG_DEFAULT;
this->root_spritegroup = statspec->grf_prop.GetSpriteGroup(ctype); this->root_spritegroup = statspec->grf_prop.GetSpriteGroup(ctype);
} }

View File

@ -110,13 +110,8 @@ struct StationSpec : NewGRFSpecBase<StationClassID> {
cargo_threshold(0), cargo_triggers(0), cargo_threshold(0), cargo_triggers(0),
callback_mask(0), flags(0) callback_mask(0), flags(0)
{} {}
/**
* Properties related the the grf file. CargoGRFFileProps grf_prop; ///< Link to NewGRF
* 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;
StringID name; ///< Name of this station. StringID name; ///< Name of this station.
/** /**