diff --git a/src/openrct2-ui/windows/Player.cpp b/src/openrct2-ui/windows/Player.cpp index 8425d8bee3..ec560a8009 100644 --- a/src/openrct2-ui/windows/Player.cpp +++ b/src/openrct2-ui/windows/Player.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -310,8 +311,14 @@ void window_player_overview_dropdown(rct_window* w, rct_widgetindex widgetIndex, return; } int32_t group = network_get_group_id(dropdownIndex); - game_do_command(0, GAME_COMMAND_FLAG_APPLY, w->number, group, GAME_COMMAND_SET_PLAYER_GROUP, 0, 0); - window_invalidate(w); + auto playerSetGroupAction = PlayerSetGroupAction(w->number, group); + playerSetGroupAction.SetCallback([=](const GameAction* ga, const GameActionResult* result) { + if (result->Error == GA_ERROR::OK) + { + window_invalidate(w); + } + }); + GameActions::Execute(&playerSetGroupAction); } void window_player_overview_resize(rct_window* w) diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 1b289cd05e..37830717af 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -1264,7 +1264,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_set_player_group, + nullptr, game_command_modify_groups, game_command_kick_player, game_command_cheat, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index bd7e0b674d..612e12f632 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -81,7 +81,7 @@ enum GAME_COMMAND GAME_COMMAND_SET_SIGN_NAME, // GA GAME_COMMAND_SET_BANNER_STYLE, // GA GAME_COMMAND_SET_SIGN_STYLE, // GA - GAME_COMMAND_SET_PLAYER_GROUP, + GAME_COMMAND_SET_PLAYER_GROUP, // GA GAME_COMMAND_MODIFY_GROUPS, GAME_COMMAND_KICK_PLAYER, GAME_COMMAND_CHEAT, diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index d9e69ae2e3..2b50cbaaf4 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -39,6 +39,7 @@ #include "PauseToggleAction.hpp" #include "PlaceParkEntranceAction.hpp" #include "PlacePeepSpawnAction.hpp" +#include "PlayerSetGroupAction.hpp" #include "RideCreateAction.hpp" #include "RideDemolishAction.hpp" #include "RideEntranceExitPlaceAction.hpp" @@ -97,6 +98,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/PlayerSetGroupAction.hpp b/src/openrct2/actions/PlayerSetGroupAction.hpp new file mode 100644 index 0000000000..688d26ab03 --- /dev/null +++ b/src/openrct2/actions/PlayerSetGroupAction.hpp @@ -0,0 +1,52 @@ +/***************************************************************************** + * Copyright (c) 2014-2019 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#include "../network/network.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(PlayerSetGroupAction, GAME_COMMAND_SET_PLAYER_GROUP, GameActionResult) +{ +private: + NetworkPlayerId_t _playerId{ -1 }; + uint8_t _groupId{ std::numeric_limits::max() }; + +public: + PlayerSetGroupAction() + { + } + + PlayerSetGroupAction(NetworkPlayerId_t playerId, uint8_t groupId) + : _playerId(playerId) + , _groupId(groupId) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_playerId) << DS_TAG(_groupId); + } + GameActionResult::Ptr Query() const override + { + return network_set_player_group(GetPlayer(), _playerId, _groupId, false); + } + + GameActionResult::Ptr Execute() const override + { + return network_set_player_group(GetPlayer(), _playerId, _groupId, true); + } +}; diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 4fae374021..6e890297ff 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -31,7 +31,7 @@ // This string specifies which version of network stream current build uses. // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "20" +#define NETWORK_STREAM_VERSION "21" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; @@ -3364,61 +3364,51 @@ void network_chat_show_server_greeting() } } -void game_command_set_player_group( - [[maybe_unused]] int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, - [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) +GameActionResult::Ptr network_set_player_group( + NetworkPlayerId_t actionPlayerId, NetworkPlayerId_t playerId, uint8_t groupId, bool isExecuting) { - uint8_t playerid = (uint8_t)*ecx; - uint8_t groupid = (uint8_t)*edx; - NetworkPlayer* player = gNetwork.GetPlayerByID(playerid); - NetworkGroup* fromgroup = gNetwork.GetGroupByID(game_command_playerid); - if (!player) + NetworkPlayer* player = gNetwork.GetPlayerByID(playerId); + + NetworkGroup* fromgroup = gNetwork.GetGroupByID(actionPlayerId); + if (player == nullptr) { - gGameCommandErrorTitle = STR_CANT_DO_THIS; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_DO_THIS); } - if (!gNetwork.GetGroupByID(groupid)) + + if (!gNetwork.GetGroupByID(groupId)) { - gGameCommandErrorTitle = STR_CANT_DO_THIS; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_DO_THIS); } + if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER) { - gGameCommandErrorTitle = STR_CANT_CHANGE_GROUP_THAT_THE_HOST_BELONGS_TO; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_GROUP_THAT_THE_HOST_BELONGS_TO); } - if (groupid == 0 && fromgroup && fromgroup->Id != 0) + + if (groupId == 0 && fromgroup && fromgroup->Id != 0) { - gGameCommandErrorTitle = STR_CANT_SET_TO_THIS_GROUP; - gGameCommandErrorText = STR_NONE; - *ebx = MONEY32_UNDEFINED; - return; + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, STR_CANT_SET_TO_THIS_GROUP); } - if (*ebx & GAME_COMMAND_FLAG_APPLY) + + if (isExecuting) { - player->Group = groupid; + player->Group = groupId; if (network_get_mode() == NETWORK_MODE_SERVER) { // Add or update saved user NetworkUserManager* userManager = &gNetwork._userManager; NetworkUser* networkUser = userManager->GetOrAddUser(player->KeyHash); - networkUser->GroupId = groupid; + networkUser->GroupId = groupId; networkUser->Name = player->Name; userManager->Save(); } - window_invalidate_by_number(WC_PLAYER, playerid); + window_invalidate_by_number(WC_PLAYER, playerId); // Log set player group event - NetworkPlayer* game_command_player = gNetwork.GetPlayerByID(game_command_playerid); - NetworkGroup* new_player_group = gNetwork.GetGroupByID(groupid); + NetworkPlayer* game_command_player = gNetwork.GetPlayerByID(actionPlayerId); + NetworkGroup* new_player_group = gNetwork.GetGroupByID(groupId); char log_msg[256]; const char* args[3] = { player->Name.c_str(), @@ -3428,7 +3418,7 @@ void game_command_set_player_group( format_string(log_msg, 256, STR_LOG_SET_PLAYER_GROUP, args); network_append_server_log(log_msg); } - *ebx = 0; + return std::make_unique(); } void game_command_modify_groups( @@ -4089,9 +4079,11 @@ const char* network_get_group_name(uint32_t index) { return ""; }; -void game_command_set_player_group( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp) + +GameActionResult::Ptr network_set_player_group( + NetworkPlayerId_t actionPlayerId, NetworkPlayerId_t playerId, uint8_t groupId, bool isExecuting) { + return std::make_unique(); } void game_command_modify_groups( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp) diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index 693bcd44dc..5d528eae17 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -22,6 +22,7 @@ struct GameAction; struct Peep; struct LocationXYZ16; +class GameActionResult; namespace OpenRCT2 { @@ -65,8 +66,8 @@ int32_t network_get_current_player_group_index(); uint8_t network_get_group_id(uint32_t index); int32_t network_get_num_groups(); const char* network_get_group_name(uint32_t index); -void game_command_set_player_group( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); +std::unique_ptr network_set_player_group( + NetworkPlayerId_t actionPlayerId, NetworkPlayerId_t playerId, uint8_t groupId, bool isExecuting); void game_command_modify_groups( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_kick_player(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp);