diff --git a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp index 6bd6350ff9..6ef1f1ac3c 100644 --- a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp +++ b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -794,11 +795,14 @@ static void window_editor_objective_options_main_textinput(rct_window *w, rct_wi switch (widgetIndex) { case WIDX_PARK_NAME: - park_set_name(text); + { + auto action = ParkSetNameAction(text); + GameActions::Execute(&action); - if (gS6Info.name[0] == '\0') - format_string(gS6Info.name, 64, gParkName, &gParkNameArgs); - break; + if (gS6Info.name[0] == '\0') + format_string(gS6Info.name, 64, gParkName, &gParkNameArgs); + break; + } case WIDX_SCENARIO_NAME: safe_strcpy(gS6Info.name, text, Util::CountOf(gS6Info.name)); window_invalidate(w); diff --git a/src/openrct2-ui/windows/Park.cpp b/src/openrct2-ui/windows/Park.cpp index 0700d12d7d..cbe4fe62fd 100644 --- a/src/openrct2-ui/windows/Park.cpp +++ b/src/openrct2-ui/windows/Park.cpp @@ -14,6 +14,7 @@ *****************************************************************************/ #pragma endregion +#include #include #include #include @@ -747,7 +748,10 @@ static void window_park_entrance_update(rct_window *w) static void window_park_entrance_textinput(rct_window *w, rct_widgetindex widgetIndex, char *text) { if (widgetIndex == WIDX_RENAME && text != nullptr) - park_set_name(text); + { + auto action = ParkSetNameAction(text); + GameActions::Execute(&action); + } } /** diff --git a/src/openrct2/actions/ParkSetNameAction.hpp b/src/openrct2/actions/ParkSetNameAction.hpp index fab0d9bd9b..23b39e0aa4 100644 --- a/src/openrct2/actions/ParkSetNameAction.hpp +++ b/src/openrct2/actions/ParkSetNameAction.hpp @@ -17,11 +17,15 @@ #pragma once #include "../Context.h" +#include "../config/Config.h" +#include "../core/MemoryStream.h" #include "../drawing/Drawing.h" #include "../localisation/Localisation.h" -#include "../localisation/StringIds.h" +#include "../management/Finance.h" +#include "../network/network.h" #include "../ui/UiContext.h" -#include "../world/Sprite.h" +#include "../ui/WindowManager.h" +#include "../windows/Intent.h" #include "../world/Park.h" #include "GameAction.h" @@ -52,37 +56,72 @@ public: { if (_name.empty()) { - return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_RIDE_ATTRACTION_NAME); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_RENAME_PARK, STR_INVALID_NAME_FOR_PARK); } - // Ensure user string space. - rct_string_id stringId = user_string_allocate(USER_STRING_HIGH_ID_NUMBER, _name.c_str()); - if (stringId != 0) + // TODO create a version of user_string_allocate that only tests so we do not have to free it straight afterwards + auto stringId = user_string_allocate(USER_STRING_HIGH_ID_NUMBER, _name.c_str()); + if (stringId == 0) { - user_string_free(stringId); - } - else - { - return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_INVALID_NAME_FOR_PARK); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_RENAME_PARK, STR_INVALID_NAME_FOR_PARK); } + user_string_free(stringId); return MakeResult(); } GameActionResult::Ptr Execute() const override { - rct_string_id stringId = user_string_allocate(USER_STRING_HIGH_ID_NUMBER, _name.c_str()); - if (stringId == 0) + // Do a no-op if new name is the same as the current name is the same + std::string oldName = GetCurrentParkName(); + if (_name == oldName) { - return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_INVALID_NAME_FOR_PARK); + return MakeResult(); } - // Free the old park name. + // Allocate new string for park name + auto newNameId = user_string_allocate(USER_STRING_HIGH_ID_NUMBER, _name.c_str()); + if (newNameId == 0) + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_RENAME_PARK, STR_INVALID_NAME_FOR_PARK); + } + + // Replace park name with new string id user_string_free(gParkName); - gParkName = stringId; + gParkName = newNameId; + + // Log park rename command if we are in multiplayer and logging is enabled + if ((network_get_mode() == NETWORK_MODE_CLIENT || + network_get_mode() == NETWORK_MODE_SERVER) && gConfigNetwork.log_server_actions) + { + LogAction(oldName); + } gfx_invalidate_screen(); - return MakeResult(); } + +private: + std::string GetCurrentParkName() const + { + char buffer[128]; + format_string(buffer, sizeof(buffer), gParkName, &gParkNameArgs); + return buffer; + } + + void LogAction(const std::string &oldName) const + { + // Get player name + auto playerIndex = network_get_player_index(game_command_playerid); + auto playerName = network_get_player_name(playerIndex); + + char logMessage[256]; + const char * args[3] = { + playerName, + oldName.c_str(), + _name.c_str() + }; + format_string(logMessage, sizeof(logMessage), STR_LOG_PARK_NAME, (void *)args); + network_append_server_log(logMessage); + } }; diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index 053611bda1..4c45ec5790 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -41,7 +41,6 @@ #include "Sprite.h" #include "../windows/Intent.h" #include "../Context.h" -#include "../actions/ParkSetNameAction.hpp" rct_string_id gParkName; uint32 gParkNameArgs; @@ -779,8 +778,12 @@ void update_park_fences_around_tile(sint32 x, sint32 y) void park_set_name(const char *name) { - auto parkSetNameAction = ParkSetNameAction(name); - GameActions::Execute(&parkSetNameAction); + auto nameId = user_string_allocate(USER_STRING_HIGH_ID_NUMBER, name); + if (nameId != 0) + { + user_string_free(gParkName); + gParkName = nameId; + } } static money32 map_buy_land_rights_for_tile(sint32 x, sint32 y, sint32 setting, sint32 flags) {