|
@@ -582,25 +582,25 @@ void ListSettingDesc::ParseValue(const I
|
|
|
* these and save them.
|
|
|
*/
|
|
|
static void IniSaveSettings(IniFile *ini, const SettingTable &settings_table, const char *grpname, void *object, bool)
|
|
|
{
|
|
|
IniGroup *group_def = nullptr, *group;
|
|
|
IniItem *item;
|
|
|
char buf[512];
|
|
|
|
|
|
for (auto &sd : settings_table) {
|
|
|
/* If the setting is not saved to the configuration
|
|
|
* file, just continue with the next setting */
|
|
|
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
|
|
|
if (sd->save.conv & SLF_NOT_IN_CONFIG) continue;
|
|
|
if (sd->flags & SF_NOT_IN_CONFIG) continue;
|
|
|
|
|
|
/* XXX - wtf is this?? (group override?) */
|
|
|
std::string s{ sd->name };
|
|
|
auto sc = s.find('.');
|
|
|
if (sc != std::string::npos) {
|
|
|
group = ini->GetGroup(s.substr(0, sc));
|
|
|
s = s.substr(sc + 1);
|
|
|
} else {
|
|
|
if (group_def == nullptr) group_def = ini->GetGroup(grpname);
|
|
|
group = group_def;
|
|
|
}
|
|
|
|
|
@@ -732,42 +732,42 @@ void IniLoadWindowSettings(IniFile *ini,
|
|
|
void IniSaveWindowSettings(IniFile *ini, const char *grpname, void *desc)
|
|
|
{
|
|
|
IniSaveSettings(ini, _window_settings, grpname, desc, false);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Check whether the setting is editable in the current gamemode.
|
|
|
* @param do_command true if this is about checking a command from the server.
|
|
|
* @return true if editable.
|
|
|
*/
|
|
|
bool SettingDesc::IsEditable(bool do_command) const
|
|
|
{
|
|
|
if (!do_command && !(this->save.conv & SLF_NO_NETWORK_SYNC) && _networking && !_network_server && !(this->flags & SF_PER_COMPANY)) return false;
|
|
|
if (!do_command && !(this->flags & SF_NO_NETWORK_SYNC) && _networking && !_network_server && !(this->flags & SF_PER_COMPANY)) return false;
|
|
|
if ((this->flags & SF_NETWORK_ONLY) && !_networking && _game_mode != GM_MENU) return false;
|
|
|
if ((this->flags & SF_NO_NETWORK) && _networking) return false;
|
|
|
if ((this->flags & SF_NEWGAME_ONLY) &&
|
|
|
(_game_mode == GM_NORMAL ||
|
|
|
(_game_mode == GM_EDITOR && !(this->flags & SF_SCENEDIT_TOO)))) return false;
|
|
|
if ((this->flags & SF_SCENEDIT_ONLY) && _game_mode != GM_EDITOR) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Return the type of the setting.
|
|
|
* @return type of setting
|
|
|
*/
|
|
|
SettingType SettingDesc::GetType() const
|
|
|
{
|
|
|
if (this->flags & SF_PER_COMPANY) return ST_COMPANY;
|
|
|
return (this->save.conv & SLF_NOT_IN_SAVE) ? ST_CLIENT : ST_GAME;
|
|
|
return (this->flags & SF_NOT_IN_SAVE) ? ST_CLIENT : ST_GAME;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the setting description of this setting as an integer setting.
|
|
|
* @return The integer setting description.
|
|
|
*/
|
|
|
const IntSettingDesc *SettingDesc::AsIntSetting() const
|
|
|
{
|
|
|
assert(this->IsIntSetting());
|
|
|
return static_cast<const IntSettingDesc *>(this);
|
|
|
}
|
|
|
|
|
@@ -1835,25 +1835,25 @@ bool SetSettingValue(const IntSettingDes
|
|
|
if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) {
|
|
|
return DoCommandP(0, 0, value, CMD_CHANGE_COMPANY_SETTING, nullptr, setting->name);
|
|
|
}
|
|
|
|
|
|
setting->ChangeValue(&_settings_client.company, value);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/* If an item is company-based, we do not send it over the network
|
|
|
* (if any) to change. Also *hack*hack* we update the _newgame version
|
|
|
* of settings because changing a company-based setting in a game also
|
|
|
* changes its defaults. At least that is the convention we have chosen */
|
|
|
if (setting->save.conv & SLF_NO_NETWORK_SYNC) {
|
|
|
if (setting->flags & SF_NO_NETWORK_SYNC) {
|
|
|
if (_game_mode != GM_MENU) {
|
|
|
setting->ChangeValue(&_settings_newgame, value);
|
|
|
}
|
|
|
setting->ChangeValue(&GetGameSettings(), value);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (force_newgame) {
|
|
|
setting->ChangeValue(&_settings_newgame, value);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -1890,25 +1890,25 @@ void SyncCompanySettings()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Set a setting value with a string.
|
|
|
* @param sd the setting to change.
|
|
|
* @param value the value to write
|
|
|
* @param force_newgame force the newgame settings
|
|
|
* @note Strings WILL NOT be synced over the network
|
|
|
*/
|
|
|
bool SetSettingValue(const StringSettingDesc *sd, std::string value, bool force_newgame)
|
|
|
{
|
|
|
assert(sd->save.conv & SLF_NO_NETWORK_SYNC);
|
|
|
assert(sd->flags & SF_NO_NETWORK_SYNC);
|
|
|
|
|
|
if (GetVarMemType(sd->save.conv) == SLE_VAR_STRQ && value.compare("(null)") == 0) {
|
|
|
value.clear();
|
|
|
}
|
|
|
|
|
|
const void *object = (_game_mode == GM_MENU || force_newgame) ? &_settings_newgame : &_settings_game;
|
|
|
sd->AsStringSetting()->ChangeValue(object, value);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Handle changing a string value. This performs validation of the input value
|
|
@@ -2014,28 +2014,28 @@ void IConsoleListSettings(const char *pr
|
|
|
IConsolePrintF(CC_WARNING, "Use 'setting' command to change a value");
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Save and load handler for settings
|
|
|
* @param settings SettingDesc struct containing all information
|
|
|
* @param object can be either nullptr in which case we load global variables or
|
|
|
* a pointer to a struct which is getting saved
|
|
|
*/
|
|
|
static void LoadSettings(const SettingTable &settings, void *object)
|
|
|
{
|
|
|
for (auto &osd : settings) {
|
|
|
if (osd->save.conv & SLF_NOT_IN_SAVE) continue;
|
|
|
if (osd->flags & SF_NOT_IN_SAVE) continue;
|
|
|
|
|
|
SaveLoad sl = osd->save;
|
|
|
if ((osd->save.conv & SLF_NO_NETWORK_SYNC) && _networking && !_network_server) {
|
|
|
if ((osd->flags & SF_NO_NETWORK_SYNC) && _networking && !_network_server) {
|
|
|
/* We don't want to read this setting, so we do need to skip over it. */
|
|
|
sl = SLE_NULL(static_cast<uint16>(SlCalcConvMemLen(osd->save.conv) * osd->save.length));
|
|
|
}
|
|
|
|
|
|
void *ptr = GetVariableAddress(object, sl);
|
|
|
if (!SlObjectMember(ptr, sl)) continue;
|
|
|
|
|
|
if (osd->IsIntSetting()) {
|
|
|
const IntSettingDesc *int_setting = osd->AsIntSetting();
|
|
|
int_setting->MakeValueValidAndWrite(object, int_setting->Read(object));
|
|
|
}
|
|
|
}
|
|
@@ -2044,32 +2044,32 @@ static void LoadSettings(const SettingTa
|
|
|
/**
|
|
|
* Save and load handler for settings
|
|
|
* @param settings SettingDesc struct containing all information
|
|
|
* @param object can be either nullptr in which case we load global variables or
|
|
|
* a pointer to a struct which is getting saved
|
|
|
*/
|
|
|
static void SaveSettings(const SettingTable &settings, void *object)
|
|
|
{
|
|
|
/* We need to write the CH_RIFF header, but unfortunately can't call
|
|
|
* SlCalcLength() because we have a different format. So do this manually */
|
|
|
size_t length = 0;
|
|
|
for (auto &sd : settings) {
|
|
|
if (sd->save.conv & SLF_NOT_IN_SAVE) continue;
|
|
|
if (sd->flags & SF_NOT_IN_SAVE) continue;
|
|
|
|
|
|
length += SlCalcObjMemberLength(object, sd->save);
|
|
|
}
|
|
|
SlSetLength(length);
|
|
|
|
|
|
for (auto &sd : settings) {
|
|
|
if (sd->save.conv & SLF_NOT_IN_SAVE) continue;
|
|
|
if (sd->flags & SF_NOT_IN_SAVE) continue;
|
|
|
|
|
|
void *ptr = GetVariableAddress(object, sd->save);
|
|
|
SlObjectMember(ptr, sd->save);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
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();
|