1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-18 04:23:20 +01:00

Implement banner set colour action

This commit is contained in:
duncanspumpkin
2019-04-07 09:15:41 +01:00
parent 5ab42488a9
commit 3593366e95
7 changed files with 121 additions and 90 deletions

View File

@@ -25,6 +25,7 @@
#include <openrct2/Input.h>
#include <openrct2/OpenRCT2.h>
#include <openrct2/ParkImporter.h>
#include <openrct2/actions/BannerSetColourAction.hpp>
#include <openrct2/actions/ClearAction.hpp>
#include <openrct2/actions/FootpathSceneryPlaceAction.hpp>
#include <openrct2/actions/LandLowerAction.hpp>
@@ -1056,10 +1057,11 @@ static void repaint_scenery_tool_down(int16_t x, int16_t y, rct_widgetindex widg
rct_scenery_entry* scenery_entry = get_banner_entry(banner->type);
if (scenery_entry->banner.flags & BANNER_ENTRY_FLAG_HAS_PRIMARY_COLOUR)
{
gGameCommandErrorTitle = STR_CANT_REPAINT_THIS;
game_do_command(
grid_x, 1, grid_y, tile_element->base_height | ((tile_element->AsBanner()->GetPosition() & 0x3) << 8),
GAME_COMMAND_SET_BANNER_COLOUR, 0, gWindowSceneryPrimaryColour | (gWindowScenerySecondaryColour << 8));
auto repaintScenery = BannerSetColourAction(
{ grid_x, grid_y, tile_element->base_height * 8, tile_element->AsBanner()->GetPosition()},
gWindowSceneryPrimaryColour);
GameActions::Execute(&repaintScenery);
}
break;
}

View File

@@ -643,7 +643,7 @@ 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_COLOUR || command == GAME_COMMAND_SET_BANNER_STYLE)
else if (command == GAME_COMMAND_SET_BANNER_STYLE)
{
// Log editing scenery
char* args[1] = {
@@ -651,30 +651,6 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c
};
format_string(log_msg, 256, STR_LOG_EDIT_SCENERY, args);
network_append_server_log(log_msg);
if (command == GAME_COMMAND_SET_BANNER_NAME || command == GAME_COMMAND_SET_SIGN_NAME)
{
static char banner_name[128];
std::fill_n(banner_name, sizeof(banner_name), ' ');
int nameChunkIndex = *eax & 0xFFFF;
int nameChunkOffset = nameChunkIndex - 1;
if (nameChunkOffset < 0)
nameChunkOffset = 2;
nameChunkOffset *= 12;
nameChunkOffset = std::min(nameChunkOffset, (int32_t)(std::size(banner_name) - 12));
std::memcpy(banner_name + nameChunkOffset + 0, edx, 4);
std::memcpy(banner_name + nameChunkOffset + 4, ebp, 4);
std::memcpy(banner_name + nameChunkOffset + 8, edi, 4);
banner_name[sizeof(banner_name) - 1] = '\0';
char* args_sign[2] = {
(char*)player_name,
(char*)banner_name,
};
format_string(log_msg, 256, STR_LOG_SET_SIGN_NAME, args_sign);
network_append_server_log(log_msg);
}
}
}
@@ -1292,7 +1268,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = {
nullptr,
nullptr,
nullptr,
game_command_set_banner_colour,
nullptr,
game_command_set_land_ownership,
nullptr,
nullptr,

View File

@@ -74,7 +74,7 @@ enum GAME_COMMAND
GAME_COMMAND_SET_SCENERY_COLOUR, // GA
GAME_COMMAND_SET_WALL_COLOUR, // GA
GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, // GA
GAME_COMMAND_SET_BANNER_COLOUR,
GAME_COMMAND_SET_BANNER_COLOUR, // GA
GAME_COMMAND_SET_LAND_OWNERSHIP,
GAME_COMMAND_CLEAR_SCENERY, // GA
GAME_COMMAND_SET_BANNER_NAME, // GA

View File

@@ -0,0 +1,110 @@
/*****************************************************************************
* 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"
DEFINE_GAME_ACTION(BannerSetColourAction, GAME_COMMAND_SET_BANNER_COLOUR, GameActionResult)
{
private:
CoordsXYZD _loc;
uint8_t _primaryColour;
public:
BannerSetColourAction() = default;
BannerSetColourAction(CoordsXYZD loc, uint8_t primaryColour)
: _loc(loc)
, _primaryColour(primaryColour)
{
}
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(_primaryColour);
}
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 (_loc.x < 0 || _loc.y < 0 || _loc.x > gMapSizeMaxXY || _loc.y > gMapSizeMaxXY)
{
log_error("Invalid x / y coordinates: x = %d, y = %d", _loc.x, _loc.y);
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS);
}
if (_primaryColour > 31)
{
log_error("Invalid primary colour: colour = %u", _primaryColour);
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REPAINT_THIS);
}
if (!map_can_build_at(_loc.x, _loc.y, _loc.z - 16))
{
return MakeResult(GA_ERROR::NOT_OWNED, STR_CANT_REPAINT_THIS, STR_LAND_NOT_OWNED_BY_PARK);
}
auto bannerElement = map_get_banner_element_at(_loc.x / 32, _loc.y / 32, _loc.z / 8, _loc.direction);
if (bannerElement == nullptr)
{
log_error(
"Could not find banner at: x = %d, y = %d, z = %d, direction = %u", _loc.x, _loc.y, _loc.z, _loc.direction);
return MakeResult(GA_ERROR::UNKNOWN, STR_CANT_REPAINT_THIS);
}
auto index = bannerElement->GetIndex();
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);
}
if (isExecuting)
{
auto intent = Intent(INTENT_ACTION_UPDATE_BANNER);
intent.putExtra(INTENT_EXTRA_BANNER_INDEX, index);
context_broadcast_intent(&intent);
gBanners[index].colour = _primaryColour;
map_invalidate_tile_zoom1(_loc.x, _loc.y, _loc.z, _loc.z + 32);
}
return res;
}
};

View File

@@ -7,6 +7,7 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include "BannerSetColourAction.hpp"
#include "BannerSetNameAction.hpp"
#include "ClearAction.hpp"
#include "ClimateSetAction.hpp"
@@ -75,6 +76,7 @@ namespace GameActions
{
void Register()
{
Register<BannerSetColourAction>();
Register<BannerSetNameAction>();
Register<ClimateSetAction>();
Register<FootpathPlaceAction>();

View File

@@ -117,52 +117,6 @@ static money32 BannerRemove(int16_t x, int16_t y, uint8_t baseHeight, uint8_t di
return refund;
}
static money32 BannerSetColour(int16_t x, int16_t y, uint8_t baseHeight, uint8_t direction, uint8_t colour, 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 (!map_can_build_at(x, y, z - 16))
{
return MONEY32_UNDEFINED;
}
if (flags & GAME_COMMAND_FLAG_APPLY)
{
TileElement* tileElement = map_get_first_element_at(x / 32, y / 32);
bool found = false;
do
{
if (tileElement->GetType() != TILE_ELEMENT_TYPE_BANNER)
continue;
if (tileElement->AsBanner()->GetPosition() != direction)
continue;
found = true;
break;
} while (!(tileElement++)->IsLastForTile());
if (!found)
{
return MONEY32_UNDEFINED;
}
auto intent = Intent(INTENT_ACTION_UPDATE_BANNER);
intent.putExtra(INTENT_EXTRA_BANNER_INDEX, tileElement->AsBanner()->GetIndex());
context_broadcast_intent(&intent);
gBanners[tileElement->AsBanner()->GetIndex()].colour = colour;
map_invalidate_tile_zoom1(x, y, z, z + 32);
}
return 0;
}
static money32 BannerPlace(
int16_t x, int16_t y, uint8_t pathBaseHeight, uint8_t direction, uint8_t colour, uint8_t type, BannerIndex* bannerIndex,
uint8_t flags)
@@ -540,17 +494,6 @@ void game_command_remove_banner(
*ebx = BannerRemove(*eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFF, (*edx >> 8) & 0xFF, *ebx & 0xFF);
}
/**
*
* rct2: 0x006BA16A
*/
void game_command_set_banner_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 = BannerSetColour(*eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFF, (*edx >> 8) & 0xFF, *ebp & 0xFF, *ebx & 0xFF);
}
/**
*
* rct2: 0x006B9E6D

View File

@@ -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_banner_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_place_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_place_large_scenery(