summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intro_gui.c2
-rw-r--r--lang/english.txt2
-rw-r--r--main_gui.c2
-rw-r--r--misc_gui.c6
-rw-r--r--network_gui.c2
-rw-r--r--newgrf.h1
-rw-r--r--newgrf_config.h2
-rw-r--r--newgrf_gui.c68
-rw-r--r--openttd.c21
-rw-r--r--vehicle.c15
-rw-r--r--vehicle.h1
11 files changed, 102 insertions, 20 deletions
diff --git a/intro_gui.c b/intro_gui.c
index b6bce05ad..9d0198d44 100644
--- a/intro_gui.c
+++ b/intro_gui.c
@@ -84,7 +84,7 @@ static void SelectGameWndProc(Window *w, WindowEvent *e)
case 12: ShowGameOptions(); break;
case 13: ShowGameDifficulty(); break;
case 14: ShowPatchesSelection(); break;
- case 15: ShowNewGRFSettings(true, true, &_grfconfig_newgame); break;
+ case 15: ShowNewGRFSettings(true, true, false, &_grfconfig_newgame); break;
case 16: HandleExitGameRequest(); break;
}
break;
diff --git a/lang/english.txt b/lang/english.txt
index 26360d36f..3306dedc6 100644
--- a/lang/english.txt
+++ b/lang/english.txt
@@ -154,6 +154,7 @@ STR_00B0_MAP :{WHITE}Map - {S
STR_00B1_GAME_OPTIONS :{WHITE}Game Options
STR_00B2_MESSAGE :{YELLOW}Message
STR_00B3_MESSAGE_FROM :{YELLOW}Message from {STRING1}
+STR_POPUP_CAUTION_CAPTION :{WHITE}Caution!
STR_00B4_CAN_T_DO_THIS :{WHITE}Can't do this....
STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Can't clear this area....
STR_00B6_ORIGINAL_COPYRIGHT :{BLACK}Original copyright {COPYRIGHT} 1995 Chris Sawyer, All rights reserved
@@ -2889,6 +2890,7 @@ STR_NEWGRF_NO_FILES_INSTALLED :{BLACK}There ar
STR_NEWGRF_FILENAME :{BLACK}Filename: {SILVER}{STRING}
STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
+STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}You are about to make changes to a running game; this can crash OpenTTD.{}Are you absolutely sure about this?
STR_NEWGRF_ADD :{BLACK}Add
STR_NEWGRF_ADD_TIP :{BLACK}Add a NewGRF file to the list
diff --git a/main_gui.c b/main_gui.c
index 37bfb5db0..774df16a9 100644
--- a/main_gui.c
+++ b/main_gui.c
@@ -153,7 +153,7 @@ static void MenuClickSettings(int index)
case 0: ShowGameOptions(); return;
case 1: ShowGameDifficulty(); return;
case 2: ShowPatchesSelection(); return;
- case 3: ShowNewGRFSettings(false, true, &_grfconfig); return;
+ case 3: ShowNewGRFSettings(!_networking, true, true, &_grfconfig); return;
case 5: _display_opt ^= DO_SHOW_TOWN_NAMES; break;
case 6: _display_opt ^= DO_SHOW_STATION_NAMES; break;
diff --git a/misc_gui.c b/misc_gui.c
index 371f7fc12..b10073d54 100644
--- a/misc_gui.c
+++ b/misc_gui.c
@@ -6,7 +6,7 @@
#include "heightmap.h"
#include "debug.h"
#include "functions.h"
-#include "gfxinit.h"
+#include "newgrf.h"
#include "saveload.h"
#include "strings.h"
#include "table/sprites.h"
@@ -1658,9 +1658,7 @@ static int32 ClickChangeClimateCheat(int32 p1, int32 p2)
if (p1 == -1) p1 = 3;
if (p1 == 4) p1 = 0;
_opt.landscape = p1;
- GfxLoadSprites();
- LoadStringWidthTable();
- MarkWholeScreenDirty();
+ ReloadNewGRFData();
return _opt.landscape;
}
diff --git a/network_gui.c b/network_gui.c
index 99d866055..207d93fbe 100644
--- a/network_gui.c
+++ b/network_gui.c
@@ -442,7 +442,7 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
NetworkQueryServer(nd->server->info.hostname, nd->server->port, true);
break;
case 18: // NewGRF Settings
- if (nd->server != NULL) ShowNewGRFSettings(false, false, &nd->server->info.grfconfig);
+ if (nd->server != NULL) ShowNewGRFSettings(false, false, false, &nd->server->info.grfconfig);
break;
} break;
diff --git a/newgrf.h b/newgrf.h
index 4d57ff4c9..2cefa9c84 100644
--- a/newgrf.h
+++ b/newgrf.h
@@ -66,5 +66,6 @@ extern bool _have_2cc;
void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage);
void LoadNewGRF(uint load_index, uint file_index);
+void ReloadNewGRFData(void); // in openttd.c
#endif /* NEWGRF_H */
diff --git a/newgrf_config.h b/newgrf_config.h
index b0660e3a6..24721a555 100644
--- a/newgrf_config.h
+++ b/newgrf_config.h
@@ -52,7 +52,7 @@ bool FillGRFDetails(GRFConfig *config, bool is_static);
char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last);
/* In newgrf_gui.c */
-void ShowNewGRFSettings(bool editable, bool show_params, GRFConfig **config);
+void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config);
/* For communication about GRFs over the network */
#define UNKNOWN_GRF_NAME_PLACEHOLDER "<Unknown>"
diff --git a/newgrf_gui.c b/newgrf_gui.c
index 3fe0bdcd8..6771174fa 100644
--- a/newgrf_gui.c
+++ b/newgrf_gui.c
@@ -9,6 +9,7 @@
#include "window.h"
#include "table/strings.h"
#include "table/sprites.h"
+#include "newgrf.h"
#include "newgrf_config.h"
@@ -219,13 +220,16 @@ static const WindowDesc _newgrf_add_dlg_desc = {
/* 'NewGRF Settings' dialogue */
typedef struct newgrf_d {
- GRFConfig **list;
- GRFConfig *sel;
- bool editable;
- bool show_params;
+ GRFConfig **orig_list; ///< grf list the window is shown with
+ GRFConfig **list; ///< temporary grf list to which changes are made
+ GRFConfig *sel; ///< selected grf item
+ 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
} newgrf_d;
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(newgrf_d));
+
enum ShowNewGRFStateWidgets {
SNGRFS_ADD = 3,
SNGRFS_REMOVE,
@@ -234,8 +238,10 @@ enum ShowNewGRFStateWidgets {
SNGRFS_FILE_LIST = 7,
SNGRFS_NEWGRF_INFO = 9,
SNGRFS_SET_PARAMETERS,
+ SNGRFS_APPLY_CHANGES,
};
+
static void SetupNewGRFState(Window *w)
{
bool disable_all = WP(w, newgrf_d).sel == NULL || !WP(w, newgrf_d).editable;
@@ -266,6 +272,21 @@ static void SetupNewGRFWindow(Window *w)
w->vscroll.cap = (w->widget[SNGRFS_FILE_LIST].bottom - w->widget[SNGRFS_FILE_LIST].top) / 14 + 1;
SetVScrollCount(w, i);
+ SetWindowWidgetDisabledState(w, SNGRFS_APPLY_CHANGES, !WP(w, newgrf_d).editable);
+}
+
+
+/** Callback function for the newgrf 'apply changes' confirmation window
+ * @param yes_clicked boolean value, true when yes was clicked, false otherwise */
+static void NewGRFConfirmationCallback(bool yes_clicked)
+{
+ if (yes_clicked) {
+ Window *w = FindWindowById(WC_GAME_OPTIONS, 0);
+ newgrf_d *nd = &WP(w, newgrf_d);
+
+ CopyGRFConfigList(nd->orig_list, *nd->list);
+ ReloadNewGRFData();
+ }
}
@@ -398,6 +419,20 @@ static void NewGRFWndProc(Window *w, WindowEvent *e)
break;
}
+ case SNGRFS_APPLY_CHANGES: /* Apply changes made to GRF list */
+ if (WP(w, newgrf_d).execute) {
+ ShowQuery(
+ STR_POPUP_CAUTION_CAPTION,
+ STR_NEWGRF_CONFIRMATION_TEXT,
+ NewGRFConfirmationCallback,
+ w->window_class,
+ w->window_number
+ );
+ } else {
+ CopyGRFConfigList(WP(w, newgrf_d).orig_list, *WP(w, newgrf_d).list);
+ }
+ break;
+
case SNGRFS_SET_PARAMETERS: { /* Edit parameters */
char buff[512];
if (WP(w, newgrf_d).sel == NULL) break;
@@ -421,6 +456,11 @@ static void NewGRFWndProc(Window *w, WindowEvent *e)
SetWindowDirty(w);
break;
+ case WE_DESTROY:
+ /* Remove the temporary copy of grf-list used in window */
+ ClearGRFConfigList(WP(w, newgrf_d).list);
+ break;
+
case WE_RESIZE:
w->vscroll.cap += e->we.sizing.diff.y / 14;
w->widget[SNGRFS_FILE_LIST].data = (w->vscroll.cap << 8) + 1;
@@ -447,8 +487,10 @@ static const Widget _newgrf_widgets[] = {
/* NewGRF file info */
{ WWT_PANEL, RESIZE_RTB, 10, 0, 299, 100, 199, STR_NULL, STR_NULL },
-/* Edit parameter button... */
-{ WWT_PUSHTXTBTN, RESIZE_RTB, 10, 0, 287, 200, 211, STR_NEWGRF_SET_PARAMETERS, STR_NULL },
+/* Edit parameter and apply changes button... */
+{ WWT_PUSHTXTBTN, RESIZE_TB, 10, 0, 143, 200, 211, STR_NEWGRF_SET_PARAMETERS, STR_NULL },
+{ WWT_PUSHTXTBTN, RESIZE_RTB, 10, 144, 287, 200, 211, STR_NEWGRF_APPLY_CHANGES, STR_NULL },
+
{ WWT_RESIZEBOX, RESIZE_LRTB, 10, 288, 299, 200, 211, 0x0, STR_RESIZE_BUTTON },
{ WIDGETS_END },
@@ -464,8 +506,15 @@ static const WindowDesc _newgrf_desc = {
};
-void ShowNewGRFSettings(bool editable, bool show_params, GRFConfig **config)
+/** Setup the NewGRF gui
+ * @param editable allow the user to make changes to the grfconfig in the window
+ * @param show_params show information about what parameters are set for the grf files
+ * @param exec_changes if changes are made to the list (editable is true), apply these
+ * changes immediately or only update the list
+ * @param config pointer to a linked-list of grfconfig's that will be shown */
+void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config)
{
+ static GRFConfig *local = NULL;
Window *w;
DeleteWindowByClass(WC_GAME_OPTIONS);
@@ -473,11 +522,14 @@ void ShowNewGRFSettings(bool editable, bool show_params, GRFConfig **config)
if (w == NULL) return;
w->resize.step_height = 14;
+ CopyGRFConfigList(&local, *config);
/* Clear selections */
WP(w, newgrf_d).sel = NULL;
- WP(w, newgrf_d).list = config;
+ WP(w, newgrf_d).list = &local;
+ WP(w, newgrf_d).orig_list = config;
WP(w, newgrf_d).editable = editable;
+ WP(w, newgrf_d).execute = exec_changes;
WP(w, newgrf_d).show_params = show_params;
SetupNewGRFWindow(w);
diff --git a/openttd.c b/openttd.c
index c9d59c2f1..8ed10a6b3 100644
--- a/openttd.c
+++ b/openttd.c
@@ -1559,3 +1559,24 @@ bool AfterLoadGame(void)
return true;
}
+
+/** Reload all NewGRF files during a running game. This is a cut-down
+ * version of AfterLoadGame().
+ * XXX - We need to reset the vehicle position hash because with a non-empty
+ * hash AfterLoadVehicles() will loop infinitely. We need AfterLoadVehicles()
+ * to recalculate vehicle data as some NewGRF vehicle sets could have been
+ * removed or added and changed statistics */
+void ReloadNewGRFData(void)
+{
+ /* reload grf data */
+ GfxLoadSprites();
+ LoadStringWidthTable();
+ /* reload vehicles */
+ ResetVehiclePosHash();
+ AfterLoadVehicles();
+ /* update station and waypoint graphics */
+ AfterLoadWaypoints();
+ AfterLoadStations();
+ /* redraw the whole screen */
+ MarkWholeScreenDirty();
+}
diff --git a/vehicle.c b/vehicle.c
index 89d2ed0a3..9ef5918a0 100644
--- a/vehicle.c
+++ b/vehicle.c
@@ -440,6 +440,14 @@ static void UpdateVehiclePosHash(Vehicle* v, int x, int y)
}
}
+void ResetVehiclePosHash(void)
+{
+ uint i;
+ for (i = 0; i < lengthof(_vehicle_position_hash); i++) {
+ _vehicle_position_hash[i] = INVALID_VEHICLE;
+ }
+}
+
void InitializeVehicles(void)
{
uint i;
@@ -449,12 +457,11 @@ void InitializeVehicles(void)
* vehicles (which is increased on-the-fly) */
CleanPool(&_Vehicle_pool);
AddBlockToPool(&_Vehicle_pool);
- for (i = 0; i < BLOCKS_FOR_SPECIAL_VEHICLES; i++)
+ for (i = 0; i < BLOCKS_FOR_SPECIAL_VEHICLES; i++) {
AddBlockToPool(&_Vehicle_pool);
-
- for (i = 0; i < lengthof(_vehicle_position_hash); i++) {
- _vehicle_position_hash[i] = INVALID_VEHICLE;
}
+
+ ResetVehiclePosHash();
}
Vehicle *GetLastVehicleInChain(Vehicle *v)
diff --git a/vehicle.h b/vehicle.h
index a75b0bf6b..20c1b7018 100644
--- a/vehicle.h
+++ b/vehicle.h
@@ -277,6 +277,7 @@ Vehicle *FindVehicleOnTileZ(TileIndex tile, byte z);
void InitializeTrains(void);
byte VehicleRandomBits(void);
+void ResetVehiclePosHash(void);
bool CanFillVehicle(Vehicle *v);
bool CanRefitTo(EngineID engine_type, CargoID cid_to);