1
0
Fork 0

Codechange: Add NewGRFSpecsBase class to hold class/index information.

Standardises how the class index is stored in the spec, instead of relying ot the Spec structs having the same members.

This allows retrieving class_index and index without searching or using pointer arithmetic.

'cls_id' is renamed to 'class_index' to make it clearer that it is an index rather than the multichar label of the class.
pull/12653/head
Peter Nelson 2024-05-07 12:13:46 +01:00 committed by Peter Nelson
parent 733284cc16
commit d5671030b1
13 changed files with 83 additions and 78 deletions

View File

@ -1945,7 +1945,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
/* Swap classid because we read it in BE meaning WAYP or DFLT */ /* Swap classid because we read it in BE meaning WAYP or DFLT */
uint32_t classid = buf->ReadDWord(); uint32_t classid = buf->ReadDWord();
statspec->cls_id = StationClass::Allocate(BSWAP32(classid)); statspec->class_index = StationClass::Allocate(BSWAP32(classid));
break; break;
} }
@ -2141,7 +2141,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
break; break;
case 0x1D: // Station Class name case 0x1D: // Station Class name
AddStringForMapping(buf->ReadWord(), [statspec](StringID str) { StationClass::Get(statspec->cls_id)->name = str; }); AddStringForMapping(buf->ReadWord(), [statspec](StringID str) { StationClass::Get(statspec->class_index)->name = str; });
break; break;
default: default:
@ -4103,12 +4103,12 @@ static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteRea
/* Swap classid because we read it in BE. */ /* Swap classid because we read it in BE. */
uint32_t classid = buf->ReadDWord(); uint32_t classid = buf->ReadDWord();
spec->cls_id = ObjectClass::Allocate(BSWAP32(classid)); spec->class_index = ObjectClass::Allocate(BSWAP32(classid));
break; break;
} }
case 0x09: { // Class name case 0x09: { // Class name
AddStringForMapping(buf->ReadWord(), [spec](StringID str) { ObjectClass::Get(spec->cls_id)->name = str; }); AddStringForMapping(buf->ReadWord(), [spec](StringID str) { ObjectClass::Get(spec->class_index)->name = str; });
break; break;
} }
@ -4790,7 +4790,7 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, ByteR
} }
uint32_t classid = buf->ReadDWord(); uint32_t classid = buf->ReadDWord();
rs->cls_id = RoadStopClass::Allocate(BSWAP32(classid)); rs->class_index = RoadStopClass::Allocate(BSWAP32(classid));
break; break;
} }
@ -4803,7 +4803,7 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, ByteR
break; break;
case 0x0B: // Road Stop Class name case 0x0B: // Road Stop Class name
AddStringForMapping(buf->ReadWord(), [rs](StringID str) { RoadStopClass::Get(rs->cls_id)->name = str; }); AddStringForMapping(buf->ReadWord(), [rs](StringID str) { RoadStopClass::Get(rs->class_index)->name = str; });
break; break;
case 0x0C: // The draw mode case 0x0C: // The draw mode
@ -6270,8 +6270,8 @@ static void FeatureNewName(ByteReader *buf)
if (GB(id, 0, 8) >= _cur.grffile->stations.size() || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) { if (GB(id, 0, 8) >= _cur.grffile->stations.size() || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) {
GrfMsg(1, "FeatureNewName: Attempt to name undefined station 0x{:X}, ignoring", GB(id, 0, 8)); GrfMsg(1, "FeatureNewName: Attempt to name undefined station 0x{:X}, ignoring", GB(id, 0, 8));
} else { } else {
StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id; StationClassID class_index = _cur.grffile->stations[GB(id, 0, 8)]->class_index;
StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED); StationClass::Get(class_index)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
} }
break; break;

View File

@ -102,7 +102,7 @@ struct AirportTileLayout {
/** /**
* Defines the data structure for an airport. * Defines the data structure for an airport.
*/ */
struct AirportSpec { struct AirportSpec : NewGRFSpecBase<AirportClassID> {
const struct AirportFTAClass *fsm; ///< the finite statemachine for the default airports const struct AirportFTAClass *fsm; ///< the finite statemachine for the default airports
std::vector<AirportTileLayout> layouts; ///< List of layouts composing the airport. std::vector<AirportTileLayout> layouts; ///< List of layouts composing the airport.
std::span<const HangarTileTable> depots; ///< Position of the depots on the airports. std::span<const HangarTileTable> depots; ///< Position of the depots on the airports.
@ -114,7 +114,6 @@ struct AirportSpec {
TimerGameCalendar::Year max_year; ///< last year the airport is available TimerGameCalendar::Year max_year; ///< last year the airport is available
StringID name; ///< name of this airport StringID name; ///< name of this airport
TTDPAirportType ttd_airport_type; ///< ttdpatch airport type (Small/Large/Helipad/Oilrig) TTDPAirportType ttd_airport_type; ///< ttdpatch airport type (Small/Large/Helipad/Oilrig)
AirportClassID cls_id; ///< the class to which this airport type belongs
SpriteID preview_sprite; ///< preview sprite for this airport SpriteID preview_sprite; ///< preview sprite for this airport
uint16_t maintenance_cost; ///< maintenance cost multiplier uint16_t maintenance_cost; ///< maintenance cost multiplier
/* Newgrf data */ /* Newgrf data */

View File

@ -12,21 +12,31 @@
#include "strings_type.h" #include "strings_type.h"
/* Base for each type of NewGRF spec to be used with NewGRFClass. */
template <typename Tindex>
struct NewGRFSpecBase {
Tindex class_index; ///< Class index of this spec, invalid until class is allocated.
uint16_t index; ///< Index within class of this spec, invalid until inserted into class.
};
/** /**
* Struct containing information relating to NewGRF classes for stations and airports. * Struct containing information relating to NewGRF classes for stations and airports.
*/ */
template <typename Tspec, typename Tid, Tid Tmax> template <typename Tspec, typename Tindex, Tindex Tmax>
class NewGRFClass { class NewGRFClass {
private: private:
/* Tspec must be of NewGRFSpecBase<Tindex>. */
static_assert(std::is_base_of_v<NewGRFSpecBase<Tindex>, Tspec>);
uint ui_count = 0; ///< Number of specs in this class potentially available to the user. uint ui_count = 0; ///< Number of specs in this class potentially available to the user.
Tindex index; ///< Index of class within the list of classes.
std::vector<Tspec *> spec; ///< List of specifications. std::vector<Tspec *> spec; ///< List of specifications.
/** /**
* The actual classes. * The actual classes.
* @note This may be reallocated during initialization so pointers may be invalidated. * @note This may be reallocated during initialization so pointers may be invalidated.
*/ */
static inline std::vector<NewGRFClass<Tspec, Tid, Tmax>> classes; static inline std::vector<NewGRFClass<Tspec, Tindex, Tmax>> classes;
/** Initialise the defaults. */ /** Initialise the defaults. */
static void InsertDefaults(); static void InsertDefaults();
@ -48,11 +58,11 @@ public:
* Get read-only span of all classes of this type. * Get read-only span of all classes of this type.
* @return Read-only span of classes. * @return Read-only span of classes.
*/ */
static std::span<NewGRFClass<Tspec, Tid, Tmax> const> Classes() { return NewGRFClass::classes; } static std::span<NewGRFClass<Tspec, Tindex, Tmax> const> Classes() { return NewGRFClass::classes; }
void Insert(Tspec *spec); void Insert(Tspec *spec);
Tid Index() const { return static_cast<Tid>(std::distance(&*std::cbegin(NewGRFClass::classes), this)); } Tindex Index() const { return this->index; }
/** Get the number of allocated specs within the class. */ /** Get the number of allocated specs within the class. */
uint GetSpecCount() const { return static_cast<uint>(this->spec.size()); } uint GetSpecCount() const { return static_cast<uint>(this->spec.size()); }
/** Get the number of potentially user-available specs within the class. */ /** Get the number of potentially user-available specs within the class. */
@ -66,14 +76,14 @@ public:
bool IsUIAvailable(uint index) const; bool IsUIAvailable(uint index) const;
static void Reset(); static void Reset();
static Tid Allocate(uint32_t global_id); static Tindex Allocate(uint32_t global_id);
static void Assign(Tspec *spec); static void Assign(Tspec *spec);
static uint GetClassCount(); static uint GetClassCount();
static uint GetUIClassCount(); static uint GetUIClassCount();
static Tid GetUIClass(uint index); static Tindex GetUIClass(uint index);
static NewGRFClass *Get(Tid cls_id); static NewGRFClass *Get(Tindex class_index);
static const Tspec *GetByGrf(uint32_t grfid, uint16_t local_id, int *index); static const Tspec *GetByGrf(uint32_t grfid, uint16_t local_id);
}; };
#endif /* NEWGRF_CLASS_H */ #endif /* NEWGRF_CLASS_H */

View File

@ -12,8 +12,8 @@
#include "table/strings.h" #include "table/strings.h"
/** Reset the classes, i.e. clear everything. */ /** Reset the classes, i.e. clear everything. */
template <typename Tspec, typename Tid, Tid Tmax> template <typename Tspec, typename Tindex, Tindex Tmax>
void NewGRFClass<Tspec, Tid, Tmax>::Reset() void NewGRFClass<Tspec, Tindex, Tmax>::Reset()
{ {
NewGRFClass::classes.clear(); NewGRFClass::classes.clear();
NewGRFClass::classes.shrink_to_fit(); NewGRFClass::classes.shrink_to_fit();
@ -28,8 +28,8 @@ void NewGRFClass<Tspec, Tid, Tmax>::Reset()
* @note Upon allocating the same global class ID for a * @note Upon allocating the same global class ID for a
* second time, this first allocation will be given. * second time, this first allocation will be given.
*/ */
template <typename Tspec, typename Tid, Tid Tmax> template <typename Tspec, typename Tindex, Tindex Tmax>
Tid NewGRFClass<Tspec, Tid, Tmax>::Allocate(uint32_t global_id) Tindex NewGRFClass<Tspec, Tindex, Tmax>::Allocate(uint32_t global_id)
{ {
auto found = std::find_if(std::begin(NewGRFClass::classes), std::end(NewGRFClass::classes), [global_id](const auto &cls) { return cls.global_id == global_id; }); auto found = std::find_if(std::begin(NewGRFClass::classes), std::end(NewGRFClass::classes), [global_id](const auto &cls) { return cls.global_id == global_id; });
@ -38,56 +38,59 @@ Tid NewGRFClass<Tspec, Tid, Tmax>::Allocate(uint32_t global_id)
/* More slots available, allocate a slot to the global id. */ /* More slots available, allocate a slot to the global id. */
if (NewGRFClass::classes.size() < Tmax) { if (NewGRFClass::classes.size() < Tmax) {
auto &cls = NewGRFClass::classes.emplace_back(global_id, STR_EMPTY); auto it = NewGRFClass::classes.emplace(std::end(NewGRFClass::classes), global_id, STR_EMPTY);
return cls.Index(); it->index = static_cast<Tindex>(std::distance(std::begin(NewGRFClass::classes), it));
return it->Index();
} }
GrfMsg(2, "ClassAllocate: already allocated {} classes, using default", Tmax); GrfMsg(2, "ClassAllocate: already allocated {} classes, using default", Tmax);
return static_cast<Tid>(0); return static_cast<Tindex>(0);
} }
/** /**
* Insert a spec into the class. * Insert a spec into the class, and update its index.
* @param spec The spec to insert. * @param spec The spec to insert.
*/ */
template <typename Tspec, typename Tid, Tid Tmax> template <typename Tspec, typename Tindex, Tindex Tmax>
void NewGRFClass<Tspec, Tid, Tmax>::Insert(Tspec *spec) void NewGRFClass<Tspec, Tindex, Tmax>::Insert(Tspec *spec)
{ {
this->spec.push_back(spec); auto it = this->spec.insert(std::end(this->spec), spec);
uint16_t index = static_cast<uint16_t>(std::distance(std::begin(this->spec), it));
if (spec != nullptr) (*it)->index = index;
if (this->IsUIAvailable(static_cast<uint>(this->spec.size() - 1))) this->ui_count++; if (this->IsUIAvailable(index)) this->ui_count++;
} }
/** /**
* Assign a spec to one of the classes. * Assign a spec to one of the classes.
* @param spec The spec to assign. * @param spec The spec to assign.
* @note The spec must have a valid class id set. * @note The spec must have a valid class index set.
*/ */
template <typename Tspec, typename Tid, Tid Tmax> template <typename Tspec, typename Tindex, Tindex Tmax>
void NewGRFClass<Tspec, Tid, Tmax>::Assign(Tspec *spec) void NewGRFClass<Tspec, Tindex, Tmax>::Assign(Tspec *spec)
{ {
assert(static_cast<size_t>(spec->cls_id) < NewGRFClass::classes.size()); assert(static_cast<size_t>(spec->class_index) < NewGRFClass::classes.size());
Get(spec->cls_id)->Insert(spec); Get(spec->class_index)->Insert(spec);
} }
/** /**
* Get a particular class. * Get a particular class.
* @param cls_id The id for the class. * @param class_index The index of the class.
* @pre cls_id < Tmax * @pre class_index < Tmax
*/ */
template <typename Tspec, typename Tid, Tid Tmax> template <typename Tspec, typename Tindex, Tindex Tmax>
NewGRFClass<Tspec, Tid, Tmax> *NewGRFClass<Tspec, Tid, Tmax>::Get(Tid cls_id) NewGRFClass<Tspec, Tindex, Tmax> *NewGRFClass<Tspec, Tindex, Tmax>::Get(Tindex class_index)
{ {
assert(static_cast<size_t>(cls_id) < NewGRFClass::classes.size()); assert(static_cast<size_t>(class_index) < NewGRFClass::classes.size());
return &NewGRFClass::classes[cls_id]; return &NewGRFClass::classes[class_index];
} }
/** /**
* Get the number of allocated classes. * Get the number of allocated classes.
* @return The number of classes. * @return The number of classes.
*/ */
template <typename Tspec, typename Tid, Tid Tmax> template <typename Tspec, typename Tindex, Tindex Tmax>
uint NewGRFClass<Tspec, Tid, Tmax>::GetClassCount() uint NewGRFClass<Tspec, Tindex, Tmax>::GetClassCount()
{ {
return static_cast<uint>(NewGRFClass::classes.size()); return static_cast<uint>(NewGRFClass::classes.size());
} }
@ -96,8 +99,8 @@ uint NewGRFClass<Tspec, Tid, Tmax>::GetClassCount()
* Get the number of classes available to the user. * Get the number of classes available to the user.
* @return The number of classes. * @return The number of classes.
*/ */
template <typename Tspec, typename Tid, Tid Tmax> template <typename Tspec, typename Tindex, Tindex Tmax>
uint NewGRFClass<Tspec, Tid, Tmax>::GetUIClassCount() uint NewGRFClass<Tspec, Tindex, Tmax>::GetUIClassCount()
{ {
return std::count_if(std::begin(NewGRFClass::classes), std::end(NewGRFClass::classes), [](const auto &cls) { return cls.GetUISpecCount() > 0; }); return std::count_if(std::begin(NewGRFClass::classes), std::end(NewGRFClass::classes), [](const auto &cls) { return cls.GetUISpecCount() > 0; });
} }
@ -107,8 +110,8 @@ uint NewGRFClass<Tspec, Tid, Tmax>::GetUIClassCount()
* @param index UI index of a class. * @param index UI index of a class.
* @return The class ID of the class. * @return The class ID of the class.
*/ */
template <typename Tspec, typename Tid, Tid Tmax> template <typename Tspec, typename Tindex, Tindex Tmax>
Tid NewGRFClass<Tspec, Tid, Tmax>::GetUIClass(uint index) Tindex NewGRFClass<Tspec, Tindex, Tmax>::GetUIClass(uint index)
{ {
for (const auto &cls : NewGRFClass::classes) { for (const auto &cls : NewGRFClass::classes) {
if (cls.GetUISpecCount() == 0) continue; if (cls.GetUISpecCount() == 0) continue;
@ -122,8 +125,8 @@ Tid NewGRFClass<Tspec, Tid, Tmax>::GetUIClass(uint index)
* @param index The index where to find the spec. * @param index The index where to find the spec.
* @return The spec at given location. * @return The spec at given location.
*/ */
template <typename Tspec, typename Tid, Tid Tmax> template <typename Tspec, typename Tindex, Tindex Tmax>
const Tspec *NewGRFClass<Tspec, Tid, Tmax>::GetSpec(uint index) const const Tspec *NewGRFClass<Tspec, Tindex, Tmax>::GetSpec(uint index) const
{ {
/* If the custom spec isn't defined any more, then the GRF file probably was not loaded. */ /* If the custom spec isn't defined any more, then the GRF file probably was not loaded. */
return index < this->GetSpecCount() ? this->spec[index] : nullptr; return index < this->GetSpecCount() ? this->spec[index] : nullptr;
@ -134,8 +137,8 @@ const Tspec *NewGRFClass<Tspec, Tid, Tmax>::GetSpec(uint index) const
* @param ui_index UI index of the spec. * @param ui_index UI index of the spec.
* @return index of the spec, or -1 if out of range. * @return index of the spec, or -1 if out of range.
*/ */
template <typename Tspec, typename Tid, Tid Tmax> template <typename Tspec, typename Tindex, Tindex Tmax>
int NewGRFClass<Tspec, Tid, Tmax>::GetIndexFromUI(int ui_index) const int NewGRFClass<Tspec, Tindex, Tmax>::GetIndexFromUI(int ui_index) const
{ {
if (ui_index < 0) return -1; if (ui_index < 0) return -1;
for (uint i = 0; i < this->GetSpecCount(); i++) { for (uint i = 0; i < this->GetSpecCount(); i++) {
@ -150,8 +153,8 @@ int NewGRFClass<Tspec, Tid, Tmax>::GetIndexFromUI(int ui_index) const
* @param index index of the spec. * @param index index of the spec.
* @return UI index of the spec, or -1 if out of range. * @return UI index of the spec, or -1 if out of range.
*/ */
template <typename Tspec, typename Tid, Tid Tmax> template <typename Tspec, typename Tindex, Tindex Tmax>
int NewGRFClass<Tspec, Tid, Tmax>::GetUIFromIndex(int index) const int NewGRFClass<Tspec, Tindex, Tmax>::GetUIFromIndex(int index) const
{ {
if ((uint)index >= this->GetSpecCount()) return -1; if ((uint)index >= this->GetSpecCount()) return -1;
uint ui_index = 0; uint ui_index = 0;
@ -168,16 +171,13 @@ int NewGRFClass<Tspec, Tid, Tmax>::GetUIFromIndex(int index) const
* @param index Pointer to return the index of the spec in its class. If nullptr then not used. * @param index Pointer to return the index of the spec in its class. If nullptr then not used.
* @return The spec. * @return The spec.
*/ */
template <typename Tspec, typename Tid, Tid Tmax> template <typename Tspec, typename Tindex, Tindex Tmax>
const Tspec *NewGRFClass<Tspec, Tid, Tmax>::GetByGrf(uint32_t grfid, uint16_t local_id, int *index) const Tspec *NewGRFClass<Tspec, Tindex, Tmax>::GetByGrf(uint32_t grfid, uint16_t local_id)
{ {
for (const auto &cls : NewGRFClass::classes) { for (const auto &cls : NewGRFClass::classes) {
for (const auto &spec : cls.spec) { for (const auto &spec : cls.spec) {
if (spec == nullptr) continue; if (spec == nullptr) continue;
if (spec->grf_prop.grffile->grfid == grfid && spec->grf_prop.local_id == local_id) { if (spec->grf_prop.grffile->grfid == grfid && spec->grf_prop.local_id == local_id) return spec;
if (index != nullptr) *index = static_cast<int>(std::distance(cls.spec.data(), &spec));
return spec;
}
} }
} }

View File

@ -111,7 +111,7 @@ uint ObjectSpec::Index() const
/* static */ void ObjectSpec::BindToClasses() /* static */ void ObjectSpec::BindToClasses()
{ {
for (auto &spec : _object_specs) { for (auto &spec : _object_specs) {
if (spec.IsEnabled() && spec.cls_id != INVALID_OBJECT_CLASS) { if (spec.IsEnabled() && spec.class_index != INVALID_OBJECT_CLASS) {
ObjectClass::Assign(&spec); ObjectClass::Assign(&spec);
} }
} }
@ -132,8 +132,8 @@ void ResetObjects()
} }
/* Set class for originals. */ /* Set class for originals. */
_object_specs[OBJECT_LIGHTHOUSE].cls_id = ObjectClass::Allocate('LTHS'); _object_specs[OBJECT_LIGHTHOUSE].class_index = ObjectClass::Allocate('LTHS');
_object_specs[OBJECT_TRANSMITTER].cls_id = ObjectClass::Allocate('TRNS'); _object_specs[OBJECT_TRANSMITTER].class_index = ObjectClass::Allocate('TRNS');
} }
template <> template <>

View File

@ -57,11 +57,10 @@ DECLARE_POSTFIX_INCREMENT(ObjectClassID)
* @note If you change this struct, adopt the initialization of * @note If you change this struct, adopt the initialization of
* default objects in table/object_land.h * default objects in table/object_land.h
*/ */
struct ObjectSpec { struct ObjectSpec : NewGRFSpecBase<ObjectClassID> {
/* 2 because of the "normal" and "buy" sprite stacks. */ /* 2 because of the "normal" and "buy" sprite stacks. */
GRFFilePropsBase<2> grf_prop; ///< Properties related the the grf file GRFFilePropsBase<2> grf_prop; ///< Properties related the the grf file
AnimationInfo animation; ///< Information about the animation. AnimationInfo animation; ///< Information about the animation.
ObjectClassID cls_id; ///< The class to which this spec belongs.
StringID name; ///< The name for this object. StringID name; ///< The name for this object.
uint8_t climate; ///< In which climates is this object available? uint8_t climate; ///< In which climates is this object available?

View File

@ -118,7 +118,7 @@ struct RoadStopResolverObject : public ResolverObject {
}; };
/** Road stop specification. */ /** Road stop specification. */
struct RoadStopSpec { struct RoadStopSpec : NewGRFSpecBase<RoadStopClassID> {
/** /**
* Properties related the the grf file. * Properties related the the grf file.
* NUM_CARGO real cargo plus three pseudo cargo sprite groups. * NUM_CARGO real cargo plus three pseudo cargo sprite groups.
@ -126,7 +126,6 @@ struct RoadStopSpec {
* evaluating callbacks. * evaluating callbacks.
*/ */
GRFFilePropsBase<NUM_CARGO + 3> grf_prop; GRFFilePropsBase<NUM_CARGO + 3> grf_prop;
RoadStopClassID cls_id; ///< The class to which this spec belongs.
StringID name; ///< Name of this stop StringID name; ///< Name of this stop
RoadStopAvailabilityType stop_type = ROADSTOPTYPE_ALL; RoadStopAvailabilityType stop_type = ROADSTOPTYPE_ALL;

View File

@ -108,8 +108,8 @@ enum StationRandomTrigger {
}; };
/** Station specification. */ /** Station specification. */
struct StationSpec { struct StationSpec : NewGRFSpecBase<StationClassID> {
StationSpec() : cls_id(STAT_CLASS_DFLT), name(0), StationSpec() : name(0),
disallowed_platforms(0), disallowed_lengths(0), disallowed_platforms(0), disallowed_lengths(0),
cargo_threshold(0), cargo_triggers(0), cargo_threshold(0), cargo_triggers(0),
callback_mask(0), flags(0), pylons(0), wires(0), blocked(0), callback_mask(0), flags(0), pylons(0), wires(0), blocked(0),
@ -121,7 +121,6 @@ struct StationSpec {
* evaluating callbacks. * evaluating callbacks.
*/ */
GRFFilePropsBase<NUM_CARGO + 3> grf_prop; GRFFilePropsBase<NUM_CARGO + 3> grf_prop;
StationClassID cls_id; ///< The class to which this spec belongs.
StringID name; ///< Name of this station. StringID name; ///< Name of this station.
/** /**

View File

@ -114,11 +114,11 @@ void AfterLoadStations()
for (BaseStation *st : BaseStation::Iterate()) { for (BaseStation *st : BaseStation::Iterate()) {
for (auto &sm : GetStationSpecList<StationSpec>(st)) { for (auto &sm : GetStationSpecList<StationSpec>(st)) {
if (sm.grfid == 0) continue; if (sm.grfid == 0) continue;
sm.spec = StationClass::GetByGrf(sm.grfid, sm.localidx, nullptr); sm.spec = StationClass::GetByGrf(sm.grfid, sm.localidx);
} }
for (auto &sm : GetStationSpecList<RoadStopSpec>(st)) { for (auto &sm : GetStationSpecList<RoadStopSpec>(st)) {
if (sm.grfid == 0) continue; if (sm.grfid == 0) continue;
sm.spec = RoadStopClass::GetByGrf(sm.grfid, sm.localidx, nullptr); sm.spec = RoadStopClass::GetByGrf(sm.grfid, sm.localidx);
} }
if (Station::IsExpected(st)) { if (Station::IsExpected(st)) {

View File

@ -193,13 +193,12 @@
bool adjacent = station_id != ScriptStation::STATION_JOIN_ADJACENT; bool adjacent = station_id != ScriptStation::STATION_JOIN_ADJACENT;
StationID to_join = ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION; StationID to_join = ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION;
if (res != CALLBACK_FAILED) { if (res != CALLBACK_FAILED) {
int index = 0; const StationSpec *spec = StationClass::GetByGrf(file->grfid, res);
const StationSpec *spec = StationClass::GetByGrf(file->grfid, res, &index);
if (spec == nullptr) { if (spec == nullptr) {
Debug(grf, 1, "{} returned an invalid station ID for 'AI construction/purchase selection (18)' callback", file->filename); Debug(grf, 1, "{} returned an invalid station ID for 'AI construction/purchase selection (18)' callback", file->filename);
} else { } else {
/* We might have gotten an usable station spec. Try to build it, but if it fails we'll fall back to the original station. */ /* We might have gotten an usable station spec. Try to build it, but if it fails we'll fall back to the original station. */
if (ScriptObject::Command<CMD_BUILD_RAIL_STATION>::Do(tile, (::RailType)GetCurrentRailType(), axis, num_platforms, platform_length, spec->cls_id, index, to_join, adjacent)) return true; if (ScriptObject::Command<CMD_BUILD_RAIL_STATION>::Do(tile, (::RailType)GetCurrentRailType(), axis, num_platforms, platform_length, spec->class_index, spec->index, to_join, adjacent)) return true;
} }
} }

View File

@ -3346,7 +3346,7 @@ void FillTileDescRailStation(TileIndex tile, TileDesc *td)
const StationSpec *spec = GetStationSpec(tile); const StationSpec *spec = GetStationSpec(tile);
if (spec != nullptr) { if (spec != nullptr) {
td->station_class = StationClass::Get(spec->cls_id)->name; td->station_class = StationClass::Get(spec->class_index)->name;
td->station_name = spec->name; td->station_name = spec->name;
if (spec->grf_prop.grffile != nullptr) { if (spec->grf_prop.grffile != nullptr) {
@ -3363,7 +3363,7 @@ void FillTileDescRailStation(TileIndex tile, TileDesc *td)
void FillTileDescAirport(TileIndex tile, TileDesc *td) void FillTileDescAirport(TileIndex tile, TileDesc *td)
{ {
const AirportSpec *as = Station::GetByTile(tile)->airport.GetSpec(); const AirportSpec *as = Station::GetByTile(tile)->airport.GetSpec();
td->airport_class = AirportClass::Get(as->cls_id)->name; td->airport_class = AirportClass::Get(as->class_index)->name;
td->airport_name = as->name; td->airport_name = as->name;
const AirportTileSpec *ats = AirportTileSpec::GetByTile(tile); const AirportTileSpec *ats = AirportTileSpec::GetByTile(tile);

View File

@ -378,7 +378,7 @@ static const std::initializer_list<AirportTileLayout> _tile_table_helistation =
/** General AirportSpec definition. */ /** General AirportSpec definition. */
#define AS_GENERIC(fsm, layouts, depots, size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, enabled) \ #define AS_GENERIC(fsm, layouts, depots, size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, enabled) \
{fsm, layouts, depots, size_x, size_y, noise, catchment, min_year, max_year, name, ttdpatch_type, class_id, preview, maint_cost, enabled, GRFFileProps(AT_INVALID)} {{class_id, 0}, fsm, layouts, depots, size_x, size_y, noise, catchment, min_year, max_year, name, ttdpatch_type, preview, maint_cost, enabled, GRFFileProps(AT_INVALID)}
/** AirportSpec definition for airports without any depot. */ /** AirportSpec definition for airports without any depot. */
#define AS_ND(ap_name, size_x, size_y, min_year, max_year, catchment, noise, maint_cost, ttdpatch_type, class_id, name, preview) \ #define AS_ND(ap_name, size_x, size_y, min_year, max_year, catchment, noise, maint_cost, ttdpatch_type, class_id, name, preview) \

View File

@ -121,7 +121,7 @@ static const DrawTileSprites _object_hq[] = {
#undef TILE_SPRITE_LINE #undef TILE_SPRITE_LINE
#define M(name, size, build_cost_multiplier, clear_cost_multiplier, height, climate, gen_amount, flags) { GRFFilePropsBase<2>(), {0, 0, 0, 0}, INVALID_OBJECT_CLASS, name, climate, size, build_cost_multiplier, clear_cost_multiplier, 0, CalendarTime::MAX_DATE + 1, flags, 0, height, 1, gen_amount } #define M(name, size, build_cost_multiplier, clear_cost_multiplier, height, climate, gen_amount, flags) {{INVALID_OBJECT_CLASS, 0}, GRFFilePropsBase<2>(), {0, 0, 0, 0}, name, climate, size, build_cost_multiplier, clear_cost_multiplier, 0, CalendarTime::MAX_DATE + 1, flags, 0, height, 1, gen_amount}
/* Climates /* Climates
* T = Temperate * T = Temperate