diff --git a/src/ai/api/ai_company.cpp b/src/ai/api/ai_company.cpp --- a/src/ai/api/ai_company.cpp +++ b/src/ai/api/ai_company.cpp @@ -13,6 +13,7 @@ #include "../../tile_map.h" #include "../../core/alloc_func.hpp" #include "../../string_func.h" +#include "../../settings_func.h" #include "table/strings.h" /* static */ AICompany::CompanyID AICompany::ResolveCompanyID(AICompany::CompanyID company) @@ -148,7 +149,7 @@ /* static */ bool AICompany::SetAutoRenewStatus(bool autorenew) { - return AIObject::DoCommand(0, 0, autorenew ? 1 : 0, CMD_SET_AUTOREPLACE); + return AIObject::DoCommand(0, ::GetCompanySettingIndex("company.engine_renew"), autorenew ? 1 : 0, CMD_CHANGE_COMPANY_SETTING); } /* static */ bool AICompany::GetAutoRenewStatus(CompanyID company) @@ -161,7 +162,7 @@ /* static */ bool AICompany::SetAutoRenewMonths(int16 months) { - return AIObject::DoCommand(0, 1, months, CMD_SET_AUTOREPLACE); + return AIObject::DoCommand(0, ::GetCompanySettingIndex("company.engine_renew_months"), months, CMD_CHANGE_COMPANY_SETTING); } /* static */ int16 AICompany::GetAutoRenewMonths(CompanyID company) @@ -174,7 +175,7 @@ /* static */ bool AICompany::SetAutoRenewMoney(uint32 money) { - return AIObject::DoCommand(0, 2, money, CMD_SET_AUTOREPLACE); + return AIObject::DoCommand(0, ::GetCompanySettingIndex("company.engine_renew_money"), money, CMD_CHANGE_COMPANY_SETTING); } /* static */ uint32 AICompany::GetAutoRenewMoney(CompanyID company) diff --git a/src/ai/api/ai_group.cpp b/src/ai/api/ai_group.cpp --- a/src/ai/api/ai_group.cpp +++ b/src/ai/api/ai_group.cpp @@ -12,6 +12,7 @@ #include "../../core/alloc_func.hpp" #include "../../command_func.h" #include "../../autoreplace_func.h" +#include "../../settings_func.h" #include "table/strings.h" /* static */ bool AIGroup::IsValidGroup(GroupID group_id) @@ -96,7 +97,7 @@ { if (HasWagonRemoval() == enable_removal) return true; - return AIObject::DoCommand(0, 5, enable_removal ? 1 : 0, CMD_SET_AUTOREPLACE); + return AIObject::DoCommand(0, ::GetCompanySettingIndex("company.renew_keep_length"), enable_removal ? 1 : 0, CMD_CHANGE_COMPANY_SETTING); } /* static */ bool AIGroup::HasWagonRemoval() @@ -109,7 +110,7 @@ EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_ALL); EnforcePrecondition(false, AIEngine::IsValidEngine(engine_id_new)); - return AIObject::DoCommand(0, 3 | (group_id << 16), (engine_id_new << 16) | engine_id_old, CMD_SET_AUTOREPLACE); + return AIObject::DoCommand(0, group_id << 16, (engine_id_new << 16) | engine_id_old, CMD_SET_AUTOREPLACE); } /* static */ EngineID AIGroup::GetEngineReplacement(GroupID group_id, EngineID engine_id) @@ -123,5 +124,5 @@ { EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_ALL); - return AIObject::DoCommand(0, 3 | (group_id << 16), (::INVALID_ENGINE << 16) | engine_id, CMD_SET_AUTOREPLACE); + return AIObject::DoCommand(0, group_id << 16, (::INVALID_ENGINE << 16) | engine_id, CMD_SET_AUTOREPLACE); } diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -17,6 +17,7 @@ #include "engine_base.h" #include "window_gui.h" #include "engine_gui.h" +#include "settings_func.h" #include "table/strings.h" @@ -347,19 +348,19 @@ public: } case RVW_WIDGET_TRAIN_WAGONREMOVE_TOGGLE: // toggle renew_keep_length - DoCommandP(0, 5, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_SET_AUTOREPLACE); + DoCommandP(0, GetCompanySettingIndex("company.renew_keep_length"), Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING); break; case RVW_WIDGET_START_REPLACE: { // Start replacing EngineID veh_from = this->sel_engine[0]; EngineID veh_to = this->sel_engine[1]; - DoCommandP(0, 3 + (this->sel_group << 16) , veh_from + (veh_to << 16), CMD_SET_AUTOREPLACE); + DoCommandP(0, this->sel_group << 16, veh_from + (veh_to << 16), CMD_SET_AUTOREPLACE); this->SetDirty(); } break; case RVW_WIDGET_STOP_REPLACE: { // Stop replacing EngineID veh_from = this->sel_engine[0]; - DoCommandP(0, 3 + (this->sel_group << 16), veh_from + (INVALID_ENGINE << 16), CMD_SET_AUTOREPLACE); + DoCommandP(0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16), CMD_SET_AUTOREPLACE); this->SetDirty(); } break; diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -29,6 +29,7 @@ #include "rail.h" #include "sprite.h" #include "core/pool_func.hpp" +#include "settings_func.h" #include "table/strings.h" @@ -531,126 +532,33 @@ void CompaniesYearlyLoop() /** Change engine renewal parameters * @param tile unused * @param flags operation to perform - * @param p1 bits 0-3 command - * - p1 = 0 - change auto renew bool - * - p1 = 1 - change auto renew months - * - p1 = 2 - change auto renew money - * - p1 = 3 - change auto renew array - * - p1 = 4 - change bool, months & money all together - * - p1 = 5 - change renew_keep_length - * @param p2 value to set - * if p1 = 0, then: - * - p2 = enable engine renewal - * if p1 = 1, then: - * - p2 = months left before engine expires to replace it - * if p1 = 2, then - * - p2 = minimum amount of money available - * if p1 = 3, then: + * @param * - p1 bits 16-31 = engine group * - p2 bits 0-15 = old engine type * - p2 bits 16-31 = new engine type - * if p1 = 4, then: - * - p1 bit 15 = enable engine renewal - * - p1 bits 16-31 = months left before engine expires to replace it - * - p2 bits 0-31 = minimum amount of money available - * if p1 = 5, then - * - p2 = enable renew_keep_length */ CommandCost CmdSetAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Company *c = Company::GetIfValid(_current_company); if (c == NULL) return CMD_ERROR; - switch (GB(p1, 0, 3)) { - case 0: - if (c->settings.engine_renew == HasBit(p2, 0)) return CMD_ERROR; - - if (flags & DC_EXEC) { - c->settings.engine_renew = HasBit(p2, 0); - if (IsLocalCompany()) { - _settings_client.company.engine_renew = c->settings.engine_renew; - InvalidateWindow(WC_GAME_OPTIONS, 0); - } - } - break; - - case 1: - if (Clamp((int16)p2, -12, 12) != (int16)p2) return CMD_ERROR; - if (c->settings.engine_renew_months == (int16)p2) return CMD_ERROR; - - if (flags & DC_EXEC) { - c->settings.engine_renew_months = (int16)p2; - if (IsLocalCompany()) { - _settings_client.company.engine_renew_months = c->settings.engine_renew_months; - InvalidateWindow(WC_GAME_OPTIONS, 0); - } - } - break; - - case 2: - if (ClampU(p2, 0, 2000000) != p2) return CMD_ERROR; - if (c->settings.engine_renew_money == p2) return CMD_ERROR; - - if (flags & DC_EXEC) { - c->settings.engine_renew_money = p2; - if (IsLocalCompany()) { - _settings_client.company.engine_renew_money = c->settings.engine_renew_money; - InvalidateWindow(WC_GAME_OPTIONS, 0); - } - } - break; + EngineID old_engine_type = GB(p2, 0, 16); + EngineID new_engine_type = GB(p2, 16, 16); + GroupID id_g = GB(p1, 16, 16); + CommandCost cost; - case 3: { - EngineID old_engine_type = GB(p2, 0, 16); - EngineID new_engine_type = GB(p2, 16, 16); - GroupID id_g = GB(p1, 16, 16); - CommandCost cost; - - if (!Group::IsValidID(id_g) && !IsAllGroupID(id_g) && !IsDefaultGroupID(id_g)) return CMD_ERROR; - if (new_engine_type != INVALID_ENGINE) { - if (!CheckAutoreplaceValidity(old_engine_type, new_engine_type, _current_company)) return CMD_ERROR; - - cost = AddEngineReplacementForCompany(c, old_engine_type, new_engine_type, id_g, flags); - } else { - cost = RemoveEngineReplacementForCompany(c, old_engine_type, id_g, flags); - } - - if (IsLocalCompany()) InvalidateAutoreplaceWindow(old_engine_type, id_g); - - return cost; - } - - case 4: - if (Clamp((int16)GB(p1, 16, 16), -12, 12) != (int16)GB(p1, 16, 16)) return CMD_ERROR; - if (ClampU(p2, 0, 2000000) != p2) return CMD_ERROR; + if (!Group::IsValidID(id_g) && !IsAllGroupID(id_g) && !IsDefaultGroupID(id_g)) return CMD_ERROR; + if (new_engine_type != INVALID_ENGINE) { + if (!CheckAutoreplaceValidity(old_engine_type, new_engine_type, _current_company)) return CMD_ERROR; - if (flags & DC_EXEC) { - c->settings.engine_renew = HasBit(p1, 15); - c->settings.engine_renew_months = (int16)GB(p1, 16, 16); - c->settings.engine_renew_money = p2; - - if (IsLocalCompany()) { - _settings_client.company.engine_renew = c->settings.engine_renew; - _settings_client.company.engine_renew_months = c->settings.engine_renew_months; - _settings_client.company.engine_renew_money = c->settings.engine_renew_money; - InvalidateWindow(WC_GAME_OPTIONS, 0); - } - } - break; - - case 5: - if (c->settings.renew_keep_length == HasBit(p2, 0)) return CMD_ERROR; - - if (flags & DC_EXEC) { - c->settings.renew_keep_length = HasBit(p2, 0); - if (IsLocalCompany()) { - InvalidateWindow(WC_REPLACE_VEHICLE, VEH_TRAIN); - } - } - break; + cost = AddEngineReplacementForCompany(c, old_engine_type, new_engine_type, id_g, flags); + } else { + cost = RemoveEngineReplacementForCompany(c, old_engine_type, id_g, flags); } - return CommandCost(); + if (IsLocalCompany()) InvalidateAutoreplaceWindow(old_engine_type, id_g); + + return cost; } /** @@ -742,9 +650,6 @@ CommandCost CmdCompanyCtrl(TileIndex til /* This is the client (or non-dedicated server) who wants a new company */ if (cid == _network_own_client_id) { - /* Create p1 and p2 here because SetLocalCompany resets the gui.autorenew* settings. */ - uint32 p1 = (_settings_client.company.engine_renew << 15 ) | (_settings_client.company.engine_renew_months << 16) | 4; - uint32 p2 = _settings_client.company.engine_renew_money; assert(_local_company == COMPANY_SPECTATOR); SetLocalCompany(c->index); if (!StrEmpty(_settings_client.network.default_company_pass)) { @@ -754,9 +659,9 @@ CommandCost CmdCompanyCtrl(TileIndex til _current_company = _local_company; - /* Now that we have a new company, broadcast our autorenew settings to + /* Now that we have a new company, broadcast our company settings to * all clients so everything is in sync */ - NetworkSend_Command(0, p1, p2, CMD_SET_AUTOREPLACE, NULL, NULL); + SyncCompanySettings(); MarkWholeScreenDirty(); } diff --git a/src/settings.cpp b/src/settings.cpp --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1425,6 +1425,7 @@ CommandCost CmdChangeSetting(TileIndex t */ CommandCost CmdChangeCompanySetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { + DEBUG(misc, 0, "Change company setting: %u into %u", p1, p2); if (p1 >= lengthof(_company_settings)) return CMD_ERROR; const SettingDesc *sd = &_company_settings[p1]; @@ -1502,6 +1503,35 @@ void SetCompanySetting(uint index, int32 } /** + * Sync all company settings in a multiplayer game. + */ +void SyncCompanySettings() +{ + const SettingDesc *sd; + uint i = 0; + for (sd = _company_settings; sd->save.cmd != SL_END; sd++, i++) { + const void *old_var = GetVariableAddress(&Company::Get(_current_company)->settings, &sd->save); + const void *new_var = GetVariableAddress(&_settings_client.company, &sd->save); + uint32 old_value = (uint32)ReadValue(old_var, sd->save.conv); + uint32 new_value = (uint32)ReadValue(new_var, sd->save.conv); + if (old_value != new_value) NetworkSend_Command(0, i, new_value, CMD_CHANGE_COMPANY_SETTING, NULL, NULL); + } +} + +/** + * 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) +{ + uint i; + const SettingDesc *sd = GetSettingFromName(name, &i); + assert(sd != NULL && (sd->desc.flags & SGF_PER_COMPANY) != 0); + return i; +} + +/** * Set a setting value with a string. * @param index the settings index. * @param value the value to write diff --git a/src/settings_func.h b/src/settings_func.h --- a/src/settings_func.h +++ b/src/settings_func.h @@ -25,4 +25,7 @@ struct GRFConfig *LoadGRFPresetFromConfi void SaveGRFPresetToConfig(const char *config_name, struct GRFConfig *config); void DeleteGRFPresetFromConfig(const char *config_name); +uint GetCompanySettingIndex(const char *name); +void SyncCompanySettings(); + #endif /* SETTINGS_FUNC_H */ diff --git a/src/table/settings.h b/src/table/settings.h --- a/src/table/settings.h +++ b/src/table/settings.h @@ -618,6 +618,7 @@ static const SettingDesc _company_settin SDT_BOOL(CompanySettings, engine_renew, 0, PC, false, STR_CONFIG_SETTING_AUTORENEW_VEHICLE, NULL), SDT_VAR(CompanySettings, engine_renew_months, SLE_INT16, 0, PC, 6, -12, 12, 0, STR_CONFIG_SETTING_AUTORENEW_MONTHS, NULL), SDT_VAR(CompanySettings, engine_renew_money, SLE_UINT, 0, PC|CR,100000, 0, 2000000, 0, STR_CONFIG_SETTING_AUTORENEW_MONEY, NULL), + SDT_BOOL(CompanySettings, renew_keep_length, 0, PC, false, STR_NULL, NULL), SDT_END() };