summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lang/english.txt2
-rw-r--r--src/newgrf_gui.cpp66
-rw-r--r--src/script/api/game/game_window.hpp.sq1
-rw-r--r--src/script/api/script_window.hpp1
-rw-r--r--src/widgets/newgrf_widget.h1
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.