(svn r13256) -Codechange: merge the OPTS and PATS chuncks.

-Codechange: split the diff_custom variable.
-Feature: allow changing some of the diff_custom variables via the console in network games.
pull/155/head
rubidium 16 years ago
parent d289464d69
commit c4c440cc20

@ -152,7 +152,6 @@ DEF_COMMAND(CmdDoTownAction);
DEF_COMMAND(CmdSetRoadDriveSide);
DEF_COMMAND(CmdChangeDifficultyLevel);
DEF_COMMAND(CmdChangePatchSetting);
DEF_COMMAND(CmdStartStopShip);
@ -304,7 +303,6 @@ static const Command _command_proc_table[] = {
{CmdDoTownAction, 0}, /* CMD_DO_TOWN_ACTION */
{CmdSetRoadDriveSide, CMD_SERVER}, /* CMD_SET_ROAD_DRIVE_SIDE */
{CmdChangeDifficultyLevel, CMD_SERVER}, /* CMD_CHANGE_DIFFICULTY_LEVEL */
{CmdStartStopShip, 0}, /* CMD_START_STOP_SHIP */
{CmdSellShip, 0}, /* CMD_SELL_SHIP */

@ -233,8 +233,6 @@ enum {
CMD_SET_ROAD_DRIVE_SIDE, ///< set the side where the road vehicles drive
CMD_CHANGE_DIFFICULTY_LEVEL, ///< change the difficult of a game (each setting for it own)
CMD_START_STOP_SHIP, ///< start/stop a ship
CMD_SELL_SHIP, ///< sell a ship
CMD_BUILD_SHIP, ///< build a new ship

@ -832,7 +832,7 @@ void StartupEconomy()
_economy.interest_rate = _settings.difficulty.initial_interest;
_economy.infl_amount = _settings.difficulty.initial_interest;
_economy.infl_amount_pr = max(0, _settings.difficulty.initial_interest - 1);
_economy.max_loan_unround = _economy.max_loan = _settings.difficulty.max_loan * 1000;
_economy.max_loan_unround = _economy.max_loan = _settings.difficulty.max_loan;
_economy.fluct = GB(Random(), 0, 8) + 168;
}

@ -48,7 +48,7 @@ extern void SwitchMode(int new_mode);
static inline void SetNewLandscapeType(byte landscape)
{
_settings.game_creation.landscape = landscape;
_settings_newgame.game_creation.landscape = landscape;
InvalidateWindowClasses(WC_SELECT_GAME);
InvalidateWindowClasses(WC_GENERATE_LANDSCAPE);
}
@ -253,7 +253,7 @@ struct GenerateLandscapeWindow : public QueryStringBaseWindow {
GenerateLandscapeWindow(const WindowDesc *desc, WindowNumber number = 0) : QueryStringBaseWindow(desc, number)
{
this->LowerWidget(_settings.game_creation.landscape + GLAND_TEMPERATE);
this->LowerWidget(_settings_newgame.game_creation.landscape + GLAND_TEMPERATE);
snprintf(this->edit_str_buf, sizeof(this->edit_str_buf), "%u", _settings_newgame.game_creation.generation_seed);
InitializeTextBuffer(&this->text, this->edit_str_buf, lengthof(this->edit_str_buf), 120);
@ -272,7 +272,7 @@ struct GenerateLandscapeWindow : public QueryStringBaseWindow {
this->SetWidgetDisabledState(GLAND_SMOOTHNESS_PULLDOWN, _settings_newgame.game_creation.land_generator == 0);
}
/* Disable snowline if not hilly */
this->SetWidgetDisabledState(GLAND_SNOW_LEVEL_TEXT, _settings.game_creation.landscape != LT_ARCTIC);
this->SetWidgetDisabledState(GLAND_SNOW_LEVEL_TEXT, _settings_newgame.game_creation.landscape != LT_ARCTIC);
/* Disable town, industry and trees in SE */
this->SetWidgetDisabledState(GLAND_TOWN_PULLDOWN, _game_mode == GM_EDITOR);
this->SetWidgetDisabledState(GLAND_INDUSTRY_PULLDOWN, _game_mode == GM_EDITOR);
@ -280,13 +280,13 @@ struct GenerateLandscapeWindow : public QueryStringBaseWindow {
this->SetWidgetDisabledState(GLAND_START_DATE_DOWN, _settings_newgame.game_creation.starting_year <= MIN_YEAR);
this->SetWidgetDisabledState(GLAND_START_DATE_UP, _settings_newgame.game_creation.starting_year >= MAX_YEAR);
this->SetWidgetDisabledState(GLAND_SNOW_LEVEL_DOWN, _settings_newgame.game_creation.snow_line_height <= 2 || _settings.game_creation.landscape != LT_ARCTIC);
this->SetWidgetDisabledState(GLAND_SNOW_LEVEL_UP, _settings_newgame.game_creation.snow_line_height >= MAX_SNOWLINE_HEIGHT || _settings.game_creation.landscape != LT_ARCTIC);
this->SetWidgetDisabledState(GLAND_SNOW_LEVEL_DOWN, _settings_newgame.game_creation.snow_line_height <= 2 || _settings_newgame.game_creation.landscape != LT_ARCTIC);
this->SetWidgetDisabledState(GLAND_SNOW_LEVEL_UP, _settings_newgame.game_creation.snow_line_height >= MAX_SNOWLINE_HEIGHT || _settings_newgame.game_creation.landscape != LT_ARCTIC);
this->SetWidgetLoweredState(GLAND_TEMPERATE, _settings.game_creation.landscape == LT_TEMPERATE);
this->SetWidgetLoweredState(GLAND_ARCTIC, _settings.game_creation.landscape == LT_ARCTIC);
this->SetWidgetLoweredState(GLAND_TROPICAL, _settings.game_creation.landscape == LT_TROPIC);
this->SetWidgetLoweredState(GLAND_TOYLAND, _settings.game_creation.landscape == LT_TOYLAND);
this->SetWidgetLoweredState(GLAND_TEMPERATE, _settings_newgame.game_creation.landscape == LT_TEMPERATE);
this->SetWidgetLoweredState(GLAND_ARCTIC, _settings_newgame.game_creation.landscape == LT_ARCTIC);
this->SetWidgetLoweredState(GLAND_TROPICAL, _settings_newgame.game_creation.landscape == LT_TROPIC);
this->SetWidgetLoweredState(GLAND_TOYLAND, _settings_newgame.game_creation.landscape == LT_TOYLAND);
if (_game_mode == GM_EDITOR) {
this->widget[GLAND_TOWN_PULLDOWN].data = STR_6836_OFF;
@ -345,7 +345,7 @@ struct GenerateLandscapeWindow : public QueryStringBaseWindow {
case GLAND_ARCTIC:
case GLAND_TROPICAL:
case GLAND_TOYLAND:
this->RaiseWidget(_settings.game_creation.landscape + GLAND_TEMPERATE);
this->RaiseWidget(_settings_newgame.game_creation.landscape + GLAND_TEMPERATE);
SetNewLandscapeType(widget - GLAND_TEMPERATE);
break;
@ -492,13 +492,13 @@ struct GenerateLandscapeWindow : public QueryStringBaseWindow {
case GLAND_TOWN_PULLDOWN:
_settings_newgame.difficulty.number_towns = index;
if (_settings_newgame.difficulty.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
DoCommandP(0, 2, _settings_newgame.difficulty.number_towns, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
IConsoleSetPatchSetting("difficulty.number_towns", _settings_newgame.difficulty.number_towns);
break;
case GLAND_INDUSTRY_PULLDOWN:
_settings_newgame.difficulty.number_industries = index;
if (_settings_newgame.difficulty.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
DoCommandP(0, 3, _settings_newgame.difficulty.number_industries, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
IConsoleSetPatchSetting("difficulty.number_industries", _settings_newgame.difficulty.number_industries);
break;
case GLAND_LANDSCAPE_PULLDOWN:
@ -513,13 +513,13 @@ struct GenerateLandscapeWindow : public QueryStringBaseWindow {
case GLAND_TERRAIN_PULLDOWN:
_settings_newgame.difficulty.terrain_type = index;
if (_settings_newgame.difficulty.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
DoCommandP(0, 12, _settings_newgame.difficulty.terrain_type, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
IConsoleSetPatchSetting("difficulty.terrain_type", _settings_newgame.difficulty.terrain_type);
break;
case GLAND_WATER_PULLDOWN:
_settings_newgame.difficulty.quantity_sea_lakes = index;
if (_settings_newgame.difficulty.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
DoCommandP(0, 13, _settings_newgame.difficulty.quantity_sea_lakes, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
IConsoleSetPatchSetting("difficulty.quantity_sea_lakes", _settings_newgame.difficulty.quantity_sea_lakes);
break;
}
this->SetDirty();
@ -642,7 +642,7 @@ struct CreateScenarioWindow : public Window
CreateScenarioWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
{
this->LowerWidget(_settings.game_creation.landscape + CSCEN_TEMPERATE);
this->LowerWidget(_settings_newgame.game_creation.landscape + CSCEN_TEMPERATE);
this->FindWindowPlacementAndResize(desc);
}
@ -653,10 +653,10 @@ struct CreateScenarioWindow : public Window
this->SetWidgetDisabledState(CSCEN_FLAT_LAND_HEIGHT_DOWN, _settings_newgame.game_creation.se_flat_world_height <= 0);
this->SetWidgetDisabledState(CSCEN_FLAT_LAND_HEIGHT_UP, _settings_newgame.game_creation.se_flat_world_height >= MAX_TILE_HEIGHT);
this->SetWidgetLoweredState(CSCEN_TEMPERATE, _settings.game_creation.landscape == LT_TEMPERATE);
this->SetWidgetLoweredState(CSCEN_ARCTIC, _settings.game_creation.landscape == LT_ARCTIC);
this->SetWidgetLoweredState(CSCEN_TROPICAL, _settings.game_creation.landscape == LT_TROPIC);
this->SetWidgetLoweredState(CSCEN_TOYLAND, _settings.game_creation.landscape == LT_TOYLAND);
this->SetWidgetLoweredState(CSCEN_TEMPERATE, _settings_newgame.game_creation.landscape == LT_TEMPERATE);
this->SetWidgetLoweredState(CSCEN_ARCTIC, _settings_newgame.game_creation.landscape == LT_ARCTIC);
this->SetWidgetLoweredState(CSCEN_TROPICAL, _settings_newgame.game_creation.landscape == LT_TROPIC);
this->SetWidgetLoweredState(CSCEN_TOYLAND, _settings_newgame.game_creation.landscape == LT_TOYLAND);
/* Set parameters for widget text that requires them */
SetDParam(0, ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1)); // CSCEN_START_DATE_TEXT
@ -674,7 +674,7 @@ struct CreateScenarioWindow : public Window
case CSCEN_ARCTIC:
case CSCEN_TROPICAL:
case CSCEN_TOYLAND:
this->RaiseWidget(_settings.game_creation.landscape + CSCEN_TEMPERATE);
this->RaiseWidget(_settings_newgame.game_creation.landscape + CSCEN_TEMPERATE);
SetNewLandscapeType(widget - CSCEN_TEMPERATE);
break;

@ -67,6 +67,7 @@ void InitializeGame(int mode, uint size_x, uint size_y)
_realtime_tick = 0;
_date_fract = 0;
_cur_tileloop_tile = 0;
_settings = _settings_newgame;
if ((mode & IG_DATE_RESET) == IG_DATE_RESET) {
SetDate(ConvertYMDToDate(_settings.game_creation.starting_year, 0, 1));

@ -22,7 +22,6 @@
#include "player_base.h"
#include "player_gui.h"
#include "settings_type.h"
#include "station_func.h"
#include "table/strings.h"
@ -380,46 +379,3 @@ CommandCost CmdGiveMoney(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
/* Subtract money from local-player */
return amount;
}
/** Change difficulty level/settings (server-only).
* We cannot really check for valid values of p2 (too much work mostly); stored
* in file 'settings_gui.c' _game_setting_info[]; we'll just trust the server it knows
* what to do and does this correctly
* @param tile unused
* @param flags operation to perform
* @param p1 the difficulty setting being changed. If it is -1, the difficulty level
* itself is changed. The new value is inside p2
* @param p2 new value for a difficulty setting or difficulty level
*/
CommandCost CmdChangeDifficultyLevel(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
if (p1 != (uint32)-1L && ((int32)p1 >= GAME_DIFFICULTY_NUM || (int32)p1 < 0)) return CMD_ERROR;
DifficultySettings *opt_ptr = (_game_mode == GM_MENU) ? &_settings_newgame.difficulty : &_settings.difficulty;
if (flags & DC_EXEC) {
if (p1 != (uint32)-1L) {
((GDType*)opt_ptr)[p1] = p2;
opt_ptr->diff_level = 3; // custom difficulty level
} else {
opt_ptr->diff_level = p2;
}
/* Since the tolerance of the town council has a direct impact on the noise generation/tolerance,
* launch a re-evaluation of the actual values only when setting has changed */
if (p2 == GAME_DIFFICULTY_TOWNCOUNCIL_TOLERANCE && _game_mode == GM_NORMAL) {
UpdateAirportsNoise();
if (_settings.economy.station_noise_level) {
InvalidateWindowClassesData(WC_TOWN_VIEW, 0);
}
}
/* If we are a network-client, update the difficult setting (if it is open).
* Use this instead of just dirtying the window because we need to load in
* the new difficulty settings */
if (_networking && !_network_server && FindWindowById(WC_GAME_OPTIONS, 0) != NULL) {
ShowGameDifficulty();
}
}
return CommandCost();
}

@ -1374,7 +1374,7 @@ static const OldChunks game_difficulty_chunk[] = {
OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, competitor_start_time ),
OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, number_towns ),
OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, number_industries ),
OCL_SVAR( OC_FILE_U16 | OC_VAR_U16, DifficultySettings, max_loan ),
OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, DifficultySettings, max_loan ),
OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, initial_interest ),
OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, vehicle_costs ),
OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, DifficultySettings, competitor_speed ),
@ -1392,7 +1392,9 @@ static const OldChunks game_difficulty_chunk[] = {
static inline bool LoadOldGameDifficulty(LoadgameState *ls, int num)
{
return LoadChunk(ls, &_settings.difficulty, game_difficulty_chunk);
bool ret = LoadChunk(ls, &_settings.difficulty, game_difficulty_chunk);
_settings.difficulty.max_loan *= 1000;
return ret;
}

@ -35,7 +35,7 @@
#include "table/strings.h"
extern const uint16 SAVEGAME_VERSION = 96;
extern const uint16 SAVEGAME_VERSION = 97;
SavegameType _savegame_type; ///< type of savegame we are loading

@ -60,6 +60,7 @@
#include "sound/sound_driver.hpp"
#include "music/music_driver.hpp"
#include "blitter/factory.hpp"
#include "station_func.h"
#include "table/strings.h"
@ -764,7 +765,7 @@ static void ini_load_settings(IniFile *ini, const SettingDesc *sd, const char *g
}
p = (item == NULL) ? sdb->def : string_to_val(sdb, item->value);
ptr = GetVariableAddress(object, sld);
ptr = GetVariableAddress(sld->global ? NULL : object, sld);
switch (sdb->cmd) {
case SDT_BOOLX: /* All four are various types of (integer) numbers */
@ -1133,6 +1134,7 @@ static void ini_save_setting_list(IniFile *ini, const char *grpname, char **list
#define NO SGF_NETWORK_ONLY
#define CR SGF_CURRENCY
#define NN SGF_NO_NETWORK
#define NG SGF_NEWGAME_ONLY
/* Begin - Callback Functions for the various settings */
/* virtual PositionMainToolbar function, calls the right one.*/
@ -1274,6 +1276,92 @@ static int32 DragSignalsDensityChanged(int32)
return 0;
}
/*
* A: competitors
* B: start time in months / 3
* C: town count (3 = high, 0 = very low)
* D: industry count (4 = high, 0 = none)
* E: inital loan (in GBP)
* F: interest rate
* G: running costs (0 = low, 2 = high)
* H: construction speed of competitors (0 = very slow, 4 = very fast)
* I: intelligence (0-2)
* J: breakdowns (0 = off, 2 = normal)
* K: subsidy multiplier (0 = 1.5, 3 = 4.0)
* L: construction cost (0-2)
* M: terrain type (0 = very flat, 3 = mountainous)
* N: amount of water (0 = very low, 3 = high)
* O: economy (0 = steady, 1 = fluctuating)
* P: Train reversing (0 = end of line + stations, 1 = end of line)
* Q: disasters
* R: area restructuring (0 = permissive, 2 = hostile)
* S: the difficulty level
*/
static const DifficultySettings _default_game_diff[3] = { /*
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S*/
{2, 2, 2, 4, 300000, 2, 0, 2, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0, 0}, ///< easy
{4, 1, 2, 3, 150000, 3, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1}, ///< medium
{7, 0, 3, 3, 100000, 4, 1, 3, 2, 2, 0, 2, 3, 2, 1, 1, 1, 2, 2}, ///< hard
};
void SetDifficultyLevel(int mode, DifficultySettings *gm_opt)
{
assert(mode <= 3);
if (mode != 3) {
*gm_opt = _default_game_diff[mode];
} else {
gm_opt->diff_level = 3;
}
}
/**
* Checks the difficulty levels read from the configuration and
* forces them to be correct when invalid.
*/
void CheckDifficultyLevels()
{
if (_settings_newgame.difficulty.diff_level != 3) {
SetDifficultyLevel(_settings_newgame.difficulty.diff_level, &_settings_newgame.difficulty);
}
}
static int32 DifficultyReset(int32 level)
{
SetDifficultyLevel(level, (_game_mode == GM_MENU) ? &_settings_newgame.difficulty : &_settings.difficulty);
return 0;
}
static int32 DifficultyChange(int32)
{
if (_game_mode == GM_MENU) {
_settings_newgame.difficulty.diff_level = 3;
} else {
_settings.difficulty.diff_level = 3;
}
/* If we are a network-client, update the difficult setting (if it is open).
* Use this instead of just dirtying the window because we need to load in
* the new difficulty settings */
if (_networking && FindWindowById(WC_GAME_OPTIONS, 0) != NULL) {
ShowGameDifficulty();
}
return 0;
}
static int32 DifficultyNoiseChange(int32 i)
{
if (_game_mode == GM_NORMAL) {
UpdateAirportsNoise();
if (_settings.economy.station_noise_level) {
InvalidateWindowClassesData(WC_TOWN_VIEW, 0);
}
}
return DifficultyChange(i);
}
/**
* Check for right TownLayout usage in editor mode.
* The No Road mode is not desirable since towns have to be
@ -1417,6 +1505,9 @@ static const SettingDescGlobVarList _network_settings[] = {
};
#endif /* ENABLE_NETWORK */
static const uint GAME_DIFFICULTY_NUM = 18;
uint16 _old_diff_custom[GAME_DIFFICULTY_NUM];
static const SettingDesc _gameopt_settings[] = {
/* In version 4 a new difficulty setting has been added to the difficulty settings,
* town attitude towards demolishing. Needs special handling because some dimwit thought
@ -1427,18 +1518,19 @@ static const SettingDesc _gameopt_settings[] = {
* and why not byte for example?
* 'SLE_FILE_I16 | SLE_VAR_U16' in "diff_custom" is needed to get around SlArray() hack
* for savegames version 0 - though it is an array, it has to go through the byteswap process */
SDT_GENERAL("diff_custom", SDT_INTLIST, SL_ARR, SLE_FILE_I16 | SLE_VAR_U16, 0, 0, Settings, difficulty, 17, 0, 0, 0, 0, NULL, STR_NULL, NULL, NULL, 0, 3),
SDT_GENERAL("diff_custom", SDT_INTLIST, SL_ARR, SLE_UINT16, 0, 0, Settings, difficulty, 18, 0, 0, 0, 0, NULL, STR_NULL, NULL, NULL, 4, SL_MAX_VERSION),
SDT_VAR(Settings, difficulty.diff_level, SLE_UINT8, 0, 0, 0, 0, 3, 0, STR_NULL, NULL),
SDT_OMANY(Settings, gui.currency, SLE_UINT8, N, 0, 0, CUSTOM_CURRENCY_ID, "GBP|USD|EUR|YEN|ATS|BEF|CHF|CZK|DEM|DKK|ESP|FIM|FRF|GRD|HUF|ISK|ITL|NLG|NOK|PLN|ROL|RUR|SIT|SEK|YTL|SKK|BRR|custom", STR_NULL, NULL, NULL),
SDT_OMANY(Settings, gui.units, SLE_UINT8, N, 0, 1, 2, "imperial|metric|si", STR_NULL, NULL, NULL),
SDTG_GENERAL("diff_custom", SDT_INTLIST, SL_ARR, SLE_FILE_I16 | SLE_VAR_U16, C, 0, _old_diff_custom, 17, 0, 0, 0, 0, NULL, STR_NULL, NULL, 0, 3),
SDTG_GENERAL("diff_custom", SDT_INTLIST, SL_ARR, SLE_UINT16, C, 0, _old_diff_custom, 18, 0, 0, 0, 0, NULL, STR_NULL, NULL, 4, 96),
SDT_VAR(Settings, difficulty.diff_level, SLE_UINT8, 0, 0, 0, 0, 3, 0, STR_NULL, NULL),
SDT_OMANY(Settings, gui.currency, SLE_UINT8, N, 0, 0, CUSTOM_CURRENCY_ID, "GBP|USD|EUR|YEN|ATS|BEF|CHF|CZK|DEM|DKK|ESP|FIM|FRF|GRD|HUF|ISK|ITL|NLG|NOK|PLN|ROL|RUR|SIT|SEK|YTL|SKK|BRR|custom", STR_NULL, NULL, NULL),
SDT_OMANY(Settings, gui.units, SLE_UINT8, N, 0, 1, 2, "imperial|metric|si", STR_NULL, NULL, NULL),
/* There are only 21 predefined town_name values (0-20), but you can have more with newgrf action F so allow these bigger values (21-255). Invalid values will fallback to english on use and (undefined string) in GUI. */
SDT_OMANY(Settings, game_creation.town_name, SLE_UINT8, 0, 0, 0, 255, "english|french|german|american|latin|silly|swedish|dutch|finnish|polish|slovakish|norwegian|hungarian|austrian|romanian|czech|swiss|danish|turkish|italian|catalan", STR_NULL, NULL, NULL),
SDT_OMANY(Settings, game_creation.landscape, SLE_UINT8, 0, 0, 0, 3, "temperate|arctic|tropic|toyland", STR_NULL, NULL, ConvertLandscape),
SDT_VAR(Settings, game_creation.snow_line, SLE_UINT8, 0, 0, 7 * TILE_HEIGHT, 2 * TILE_HEIGHT, 13 * TILE_HEIGHT, 0, STR_NULL, NULL),
SDT_CONDOMANY(Settings,gui.autosave, SLE_UINT8, 0, 22, N, 0, 0, 0, "", STR_NULL, NULL, NULL),
SDT_CONDOMANY(Settings,gui.autosave, SLE_UINT8,23, SL_MAX_VERSION, S, 0, 1, 4, "off|monthly|quarterly|half year|yearly", STR_NULL, NULL, NULL),
SDT_OMANY(Settings, vehicle.road_side, SLE_UINT8, 0, 0, 1, 1, "left|right", STR_NULL, NULL, NULL),
SDT_OMANY(Settings, game_creation.town_name, SLE_UINT8, 0, 0, 0, 255, "english|french|german|american|latin|silly|swedish|dutch|finnish|polish|slovakish|norwegian|hungarian|austrian|romanian|czech|swiss|danish|turkish|italian|catalan", STR_NULL, NULL, NULL),
SDT_OMANY(Settings, game_creation.landscape, SLE_UINT8, 0, 0, 0, 3, "temperate|arctic|tropic|toyland", STR_NULL, NULL, ConvertLandscape),
SDT_VAR(Settings, game_creation.snow_line, SLE_UINT8, 0, 0, 7 * TILE_HEIGHT, 2 * TILE_HEIGHT, 13 * TILE_HEIGHT, 0, STR_NULL, NULL),
SDT_CONDOMANY(Settings, gui.autosave, SLE_UINT8, 0, 22, N, 0, 0, 0, "", STR_NULL, NULL, NULL),
SDT_CONDOMANY(Settings, gui.autosave, SLE_UINT8, 23, SL_MAX_VERSION, S, 0, 1, 4, "off|monthly|quarterly|half year|yearly", STR_NULL, NULL, NULL),
SDT_OMANY(Settings, vehicle.road_side, SLE_UINT8, 0, 0, 1, 1, "left|right", STR_NULL, NULL, NULL),
SDT_END()
};
@ -1454,6 +1546,32 @@ static const SettingDesc _gameopt_settings[] = {
const SettingDesc _patch_settings[] = {
/***************************************************************************/
/* Saved patch variables. */
/* Do not ADD or REMOVE something in this "difficulty.XXX" table or before it. It breaks savegame compatability. */
SDT_CONDVAR(Settings, difficulty.max_no_competitors, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 2, 0, 7, 1, STR_NULL, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.competitor_start_time, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 2, 0, 3, 1, STR_6830_IMMEDIATE, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.number_towns, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 2, 0, 3, 1, STR_NUM_VERY_LOW, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.number_industries, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 4, 0, 4, 1, STR_NONE, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.max_loan, SLE_UINT32, 97, SL_MAX_VERSION, 0,NG|CR,300000,100000,500000,50000,STR_NULL, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.initial_interest, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 2, 2, 4, 1, STR_NULL, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.vehicle_costs, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 0, 0, 2, 1, STR_6820_LOW, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.competitor_speed, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 2, 0, 4, 1, STR_681B_VERY_SLOW, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.competitor_intelligence, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 0, 0, 2, 1, STR_6820_LOW, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.vehicle_breakdowns, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 1, 0, 2, 1, STR_6823_NONE, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.subsidy_multiplier, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 2, 0, 3, 1, STR_6826_X1_5, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.construction_cost, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 0, 0, 2, 1, STR_6820_LOW, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.terrain_type, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 1, 0, 3, 1, STR_682A_VERY_FLAT, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.quantity_sea_lakes, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 0, 0, 3, 1, STR_VERY_LOW, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.economy, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 0, 0, 1, 1, STR_682E_STEADY, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.line_reverse_mode, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 0, 0, 1, 1, STR_6834_AT_END_OF_LINE_AND_AT_STATIONS, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.disasters, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 0, 0, 1, 1, STR_6836_OFF, DifficultyChange),
SDT_CONDVAR(Settings, difficulty.town_council_tolerance, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 0, 0, 2, 1, STR_PERMISSIVE, DifficultyNoiseChange),
SDT_CONDVAR(Settings, difficulty.diff_level, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 0, 0, 3, 0, STR_NULL, DifficultyReset),
/* There are only 21 predefined town_name values (0-20), but you can have more with newgrf action F so allow these bigger values (21-255). Invalid values will fallback to english on use and (undefined string) in GUI. */
SDT_CONDOMANY(Settings, game_creation.town_name, SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 0, 255, "english|french|german|american|latin|silly|swedish|dutch|finnish|polish|slovakish|norwegian|hungarian|austrian|romanian|czech|swiss|danish|turkish|italian|catalan", STR_NULL, NULL, NULL),
SDT_CONDOMANY(Settings, game_creation.landscape, SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 0, 3, "temperate|arctic|tropic|toyland", STR_NULL, NULL, ConvertLandscape),
SDT_CONDVAR(Settings, game_creation.snow_line, SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 7 * TILE_HEIGHT, 2 * TILE_HEIGHT, 13 * TILE_HEIGHT, 0, STR_NULL, NULL),
SDT_CONDOMANY(Settings, vehicle.road_side, SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 1, 1, "left|right", STR_NULL, NULL, NULL),
SDT_BOOL(Settings, construction.build_on_slopes, 0,NN, true, STR_CONFIG_PATCHES_BUILDONSLOPES, NULL),
SDT_CONDBOOL(Settings, construction.autoslope, 75, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_PATCHES_AUTOSLOPE, NULL),
@ -1593,8 +1711,12 @@ const SettingDesc _patch_settings[] = {
SDT_VAR(Settings, game_creation.heightmap_rotation, SLE_UINT8, S,MS, 0, 0, 1, 0, STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION, NULL),
SDT_VAR(Settings, game_creation.se_flat_world_height, SLE_UINT8, S, 0, 0, 0, 15, 0, STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT, NULL),
SDT_CONDOMANY(Settings, gui.currency, SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 0, CUSTOM_CURRENCY_ID, "GBP|USD|EUR|YEN|ATS|BEF|CHF|CZK|DEM|DKK|ESP|FIM|FRF|GRD|HUF|ISK|ITL|NLG|NOK|PLN|ROL|RUR|SIT|SEK|YTL|SKK|BRR|custom", STR_NULL, NULL, NULL),
SDT_CONDOMANY(Settings, gui.units, SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 1, 2, "imperial|metric|si", STR_NULL, NULL, NULL),
/***************************************************************************/
/* Unsaved patch variables. */
SDT_OMANY(Settings, gui.autosave, SLE_UINT8, S, 0, 1, 4, "off|monthly|quarterly|half year|yearly", STR_NULL, NULL, NULL),
SDT_BOOL(Settings, gui.vehicle_speed, S, 0, true, STR_CONFIG_PATCHES_VEHICLESPEED, NULL),
SDT_BOOL(Settings, gui.status_long_date, S, 0, true, STR_CONFIG_PATCHES_LONGDATE, NULL),
SDT_BOOL(Settings, gui.show_finances, S, 0, true, STR_CONFIG_PATCHES_SHOWFINANCES, NULL),
@ -1671,6 +1793,31 @@ static const SettingDesc _currency_settings[] = {
#undef NO
#undef CR
static void PrepareOldDiffCustom()
{
memset(_old_diff_custom, 0, sizeof(_old_diff_custom));
}
static void HandleOldDiffCustom()
{
uint options_to_load = GAME_DIFFICULTY_NUM - (CheckSavegameVersion(4) ? 1 : 0);
/* If we did read to old_diff_custom, then at least one value must be non 0. */
bool old_diff_custom_used = false;
for (uint i = 0; i < options_to_load && !old_diff_custom_used; i++) {
old_diff_custom_used = (_old_diff_custom[i] != 0);
}
if (!old_diff_custom_used) return;
for (uint i = 0; i < options_to_load; i++) {
const SettingDesc *sd = &_patch_settings[i];
void *var = GetVariableAddress((_game_mode == GM_MENU) ? &_settings_newgame : &_settings, &sd->save);
Write_ValidateSetting(var, sd, (int32)((i == 4 ? 1000 : 1) * _old_diff_custom[i]));
}
}
static void NewsDisplayLoadConfig(IniFile *ini, const char *grpname)
{
IniGroup *group = ini_getgroup(ini, grpname);
@ -1836,7 +1983,10 @@ static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescP
proc(ini, (const SettingDesc*)_win32_settings, "win32", NULL);
#endif /* WIN32 */
PrepareOldDiffCustom();
proc(ini, _gameopt_settings, "gameopt", &_settings_newgame);
HandleOldDiffCustom();
proc(ini, _patch_settings, "patches", &_settings_newgame);
proc(ini, _currency_settings,"currency", &_custom_currency);
@ -1847,8 +1997,6 @@ static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescP
#endif /* ENABLE_NETWORK */
}
extern void CheckDifficultyLevels();
/** Load the values from the configuration files */
void LoadFromConfig()
{
@ -1870,6 +2018,7 @@ void SaveToConfig()
/* Remove some obsolete groups. These have all been loaded into other groups. */
ini_removegroup(ini, "patches");
ini_removegroup(ini, "yapf");
ini_removegroup(ini, "gameopt");
HandleSettingDescs(ini, ini_save_settings, ini_save_setting_list);
GRFSaveConfig(ini, "newgrf", _grfconfig_newgame);
@ -1903,6 +2052,7 @@ CommandCost CmdChangePatchSetting(TileIndex tile, uint32 flags, uint32 p1, uint3
if ((sd->desc.flags & SGF_NETWORK_ONLY) && !_networking) return CMD_ERROR;
if ((sd->desc.flags & SGF_NO_NETWORK) && _networking) return CMD_ERROR;
if ((sd->desc.flags & SGF_NEWGAME_ONLY) && _game_mode != GM_MENU) return CMD_ERROR;
if (flags & DC_EXEC) {
Settings *s = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings;
@ -2034,7 +2184,7 @@ static void LoadSettings(const SettingDesc *osd, void *object)
{
for (; osd->save.cmd != SL_END; osd++) {
const SaveLoad *sld = &osd->save;
void *ptr = GetVariableAddress(object, sld);
void *ptr = GetVariableAddress(sld->global ? NULL : object, sld);
if (!SlObjectMember(ptr, sld)) continue;
}
@ -2084,12 +2234,9 @@ static void Load_OPTS()
/* Copy over default setting since some might not get loaded in
* a networking environment. This ensures for example that the local
* autosave-frequency stays when joining a network-server */
PrepareOldDiffCustom();
LoadSettings(_gameopt_settings, &_settings);
}
static void Save_OPTS()
{
SaveSettings(_gameopt_settings, &_settings);
HandleOldDiffCustom();
}
static void Load_PATS()
@ -2124,7 +2271,7 @@ void UpdatePatches()
}
extern const ChunkHandler _setting_chunk_handlers[] = {
{ 'OPTS', Save_OPTS, Load_OPTS, CH_RIFF},
{ 'OPTS', NULL, Load_OPTS, CH_RIFF},
{ 'PATS', Save_PATS, Load_PATS, CH_RIFF | CH_LAST},
};

@ -289,7 +289,7 @@ struct GameOptionsWindow : Window {
break;
case GAMEOPT_AUTOSAVE_BTN: // Autosave options
_settings.gui.autosave = _settings.gui.autosave = index;
_settings.gui.autosave = _settings_newgame.gui.autosave = index;
this->SetDirty();
break;
@ -361,90 +361,6 @@ void ShowGameOptions()
new GameOptionsWindow(&_game_options_desc);
}
struct GameSettingData {
int16 min;
int16 max;
int16 step;
StringID str;
};
static const GameSettingData _game_setting_info[] = {
{ 0, 7, 1, STR_NULL},
{ 0, 3, 1, STR_6830_IMMEDIATE},
{ 0, 3, 1, STR_NUM_VERY_LOW},
{ 0, 4, 1, STR_NONE},
{100, 500, 50, STR_NULL},
{ 2, 4, 1, STR_NULL},
{ 0, 2, 1, STR_6820_LOW},
{ 0, 4, 1, STR_681B_VERY_SLOW},
{ 0, 2, 1, STR_6820_LOW},
{ 0, 2, 1, STR_6823_NONE},
{ 0, 3, 1, STR_6826_X1_5},
{ 0, 2, 1, STR_6820_LOW},
{ 0, 3, 1, STR_682A_VERY_FLAT},
{ 0, 3, 1, STR_VERY_LOW},
{ 0, 1, 1, STR_682E_STEADY},
{ 0, 1, 1, STR_6834_AT_END_OF_LINE_AND_AT_STATIONS},
{ 0, 1, 1, STR_6836_OFF},
{ 0, 2, 1, STR_PERMISSIVE},
};
/*
* A: competitors
* B: start time in months / 3
* C: town count (3 = high, 0 = very low)
* D: industry count (4 = high, 0 = none)
* E: inital loan / 1000 (in GBP)
* F: interest rate
* G: running costs (0 = low, 2 = high)
* H: construction speed of competitors (0 = very slow, 4 = very fast)
* I: intelligence (0-2)
* J: breakdowns (0 = off, 2 = normal)
* K: subsidy multiplier (0 = 1.5, 3 = 4.0)
* L: construction cost (0-2)
* M: terrain type (0 = very flat, 3 = mountainous)
* N: amount of water (0 = very low, 3 = high)
* O: economy (0 = steady, 1 = fluctuating)
* P: Train reversing (0 = end of line + stations, 1 = end of line)
* Q: disasters
* R: area restructuring (0 = permissive, 2 = hostile)
*/
static const GDType _default_game_diff[3][GAME_DIFFICULTY_NUM] = { /*
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R*/
{2, 2, 2, 4, 300, 2, 0, 2, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0}, ///< easy
{4, 1, 2, 3, 150, 3, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1}, ///< medium
{7, 0, 3, 3, 100, 4, 1, 3, 2, 2, 0, 2, 3, 2, 1, 1, 1, 2}, ///< hard
};
void SetDifficultyLevel(int mode, DifficultySettings *gm_opt)
{
int i;
assert(mode <= 3);
gm_opt->diff_level = mode;
if (mode != 3) { // not custom
for (i = 0; i != GAME_DIFFICULTY_NUM; i++)
((GDType*)gm_opt)[i] = _default_game_diff[mode][i];
}
}
/**
* Checks the difficulty levels read from the configuration and
* forces them to be correct when invalid.
*/
void CheckDifficultyLevels()
{
if (_settings_newgame.difficulty.diff_level != 3) {
SetDifficultyLevel(_settings_newgame.difficulty.diff_level, &_settings_newgame.difficulty);
} else {
for (uint i = 0; i < GAME_DIFFICULTY_NUM; i++) {
GDType *diff = ((GDType*)&_settings_newgame.difficulty) + i;
*diff = Clamp(*diff, _game_setting_info[i].min, _game_setting_info[i].max);
*diff -= *diff % _game_setting_info[i].step;
}
}
}
extern void StartupEconomy();
/* Widget definition for the game difficulty settings window */
@ -472,20 +388,21 @@ static const WindowDesc _game_difficulty_desc = {
_game_difficulty_widgets,
};
void SetDifficultyLevel(int mode, DifficultySettings *gm_opt);
struct GameDifficultyWindow : public Window {
private:
static const uint GAME_DIFFICULTY_NUM = 18;
bool clicked_increase;
uint8 clicked_button;
uint8 timeout;
/* Temporary holding place of values in the difficulty window until 'Save' is clicked */
DifficultySettings opt_mod_temp;
Settings opt_mod_temp;
enum {
GAMEDIFF_WND_TOP_OFFSET = 45,
GAMEDIFF_WND_ROWSIZE = 9,
// 0x383E = (1 << 13) | (1 << 12) | (1 << 11) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1)
DIFF_INGAME_DISABLED_BUTTONS = 0x383E,
NO_SETTINGS_BUTTON = 0xFF,
};
@ -510,7 +427,7 @@ public:
{
/* Copy current settings (ingame or in intro) to temporary holding place
* change that when setting stuff, copy back on clicking 'OK' */
this->opt_mod_temp = (_game_mode == GM_MENU) ? _settings_newgame.difficulty : _settings.difficulty;
this->opt_mod_temp = (_game_mode == GM_MENU) ? _settings_newgame : _settings;
this->clicked_increase = false;
this->clicked_button = NO_SETTINGS_BUTTON;
this->timeout = 0;
@ -527,7 +444,7 @@ public:
WIDGET_LIST_END);
this->SetWidgetDisabledState(GDW_HIGHSCORE, _game_mode == GM_EDITOR || _networking); // highscore chart in multiplayer
this->SetWidgetDisabledState(GDW_ACCEPT, _networking && !_network_server); // Save-button in multiplayer (and if client)
this->LowerWidget(GDW_LVL_EASY + this->opt_mod_temp.diff_level);
this->LowerWidget(GDW_LVL_EASY + this->opt_mod_temp.difficulty.diff_level);
this->FindWindowPlacementAndResize(&_game_difficulty_desc);
}
@ -535,29 +452,20 @@ public:
{
this->DrawWidgets();
/* XXX - Disabled buttons in normal gameplay or during muliplayer as non server.
* Bitshifted for each button to see if that bit is set. If it is set, the
* button is disabled */
uint32 disabled = 0;
if (_networking && !_network_server) {
disabled = MAX_UVALUE(uint32); // Disable all
} else if (_game_mode == GM_NORMAL) {
disabled = DIFF_INGAME_DISABLED_BUTTONS;
}
int value;
uint i;
const SettingDesc *sd = GetPatchFromName("difficulty.max_no_competitors", &i);
int y = GAMEDIFF_WND_TOP_OFFSET;
for (uint i = 0; i != GAME_DIFFICULTY_NUM; i++) {
const GameSettingData *gsd = &_game_setting_info[i];
value = ((GDType*)&this->opt_mod_temp)[i];
for (i = 0; i < GAME_DIFFICULTY_NUM; i++, sd++) {
const SettingDescBase *sdb = &sd->desc;
int32 value = (int32)ReadValue(GetVariableAddress(&this->opt_mod_temp, &sd->save), sd->save.conv);
bool editable = (_game_mode == GM_MENU || (sdb->flags & SGF_NEWGAME_ONLY) == 0);
DrawArrowButtons(5, y, 3,
(this->clicked_button == i) ? 1 + !!this->clicked_increase : 0,
!(HasBit(disabled, i) || gsd->min == value),
!(HasBit(disabled, i) || gsd->max == value));
editable && sdb->min != value,
editable && sdb->max != value);
value += _game_setting_info[i].str;
if (i == 4) value *= 1000; // XXX - handle currency option
value += sdb->str;
SetDParam(0, value);
DrawString(30, y, STR_6805_MAXIMUM_NO_COMPETITORS + i, TC_FROMSTRING);
@ -582,30 +490,33 @@ public:
const uint8 btn = y / (GAMEDIFF_WND_ROWSIZE + 2);
if (btn >= GAME_DIFFICULTY_NUM || y % (GAMEDIFF_WND_ROWSIZE + 2) >= 9) return;
uint i;
const SettingDesc *sd = GetPatchFromName("difficulty.max_no_competitors", &i) + btn;
const SettingDescBase *sdb = &sd->desc;
/* Clicked disabled button? */
if (_game_mode == GM_NORMAL && HasBit((int)DIFF_INGAME_DISABLED_BUTTONS, btn)) return;
bool editable = (_game_mode == GM_MENU || (sdb->flags & SGF_NEWGAME_ONLY) == 0);
if (!editable) return;
this->timeout = 5;
int32 val = (int32)ReadValue(GetVariableAddress(&this->opt_mod_temp, &sd->save), sd->save.conv);
int16 val = ((GDType*)&this->opt_mod_temp)[btn];
const GameSettingData *info = &_game_setting_info[btn]; // get information about the difficulty setting
if (x >= 10) {
/* Increase button clicked */
val = min(val + info->step, info->max);
val = min(val + sdb->interval, sdb->max);
this->clicked_increase = true;
} else {
/* Decrease button clicked */
val -= info->step;
val = max(val, info->min);
val -= sdb->interval;
val = max(val, sdb->min);
this->clicked_increase = false;
}
this->clicked_button = btn;
/* save value in temporary variable */
((GDType*)&this->opt_mod_temp)[btn] = val;
this->RaiseWidget(GDW_LVL_EASY + this->opt_mod_temp.diff_level);
SetDifficultyLevel(3, &this->opt_mod_temp); // set difficulty level to custom
WriteValue(GetVariableAddress(&this->opt_mod_temp, &sd->save), sd->save.conv, val);
this->RaiseWidget(GDW_LVL_EASY + this->opt_mod_temp.difficulty.diff_level);
SetDifficultyLevel(3, &this->opt_mod_temp.difficulty); // set difficulty level to custom
this->LowerWidget(GDW_LVL_CUSTOM);
this->SetDirty();
} break;
@ -615,27 +526,32 @@ public:
case GDW_LVL_HARD:
case GDW_LVL_CUSTOM:
/* temporarily change difficulty level */
this->RaiseWidget(GDW_LVL_EASY + this->opt_mod_temp.diff_level);
SetDifficultyLevel(widget - GDW_LVL_EASY, &this->opt_mod_temp);
this->LowerWidget(GDW_LVL_EASY + this->opt_mod_temp.diff_level);
this->RaiseWidget(GDW_LVL_EASY + this->opt_mod_temp.difficulty.diff_level);
SetDifficultyLevel(widget - GDW_LVL_EASY, &this->opt_mod_temp.difficulty);
this->LowerWidget(GDW_LVL_EASY + this->opt_mod_temp.difficulty.diff_level);
this->SetDirty();
break;
case GDW_HIGHSCORE: // Highscore Table
ShowHighscoreTable(this->opt_mod_temp.diff_level, -1);
ShowHighscoreTable(this->opt_mod_temp.difficulty.diff_level, -1);
break;
case GDW_ACCEPT: { // Save button - save changes
GDType btn, val;
Settings *opt_ptr = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings;
for (btn = 0; btn != GAME_DIFFICULTY_NUM; btn++) {
val = ((GDType*)&this->opt_mod_temp)[btn];
uint i;
const SettingDesc *sd = GetPatchFromName("difficulty.max_no_competitors", &i);
for (uint btn = 0; btn != GAME_DIFFICULTY_NUM; btn++, sd++) {
int32 new_val = (int32)ReadValue(GetVariableAddress(&this->opt_mod_temp, &sd->save), sd->save.conv);
int32 cur_val = (int32)ReadValue(GetVariableAddress(opt_ptr, &sd->save), sd->save.conv);
/* if setting has changed, change it */
if (val != ((GDType*)&opt_ptr->difficulty)[btn]) {
DoCommandP(0, btn, val, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
if (new_val != cur_val) {
DoCommandP(0, i + btn, new_val, NULL, CMD_CHANGE_PATCH_SETTING);
}
}
DoCommandP(0, UINT_MAX, this->opt_mod_temp.diff_level, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
GetPatchFromName("difficulty.diff_level", &i);
DoCommandP(0, i, this->opt_mod_temp.difficulty.diff_level, NULL, CMD_CHANGE_PATCH_SETTING);
delete this;
/* If we are in the editor, we should reload the economy.
* This way when you load a game, the max loan and interest rate

@ -39,8 +39,8 @@ enum SettingGuiFlagLong {
SGF_NETWORK_ONLY = 1 << 3, ///< this setting only applies to network games
SGF_CURRENCY = 1 << 4, ///< the number represents money, so when reading value multiply by exchange rate
SGF_NO_NETWORK = 1 << 5, ///< this setting does not apply to network games; it may not be changed during the game
SGF_END = 1 << 6,
/* 3 more possible flags */
SGF_NEWGAME_ONLY = 1 << 6, ///< this setting cannot be changed in inside a game
SGF_END = 1 << 7,
};
DECLARE_ENUM_AS_BIT_SET(SettingGuiFlagLong);

@ -9,51 +9,27 @@
#include "town_type.h"
#include "transport_type.h"
enum {
GAME_DIFFICULTY_AI_NUMBER,
GAME_DIFFICULTY_AI_STARTTIME,
GAME_DIFFICULTY_TOWN_NUMBER,
GAME_DIFFICULTY_INDUSTRIE_NUMBER,
GAME_DIFFICULTY_MAX_LOAN,
GAME_DIFFICULTY_INITIAL_INTEREST,
GAME_DIFFICULTY_VEHICLE_COST,
GAME_DIFFICULTY_AI_SPEED,
GAME_DIFFICULTY_AI_INTELLIGENCE, ///< no longer in use
GAME_DIFFICULTY_VEHICLES_BREAKDOWN,
GAME_DIFFICULTY_SUBSIDY_MULTIPLIER,
GAME_DIFFICULTY_CONSTRUCTION_COST,
GAME_DIFFICULTY_TYPE_TERRAIN,
GAME_DIFFICULTY_SEALAKE_NUMBER,
GAME_DIFFICULTY_ECONOMY,
GAME_DIFFICULTY_LINE_REVERSEMODE,
GAME_DIFFICULTY_DISASTERS,
GAME_DIFFICULTY_TOWNCOUNCIL_TOLERANCE, ///< minimum required town ratings to be allowed to demolish stuff
GAME_DIFFICULTY_NUM,
};
/** Specific type for Game Difficulty to ease changing the type */
typedef uint16 GDType;
/** Settings related to the difficulty of the game */
struct DifficultySettings {
GDType max_no_competitors; ///< the number of competitors (AIs)
GDType competitor_start_time; ///< how long to wait for the first competitors (AIs)
GDType number_towns; ///< the amount of towns
GDType number_industries; ///< the amount of industries
GDType max_loan; ///< the maximum initial loan
GDType initial_interest; ///< amount of interest (to pay over the loan)
GDType vehicle_costs; ///< amount of money spent on vehicle running cost
GDType competitor_speed; ///< the speed at which the AI builds
GDType competitor_intelligence; ///< the competior's (AI) intelligence
GDType vehicle_breakdowns; ///< likelihood of vehicles breaking down
GDType subsidy_multiplier; ///< amount of subsidy
GDType construction_cost; ///< how expensive is building
GDType terrain_type; ///< the mountainousness of the landscape
GDType quantity_sea_lakes; ///< the amount of seas/lakes
GDType economy; ///< how volatile is the economy
GDType line_reverse_mode; ///< reversing at stations or not
GDType disasters; ///< are disasters enabled
GDType town_council_tolerance; ///< minimum required town ratings to be allowed to demolish stuff
GDType diff_level; ///< the difficulty level
byte max_no_competitors; ///< the number of competitors (AIs)
byte competitor_start_time; ///< how long to wait for the first competitors (AIs)
byte number_towns; ///< the amount of towns
byte number_industries; ///< the amount of industries
uint32 max_loan; ///< the maximum initial loan
byte initial_interest; ///< amount of interest (to pay over the loan)
byte vehicle_costs; ///< amount of money spent on vehicle running cost
byte competitor_speed; ///< the speed at which the AI builds
byte competitor_intelligence; ///< the competior's (AI) intelligence
byte vehicle_breakdowns; ///< likelihood of vehicles breaking down
byte subsidy_multiplier; ///< amount of subsidy
byte construction_cost; ///< how expensive is building
byte terrain_type; ///< the mountainousness of the landscape
byte quantity_sea_lakes; ///< the amount of seas/lakes
byte economy; ///< how volatile is the economy
byte line_reverse_mode; ///< reversing at stations or not
byte disasters; ///< are disasters enabled
byte town_council_tolerance; ///< minimum required town ratings to be allowed to demolish stuff
byte diff_level; ///< the difficulty level
};
/** Settings related to the GUI and other stuff that is not saved in the savegame. */

Loading…
Cancel
Save