@@ -58,24 +58,32 @@ GRFConfig::GRFConfig(const GRFConfig &co
status(config.status),
grf_bugs(config.grf_bugs),
param(config.param),
num_params(config.num_params),
num_valid_params(config.num_valid_params),
palette(config.palette),
param_info(config.param_info),
has_param_defaults(config.has_param_defaults)
{
}
/**
* Return whether this NewGRF can replace an older version of the same NewGRF.
*/
bool GRFConfig::IsCompatible(uint32_t old_version) const
return this->min_loadable_version <= old_version && old_version <= this->version;
* Copy the parameter information from the \a src config.
* @param src Source config.
void GRFConfig::CopyParams(const GRFConfig &src)
this->num_params = src.num_params;
this->param = src.param;
* Get the name of this grf. In case the name isn't known
* the filename is returned.
@@ -676,25 +684,25 @@ void ScanNewGRFFiles(NewGRFScanCallback
const GRFConfig *FindGRFConfig(uint32_t grfid, FindGRFConfigMode mode, const MD5Hash *md5sum, uint32_t desired_version)
assert((mode == FGCM_EXACT) != (md5sum == nullptr));
const GRFConfig *best = nullptr;
for (const GRFConfig *c = _all_grfs; c != nullptr; c = c->next) {
/* if md5sum is set, we look for an exact match and continue if not found */
if (!c->ident.HasGrfIdentifier(grfid, md5sum)) continue;
/* return it, if the exact same newgrf is found, or if we do not care about finding "the best" */
if (md5sum != nullptr || mode == FGCM_ANY) return c;
/* Skip incompatible stuff, unless explicitly allowed */
if (mode != FGCM_NEWEST && HasBit(c->flags, GCF_INVALID)) continue;
/* check version compatibility */
if (mode == FGCM_COMPATIBLE && (c->version < desired_version || c->min_loadable_version > desired_version)) continue;
if (mode == FGCM_COMPATIBLE && !c->IsCompatible(desired_version)) continue;
/* remember the newest one as "the best" */
if (best == nullptr || c->version > best->version) best = c;
return best;
* Retrieve a NewGRF from the current config by its grfid.
* @param grfid grf to look for.
* @param mask GRFID mask to allow for partial matching.
* @return The grf config, if it exists, else \c nullptr.
@@ -164,24 +164,25 @@ struct GRFConfig : ZeroedMemoryAllocator
uint8_t flags; ///< NOSAVE: GCF_Flags, bitset
GRFStatus status; ///< NOSAVE: GRFStatus, enum
uint32_t grf_bugs; ///< NOSAVE: bugs in this GRF in this run, @see enum GRFBugs
std::array<uint32_t, 0x80> param; ///< GRF parameters
uint8_t num_params; ///< Number of used parameters
uint8_t num_valid_params; ///< NOSAVE: Number of valid parameters (action 0x14)
uint8_t palette; ///< GRFPalette, bitset
std::vector<std::optional<GRFParameterInfo>> param_info; ///< NOSAVE: extra information about the parameters
bool has_param_defaults; ///< NOSAVE: did this newgrf specify any defaults for it's parameters
struct GRFConfig *next; ///< NOSAVE: Next item in the linked list
bool IsCompatible(uint32_t old_version) const;
void CopyParams(const GRFConfig &src);
std::optional<std::string> GetTextfile(TextfileType type) const;
const char *GetName() const;
const char *GetDescription() const;
const char *GetURL() const;
void SetParameterDefaults();
void SetSuitablePalette();
void FinalizeParameterInfo();
};
@@ -714,25 +714,29 @@ struct NewGRFWindow : public Window, New
GrfIdMap grfid_map;
FillGrfidMap(this->actives, &grfid_map);
for (const GRFConfig *a = _all_grfs; a != nullptr; a = a->next) {
GrfIdMap::iterator iter = grfid_map.find(a->ident.grfid);
if (iter == grfid_map.end() || iter->second->version >= a->version) continue;
GRFConfig **c = &this->actives;
while (*c != iter->second) c = &(*c)->next;
GRFConfig *d = new GRFConfig(*a);
d->next = (*c)->next;
d->CopyParams(**c);
if (d->IsCompatible((*c)->version)) {
} else {
d->SetParameterDefaults();
if (this->active_sel == *c) {
CloseWindowByClass(WC_GRF_PARAMETERS);
CloseWindowByClass(WC_TEXTFILE);
this->active_sel = nullptr;
delete *c;
*c = d;
iter->second = d;
void UpdateWidgetSize(int widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
Status change: