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;
/* 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<WagonOverride> overrides{};
std::vector<BadgeID> badges{};

View File

@ -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<GrfSpecFeature>(ctype), _cur_gps.spritegroups[groupid]);
}
}

View File

@ -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<GrfSpecFeature> grf_prop; ///< Sprite information.
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 "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;

View File

@ -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;
}
}

View File

@ -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 <class Tkey>
struct VariableGRFFileProps : GRFFilePropsBase {
using CargoSpriteGroup = std::pair<size_t, const struct SpriteGroup *>;
std::vector<CargoSpriteGroup> spritegroups; ///< pointers to the different sprite groups of the entity
using ValueType = std::pair<Tkey, const struct SpriteGroup *>;
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. */

View File

@ -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);
}
}
}

View File

@ -229,11 +229,11 @@ RoadStopResolverObject::RoadStopResolverObject(const RoadStopSpec *roadstopspec,
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)
{
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);
}

View File

@ -128,13 +128,7 @@ struct RoadStopResolverObject : public SpecializedResolverObject<StationRandomTr
/** Road stop specification. */
struct RoadStopSpec : NewGRFSpecBase<RoadStopClassID> {
/**
* 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;

View File

@ -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);
}

View File

@ -110,13 +110,8 @@ struct StationSpec : NewGRFSpecBase<StationClassID> {
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.
/**