1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-24 23:34:37 +01:00

Implement game action for sign naming.

This commit is contained in:
ZehMatt
2018-03-24 04:52:47 +01:00
parent a913fd2d4a
commit 199a3e33f4
7 changed files with 131 additions and 76 deletions

View File

@@ -28,6 +28,7 @@
#include <openrct2-ui/interface/Dropdown.h>
#include <openrct2/sprites.h>
#include <openrct2/world/Banner.h>
#include <openrct2/actions/SignSetNameAction.hpp>
#define WW 113
#define WH 96
@@ -316,10 +317,10 @@ static void window_sign_dropdown(rct_window *w, rct_widgetindex widgetIndex, sin
*/
static void window_sign_textinput(rct_window *w, rct_widgetindex widgetIndex, char *text)
{
if (widgetIndex == WIDX_SIGN_TEXT && text != nullptr) {
game_do_command(1, GAME_COMMAND_FLAG_APPLY, w->number, *((sint32*)(text + 0)), GAME_COMMAND_SET_SIGN_NAME, *((sint32*)(text + 8)), *((sint32*)(text + 4)));
game_do_command(2, GAME_COMMAND_FLAG_APPLY, w->number, *((sint32*)(text + 12)), GAME_COMMAND_SET_SIGN_NAME, *((sint32*)(text + 20)), *((sint32*)(text + 16)));
game_do_command(0, GAME_COMMAND_FLAG_APPLY, w->number, *((sint32*)(text + 24)), GAME_COMMAND_SET_SIGN_NAME, *((sint32*)(text + 32)), *((sint32*)(text + 28)));
if (widgetIndex == WIDX_SIGN_TEXT && text != nullptr)
{
auto signSetNameAction = SignSetNameAction(w->number, text);
GameActions::Execute(&signSetNameAction);
}
}

View File

@@ -1747,7 +1747,7 @@ GAME_COMMAND_POINTER * new_game_command_table[GAME_COMMAND_COUNT] = {
game_command_set_land_ownership,
game_command_clear_scenery,
game_command_set_banner_name,
game_command_set_sign_name,
nullptr,
game_command_set_banner_style,
game_command_set_sign_style,
game_command_set_player_group,

View File

@@ -83,7 +83,7 @@ enum GAME_COMMAND
GAME_COMMAND_SET_LAND_OWNERSHIP,
GAME_COMMAND_CLEAR_SCENERY,
GAME_COMMAND_SET_BANNER_NAME,
GAME_COMMAND_SET_SIGN_NAME,
GAME_COMMAND_SET_SIGN_NAME, // GA
GAME_COMMAND_SET_BANNER_STYLE,
GAME_COMMAND_SET_SIGN_STYLE,
GAME_COMMAND_SET_PLAYER_GROUP,

View File

@@ -29,6 +29,7 @@
#include "RideDemolishAction.hpp"
#include "PlacePeepSpawnAction.hpp"
#include "MazeSetTrackAction.hpp"
#include "SignSetNameAction.hpp"
namespace GameActions
{
@@ -48,5 +49,6 @@ namespace GameActions
Register<StaffSetNameAction>();
Register<PlacePeepSpawnAction>();
Register<MazeSetTrackAction>();
Register<SignSetNameAction>();
}
}

View File

@@ -0,0 +1,122 @@
#pragma region Copyright (c) 2014-2018 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#pragma once
#include "../Context.h"
#include "../core/MemoryStream.h"
#include "../drawing/Drawing.h"
#include "../localisation/StringIds.h"
#include "../ui/UiContext.h"
#include "../world/Sprite.h"
#include "../world/Banner.h"
#include "GameAction.h"
using namespace OpenRCT2;
struct SignSetNameAction : public GameActionBase<GAME_COMMAND_SET_SIGN_NAME, GameActionResult>
{
private:
sint32 _bannerIndex;
std::string _name;
public:
SignSetNameAction() {}
SignSetNameAction(sint32 bannerIndex, const std::string& name)
: _bannerIndex(bannerIndex),
_name(name)
{
}
uint16 GetActionFlags() const override
{
return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED;
}
void Serialise(DataSerialiser& stream) override
{
GameAction::Serialise(stream);
stream << _bannerIndex << _name;
}
GameActionResult::Ptr Query() const override
{
if (_bannerIndex >= MAX_BANNERS || _bannerIndex < 0)
{
log_warning("Invalid game command for setting sign name, banner id = %d", _bannerIndex);
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE);
}
// Ensure user string space.
rct_string_id string_id = user_string_allocate(USER_STRING_DUPLICATION_PERMITTED, _name.c_str());
if (string_id != 0)
{
user_string_free(string_id);
}
else
{
return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_ERR_CANT_SET_BANNER_TEXT);
}
return MakeResult();
}
GameActionResult::Ptr Execute() const override
{
rct_banner* banner = &gBanners[_bannerIndex];
sint32 x = banner->x << 5;
sint32 y = banner->y << 5;
if (_name.empty() == false)
{
rct_string_id string_id = user_string_allocate(USER_STRING_DUPLICATION_PERMITTED, _name.c_str());
if (string_id != 0)
{
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = string_id;
user_string_free(prev_string_id);
banner->flags &= ~(BANNER_FLAG_LINKED_TO_RIDE);
gfx_invalidate_screen();
}
else
{
return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_ERR_CANT_SET_BANNER_TEXT);
}
}
else
{
// If empty name take closest ride name.
sint32 rideIndex = banner_get_closest_ride_index(x, y, 16);
if (rideIndex == -1)
{
return MakeResult();
}
banner->colour = rideIndex;
banner->flags |= BANNER_FLAG_LINKED_TO_RIDE;
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = STR_DEFAULT_SIGN;
user_string_free(prev_string_id);
gfx_invalidate_screen();
}
return MakeResult();
}
};

View File

@@ -4250,75 +4250,6 @@ void map_clear_all_elements()
}
}
void game_command_set_sign_name(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) {
static char newName[128];
if ((*ecx >= MAX_BANNERS) || (*ecx < 0))
{
log_warning("Invalid game command for setting sign name, banner id = %d", *ecx);
*ebx = MONEY32_UNDEFINED;
return;
}
rct_banner* banner = &gBanners[*ecx];
sint32 x = banner->x << 5;
sint32 y = banner->y << 5;
sint32 nameChunkIndex = *eax & 0xFFFF;
gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS;
sint32 nameChunkOffset = nameChunkIndex - 1;
if (nameChunkOffset < 0)
nameChunkOffset = 2;
nameChunkOffset *= 12;
nameChunkOffset = std::min(nameChunkOffset, (sint32)Util::CountOf(newName) - 12);
memcpy(newName + nameChunkOffset + 0, edx, 4);
memcpy(newName + nameChunkOffset + 4, ebp, 4);
memcpy(newName + nameChunkOffset + 8, edi, 4);
if (nameChunkIndex != 0) {
*ebx = 0;
return;
}
if (!(*ebx & GAME_COMMAND_FLAG_APPLY)) {
*ebx = 0;
return;
}
if (newName[0] != 0) {
rct_string_id string_id = user_string_allocate(USER_STRING_DUPLICATION_PERMITTED, newName);
if (string_id != 0) {
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = string_id;
user_string_free(prev_string_id);
banner->flags &= ~(BANNER_FLAG_LINKED_TO_RIDE);
gfx_invalidate_screen();
} else {
gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT;
*ebx = MONEY32_UNDEFINED;
return;
}
}
else{
sint32 rideIndex = banner_get_closest_ride_index(x, y, 16);
if (rideIndex == -1) {
*ebx = 0;
return;
}
banner->colour = rideIndex;
banner->flags |= BANNER_FLAG_LINKED_TO_RIDE;
rct_string_id prev_string_id = banner->string_idx;
banner->string_idx = STR_DEFAULT_SIGN;
user_string_free(prev_string_id);
gfx_invalidate_screen();
}
*ebx = 0;
}
void game_command_set_sign_style(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp) {
uint8 bannerId = *ecx & 0xFF;
if (bannerId > Util::CountOf(gBanners)) {

View File

@@ -498,7 +498,6 @@ void game_command_place_wall(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx,
void game_command_place_large_scenery(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp);
void game_command_place_park_entrance(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp);
void game_command_set_banner_name(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp);
void game_command_set_sign_name(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp);
void game_command_set_banner_style(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp);
void game_command_set_sign_style(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp);
void game_command_modify_tile(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp);