mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r7523) -Feature: Add the possibility to change the newgrf configuration of a running game.
This is only possible in SP (or in the intro menu). During game play you will get a confirmation window when applying the changes as some actions can crash OpenTTD and/or make your current game unplayable.
This commit is contained in:
parent
739e93fd23
commit
9b9add65c3
|
@ -84,7 +84,7 @@ static void SelectGameWndProc(Window *w, WindowEvent *e)
|
||||||
case 12: ShowGameOptions(); break;
|
case 12: ShowGameOptions(); break;
|
||||||
case 13: ShowGameDifficulty(); break;
|
case 13: ShowGameDifficulty(); break;
|
||||||
case 14: ShowPatchesSelection(); 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;
|
case 16: HandleExitGameRequest(); break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -154,6 +154,7 @@ STR_00B0_MAP :{WHITE}Map - {S
|
||||||
STR_00B1_GAME_OPTIONS :{WHITE}Game Options
|
STR_00B1_GAME_OPTIONS :{WHITE}Game Options
|
||||||
STR_00B2_MESSAGE :{YELLOW}Message
|
STR_00B2_MESSAGE :{YELLOW}Message
|
||||||
STR_00B3_MESSAGE_FROM :{YELLOW}Message from {STRING1}
|
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_00B4_CAN_T_DO_THIS :{WHITE}Can't do this....
|
||||||
STR_00B5_CAN_T_CLEAR_THIS_AREA :{WHITE}Can't clear this area....
|
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
|
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_FILENAME :{BLACK}Filename: {SILVER}{STRING}
|
||||||
STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
|
STR_NEWGRF_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING}
|
||||||
STR_NEWGRF_MD5SUM :{BLACK}MD5sum: {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 :{BLACK}Add
|
||||||
STR_NEWGRF_ADD_TIP :{BLACK}Add a NewGRF file to the list
|
STR_NEWGRF_ADD_TIP :{BLACK}Add a NewGRF file to the list
|
||||||
|
|
|
@ -153,7 +153,7 @@ static void MenuClickSettings(int index)
|
||||||
case 0: ShowGameOptions(); return;
|
case 0: ShowGameOptions(); return;
|
||||||
case 1: ShowGameDifficulty(); return;
|
case 1: ShowGameDifficulty(); return;
|
||||||
case 2: ShowPatchesSelection(); 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 5: _display_opt ^= DO_SHOW_TOWN_NAMES; break;
|
||||||
case 6: _display_opt ^= DO_SHOW_STATION_NAMES; break;
|
case 6: _display_opt ^= DO_SHOW_STATION_NAMES; break;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "heightmap.h"
|
#include "heightmap.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "gfxinit.h"
|
#include "newgrf.h"
|
||||||
#include "saveload.h"
|
#include "saveload.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
|
@ -1658,9 +1658,7 @@ static int32 ClickChangeClimateCheat(int32 p1, int32 p2)
|
||||||
if (p1 == -1) p1 = 3;
|
if (p1 == -1) p1 = 3;
|
||||||
if (p1 == 4) p1 = 0;
|
if (p1 == 4) p1 = 0;
|
||||||
_opt.landscape = p1;
|
_opt.landscape = p1;
|
||||||
GfxLoadSprites();
|
ReloadNewGRFData();
|
||||||
LoadStringWidthTable();
|
|
||||||
MarkWholeScreenDirty();
|
|
||||||
return _opt.landscape;
|
return _opt.landscape;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -442,7 +442,7 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
|
||||||
NetworkQueryServer(nd->server->info.hostname, nd->server->port, true);
|
NetworkQueryServer(nd->server->info.hostname, nd->server->port, true);
|
||||||
break;
|
break;
|
||||||
case 18: // NewGRF Settings
|
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;
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
1
newgrf.h
1
newgrf.h
|
@ -66,5 +66,6 @@ extern bool _have_2cc;
|
||||||
|
|
||||||
void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage);
|
void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage);
|
||||||
void LoadNewGRF(uint load_index, uint file_index);
|
void LoadNewGRF(uint load_index, uint file_index);
|
||||||
|
void ReloadNewGRFData(void); // in openttd.c
|
||||||
|
|
||||||
#endif /* NEWGRF_H */
|
#endif /* NEWGRF_H */
|
||||||
|
|
|
@ -52,7 +52,7 @@ bool FillGRFDetails(GRFConfig *config, bool is_static);
|
||||||
char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last);
|
char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last);
|
||||||
|
|
||||||
/* In newgrf_gui.c */
|
/* 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 */
|
/* For communication about GRFs over the network */
|
||||||
#define UNKNOWN_GRF_NAME_PLACEHOLDER "<Unknown>"
|
#define UNKNOWN_GRF_NAME_PLACEHOLDER "<Unknown>"
|
||||||
|
|
68
newgrf_gui.c
68
newgrf_gui.c
|
@ -9,6 +9,7 @@
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
|
#include "newgrf.h"
|
||||||
#include "newgrf_config.h"
|
#include "newgrf_config.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -219,13 +220,16 @@ static const WindowDesc _newgrf_add_dlg_desc = {
|
||||||
|
|
||||||
/* 'NewGRF Settings' dialogue */
|
/* 'NewGRF Settings' dialogue */
|
||||||
typedef struct newgrf_d {
|
typedef struct newgrf_d {
|
||||||
GRFConfig **list;
|
GRFConfig **orig_list; ///< grf list the window is shown with
|
||||||
GRFConfig *sel;
|
GRFConfig **list; ///< temporary grf list to which changes are made
|
||||||
bool editable;
|
GRFConfig *sel; ///< selected grf item
|
||||||
bool show_params;
|
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;
|
} newgrf_d;
|
||||||
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(newgrf_d));
|
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(newgrf_d));
|
||||||
|
|
||||||
|
|
||||||
enum ShowNewGRFStateWidgets {
|
enum ShowNewGRFStateWidgets {
|
||||||
SNGRFS_ADD = 3,
|
SNGRFS_ADD = 3,
|
||||||
SNGRFS_REMOVE,
|
SNGRFS_REMOVE,
|
||||||
|
@ -234,8 +238,10 @@ enum ShowNewGRFStateWidgets {
|
||||||
SNGRFS_FILE_LIST = 7,
|
SNGRFS_FILE_LIST = 7,
|
||||||
SNGRFS_NEWGRF_INFO = 9,
|
SNGRFS_NEWGRF_INFO = 9,
|
||||||
SNGRFS_SET_PARAMETERS,
|
SNGRFS_SET_PARAMETERS,
|
||||||
|
SNGRFS_APPLY_CHANGES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void SetupNewGRFState(Window *w)
|
static void SetupNewGRFState(Window *w)
|
||||||
{
|
{
|
||||||
bool disable_all = WP(w, newgrf_d).sel == NULL || !WP(w, newgrf_d).editable;
|
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;
|
w->vscroll.cap = (w->widget[SNGRFS_FILE_LIST].bottom - w->widget[SNGRFS_FILE_LIST].top) / 14 + 1;
|
||||||
SetVScrollCount(w, i);
|
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;
|
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 */
|
case SNGRFS_SET_PARAMETERS: { /* Edit parameters */
|
||||||
char buff[512];
|
char buff[512];
|
||||||
if (WP(w, newgrf_d).sel == NULL) break;
|
if (WP(w, newgrf_d).sel == NULL) break;
|
||||||
|
@ -421,6 +456,11 @@ static void NewGRFWndProc(Window *w, WindowEvent *e)
|
||||||
SetWindowDirty(w);
|
SetWindowDirty(w);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WE_DESTROY:
|
||||||
|
/* Remove the temporary copy of grf-list used in window */
|
||||||
|
ClearGRFConfigList(WP(w, newgrf_d).list);
|
||||||
|
break;
|
||||||
|
|
||||||
case WE_RESIZE:
|
case WE_RESIZE:
|
||||||
w->vscroll.cap += e->we.sizing.diff.y / 14;
|
w->vscroll.cap += e->we.sizing.diff.y / 14;
|
||||||
w->widget[SNGRFS_FILE_LIST].data = (w->vscroll.cap << 8) + 1;
|
w->widget[SNGRFS_FILE_LIST].data = (w->vscroll.cap << 8) + 1;
|
||||||
|
@ -447,8 +487,10 @@ static const Widget _newgrf_widgets[] = {
|
||||||
/* NewGRF file info */
|
/* NewGRF file info */
|
||||||
{ WWT_PANEL, RESIZE_RTB, 10, 0, 299, 100, 199, STR_NULL, STR_NULL },
|
{ WWT_PANEL, RESIZE_RTB, 10, 0, 299, 100, 199, STR_NULL, STR_NULL },
|
||||||
|
|
||||||
/* Edit parameter button... */
|
/* Edit parameter and apply changes button... */
|
||||||
{ WWT_PUSHTXTBTN, RESIZE_RTB, 10, 0, 287, 200, 211, STR_NEWGRF_SET_PARAMETERS, STR_NULL },
|
{ 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 },
|
{ WWT_RESIZEBOX, RESIZE_LRTB, 10, 288, 299, 200, 211, 0x0, STR_RESIZE_BUTTON },
|
||||||
|
|
||||||
{ WIDGETS_END },
|
{ 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;
|
Window *w;
|
||||||
|
|
||||||
DeleteWindowByClass(WC_GAME_OPTIONS);
|
DeleteWindowByClass(WC_GAME_OPTIONS);
|
||||||
|
@ -473,11 +522,14 @@ void ShowNewGRFSettings(bool editable, bool show_params, GRFConfig **config)
|
||||||
if (w == NULL) return;
|
if (w == NULL) return;
|
||||||
|
|
||||||
w->resize.step_height = 14;
|
w->resize.step_height = 14;
|
||||||
|
CopyGRFConfigList(&local, *config);
|
||||||
|
|
||||||
/* Clear selections */
|
/* Clear selections */
|
||||||
WP(w, newgrf_d).sel = NULL;
|
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).editable = editable;
|
||||||
|
WP(w, newgrf_d).execute = exec_changes;
|
||||||
WP(w, newgrf_d).show_params = show_params;
|
WP(w, newgrf_d).show_params = show_params;
|
||||||
|
|
||||||
SetupNewGRFWindow(w);
|
SetupNewGRFWindow(w);
|
||||||
|
|
21
openttd.c
21
openttd.c
|
@ -1559,3 +1559,24 @@ bool AfterLoadGame(void)
|
||||||
|
|
||||||
return true;
|
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();
|
||||||
|
}
|
||||||
|
|
15
vehicle.c
15
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)
|
void InitializeVehicles(void)
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
|
@ -449,12 +457,11 @@ void InitializeVehicles(void)
|
||||||
* vehicles (which is increased on-the-fly) */
|
* vehicles (which is increased on-the-fly) */
|
||||||
CleanPool(&_Vehicle_pool);
|
CleanPool(&_Vehicle_pool);
|
||||||
AddBlockToPool(&_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);
|
AddBlockToPool(&_Vehicle_pool);
|
||||||
|
|
||||||
for (i = 0; i < lengthof(_vehicle_position_hash); i++) {
|
|
||||||
_vehicle_position_hash[i] = INVALID_VEHICLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResetVehiclePosHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vehicle *GetLastVehicleInChain(Vehicle *v)
|
Vehicle *GetLastVehicleInChain(Vehicle *v)
|
||||||
|
|
|
@ -277,6 +277,7 @@ Vehicle *FindVehicleOnTileZ(TileIndex tile, byte z);
|
||||||
|
|
||||||
void InitializeTrains(void);
|
void InitializeTrains(void);
|
||||||
byte VehicleRandomBits(void);
|
byte VehicleRandomBits(void);
|
||||||
|
void ResetVehiclePosHash(void);
|
||||||
|
|
||||||
bool CanFillVehicle(Vehicle *v);
|
bool CanFillVehicle(Vehicle *v);
|
||||||
bool CanRefitTo(EngineID engine_type, CargoID cid_to);
|
bool CanRefitTo(EngineID engine_type, CargoID cid_to);
|
||||||
|
|
Loading…
Reference in New Issue