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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
110
src/openrct2/actions/BannerSetColourAction.hpp
Normal file
110
src/openrct2/actions/BannerSetColourAction.hpp
Normal 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;
|
||||
}
|
||||
};
|
||||
@@ -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>();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user