Codechange: Use std::vector for GRFConfig lists. (#10835)
This replaces the C-style custom managed linked-list and allows use of iterators etc.
This commit is contained in:
@@ -47,7 +47,7 @@ void ShowNewGRFError()
|
||||
/* Do not show errors when entering the main screen */
|
||||
if (_game_mode == GM_MENU) return;
|
||||
|
||||
for (const GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
|
||||
for (const auto &c : _grfconfig) {
|
||||
/* Only show Fatal and Error level messages */
|
||||
if (!c->error.has_value() || (c->error->severity != STR_NEWGRF_ERROR_MSG_FATAL && c->error->severity != STR_NEWGRF_ERROR_MSG_ERROR)) continue;
|
||||
|
||||
@@ -582,14 +582,13 @@ typedef std::map<uint32_t, const GRFConfig *> GrfIdMap; ///< Map of grfid to the
|
||||
|
||||
/**
|
||||
* Add all grf configs from \a c into the map.
|
||||
* @param c Grf list to add.
|
||||
* @param lst Grf list to add.
|
||||
* @param grfid_map Map to add them to.
|
||||
*/
|
||||
static void FillGrfidMap(const GRFConfig *c, GrfIdMap *grfid_map)
|
||||
static void FillGrfidMap(const GRFConfigList &lst, GrfIdMap &grfid_map)
|
||||
{
|
||||
while (c != nullptr) {
|
||||
grfid_map->emplace(c->ident.grfid, c);
|
||||
c = c->next;
|
||||
for (const auto &c : lst) {
|
||||
grfid_map.emplace(c->ident.grfid, c.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,10 +616,10 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
|
||||
StringList grf_presets; ///< List of known NewGRF presets.
|
||||
|
||||
GRFConfigList actives; ///< Temporary active grf list to which changes are made.
|
||||
GRFConfigList actives; ///< Temporary active grf list to which changes are made.
|
||||
GRFConfig *active_sel; ///< Selected active grf item.
|
||||
|
||||
GRFConfigList *orig_list; ///< List active grfs in the game. Used as initial value, may be updated by the window.
|
||||
GRFConfigList &orig_list; ///< List active grfs in the game. Used as initial value, may be updated by the window.
|
||||
bool editable; ///< Is the window editable?
|
||||
bool show_params; ///< Are the grf-parameters shown in the info-panel?
|
||||
bool execute; ///< On pressing 'apply changes' are grf changes applied immediately, or only list is updated.
|
||||
@@ -631,20 +630,18 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
Scrollbar *vscroll;
|
||||
Scrollbar *vscroll2;
|
||||
|
||||
NewGRFWindow(WindowDesc &desc, bool editable, bool show_params, bool execute, GRFConfigList *orig_list) : Window(desc), filter_editbox(EDITBOX_MAX_SIZE)
|
||||
NewGRFWindow(WindowDesc &desc, bool editable, bool show_params, bool execute, GRFConfigList &orig_list) : Window(desc), filter_editbox(EDITBOX_MAX_SIZE), orig_list(orig_list)
|
||||
{
|
||||
this->avail_sel = nullptr;
|
||||
this->avail_pos = -1;
|
||||
this->active_sel = nullptr;
|
||||
this->actives = nullptr;
|
||||
this->orig_list = orig_list;
|
||||
this->editable = editable;
|
||||
this->execute = execute;
|
||||
this->show_params = show_params;
|
||||
this->preset = -1;
|
||||
this->active_over = -1;
|
||||
|
||||
CopyGRFConfigList(this->actives, *orig_list, false);
|
||||
CopyGRFConfigList(this->actives, orig_list, false);
|
||||
this->grf_presets = GetGRFPresetList();
|
||||
|
||||
this->CreateNestedTree();
|
||||
@@ -679,7 +676,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
CloseWindowByClass(WC_SAVE_PRESET);
|
||||
|
||||
if (this->editable && this->modified && !this->execute && !_exit_game) {
|
||||
CopyGRFConfigList(*this->orig_list, this->actives, true);
|
||||
CopyGRFConfigList(this->orig_list, this->actives, true);
|
||||
ResetGRFConfig(false);
|
||||
ReloadNewGRFData();
|
||||
}
|
||||
@@ -687,10 +684,13 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
this->Window::Close();
|
||||
}
|
||||
|
||||
~NewGRFWindow()
|
||||
int GetCurrentActivePosition() const
|
||||
{
|
||||
/* Remove the temporary copy of grf-list used in window */
|
||||
ClearGRFConfigList(this->actives);
|
||||
if (this->active_sel != nullptr) {
|
||||
auto it = std::ranges::find_if(this->actives, [this](const auto &c) { return c.get() == this->active_sel; });
|
||||
if (it != std::end(this->actives)) return static_cast<int>(std::distance(std::begin(this->actives), it));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -700,9 +700,9 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
bool CanUpgradeCurrent()
|
||||
{
|
||||
GrfIdMap grfid_map;
|
||||
FillGrfidMap(this->actives, &grfid_map);
|
||||
FillGrfidMap(this->actives, grfid_map);
|
||||
|
||||
for (const GRFConfig *a = _all_grfs; a != nullptr; a = a->next) {
|
||||
for (const auto &a : _all_grfs) {
|
||||
GrfIdMap::const_iterator iter = grfid_map.find(a->ident.grfid);
|
||||
if (iter != grfid_map.end() && a->version > iter->second->version) return true;
|
||||
}
|
||||
@@ -713,29 +713,27 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
void UpgradeCurrent()
|
||||
{
|
||||
GrfIdMap grfid_map;
|
||||
FillGrfidMap(this->actives, &grfid_map);
|
||||
FillGrfidMap(this->actives, grfid_map);
|
||||
|
||||
for (const GRFConfig *a = _all_grfs; a != nullptr; a = a->next) {
|
||||
for (const auto &a : _all_grfs) {
|
||||
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;
|
||||
auto c = std::ranges::find_if(this->actives, [&iter](const auto &grfconfig) { return grfconfig.get() == iter->second; });
|
||||
assert(c != std::end(this->actives));
|
||||
auto d = std::make_unique<GRFConfig>(*iter->second);
|
||||
if (d->IsCompatible((*c)->version)) {
|
||||
d->CopyParams(**c);
|
||||
} else {
|
||||
d->SetParameterDefaults();
|
||||
}
|
||||
if (this->active_sel == *c) {
|
||||
if (this->active_sel == c->get()) {
|
||||
CloseWindowByClass(WC_GRF_PARAMETERS);
|
||||
CloseWindowByClass(WC_TEXTFILE);
|
||||
this->active_sel = nullptr;
|
||||
}
|
||||
delete *c;
|
||||
*c = d;
|
||||
iter->second = d;
|
||||
*c = std::move(d);
|
||||
iter->second = c->get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -868,18 +866,17 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
uint warning_left = rtl ? tr.right - square.width - warning.width - 8 : tr.left + square.width + 8;
|
||||
|
||||
int i = 0;
|
||||
for (const GRFConfig *c = this->actives; c != nullptr; c = c->next, i++) {
|
||||
for (const auto &c : this->actives) {
|
||||
if (this->vscroll->IsVisible(i)) {
|
||||
const char *text = c->GetName();
|
||||
bool h = (this->active_sel == c);
|
||||
bool h = (this->active_sel == c.get());
|
||||
PaletteID pal = this->GetPalette(*c);
|
||||
|
||||
if (h) {
|
||||
GfxFillRect(br.left, tr.top, br.right, tr.top + step_height - 1, PC_DARK_BLUE);
|
||||
} else if (i == this->active_over) {
|
||||
/* Get index of current selection. */
|
||||
int active_sel_pos = 0;
|
||||
for (GRFConfig *c = this->actives; c != nullptr && c != this->active_sel; c = c->next, active_sel_pos++) {}
|
||||
int active_sel_pos = this->GetCurrentActivePosition();
|
||||
if (active_sel_pos != this->active_over) {
|
||||
uint top = this->active_over < active_sel_pos ? tr.top + 1 : tr.top + step_height - 2;
|
||||
GfxFillRect(tr.left, top - 1, tr.right, top + 1, PC_GREY);
|
||||
@@ -891,6 +888,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
DrawString(text_left + (rtl ? 0 : txtoffset), text_right - (rtl ? txtoffset : 0), tr.top + offset_y, text, h ? TC_WHITE : TC_ORANGE);
|
||||
tr.top += step_height;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (i == this->active_over && this->vscroll->IsVisible(i)) { // Highlight is after the last GRF entry.
|
||||
GfxFillRect(tr.left, tr.top, tr.right, tr.top + 2, PC_GREY);
|
||||
@@ -986,17 +984,12 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
case WID_NS_MOVE_UP: { // Move GRF up
|
||||
if (this->active_sel == nullptr || !this->editable) break;
|
||||
|
||||
int pos = 0;
|
||||
for (GRFConfig **pc = &this->actives; *pc != nullptr; pc = &(*pc)->next, pos++) {
|
||||
GRFConfig *c = *pc;
|
||||
if (c->next == this->active_sel) {
|
||||
c->next = this->active_sel->next;
|
||||
this->active_sel->next = c;
|
||||
*pc = this->active_sel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->vscroll->ScrollTowards(pos);
|
||||
int pos = this->GetCurrentActivePosition();
|
||||
if (pos <= 0) break;
|
||||
|
||||
std::swap(this->actives[pos - 1], this->actives[pos]);
|
||||
|
||||
this->vscroll->ScrollTowards(pos - 1);
|
||||
this->preset = -1;
|
||||
this->InvalidateData(GOID_NEWGRF_LIST_EDITED);
|
||||
break;
|
||||
@@ -1005,17 +998,12 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
case WID_NS_MOVE_DOWN: { // Move GRF down
|
||||
if (this->active_sel == nullptr || !this->editable) break;
|
||||
|
||||
int pos = 1; // Start at 1 as we swap the selected newgrf with the next one
|
||||
for (GRFConfig **pc = &this->actives; *pc != nullptr; pc = &(*pc)->next, pos++) {
|
||||
GRFConfig *c = *pc;
|
||||
if (c == this->active_sel) {
|
||||
*pc = c->next;
|
||||
c->next = c->next->next;
|
||||
(*pc)->next = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->vscroll->ScrollTowards(pos);
|
||||
int pos = this->GetCurrentActivePosition();
|
||||
if (pos == -1 || static_cast<size_t>(pos) >= this->actives.size() - 1) break;
|
||||
|
||||
std::swap(this->actives[pos], this->actives[pos + 1]);
|
||||
|
||||
this->vscroll->ScrollTowards(pos + 1);
|
||||
this->preset = -1;
|
||||
this->InvalidateData(GOID_NEWGRF_LIST_EDITED);
|
||||
break;
|
||||
@@ -1024,16 +1012,17 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
case WID_NS_FILE_LIST: { // Select an active GRF.
|
||||
ResetObjectToPlace();
|
||||
|
||||
const GRFConfig *old_sel = this->active_sel;
|
||||
uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NS_FILE_LIST, WidgetDimensions::scaled.framerect.top);
|
||||
|
||||
GRFConfig *c;
|
||||
for (c = this->actives; c != nullptr && i > 0; c = c->next, i--) {}
|
||||
|
||||
if (this->active_sel != c) {
|
||||
if (i < this->actives.size()) {
|
||||
this->active_sel = this->actives[i].get();
|
||||
} else {
|
||||
this->active_sel = nullptr;
|
||||
}
|
||||
if (this->active_sel != old_sel) {
|
||||
CloseWindowByClass(WC_GRF_PARAMETERS);
|
||||
CloseWindowByClass(WC_TEXTFILE);
|
||||
}
|
||||
this->active_sel = c;
|
||||
this->avail_sel = nullptr;
|
||||
this->avail_pos = -1;
|
||||
|
||||
@@ -1052,23 +1041,18 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
CloseWindowByClass(WC_TEXTFILE);
|
||||
|
||||
/* Choose the next GRF file to be the selected file. */
|
||||
GRFConfig *newsel = this->active_sel->next;
|
||||
for (GRFConfig **pc = &this->actives; *pc != nullptr; pc = &(*pc)->next) {
|
||||
GRFConfig *c = *pc;
|
||||
/* If the new selection is empty (i.e. we're deleting the last item
|
||||
* in the list, pick the file just before the selected file */
|
||||
if (newsel == nullptr && c->next == this->active_sel) newsel = c;
|
||||
int pos = this->GetCurrentActivePosition();
|
||||
if (pos < 0) break;
|
||||
|
||||
if (c == this->active_sel) {
|
||||
if (newsel == c) newsel = nullptr;
|
||||
|
||||
*pc = c->next;
|
||||
delete c;
|
||||
break;
|
||||
}
|
||||
auto it = std::next(std::begin(this->actives), pos);
|
||||
it = this->actives.erase(it);
|
||||
if (this->actives.empty()) {
|
||||
this->active_sel = nullptr;
|
||||
} else if (it == std::end(this->actives)) {
|
||||
this->active_sel = this->actives.back().get();
|
||||
} else {
|
||||
this->active_sel = it->get();
|
||||
}
|
||||
|
||||
this->active_sel = newsel;
|
||||
this->preset = -1;
|
||||
this->avail_pos = -1;
|
||||
this->avail_sel = nullptr;
|
||||
@@ -1078,7 +1062,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
}
|
||||
|
||||
case WID_NS_UPGRADE: { // Upgrade GRF.
|
||||
if (!this->editable || this->actives == nullptr) break;
|
||||
if (!this->editable || this->actives.empty()) break;
|
||||
UpgradeCurrent();
|
||||
this->InvalidateData(GOID_NEWGRF_LIST_EDITED);
|
||||
break;
|
||||
@@ -1090,10 +1074,10 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
auto it = this->vscroll2->GetScrolledItemFromWidget(this->avails, pt.y, this, WID_NS_AVAIL_LIST, WidgetDimensions::scaled.framerect.top);
|
||||
this->active_sel = nullptr;
|
||||
CloseWindowByClass(WC_GRF_PARAMETERS);
|
||||
if (it != this->avails.end()) {
|
||||
if (it != std::end(this->avails)) {
|
||||
if (this->avail_sel != *it) CloseWindowByClass(WC_TEXTFILE);
|
||||
this->avail_sel = *it;
|
||||
this->avail_pos = it - this->avails.begin();
|
||||
this->avail_pos = static_cast<int>(std::distance(std::begin(this->avails), it));
|
||||
}
|
||||
this->InvalidateData();
|
||||
if (click_count == 1) {
|
||||
@@ -1120,7 +1104,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
NewGRFConfirmationCallback
|
||||
);
|
||||
} else {
|
||||
CopyGRFConfigList(*this->orig_list, this->actives, true);
|
||||
CopyGRFConfigList(this->orig_list, this->actives, true);
|
||||
ResetGRFConfig(false);
|
||||
ReloadNewGRFData();
|
||||
this->InvalidateData(GOID_NEWGRF_CHANGES_APPLIED);
|
||||
@@ -1216,10 +1200,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
void UpdateScrollBars()
|
||||
{
|
||||
/* Update scrollbars */
|
||||
int i = 0;
|
||||
for (const GRFConfig *c = this->actives; c != nullptr; c = c->next, i++) {}
|
||||
|
||||
this->vscroll->SetCount(i + 1); // Reserve empty space for drag and drop handling.
|
||||
this->vscroll->SetCount(this->actives.size() + 1); // Reserve empty space for drag and drop handling.
|
||||
|
||||
if (this->avail_pos >= 0) this->vscroll2->ScrollTowards(this->avail_pos);
|
||||
}
|
||||
@@ -1239,20 +1220,14 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
|
||||
case GOID_NEWGRF_RESCANNED:
|
||||
/* Search the list for items that are now found and mark them as such. */
|
||||
for (GRFConfig **l = &this->actives; *l != nullptr; l = &(*l)->next) {
|
||||
GRFConfig *c = *l;
|
||||
for (auto &c : this->actives) {
|
||||
bool compatible = HasBit(c->flags, GCF_COMPATIBLE);
|
||||
if (c->status != GCS_NOT_FOUND && !compatible) continue;
|
||||
|
||||
const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, compatible ? &c->original_md5sum : &c->ident.md5sum);
|
||||
if (f == nullptr || HasBit(f->flags, GCF_INVALID)) continue;
|
||||
|
||||
*l = new GRFConfig(*f);
|
||||
(*l)->next = c->next;
|
||||
|
||||
if (this->active_sel == c) this->active_sel = *l;
|
||||
|
||||
delete c;
|
||||
c = std::make_unique<GRFConfig>(*f);
|
||||
}
|
||||
|
||||
this->avails.ForceRebuild();
|
||||
@@ -1289,7 +1264,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
WID_NS_TOGGLE_PALETTE
|
||||
);
|
||||
this->SetWidgetDisabledState(WID_NS_ADD, !this->editable || this->avail_sel == nullptr || HasBit(this->avail_sel->flags, GCF_INVALID));
|
||||
this->SetWidgetDisabledState(WID_NS_UPGRADE, !this->editable || this->actives == nullptr || !this->CanUpgradeCurrent());
|
||||
this->SetWidgetDisabledState(WID_NS_UPGRADE, !this->editable || this->actives.empty() || !this->CanUpgradeCurrent());
|
||||
|
||||
bool disable_all = this->active_sel == nullptr || !this->editable;
|
||||
this->SetWidgetsDisabledState(disable_all,
|
||||
@@ -1311,15 +1286,15 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
|
||||
if (!disable_all) {
|
||||
/* All widgets are now enabled, so disable widgets we can't use */
|
||||
if (this->active_sel == this->actives) this->DisableWidget(WID_NS_MOVE_UP);
|
||||
if (this->active_sel->next == nullptr) this->DisableWidget(WID_NS_MOVE_DOWN);
|
||||
if (this->active_sel == this->actives.front().get()) this->DisableWidget(WID_NS_MOVE_UP);
|
||||
if (this->active_sel == this->actives.back().get()) this->DisableWidget(WID_NS_MOVE_DOWN);
|
||||
}
|
||||
|
||||
this->SetWidgetDisabledState(WID_NS_PRESET_DELETE, this->preset == -1);
|
||||
|
||||
bool has_missing = false;
|
||||
bool has_compatible = false;
|
||||
for (const GRFConfig *c = this->actives; !has_missing && c != nullptr; c = c->next) {
|
||||
for (const auto &c : this->actives) {
|
||||
has_missing |= c->status == GCS_NOT_FOUND;
|
||||
has_compatible |= HasBit(c->flags, GCF_COMPATIBLE);
|
||||
}
|
||||
@@ -1374,24 +1349,16 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
||||
|
||||
if (widget == WID_NS_FILE_LIST) {
|
||||
if (this->active_sel != nullptr) {
|
||||
/* Get pointer to the selected file in the active list. */
|
||||
int from_pos = 0;
|
||||
GRFConfig **from_prev;
|
||||
for (from_prev = &this->actives; *from_prev != this->active_sel; from_prev = &(*from_prev)->next, from_pos++) {}
|
||||
int from_pos = this->GetCurrentActivePosition();
|
||||
|
||||
/* Gets the drag-and-drop destination offset. Ignore the last dummy line. */
|
||||
int to_pos = std::min(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NS_FILE_LIST, WidgetDimensions::scaled.framerect.top), this->vscroll->GetCount() - 2);
|
||||
if (to_pos != from_pos) { // Don't move NewGRF file over itself.
|
||||
/* Get pointer to destination position. */
|
||||
GRFConfig **to_prev = &this->actives;
|
||||
for (int i = from_pos < to_pos ? -1 : 0; *to_prev != nullptr && i < to_pos; to_prev = &(*to_prev)->next, i++) {}
|
||||
if (to_pos > from_pos) ++to_pos;
|
||||
|
||||
/* Detach NewGRF file from its original position. */
|
||||
*from_prev = this->active_sel->next;
|
||||
|
||||
/* Attach NewGRF file to its new position. */
|
||||
this->active_sel->next = *to_prev;
|
||||
*to_prev = this->active_sel;
|
||||
auto from = std::next(std::begin(this->actives), from_pos);
|
||||
auto to = std::next(std::begin(this->actives), to_pos);
|
||||
Slide(from, std::next(from), to);
|
||||
|
||||
this->vscroll->ScrollTowards(to_pos);
|
||||
this->preset = -1;
|
||||
@@ -1470,13 +1437,11 @@ private:
|
||||
|
||||
this->avails.clear();
|
||||
|
||||
for (const GRFConfig *c = _all_grfs; c != nullptr; c = c->next) {
|
||||
bool found = false;
|
||||
for (const GRFConfig *grf = this->actives; grf != nullptr && !found; grf = grf->next) found = grf->ident.HasGrfIdentifier(c->ident.grfid, &c->ident.md5sum);
|
||||
if (found) continue;
|
||||
for (const auto &c : _all_grfs) {
|
||||
if (std::ranges::any_of(this->actives, [&c](const auto &gc) { return gc->ident.HasGrfIdentifier(c->ident.grfid, &c->ident.md5sum); })) continue;
|
||||
|
||||
if (_settings_client.gui.newgrf_show_old_versions) {
|
||||
this->avails.push_back(c);
|
||||
this->avails.push_back(c.get());
|
||||
} else {
|
||||
const GRFConfig *best = FindGRFConfig(c->ident.grfid, HasBit(c->flags, GCF_INVALID) ? FGCM_NEWEST : FGCM_NEWEST_VALID);
|
||||
/* Never triggers; FindGRFConfig returns either c, or a newer version of c. */
|
||||
@@ -1490,7 +1455,7 @@ private:
|
||||
* show that NewGRF!.
|
||||
*/
|
||||
if (best->version == 0 || best->ident.HasGrfIdentifier(c->ident.grfid, &c->ident.md5sum)) {
|
||||
this->avails.push_back(c);
|
||||
this->avails.push_back(c.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1520,30 +1485,26 @@ private:
|
||||
|
||||
CloseWindowByClass(WC_TEXTFILE);
|
||||
|
||||
uint count = 0;
|
||||
GRFConfig **entry = nullptr;
|
||||
GRFConfig **list;
|
||||
/* Find last entry in the list, checking for duplicate grfid on the way */
|
||||
for (list = &this->actives; *list != nullptr; list = &(*list)->next, ins_pos--) {
|
||||
if (ins_pos == 0) entry = list; // Insert position? Save.
|
||||
if ((*list)->ident.grfid == this->avail_sel->ident.grfid) {
|
||||
ShowErrorMessage(STR_NEWGRF_DUPLICATE_GRFID, INVALID_STRING_ID, WL_INFO);
|
||||
return false;
|
||||
}
|
||||
if (!HasBit((*list)->flags, GCF_STATIC)) count++;
|
||||
}
|
||||
if (entry == nullptr) entry = list;
|
||||
/* Get number of non-static NewGRFs. */
|
||||
size_t count = std::ranges::count_if(this->actives, [](const auto &gc) { return !HasBit(gc->flags, GCF_STATIC); });
|
||||
if (count >= NETWORK_MAX_GRF_COUNT) {
|
||||
ShowErrorMessage(STR_NEWGRF_TOO_MANY_NEWGRFS, INVALID_STRING_ID, WL_INFO);
|
||||
return false;
|
||||
}
|
||||
|
||||
GRFConfig *c = new GRFConfig(*this->avail_sel); // Copy GRF details from scanned list.
|
||||
c->SetParameterDefaults();
|
||||
/* Check for duplicate GRF ID. */
|
||||
if (std::ranges::any_of(this->actives, [&grfid = this->avail_sel->ident.grfid](const auto &gc) { return gc->ident.grfid == grfid; })) {
|
||||
ShowErrorMessage(STR_NEWGRF_DUPLICATE_GRFID, INVALID_STRING_ID, WL_INFO);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Insert GRF config to configuration list. */
|
||||
c->next = *entry;
|
||||
*entry = c;
|
||||
auto entry = (ins_pos >= 0 && static_cast<size_t>(ins_pos) < std::size(this->actives))
|
||||
? std::next(std::begin(this->actives), ins_pos)
|
||||
: std::end(this->actives);
|
||||
|
||||
/* Copy GRF details from scanned list. */
|
||||
entry = this->actives.insert(entry, std::make_unique<GRFConfig>(*this->avail_sel));
|
||||
(*entry)->SetParameterDefaults();
|
||||
|
||||
/* Select next (or previous, if last one) item in the list. */
|
||||
int new_pos = this->avail_pos + 1;
|
||||
@@ -1565,7 +1526,7 @@ void ShowMissingContentWindow(const GRFConfigList &list)
|
||||
{
|
||||
/* Only show the things in the current list, or everything when nothing's selected */
|
||||
ContentVector cv;
|
||||
for (const GRFConfig *c = list; c != nullptr; c = c->next) {
|
||||
for (const auto &c : list) {
|
||||
if (c->status != GCS_NOT_FOUND && !HasBit(c->flags, GCF_COMPATIBLE)) continue;
|
||||
|
||||
ContentInfo *ci = new ContentInfo();
|
||||
@@ -1983,17 +1944,24 @@ static void NewGRFConfirmationCallback(Window *w, bool confirmed)
|
||||
|
||||
_gamelog.StartAction(GLAT_GRF);
|
||||
_gamelog.GRFUpdate(_grfconfig, nw->actives); // log GRF changes
|
||||
CopyGRFConfigList(*nw->orig_list, nw->actives, false);
|
||||
CopyGRFConfigList(nw->orig_list, nw->actives, false);
|
||||
ReloadNewGRFData();
|
||||
_gamelog.StopAction();
|
||||
|
||||
/* Show new, updated list */
|
||||
GRFConfig *c;
|
||||
int i = 0;
|
||||
for (c = nw->actives; c != nullptr && c != nw->active_sel; c = c->next, i++) {}
|
||||
CopyGRFConfigList(nw->actives, *nw->orig_list, false);
|
||||
for (c = nw->actives; c != nullptr && i > 0; c = c->next, i--) {}
|
||||
nw->active_sel = c;
|
||||
int pos = nw->GetCurrentActivePosition();
|
||||
|
||||
CopyGRFConfigList(nw->actives, nw->orig_list, false);
|
||||
|
||||
if (nw->active_sel != nullptr) {
|
||||
/* Set current selection from position */
|
||||
if (static_cast<size_t>(pos) >= nw->actives.size()) {
|
||||
nw->active_sel = nw->actives.back().get();
|
||||
} else {
|
||||
auto it = std::next(std::begin(nw->actives), pos);
|
||||
nw->active_sel = it->get();
|
||||
}
|
||||
}
|
||||
nw->avails.ForceRebuild();
|
||||
nw->modified = false;
|
||||
|
||||
@@ -2017,7 +1985,7 @@ static void NewGRFConfirmationCallback(Window *w, bool confirmed)
|
||||
void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfigList &config)
|
||||
{
|
||||
CloseWindowByClass(WC_GAME_OPTIONS);
|
||||
new NewGRFWindow(_newgrf_desc, editable, show_params, exec_changes, &config);
|
||||
new NewGRFWindow(_newgrf_desc, editable, show_params, exec_changes, config);
|
||||
}
|
||||
|
||||
/** Widget parts of the save preset window. */
|
||||
|
||||
Reference in New Issue
Block a user