|
@@ -104,17 +104,6 @@ const SettingDesc *GetSettingDescription
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the setting at the given index into the company settings table.
|
|
|
* @param index The index to look for.
|
|
|
* @return The setting at the given index, or nullptr when the index is invalid.
|
|
|
*/
|
|
|
static const SettingDesc *GetCompanySettingDescription(uint index)
|
|
|
{
|
|
|
if (index >= _company_settings.size()) return nullptr;
|
|
|
return _company_settings.begin()[index].get();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Groups in openttd.cfg that are actually lists.
|
|
|
*/
|
|
|
static const char * const _list_group_names[] = {
|
|
@@ -1710,19 +1699,74 @@ void IntSettingDesc::ChangeValue(const v
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Given a name of setting, return a setting description from the table.
|
|
|
* @param name Name of the setting to return a setting description of.
|
|
|
* @param settings Table to look in for the setting.
|
|
|
* @return Pointer to the setting description of setting \a name if it can be found,
|
|
|
* \c nullptr indicates failure to obtain the description.
|
|
|
*/
|
|
|
static const SettingDesc *GetSettingFromName(const char *name, const SettingTable &settings)
|
|
|
{
|
|
|
/* First check all full names */
|
|
|
for (auto &sd : settings) {
|
|
|
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
|
|
|
if (strcmp(sd->name, name) == 0) return sd.get();
|
|
|
}
|
|
|
|
|
|
/* Then check the shortcut variant of the name. */
|
|
|
for (auto &sd : settings) {
|
|
|
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
|
|
|
const char *short_name = strchr(sd->name, '.');
|
|
|
if (short_name != nullptr) {
|
|
|
short_name++;
|
|
|
if (strcmp(short_name, name) == 0) return sd.get();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return nullptr;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Given a name of setting, return a company setting description of it.
|
|
|
* @param name Name of the company setting to return a setting description of.
|
|
|
* @return Pointer to the setting description of setting \a name if it can be found,
|
|
|
* \c nullptr indicates failure to obtain the description.
|
|
|
*/
|
|
|
static const SettingDesc *GetCompanySettingFromName(const char *name)
|
|
|
{
|
|
|
if (strncmp(name, "company.", 8) == 0) name += 8;
|
|
|
return GetSettingFromName(name, _company_settings);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Given a name of any setting, return any setting description of it.
|
|
|
* @param name Name of the setting to return a setting description of.
|
|
|
* @return Pointer to the setting description of setting \a name if it can be found,
|
|
|
* \c nullptr indicates failure to obtain the description.
|
|
|
*/
|
|
|
const SettingDesc *GetSettingFromName(const char *name)
|
|
|
{
|
|
|
auto sd = GetSettingFromName(name, _settings);
|
|
|
if (sd != nullptr) return sd;
|
|
|
|
|
|
return GetCompanySettingFromName(name);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Network-safe changing of settings (server-only).
|
|
|
* @param tile unused
|
|
|
* @param flags operation to perform
|
|
|
* @param p1 the index of the setting in the SettingDesc array which identifies it
|
|
|
* @param p1 unused
|
|
|
* @param p2 the new value for the setting
|
|
|
* The new value is properly clamped to its minimum/maximum when setting
|
|
|
* @param text unused
|
|
|
* @param text the name of the setting to change
|
|
|
* @return the cost of this operation or an error
|
|
|
* @see _settings
|
|
|
*/
|
|
|
CommandCost CmdChangeSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
|
|
{
|
|
|
const SettingDesc *sd = GetSettingDescription(p1);
|
|
|
if (text.empty()) return CMD_ERROR;
|
|
|
const SettingDesc *sd = GetSettingFromName(text.c_str());
|
|
|
|
|
|
if (sd == nullptr) return CMD_ERROR;
|
|
|
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) return CMD_ERROR;
|
|
@@ -1741,15 +1785,17 @@ CommandCost CmdChangeSetting(TileIndex t
|
|
|
* Change one of the per-company settings.
|
|
|
* @param tile unused
|
|
|
* @param flags operation to perform
|
|
|
* @param p1 the index of the setting in the _company_settings array which identifies it
|
|
|
* @param p1 unused
|
|
|
* @param p2 the new value for the setting
|
|
|
* The new value is properly clamped to its minimum/maximum when setting
|
|
|
* @param text unused
|
|
|
* @param text the name of the company setting to change
|
|
|
* @return the cost of this operation or an error
|
|
|
*/
|
|
|
CommandCost CmdChangeCompanySetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
|
|
{
|
|
|
const SettingDesc *sd = GetCompanySettingDescription(p1);
|
|
|
if (text.empty()) return CMD_ERROR;
|
|
|
const SettingDesc *sd = GetCompanySettingFromName(text.c_str());
|
|
|
|
|
|
if (sd == nullptr) return CMD_ERROR;
|
|
|
if (!sd->IsIntSetting()) return CMD_ERROR;
|
|
|
|
|
@@ -1761,44 +1807,6 @@ CommandCost CmdChangeCompanySetting(Tile
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the index of the given setting in the setting table.
|
|
|
* @param settings The settings to look through.
|
|
|
* @param setting The setting to look for.
|
|
|
* @return The index, or UINT32_MAX when it has not been found.
|
|
|
*/
|
|
|
static uint GetSettingIndex(const SettingTable &settings, const SettingDesc *setting)
|
|
|
{
|
|
|
uint index = 0;
|
|
|
for (auto &sd : settings) {
|
|
|
if (sd.get() == setting) return index;
|
|
|
index++;
|
|
|
}
|
|
|
return UINT32_MAX;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the index of the setting with this description.
|
|
|
* @param sd the setting to get the index for.
|
|
|
* @return the index of the setting to be used for CMD_CHANGE_SETTING.
|
|
|
*/
|
|
|
uint GetSettingIndex(const SettingDesc *sd)
|
|
|
{
|
|
|
assert(sd != nullptr && (sd->flags & SGF_PER_COMPANY) == 0);
|
|
|
return GetSettingIndex(_settings, sd);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the index of the company setting with this description.
|
|
|
* @param sd the setting to get the index for.
|
|
|
* @return the index of the setting to be used for CMD_CHANGE_COMPANY_SETTING.
|
|
|
*/
|
|
|
static uint GetCompanySettingIndex(const SettingDesc *sd)
|
|
|
{
|
|
|
assert(sd != nullptr && (sd->flags & SGF_PER_COMPANY) != 0);
|
|
|
return GetSettingIndex(_company_settings, sd);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Top function to save the new value of an element of the Settings struct
|
|
|
* @param index offset in the SettingDesc array of the Settings struct which
|
|
|
* identifies the setting member we want to change
|
|
@@ -1810,7 +1818,7 @@ bool SetSettingValue(const IntSettingDes
|
|
|
const IntSettingDesc *setting = sd->AsIntSetting();
|
|
|
if ((setting->flags & SGF_PER_COMPANY) != 0) {
|
|
|
if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) {
|
|
|
return DoCommandP(0, GetCompanySettingIndex(setting), value, CMD_CHANGE_COMPANY_SETTING);
|
|
|
return DoCommandP(0, 0, value, CMD_CHANGE_COMPANY_SETTING, nullptr, setting->name);
|
|
|
}
|
|
|
|
|
|
setting->ChangeValue(&_settings_client.company, value);
|
|
@@ -1836,7 +1844,7 @@ bool SetSettingValue(const IntSettingDes
|
|
|
|
|
|
/* send non-company-based settings over the network */
|
|
|
if (!_networking || (_networking && _network_server)) {
|
|
|
return DoCommandP(0, GetSettingIndex(setting), value, CMD_CHANGE_SETTING);
|
|
|
return DoCommandP(0, 0, value, CMD_CHANGE_SETTING, nullptr, setting->name);
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
@@ -1860,26 +1868,14 @@ void SyncCompanySettings()
|
|
|
{
|
|
|
const void *old_object = &Company::Get(_current_company)->settings;
|
|
|
const void *new_object = &_settings_client.company;
|
|
|
uint i = 0;
|
|
|
for (auto &sd : _company_settings) {
|
|
|
uint32 old_value = (uint32)sd->AsIntSetting()->Read(new_object);
|
|
|
uint32 new_value = (uint32)sd->AsIntSetting()->Read(old_object);
|
|
|
if (old_value != new_value) NetworkSendCommand(0, i, new_value, CMD_CHANGE_COMPANY_SETTING, nullptr, {}, _local_company);
|
|
|
i++;
|
|
|
if (old_value != new_value) NetworkSendCommand(0, 0, new_value, CMD_CHANGE_COMPANY_SETTING, nullptr, sd->name, _local_company);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the index in the _company_settings array of a setting
|
|
|
* @param name The name of the setting
|
|
|
* @return The index in the _company_settings array
|
|
|
*/
|
|
|
uint GetCompanySettingIndex(const char *name)
|
|
|
{
|
|
|
return GetCompanySettingIndex(GetSettingFromName(name));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Set a setting value with a string.
|
|
|
* @param sd the setting to change.
|
|
|
* @param value the value to write
|
|
@@ -1916,47 +1912,11 @@ void StringSettingDesc::ChangeValue(cons
|
|
|
if (_save_config) SaveToConfig();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Given a name of setting, return a setting description of it.
|
|
|
* @param name Name of the setting to return a setting description of
|
|
|
* @param i Pointer to an integer that will contain the index of the setting after the call, if it is successful.
|
|
|
* @return Pointer to the setting description of setting \a name if it can be found,
|
|
|
* \c nullptr indicates failure to obtain the description
|
|
|
*/
|
|
|
const SettingDesc *GetSettingFromName(const char *name)
|
|
|
{
|
|
|
/* First check all full names */
|
|
|
for (auto &sd : _settings) {
|
|
|
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
|
|
|
if (strcmp(sd->name, name) == 0) return sd.get();
|
|
|
}
|
|
|
|
|
|
/* Then check the shortcut variant of the name. */
|
|
|
for (auto &sd : _settings) {
|
|
|
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
|
|
|
const char *short_name = strchr(sd->name, '.');
|
|
|
if (short_name != nullptr) {
|
|
|
short_name++;
|
|
|
if (strcmp(short_name, name) == 0) return sd.get();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (strncmp(name, "company.", 8) == 0) name += 8;
|
|
|
/* And finally the company-based settings */
|
|
|
for (auto &sd : _company_settings) {
|
|
|
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
|
|
|
if (strcmp(sd->name, name) == 0) return sd.get();
|
|
|
}
|
|
|
|
|
|
return nullptr;
|
|
|
}
|
|
|
|
|
|
/* Those 2 functions need to be here, else we have to make some stuff non-static
|
|
|
* and besides, it is also better to keep stuff like this at the same place */
|
|
|
void IConsoleSetSetting(const char *name, const char *value, bool force_newgame)
|
|
|
{
|
|
|
const SettingDesc *sd = GetSettingFromName(name);
|
|
|
|
|
|
if (sd == nullptr) {
|
|
|
IConsolePrintF(CC_WARNING, "'%s' is an unknown setting.", name);
|
|
|
return;
|