From aa65e25c6b0c7c0e5148ce1de2f1b59900e7105c Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 7 Apr 2019 10:10:36 +0100 Subject: [PATCH] Implement banner set style action --- src/openrct2-ui/windows/Banner.cpp | 27 +-- src/openrct2/Game.cpp | 11 +- src/openrct2/Game.h | 10 +- .../actions/BannerSetColourAction.hpp | 2 +- src/openrct2/actions/BannerSetStyleAction.hpp | 185 ++++++++++++++++++ .../actions/GameActionRegistration.cpp | 2 + src/openrct2/world/Banner.cpp | 74 ------- src/openrct2/world/Map.h | 2 - 8 files changed, 209 insertions(+), 104 deletions(-) create mode 100644 src/openrct2/actions/BannerSetStyleAction.hpp diff --git a/src/openrct2-ui/windows/Banner.cpp b/src/openrct2-ui/windows/Banner.cpp index d080dcbd50..3fe1b278f6 100644 --- a/src/openrct2-ui/windows/Banner.cpp +++ b/src/openrct2-ui/windows/Banner.cpp @@ -12,7 +12,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -195,11 +197,13 @@ static void window_banner_mouseup(rct_window* w, rct_widgetindex widgetIndex) w, WIDX_BANNER_TEXT, STR_BANNER_TEXT, STR_ENTER_BANNER_TEXT, gBanners[w->number].string_idx, 0, 32); break; case WIDX_BANNER_NO_ENTRY: + { textinput_cancel(); - game_do_command( - 1, GAME_COMMAND_FLAG_APPLY, w->number, banner->colour, GAME_COMMAND_SET_BANNER_STYLE, banner->text_colour, - banner->flags ^ BANNER_FLAG_NO_ENTRY); + auto bannerSetStyle = BannerSetStyleAction( + BannerSetStyleType::NoEntry, w->number, banner->flags ^ BANNER_FLAG_NO_ENTRY); + GameActions::Execute(&bannerSetStyle); break; + } } } @@ -242,26 +246,25 @@ static void window_banner_mousedown(rct_window* w, rct_widgetindex widgetIndex, */ static void window_banner_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex) { - rct_banner* banner = &gBanners[w->number]; - switch (widgetIndex) { case WIDX_MAIN_COLOUR: + { if (dropdownIndex == -1) break; - game_do_command( - 1, GAME_COMMAND_FLAG_APPLY, w->number, dropdownIndex, GAME_COMMAND_SET_BANNER_STYLE, banner->text_colour, - banner->flags); + auto bannerSetStyle = BannerSetStyleAction(BannerSetStyleType::PrimaryColour, w->number, dropdownIndex); + GameActions::Execute(&bannerSetStyle); break; + } case WIDX_TEXT_COLOUR_DROPDOWN_BUTTON: + { if (dropdownIndex == -1) break; - - game_do_command( - 1, GAME_COMMAND_FLAG_APPLY, w->number, banner->colour, GAME_COMMAND_SET_BANNER_STYLE, dropdownIndex + 1, - banner->flags); + auto bannerSetStyle = BannerSetStyleAction(BannerSetStyleType::TextColour, w->number, dropdownIndex + 1); + GameActions::Execute(&bannerSetStyle); break; + } } } diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index a202acf72b..0620e3d32f 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -643,15 +643,6 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c format_string(log_msg, 256, STR_LOG_REMOVE_SCENERY, args); network_append_server_log(log_msg); } - else if (command == GAME_COMMAND_SET_BANNER_STYLE) - { - // Log editing scenery - char* args[1] = { - (char*)player_name, - }; - format_string(log_msg, 256, STR_LOG_EDIT_SCENERY, args); - network_append_server_log(log_msg); - } } void pause_toggle() @@ -1273,7 +1264,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, nullptr, nullptr, - game_command_set_banner_style, + nullptr, nullptr, game_command_set_player_group, game_command_modify_groups, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index c954315318..6b80e1c6d5 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -76,11 +76,11 @@ enum GAME_COMMAND GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, // GA GAME_COMMAND_SET_BANNER_COLOUR, // GA GAME_COMMAND_SET_LAND_OWNERSHIP, - GAME_COMMAND_CLEAR_SCENERY, // GA - GAME_COMMAND_SET_BANNER_NAME, // GA - GAME_COMMAND_SET_SIGN_NAME, // GA - GAME_COMMAND_SET_BANNER_STYLE, - GAME_COMMAND_SET_SIGN_STYLE, // GA + GAME_COMMAND_CLEAR_SCENERY, // GA + GAME_COMMAND_SET_BANNER_NAME, // GA + 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_MODIFY_GROUPS, GAME_COMMAND_KICK_PLAYER, diff --git a/src/openrct2/actions/BannerSetColourAction.hpp b/src/openrct2/actions/BannerSetColourAction.hpp index 5235d154e4..ff1d1a51d7 100644 --- a/src/openrct2/actions/BannerSetColourAction.hpp +++ b/src/openrct2/actions/BannerSetColourAction.hpp @@ -89,7 +89,7 @@ private: } auto index = bannerElement->GetIndex(); - if (index > MAX_BANNERS || index == BANNER_INDEX_NULL) + if (index >= MAX_BANNERS || index == BANNER_INDEX_NULL) { log_error("Invalid banner index: index = %u", index); return MakeResult(GA_ERROR::UNKNOWN, STR_CANT_REPAINT_THIS); diff --git a/src/openrct2/actions/BannerSetStyleAction.hpp b/src/openrct2/actions/BannerSetStyleAction.hpp new file mode 100644 index 0000000000..162231bc35 --- /dev/null +++ b/src/openrct2/actions/BannerSetStyleAction.hpp @@ -0,0 +1,185 @@ +/***************************************************************************** + * 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 "../Context.h" +#include "../management/Finance.h" +#include "../windows/Intent.h" +#include "../world/Banner.h" +#include "GameAction.h" + +// There is also the BannerSetColourAction that sets primary colour but this action takes banner index rather than x, y, z, +// direction +enum class BannerSetStyleType : uint8_t +{ + PrimaryColour, + TextColour, + NoEntry, + Count +}; + +DEFINE_GAME_ACTION(BannerSetStyleAction, GAME_COMMAND_SET_BANNER_STYLE, GameActionResult) +{ +private: + uint8_t _type = static_cast(BannerSetStyleType::Count); + uint8_t _bannerIndex = BANNER_INDEX_NULL; + uint8_t _parameter; + +public: + BannerSetStyleAction() = default; + + BannerSetStyleAction(BannerSetStyleType type, uint8_t bannerIndex, uint8_t parameter) + : _type(static_cast(type)) + , _bannerIndex(bannerIndex) + , _parameter(parameter) + { + } + + 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(_type) << DS_TAG(_bannerIndex) << DS_TAG(_parameter); + } + + GameActionResult::Ptr Query() const override + { + auto res = MakeResult(); + + if (_bannerIndex >= MAX_BANNERS || _bannerIndex == BANNER_INDEX_NULL) + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_SELECTION_OF_OBJECTS); + } + + rct_banner* banner = &gBanners[_bannerIndex]; + + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position.x = banner->x * 32 + 16; + res->Position.y = banner->y * 32 + 16; + res->Position.z = tile_element_height(banner->x, banner->y) & 0xFFFF; + + TileElement* tileElement = banner_get_tile_element(_bannerIndex); + + if (tileElement == nullptr) + { + log_error("Could not find banner index = %u", _bannerIndex); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + switch (static_cast(_type)) + { + case BannerSetStyleType::PrimaryColour: + if (_parameter > 31) + { + log_error("Invalid primary colour: colour = %u", _parameter); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + break; + + case BannerSetStyleType::TextColour: + if (_parameter > 13) + { + log_error("Invalid text colour: colour = %u", _parameter); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS); + } + break; + case BannerSetStyleType::NoEntry: + break; + default: + log_error("Invalid type: %u", _type); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + return res; + } + + GameActionResult::Ptr Execute() const override + { + auto res = MakeResult(); + + rct_banner* banner = &gBanners[_bannerIndex]; + + res->ExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; + res->Position.x = banner->x * 32 + 16; + res->Position.y = banner->y * 32 + 16; + res->Position.z = tile_element_height(banner->x, banner->y) & 0xFFFF; + + TileElement* tileElement = banner_get_tile_element(_bannerIndex); + + if (tileElement == nullptr) + { + log_error("Could not find banner index = %u", _bannerIndex); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + switch (static_cast(_type)) + { + case BannerSetStyleType::PrimaryColour: + banner->colour = _parameter; + break; + case BannerSetStyleType::TextColour: + { + banner->text_colour = _parameter; + int32_t colourCodepoint = FORMAT_COLOUR_CODE_START + banner->text_colour; + + utf8 buffer[256]; + format_string(buffer, 256, banner->string_idx, nullptr); + int32_t firstCodepoint = utf8_get_next(buffer, nullptr); + if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) + { + utf8_write_codepoint(buffer, colourCodepoint); + } + else + { + utf8_insert_codepoint(buffer, colourCodepoint); + } + + rct_string_id stringId = user_string_allocate(USER_STRING_DUPLICATION_PERMITTED, buffer); + if (stringId != 0) + { + rct_string_id prevStringId = banner->string_idx; + banner->string_idx = stringId; + user_string_free(prevStringId); + } + else + { + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_SET_BANNER_TEXT); + } + break; + } + case BannerSetStyleType::NoEntry: + { + BannerElement* bannerElement = tileElement->AsBanner(); + banner->flags &= BANNER_FLAG_NO_ENTRY; + banner->flags |= BANNER_FLAG_NO_ENTRY & (_parameter != 0); + uint8_t allowedEdges = 0xF; + if (banner->flags & BANNER_FLAG_NO_ENTRY) + { + allowedEdges &= ~(1 << bannerElement->GetPosition()); + } + bannerElement->SetAllowedEdges(allowedEdges); + break; + } + default: + log_error("Invalid type: %u", _type); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + auto intent = Intent(INTENT_ACTION_UPDATE_BANNER); + intent.putExtra(INTENT_EXTRA_BANNER_INDEX, _bannerIndex); + context_broadcast_intent(&intent); + + return res; + } +}; diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index 8ebf7cebe0..ec7c557059 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -9,6 +9,7 @@ #include "BannerSetColourAction.hpp" #include "BannerSetNameAction.hpp" +#include "BannerSetStyleAction.hpp" #include "ClearAction.hpp" #include "ClimateSetAction.hpp" #include "FootpathPlaceAction.hpp" @@ -78,6 +79,7 @@ namespace GameActions { Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/world/Banner.cpp b/src/openrct2/world/Banner.cpp index 1162f26470..6390a25eba 100644 --- a/src/openrct2/world/Banner.cpp +++ b/src/openrct2/world/Banner.cpp @@ -227,73 +227,6 @@ static money32 BannerPlace( return bannerEntry->banner.price; } -static money32 BannerSetStyle(BannerIndex bannerIndex, uint8_t colour, uint8_t textColour, uint8_t bannerFlags, uint8_t flags) -{ - if (bannerIndex >= MAX_BANNERS) - { - gGameCommandErrorText = STR_INVALID_SELECTION_OF_OBJECTS; - return MONEY32_UNDEFINED; - } - - rct_banner* banner = &gBanners[bannerIndex]; - - TileElement* tileElement = banner_get_tile_element(bannerIndex); - - if (tileElement == nullptr) - { - return MONEY32_UNDEFINED; - } - - if (!(flags & GAME_COMMAND_FLAG_APPLY)) - { - return 0; - } - - banner->colour = colour; - banner->text_colour = textColour; - banner->flags = bannerFlags; - - uint8_t allowedEdges = 0xF; - if (banner->flags & BANNER_FLAG_NO_ENTRY) - { - allowedEdges &= ~(1 << tileElement->AsBanner()->GetPosition()); - } - tileElement->AsBanner()->SetAllowedEdges(allowedEdges); - - int32_t colourCodepoint = FORMAT_COLOUR_CODE_START + banner->text_colour; - - utf8 buffer[256]; - format_string(buffer, 256, banner->string_idx, nullptr); - int32_t firstCodepoint = utf8_get_next(buffer, nullptr); - if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) - { - utf8_write_codepoint(buffer, colourCodepoint); - } - else - { - utf8_insert_codepoint(buffer, colourCodepoint); - } - - rct_string_id stringId = user_string_allocate(USER_STRING_DUPLICATION_PERMITTED, buffer); - if (stringId != 0) - { - rct_string_id prevStringId = banner->string_idx; - banner->string_idx = stringId; - user_string_free(prevStringId); - - auto intent = Intent(INTENT_ACTION_UPDATE_BANNER); - intent.putExtra(INTENT_EXTRA_BANNER_INDEX, bannerIndex); - context_broadcast_intent(&intent); - } - else - { - gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; - return MONEY32_UNDEFINED; - } - - return 0; -} - static BannerIndex BannerGetNewIndex() { for (BannerIndex bannerIndex = 0; bannerIndex < MAX_BANNERS; bannerIndex++) @@ -506,13 +439,6 @@ void game_command_place_banner( *ebx & 0xFF); } -void game_command_set_banner_style( - [[maybe_unused]] int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, - int32_t* ebp) -{ - *ebx = BannerSetStyle(*ecx & 0xFF, *edx & 0xFF, *edi & 0xFF, *ebp & 0xFF, *ebx & 0xFF); -} - BannerIndex BannerElement::GetIndex() const { return index; diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 0ca811bcdc..b551f6752c 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -199,8 +199,6 @@ void game_command_place_park_entrance( 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_banner_name( 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_banner_style( - int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); void game_command_modify_tile(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); struct tile_element_iterator