From b45609a27873179bdbd05607ab80ed97a1003697 Mon Sep 17 00:00:00 2001 From: ZehMatt Date: Sat, 24 Mar 2018 05:17:23 +0100 Subject: [PATCH] Implement game action for park naming. --- src/openrct2/Game.cpp | 2 +- src/openrct2/Game.h | 2 +- .../actions/GameActionRegistration.cpp | 2 + src/openrct2/actions/ParkSetNameAction.hpp | 90 +++++++++++++++++++ src/openrct2/world/Park.cpp | 90 +------------------ src/openrct2/world/Park.h | 1 - 6 files changed, 97 insertions(+), 90 deletions(-) create mode 100644 src/openrct2/actions/ParkSetNameAction.hpp diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 5cb7a105da..7cfcbb7404 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1721,7 +1721,7 @@ GAME_COMMAND_POINTER * new_game_command_table[GAME_COMMAND_COUNT] = { game_command_set_staff_patrol, game_command_fire_staff_member, game_command_set_staff_order, - game_command_set_park_name, + nullptr, game_command_set_park_open, game_command_buy_land_rights, game_command_place_park_entrance, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 3c78ef9582..4c3c533df7 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -57,7 +57,7 @@ enum GAME_COMMAND GAME_COMMAND_SET_STAFF_PATROL, GAME_COMMAND_FIRE_STAFF_MEMBER, GAME_COMMAND_SET_STAFF_ORDER, - GAME_COMMAND_SET_PARK_NAME, + GAME_COMMAND_SET_PARK_NAME, // GA GAME_COMMAND_SET_PARK_OPEN, GAME_COMMAND_BUY_LAND_RIGHTS, GAME_COMMAND_PLACE_PARK_ENTRANCE, // GA diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 807331c41c..c10a3cec4e 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -30,6 +30,7 @@ #include "PlacePeepSpawnAction.hpp" #include "MazeSetTrackAction.hpp" #include "SignSetNameAction.hpp" +#include "ParkSetNameAction.hpp" namespace GameActions { @@ -50,5 +51,6 @@ namespace GameActions Register(); Register(); Register(); + Register(); } } diff --git a/src/openrct2/actions/ParkSetNameAction.hpp b/src/openrct2/actions/ParkSetNameAction.hpp new file mode 100644 index 0000000000..704a787c93 --- /dev/null +++ b/src/openrct2/actions/ParkSetNameAction.hpp @@ -0,0 +1,90 @@ +#pragma region Copyright (c) 2014-2018 OpenRCT2 Developers +/***************************************************************************** +* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. +* +* OpenRCT2 is the work of many authors, a full list can be found in contributors.md +* For more information, visit https://github.com/OpenRCT2/OpenRCT2 +* +* OpenRCT2 is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* A full copy of the GNU General Public License can be found in licence.txt +*****************************************************************************/ +#pragma endregion + +#pragma once + +#include "../Context.h" +#include "../core/MemoryStream.h" +#include "../drawing/Drawing.h" +#include "../localisation/StringIds.h" +#include "../ui/UiContext.h" +#include "../world/Sprite.h" +#include "../world/Park.h" +#include "GameAction.h" + +using namespace OpenRCT2; + +struct ParkSetNameAction : public GameActionBase +{ +private: + std::string _name; + +public: + ParkSetNameAction() {} + ParkSetNameAction(const std::string& name) + : _name(name) + { + } + + uint16 GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser& stream) override + { + GameAction::Serialise(stream); + stream << _name; + } + + GameActionResult::Ptr Query() const override + { + if (_name.empty()) + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_RIDE_ATTRACTION_NAME); + } + + // Ensure user string space. + rct_string_id 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(); + } + + GameActionResult::Ptr Execute() const override + { + rct_string_id stringId = user_string_allocate(USER_STRING_HIGH_ID_NUMBER, _name.c_str()); + if (stringId == 0) + { + return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_INVALID_NAME_FOR_PARK); + } + + // Free the old park name. + user_string_free(gParkName); + gParkName = stringId; + + gfx_invalidate_screen(); + + return MakeResult(); + } +}; diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index abfbd9db81..053611bda1 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -41,6 +41,7 @@ #include "Sprite.h" #include "../windows/Intent.h" #include "../Context.h" +#include "../actions/ParkSetNameAction.hpp" rct_string_id gParkName; uint32 gParkNameArgs; @@ -778,93 +779,8 @@ void update_park_fences_around_tile(sint32 x, sint32 y) void park_set_name(const char *name) { - // Required else the pointer arithmetic in the game commands below could cause an access violation - char* newName = (char *)malloc(USER_STRING_MAX_LENGTH + 5); - strncpy(newName, name, USER_STRING_MAX_LENGTH); - - gGameCommandErrorTitle = STR_CANT_RENAME_PARK; - game_do_command(1, GAME_COMMAND_FLAG_APPLY, 0, *((sint32*)(newName + 0)), GAME_COMMAND_SET_PARK_NAME, *((sint32*)(newName + 8)), *((sint32*)(newName + 4))); - game_do_command(2, GAME_COMMAND_FLAG_APPLY, 0, *((sint32*)(newName + 12)), GAME_COMMAND_SET_PARK_NAME, *((sint32*)(newName + 20)), *((sint32*)(newName + 16))); - game_do_command(0, GAME_COMMAND_FLAG_APPLY, 0, *((sint32*)(newName + 24)), GAME_COMMAND_SET_PARK_NAME, *((sint32*)(newName + 32)), *((sint32*)(newName + 28))); - - free(newName); -} - -/** - * - * rct2: 0x00669C6D - */ -void game_command_set_park_name(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp) -{ - rct_string_id newUserStringId; - char oldName[128]; - static char newName[128]; - - sint32 nameChunkIndex = *eax & 0xFFFF; - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - //if (*ebx & GAME_COMMAND_FLAG_APPLY) { // this check seems to be useless and causes problems in multiplayer - sint32 nameChunkOffset = nameChunkIndex - 1; - if (nameChunkOffset < 0) - nameChunkOffset = 2; - nameChunkOffset *= 12; - nameChunkOffset = Math::Min(nameChunkOffset, (sint32)Util::CountOf(newName) - 12); - memcpy(newName + nameChunkOffset + 0, edx, 4); - memcpy(newName + nameChunkOffset + 4, ebp, 4); - memcpy(newName + nameChunkOffset + 8, edi, 4); - //} - - if (nameChunkIndex != 0) { - *ebx = 0; - return; - } - - format_string(oldName, 128, gParkName, &gParkNameArgs); - if (strcmp(oldName, newName) == 0) { - *ebx = 0; - return; - } - - if (newName[0] == 0) { - gGameCommandErrorText = STR_INVALID_RIDE_ATTRACTION_NAME; - *ebx = MONEY32_UNDEFINED; - return; - } - - newUserStringId = user_string_allocate(USER_STRING_HIGH_ID_NUMBER, newName); - if (newUserStringId == 0) { - gGameCommandErrorText = STR_INVALID_NAME_FOR_PARK; - *ebx = MONEY32_UNDEFINED; - return; - } - - if (*ebx & GAME_COMMAND_FLAG_APPLY) { - // 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) { - // Get player name - int player_index = network_get_player_index(game_command_playerid); - const char* player_name = network_get_player_name(player_index); - - char log_msg[256]; - char* args[3] = { - (char *) player_name, - oldName, - newName - }; - format_string(log_msg, 256, STR_LOG_PARK_NAME, args); - network_append_server_log(log_msg); - } - - // Free the old ride name - user_string_free(gParkName); - gParkName = newUserStringId; - - gfx_invalidate_screen(); - } else { - user_string_free(newUserStringId); - } - - *ebx = 0; + auto parkSetNameAction = ParkSetNameAction(name); + GameActions::Execute(&parkSetNameAction); } static money32 map_buy_land_rights_for_tile(sint32 x, sint32 y, sint32 setting, sint32 flags) { diff --git a/src/openrct2/world/Park.h b/src/openrct2/world/Park.h index 5b992ecf64..0b46ae3857 100644 --- a/src/openrct2/world/Park.h +++ b/src/openrct2/world/Park.h @@ -110,7 +110,6 @@ sint32 map_buy_land_rights(sint32 x0, sint32 y0, sint32 x1, sint32 y1, sint32 se void game_command_set_park_entrance_fee(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp); void game_command_set_park_open(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp); -void game_command_set_park_name(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp); void game_command_buy_land_rights(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp); money16 park_get_entrance_fee();