diff options
-rw-r--r-- | src/lang/english.txt | 2 | ||||
-rw-r--r-- | src/newgrf_gui.cpp | 66 | ||||
-rw-r--r-- | src/script/api/game/game_window.hpp.sq | 1 | ||||
-rw-r--r-- | src/script/api/script_window.hpp | 1 | ||||
-rw-r--r-- | src/widgets/newgrf_widget.h | 1 |
5 files changed, 71 insertions, 0 deletions
diff --git a/src/lang/english.txt b/src/lang/english.txt index bd60237db..b64df1757 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2759,6 +2759,8 @@ STR_NEWGRF_SETTINGS_MOVEUP :{BLACK}Move Up STR_NEWGRF_SETTINGS_MOVEUP_TOOLTIP :{BLACK}Move the selected NewGRF file up the list STR_NEWGRF_SETTINGS_MOVEDOWN :{BLACK}Move Down STR_NEWGRF_SETTINGS_MOVEDOWN_TOOLTIP :{BLACK}Move the selected NewGRF file down the list +STR_NEWGRF_SETTINGS_UPGRADE :{BLACK}Upgrade +STR_NEWGRF_SETTINGS_UPGRADE_TOOLTIP :{BLACK}Upgrade NewGRF files for which you have a newer version installed STR_NEWGRF_SETTINGS_FILE_TOOLTIP :{BLACK}A list of the NewGRF files that are installed STR_NEWGRF_SETTINGS_SET_PARAMETERS :{BLACK}Set parameters diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index b919edfaa..7c6d6ab9e 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -36,6 +36,7 @@ #include "table/sprites.h" +#include <map> #include "safeguards.h" /* Maximum number of NewGRFs that may be loaded. Six reserved slots are: @@ -586,6 +587,23 @@ public: } }; + +typedef std::map<uint32, const GRFConfig *> GrfIdMap; ///< Map of grfid to the grf config. + +/** + * Add all grf configs from \a c into the map. + * @param c Grf list to add. + * @param grfid_map Map to add them to. + */ +static void FillGrfidMap(const GRFConfig *c, GrfIdMap *grfid_map) +{ + while (c != NULL) { + std::pair<uint32, const GRFConfig *> p(c->ident.grfid, c); + grfid_map->insert(p); + c = c->next; + } +} + static void NewGRFConfirmationCallback(Window *w, bool confirmed); static void ShowSavePresetWindow(const char *initial_text); @@ -679,6 +697,44 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { _grf_preset_list.Clear(); } + /** + * Test whether the currently active set of NewGRFs can be upgraded with the available NewGRFs. + * @return Whether an upgrade is possible. + */ + bool CanUpgradeCurrent() + { + GrfIdMap grfid_map; + FillGrfidMap(this->actives, &grfid_map); + + for (const GRFConfig *a = _all_grfs; a != NULL; a = a->next) { + GrfIdMap::const_iterator iter = grfid_map.find(a->ident.grfid); + if (iter != grfid_map.end() && a->version > iter->second->version) return true; + } + return false; + } + + /** Upgrade the currently active set of NewGRFs. */ + void UpgradeCurrent() + { + GrfIdMap grfid_map; + FillGrfidMap(this->actives, &grfid_map); + + for (const GRFConfig *a = _all_grfs; a != NULL; 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 (this->active_sel == *c) this->active_sel = NULL; + delete *c; + *c = d; + iter->second = d; + } + } + virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { switch (widget) { @@ -1012,6 +1068,13 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { break; } + case WID_NS_UPGRADE: { // Upgrade GRF. + if (!this->editable || this->actives == NULL) break; + UpgradeCurrent(); + this->InvalidateData(GOID_NEWGRF_LIST_EDITED); + break; + } + case WID_NS_AVAIL_LIST: { // Select a non-active GRF. ResetObjectToPlace(); @@ -1190,6 +1253,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { WIDGET_LIST_END ); this->SetWidgetDisabledState(WID_NS_ADD, !this->editable || this->avail_sel == NULL || HasBit(this->avail_sel->flags, GCF_INVALID)); + this->SetWidgetDisabledState(WID_NS_UPGRADE, !this->editable || this->actives == NULL || !this->CanUpgradeCurrent()); bool disable_all = this->active_sel == NULL || !this->editable; this->SetWidgetsDisabledState(disable_all, @@ -1772,6 +1836,8 @@ static const NWidgetPart _nested_newgrf_actives_widgets[] = { NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_MOVE_DOWN), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_NEWGRF_SETTINGS_MOVEDOWN, STR_NEWGRF_SETTINGS_MOVEDOWN_TOOLTIP), EndContainer(), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_UPGRADE), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_NEWGRF_SETTINGS_UPGRADE, STR_NEWGRF_SETTINGS_UPGRADE_TOOLTIP), EndContainer(), NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPadding(2, 2, 2, 2), diff --git a/src/script/api/game/game_window.hpp.sq b/src/script/api/game/game_window.hpp.sq index ef8f3da42..44d300c27 100644 --- a/src/script/api/game/game_window.hpp.sq +++ b/src/script/api/game/game_window.hpp.sq @@ -788,6 +788,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_REMOVE, "WID_NS_REMOVE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_MOVE_UP, "WID_NS_MOVE_UP"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_MOVE_DOWN, "WID_NS_MOVE_DOWN"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_UPGRADE, "WID_NS_UPGRADE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_FILTER, "WID_NS_FILTER"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_FILE_LIST, "WID_NS_FILE_LIST"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NS_SCROLLBAR, "WID_NS_SCROLLBAR"); diff --git a/src/script/api/script_window.hpp b/src/script/api/script_window.hpp index 21cf28f7a..81bac27ac 100644 --- a/src/script/api/script_window.hpp +++ b/src/script/api/script_window.hpp @@ -1820,6 +1820,7 @@ public: WID_NS_REMOVE = ::WID_NS_REMOVE, ///< Remove NewGRF from active list. WID_NS_MOVE_UP = ::WID_NS_MOVE_UP, ///< Move NewGRF up in active list. WID_NS_MOVE_DOWN = ::WID_NS_MOVE_DOWN, ///< Move NewGRF down in active list. + WID_NS_UPGRADE = ::WID_NS_UPGRADE, ///< Upgrade NewGRFs that have a newer version available. WID_NS_FILTER = ::WID_NS_FILTER, ///< Filter list of available NewGRFs. WID_NS_FILE_LIST = ::WID_NS_FILE_LIST, ///< List window of active NewGRFs. WID_NS_SCROLLBAR = ::WID_NS_SCROLLBAR, ///< Scrollbar for active NewGRF list. diff --git a/src/widgets/newgrf_widget.h b/src/widgets/newgrf_widget.h index c0c00ed8b..271b6669a 100644 --- a/src/widgets/newgrf_widget.h +++ b/src/widgets/newgrf_widget.h @@ -39,6 +39,7 @@ enum NewGRFStateWidgets { WID_NS_REMOVE, ///< Remove NewGRF from active list. WID_NS_MOVE_UP, ///< Move NewGRF up in active list. WID_NS_MOVE_DOWN, ///< Move NewGRF down in active list. + WID_NS_UPGRADE, ///< Upgrade NewGRFs that have a newer version available. WID_NS_FILTER, ///< Filter list of available NewGRFs. WID_NS_FILE_LIST, ///< List window of active NewGRFs. WID_NS_SCROLLBAR, ///< Scrollbar for active NewGRF list. |