diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index d34d6c42b9..d36b17e501 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -1010,11 +1011,11 @@ static void repaint_scenery_tool_down(int16_t x, int16_t y, rct_widgetindex widg return; uint8_t quadrant = tile_element->AsSmallScenery()->GetSceneryQuadrant(); - gGameCommandErrorTitle = STR_CANT_REPAINT_THIS; - game_do_command( - grid_x, GAME_COMMAND_FLAG_APPLY | quadrant << 8, grid_y, - tile_element->base_height | (tile_element->AsSmallScenery()->GetEntryIndex() << 8), - GAME_COMMAND_SET_SCENERY_COLOUR, 0, gWindowSceneryPrimaryColour | (gWindowScenerySecondaryColour << 8)); + auto repaintScenery = SmallScenerySetColourAction( + { grid_x, grid_y, tile_element->base_height * 8 }, quadrant, tile_element->AsSmallScenery()->GetEntryIndex(), + gWindowSceneryPrimaryColour, gWindowScenerySecondaryColour); + + GameActions::Execute(&repaintScenery); break; } case VIEWPORT_INTERACTION_ITEM_WALL: diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index e8ffca0389..80ce37e882 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -644,9 +644,8 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c network_append_server_log(log_msg); } else if ( - command == GAME_COMMAND_SET_SCENERY_COLOUR || command == GAME_COMMAND_SET_WALL_COLOUR - || command == GAME_COMMAND_SET_LARGE_SCENERY_COLOUR || command == GAME_COMMAND_SET_BANNER_COLOUR - || command == GAME_COMMAND_SET_BANNER_STYLE) + command == GAME_COMMAND_SET_WALL_COLOUR || command == GAME_COMMAND_SET_LARGE_SCENERY_COLOUR + || command == GAME_COMMAND_SET_BANNER_COLOUR || command == GAME_COMMAND_SET_BANNER_STYLE) { // Log editing scenery char* args[1] = { @@ -1292,7 +1291,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_place_maze_design, game_command_place_banner, game_command_remove_banner, - game_command_set_scenery_colour, + nullptr, game_command_set_wall_colour, game_command_set_large_scenery_colour, game_command_set_banner_colour, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index c2750066e5..ed90316eb2 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -71,7 +71,7 @@ enum GAME_COMMAND GAME_COMMAND_PLACE_MAZE_DESIGN, GAME_COMMAND_PLACE_BANNER, GAME_COMMAND_REMOVE_BANNER, - GAME_COMMAND_SET_SCENERY_COLOUR, + GAME_COMMAND_SET_SCENERY_COLOUR, // GA GAME_COMMAND_SET_WALL_COLOUR, GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, GAME_COMMAND_SET_BANNER_COLOUR, diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index cda9214e33..ccb7ea18c8 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -51,6 +51,7 @@ #include "SignSetStyleAction.hpp" #include "SmallSceneryPlaceAction.hpp" #include "SmallSceneryRemoveAction.hpp" +#include "SmallScenerySetColourAction.hpp" #include "StaffFireAction.hpp" #include "StaffHireNewAction.hpp" #include "StaffSetColourAction.hpp" @@ -115,6 +116,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/SmallScenerySetColourAction.hpp b/src/openrct2/actions/SmallScenerySetColourAction.hpp new file mode 100644 index 0000000000..8f30ffd604 --- /dev/null +++ b/src/openrct2/actions/SmallScenerySetColourAction.hpp @@ -0,0 +1,116 @@ +/***************************************************************************** + * 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 "../Cheats.h" +#include "../OpenRCT2.h" +#include "../common.h" +#include "../core/MemoryStream.h" +#include "../interface/Window.h" +#include "../localisation/Localisation.h" +#include "../localisation/StringIds.h" +#include "../management/Finance.h" +#include "../ride/Ride.h" +#include "../ride/TrackDesign.h" +#include "../world/MapAnimation.h" +#include "../world/Park.h" +#include "../world/SmallScenery.h" +#include "../world/Sprite.h" +#include "../world/Surface.h" +#include "../world/TileElement.h" +#include "GameAction.h" + +DEFINE_GAME_ACTION(SmallScenerySetColourAction, GAME_COMMAND_SET_SCENERY_COLOUR, GameActionResult) +{ +private: + CoordsXYZ _loc; + uint8_t _quadrant; + uint8_t _sceneryType; + uint8_t _primaryColour; + uint8_t _secondaryColour; + +public: + SmallScenerySetColourAction() = default; + + SmallScenerySetColourAction( + CoordsXYZ loc, uint8_t quadrant, uint8_t sceneryType, uint8_t primaryColour, uint8_t secondaryColour) + : _loc(loc) + , _quadrant(quadrant) + , _sceneryType(sceneryType) + , _primaryColour(primaryColour) + , _secondaryColour(secondaryColour) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_loc) << DS_TAG(_quadrant) << DS_TAG(_sceneryType) << DS_TAG(_primaryColour) + << DS_TAG(_secondaryColour); + } + + GameActionResult::Ptr Query() const override + { + return QueryExecute(false); + } + + GameActionResult::Ptr Execute() const override + { + return QueryExecute(true); + } + +private: + GameActionResult::Ptr QueryExecute(bool isExecuting) const + { + auto res = MakeResult(); + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position.x = _loc.x + 16; + res->Position.y = _loc.y + 16; + res->Position.z = _loc.z; + res->ErrorTitle = STR_CANT_REPAINT_THIS; + + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) + { + if (!map_is_location_owned(_loc.x, _loc.y, _loc.z)) + { + return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_REPAINT_THIS, STR_LAND_NOT_OWNED_BY_PARK); + } + } + + auto sceneryElement = map_get_small_scenery_element_at(_loc.x, _loc.y, _loc.z / 8, _sceneryType, _quadrant); + + if (sceneryElement == nullptr) + { + log_error("Small scenery not found at: x = %d, y = %d, z = %d", _loc.x, _loc.y, _loc.z); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + + if ((GetFlags() & GAME_COMMAND_FLAG_GHOST) && !(sceneryElement->IsGhost())) + { + return res; + } + + if (isExecuting) + { + sceneryElement->SetPrimaryColour(_primaryColour); + sceneryElement->SetSecondaryColour(_secondaryColour); + + map_invalidate_tile_full(_loc.x, _loc.y); + } + + return res; + } +}; diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 90a907d653..734330b4b7 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -191,8 +191,6 @@ void game_command_set_land_ownership( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_remove_banner( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_command_set_scenery_colour( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_set_wall_colour( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_set_large_scenery_colour( diff --git a/src/openrct2/world/SmallScenery.cpp b/src/openrct2/world/SmallScenery.cpp index 2958c533ba..94a66bc76c 100644 --- a/src/openrct2/world/SmallScenery.cpp +++ b/src/openrct2/world/SmallScenery.cpp @@ -24,60 +24,6 @@ #include "Scenery.h" #include "Surface.h" -static money32 SmallScenerySetColour( - int16_t x, int16_t y, uint8_t baseHeight, uint8_t quadrant, uint8_t sceneryType, uint8_t primaryColour, - uint8_t secondaryColour, uint8_t flags) -{ - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; - int32_t z = baseHeight * 8; - gCommandPosition.x = x + 16; - gCommandPosition.y = y + 16; - gCommandPosition.z = z; - - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gCheatsSandboxMode) - { - if (!map_is_location_owned(x, y, z)) - { - return MONEY32_UNDEFINED; - } - } - - auto tileElement = map_get_small_scenery_element_at(x, y, baseHeight, sceneryType, quadrant); - - if (tileElement == nullptr) - { - return 0; - } - - if ((flags & GAME_COMMAND_FLAG_GHOST) && !(tileElement->IsGhost())) - { - return 0; - } - - if (flags & GAME_COMMAND_FLAG_APPLY) - { - tileElement->SetPrimaryColour(primaryColour); - tileElement->SetSecondaryColour(secondaryColour); - - map_invalidate_tile_full(x, y); - } - - return 0; -} - -/** - * - * rct2: 0x006E0F26 - */ -void game_command_set_scenery_colour( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, [[maybe_unused]] int32_t* edi, - int32_t* ebp) -{ - *ebx = SmallScenerySetColour( - *eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFF, ((*ebx >> 8) & 0xFF), (*edx >> 8) & 0xFF, *ebp & 0xFF, (*ebp >> 8) & 0xFF, - *ebx & 0xFF); -} - /** * * rct2: 0x006E0D6E, 0x006B8D88