summaryrefslogtreecommitdiff
path: root/src/settings.cpp
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2008-05-26 00:31:36 +0000
committerrubidium <rubidium@openttd.org>2008-05-26 00:31:36 +0000
commitcd8e589fa9c744a24d550de0dcd549f00ea6de1c (patch)
tree3f44a1d9be6c38b45ad872a47f1b32469c469497 /src/settings.cpp
parent8c9cc415e3eac6a7709f6a8978f213311416312e (diff)
downloadopenttd-cd8e589fa9c744a24d550de0dcd549f00ea6de1c.tar.xz
(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.
Diffstat (limited to 'src/settings.cpp')
-rw-r--r--src/settings.cpp189
1 files changed, 168 insertions, 21 deletions
diff --git a/src/settings.cpp b/src/settings.cpp
index b03bff602..b82717529 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -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},
};