diff --git a/src/command.cpp b/src/command.cpp index 160326b936..f4060fc374 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -143,6 +143,7 @@ CommandProc CmdBuyCompany; CommandProc CmdFoundTown; CommandProc CmdRenameTown; +CommandProc CmdRenameTownNonAdmin; CommandProc CmdDoTownAction; CommandProc CmdTownGrowthRate; CommandProc CmdTownRating; @@ -378,6 +379,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdFoundTown, CMD_DEITY | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_FOUND_TOWN; founding random town can fail only in exec run DEF_CMD(CmdRenameTown, CMD_DEITY | CMD_SERVER, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_TOWN + DEF_CMD(CmdRenameTownNonAdmin, 0, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_TOWN_NON_ADMIN DEF_CMD(CmdDoTownAction, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_DO_TOWN_ACTION DEF_CMD(CmdTownCargoGoal, CMD_LOG_AUX | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_CARGO_GOAL DEF_CMD(CmdTownGrowthRate, CMD_LOG_AUX | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_GROWTH_RATE diff --git a/src/command_type.h b/src/command_type.h index f474540dbd..d8a7932627 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -325,6 +325,7 @@ enum Commands { CMD_FOUND_TOWN, ///< found a town CMD_RENAME_TOWN, ///< rename a town + CMD_RENAME_TOWN_NON_ADMIN, ///< rename a town, non-admin command CMD_DO_TOWN_ACTION, ///< do a action from the town detail window (like advertises or bribe) CMD_TOWN_CARGO_GOAL, ///< set the goal of a cargo for a town CMD_TOWN_GROWTH_RATE, ///< set the town growth rate diff --git a/src/lang/english.txt b/src/lang/english.txt index 874eec5d97..a167adfb0f 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1211,6 +1211,8 @@ STR_CONFIG_SETTING_CITY_APPROVAL :Town council's STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Choose how much noise and environmental damage by companies affect their town rating and further construction actions in their area STR_CONFIG_SETTING_MONEY_CHEAT_MULTIPLAYER :Allow multiplayer clients to use the money cheat: {STRING2} STR_CONFIG_SETTING_MONEY_CHEAT_MULTIPLAYER_HELPTEXT :If enabled, non-admin multiplayer clients can use the money cheat. The money cheat is always available in single-player mode, and to the multiplayer server admin. +STR_CONFIG_SETTING_RENAME_TOWNS_MULTIPLAYER :Allow multiplayer clients to rename towns: {STRING2} +STR_CONFIG_SETTING_RENAME_TOWNS_MULTIPLAYER_HELPTEXT :If enabled, non-admin multiplayer clients which are not spectating can rename towns. Renaming towns is always available in single-player mode, and to the multiplayer server admin. STR_CONFIG_SETTING_MAX_HEIGHTLEVEL :Maximum map height: {STRING2} STR_CONFIG_SETTING_MAX_HEIGHTLEVEL_HELPTEXT :Set the maximum allowed height for mountains on the map diff --git a/src/settings.cpp b/src/settings.cpp index fe8692f378..dc556a0de5 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1500,6 +1500,12 @@ static bool DifficultyMoneyCheatMultiplayerChange(int32 i) return true; } +static bool DifficultyRenameTownsMultiplayerChange(int32 i) +{ + SetWindowClassesDirty(WC_TOWN_VIEW); + return true; +} + static bool MaxNoAIsChange(int32 i) { if (GetGameSettings().difficulty.max_no_competitors != 0 && diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index a41a589ad0..b98c571588 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1928,6 +1928,7 @@ static SettingsContainer &GetSettingsTree() ai->Add(new SettingEntry("economy.allow_shares")); ai->Add(new SettingEntry("economy.min_years_for_shares")); ai->Add(new SettingEntry("difficulty.money_cheat_in_multiplayer")); + ai->Add(new SettingEntry("difficulty.rename_towns_in_multiplayer")); } SettingsPage *scenario = main->Add(new SettingsPage(STR_CONFIG_SETTING_SCENARIO_EDITOR)); diff --git a/src/settings_type.h b/src/settings_type.h index dc5b247761..d71f5ace18 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -78,6 +78,7 @@ struct DifficultySettings { bool disasters; ///< are disasters enabled byte town_council_tolerance; ///< minimum required town ratings to be allowed to demolish stuff bool money_cheat_in_multiplayer; ///< is the money cheat permitted for non-admin multiplayer clients + bool rename_towns_in_multiplayer; ///< is renaming towns permitted for non-admin multiplayer clients }; /** Settings relating to viewport/smallmap scrolling. */ diff --git a/src/table/settings.ini b/src/table/settings.ini index ce33a4ffaf..f6ea4ffe9c 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -28,6 +28,7 @@ static bool VehListCargoFilterShownChanged(int32); static bool TownFoundingChanged(int32 p1); static bool DifficultyNoiseChange(int32 i); static bool DifficultyMoneyCheatMultiplayerChange(int32 i); +static bool DifficultyRenameTownsMultiplayerChange(int32 i); static bool MaxNoAIsChange(int32 i); static bool CheckRoadSide(int p1); static bool ChangeMaxHeightLevel(int32 p1); @@ -412,6 +413,16 @@ proc = DifficultyMoneyCheatMultiplayerChange cat = SC_EXPERT patxname = ""cheat.difficulty.money_cheat_in_multiplayer"" +[SDT_BOOL] +base = GameSettings +var = difficulty.rename_towns_in_multiplayer +def = false +str = STR_CONFIG_SETTING_RENAME_TOWNS_MULTIPLAYER +strhelp = STR_CONFIG_SETTING_RENAME_TOWNS_MULTIPLAYER_HELPTEXT +proc = DifficultyRenameTownsMultiplayerChange +cat = SC_EXPERT +patxname = ""cheat.difficulty.rename_towns_in_multiplayer"" + [SDTG_VAR] name = ""diff_level"" var = _old_diff_level diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 88819b6ded..f0cab470a9 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -3060,6 +3060,23 @@ CommandCost CmdRenameTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 return CommandCost(); } + +/** + * Rename a town (non-admin use). + * @param tile unused + * @param flags type of operation + * @param p1 town ID to rename + * @param p2 unused + * @param text the new name or an empty string when resetting to the default + * @return the cost of this operation or an error + */ +CommandCost CmdRenameTownNonAdmin(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + if (_networking && !_settings_game.difficulty.rename_towns_in_multiplayer) return CMD_ERROR; + + return CmdRenameTown(tile, flags, p1, p2, text); +} + /** * Determines the first cargo with a certain town effect * @param effect Town effect of interest diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 1bdeed3e39..1c363ddf14 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -354,7 +354,8 @@ public: { extern const Town *_viewport_highlight_town; this->SetWidgetLoweredState(WID_TV_CATCHMENT, _viewport_highlight_town == this->town); - this->SetWidgetDisabledState(WID_TV_CHANGE_NAME, _networking && !(_network_server || _network_settings_access)); + this->SetWidgetDisabledState(WID_TV_CHANGE_NAME, _networking && !(_network_server || _network_settings_access) && + !(_local_company != COMPANY_SPECTATOR && _settings_game.difficulty.rename_towns_in_multiplayer)); this->DrawWidgets(); } @@ -565,7 +566,7 @@ public: { if (str == nullptr) return; - DoCommandP(0, this->window_number, 0, CMD_RENAME_TOWN | CMD_MSG(STR_ERROR_CAN_T_RENAME_TOWN), nullptr, str); + DoCommandP(0, this->window_number, 0, ((_networking && !(_network_server || _network_settings_access)) ? CMD_RENAME_TOWN_NON_ADMIN : CMD_RENAME_TOWN) | CMD_MSG(STR_ERROR_CAN_T_RENAME_TOWN), nullptr, str); } bool IsNewGRFInspectable() const override