mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-10 09:32:29 +01:00
Merge pull request #7343 from ZehMatt/ga-stringbased
Implement some game actions for naming things
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include <openrct2/sprites.h>
|
||||
#include <openrct2/world/Banner.h>
|
||||
#include <openrct2/world/Scenery.h>
|
||||
#include <openrct2/actions/BannerSetNameAction.hpp>
|
||||
|
||||
#define WW 113
|
||||
#define WH 96
|
||||
@@ -286,10 +287,10 @@ static void window_banner_dropdown(rct_window *w, rct_widgetindex widgetIndex, s
|
||||
*/
|
||||
static void window_banner_textinput(rct_window *w, rct_widgetindex widgetIndex, char *text)
|
||||
{
|
||||
if (widgetIndex == WIDX_BANNER_TEXT && text != nullptr) {
|
||||
game_do_command(1, GAME_COMMAND_FLAG_APPLY, w->number, *((sint32*)(text + 0)), GAME_COMMAND_SET_BANNER_NAME, *((sint32*)(text + 8)), *((sint32*)(text + 4)));
|
||||
game_do_command(2, GAME_COMMAND_FLAG_APPLY, w->number, *((sint32*)(text + 12)), GAME_COMMAND_SET_BANNER_NAME, *((sint32*)(text + 20)), *((sint32*)(text + 16)));
|
||||
game_do_command(0, GAME_COMMAND_FLAG_APPLY, w->number, *((sint32*)(text + 24)), GAME_COMMAND_SET_BANNER_NAME, *((sint32*)(text + 32)), *((sint32*)(text + 28)));
|
||||
if (widgetIndex == WIDX_BANNER_TEXT && text != nullptr)
|
||||
{
|
||||
auto bannerSetNameAction = BannerSetNameAction(w->number, text);
|
||||
GameActions::Execute(&bannerSetNameAction);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1721,7 +1721,7 @@ GAME_COMMAND_POINTER * new_game_command_table[GAME_COMMAND_COUNT] = {
|
||||
game_command_set_staff_patrol,
|
||||
game_command_fire_staff_member,
|
||||
game_command_set_staff_order,
|
||||
game_command_set_park_name,
|
||||
nullptr,
|
||||
game_command_set_park_open,
|
||||
game_command_buy_land_rights,
|
||||
game_command_place_park_entrance,
|
||||
@@ -1746,8 +1746,8 @@ GAME_COMMAND_POINTER * new_game_command_table[GAME_COMMAND_COUNT] = {
|
||||
game_command_set_banner_colour,
|
||||
game_command_set_land_ownership,
|
||||
game_command_clear_scenery,
|
||||
game_command_set_banner_name,
|
||||
game_command_set_sign_name,
|
||||
nullptr,
|
||||
nullptr,
|
||||
game_command_set_banner_style,
|
||||
game_command_set_sign_style,
|
||||
game_command_set_player_group,
|
||||
|
||||
@@ -57,7 +57,7 @@ enum GAME_COMMAND
|
||||
GAME_COMMAND_SET_STAFF_PATROL,
|
||||
GAME_COMMAND_FIRE_STAFF_MEMBER,
|
||||
GAME_COMMAND_SET_STAFF_ORDER,
|
||||
GAME_COMMAND_SET_PARK_NAME,
|
||||
GAME_COMMAND_SET_PARK_NAME, // GA
|
||||
GAME_COMMAND_SET_PARK_OPEN,
|
||||
GAME_COMMAND_BUY_LAND_RIGHTS,
|
||||
GAME_COMMAND_PLACE_PARK_ENTRANCE, // GA
|
||||
@@ -82,8 +82,8 @@ enum GAME_COMMAND
|
||||
GAME_COMMAND_SET_BANNER_COLOUR,
|
||||
GAME_COMMAND_SET_LAND_OWNERSHIP,
|
||||
GAME_COMMAND_CLEAR_SCENERY,
|
||||
GAME_COMMAND_SET_BANNER_NAME,
|
||||
GAME_COMMAND_SET_SIGN_NAME,
|
||||
GAME_COMMAND_SET_BANNER_NAME, // GA
|
||||
GAME_COMMAND_SET_SIGN_NAME, // GA
|
||||
GAME_COMMAND_SET_BANNER_STYLE,
|
||||
GAME_COMMAND_SET_SIGN_STYLE,
|
||||
GAME_COMMAND_SET_PLAYER_GROUP,
|
||||
|
||||
103
src/openrct2/actions/BannerSetNameAction.hpp
Normal file
103
src/openrct2/actions/BannerSetNameAction.hpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#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/String.hpp"
|
||||
#include "../drawing/Drawing.h"
|
||||
#include "../localisation/StringIds.h"
|
||||
#include "../ui/UiContext.h"
|
||||
#include "../world/Sprite.h"
|
||||
#include "../world/Banner.h"
|
||||
#include "../windows/Intent.h"
|
||||
#include "GameAction.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
struct BannerSetNameAction : public GameActionBase<GAME_COMMAND_SET_BANNER_NAME, GameActionResult>
|
||||
{
|
||||
private:
|
||||
sint32 _bannerIndex;
|
||||
std::string _name;
|
||||
|
||||
public:
|
||||
BannerSetNameAction() {}
|
||||
BannerSetNameAction(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 banner 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];
|
||||
|
||||
utf8 *buffer = gCommonStringFormatBuffer;
|
||||
utf8 *dst = buffer;
|
||||
dst = utf8_write_codepoint(dst, FORMAT_COLOUR_CODE_START + banner->text_colour);
|
||||
String::Set(dst, sizeof(gCommonStringFormatBuffer) - (dst - buffer), _name.c_str(), _name.size());
|
||||
|
||||
rct_string_id string_id = user_string_allocate(USER_STRING_DUPLICATION_PERMITTED, buffer);
|
||||
if (string_id == 0)
|
||||
{
|
||||
return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_ERR_CANT_SET_BANNER_TEXT);
|
||||
}
|
||||
|
||||
rct_string_id prev_string_id = banner->string_idx;
|
||||
banner->string_idx = string_id;
|
||||
user_string_free(prev_string_id);
|
||||
|
||||
auto intent = Intent(INTENT_ACTION_UPDATE_BANNER);
|
||||
intent.putExtra(INTENT_EXTRA_BANNER_INDEX, _bannerIndex);
|
||||
context_broadcast_intent(&intent);
|
||||
|
||||
return MakeResult();
|
||||
}
|
||||
};
|
||||
@@ -29,6 +29,9 @@
|
||||
#include "RideDemolishAction.hpp"
|
||||
#include "PlacePeepSpawnAction.hpp"
|
||||
#include "MazeSetTrackAction.hpp"
|
||||
#include "SignSetNameAction.hpp"
|
||||
#include "ParkSetNameAction.hpp"
|
||||
#include "BannerSetNameAction.hpp"
|
||||
|
||||
namespace GameActions
|
||||
{
|
||||
@@ -48,5 +51,8 @@ namespace GameActions
|
||||
Register<StaffSetNameAction>();
|
||||
Register<PlacePeepSpawnAction>();
|
||||
Register<MazeSetTrackAction>();
|
||||
Register<SignSetNameAction>();
|
||||
Register<ParkSetNameAction>();
|
||||
Register<BannerSetNameAction>();
|
||||
}
|
||||
}
|
||||
|
||||
89
src/openrct2/actions/ParkSetNameAction.hpp
Normal file
89
src/openrct2/actions/ParkSetNameAction.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#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 "../drawing/Drawing.h"
|
||||
#include "../localisation/StringIds.h"
|
||||
#include "../ui/UiContext.h"
|
||||
#include "../world/Sprite.h"
|
||||
#include "../world/Park.h"
|
||||
#include "GameAction.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
struct ParkSetNameAction : public GameActionBase<GAME_COMMAND_SET_PARK_NAME, GameActionResult>
|
||||
{
|
||||
private:
|
||||
std::string _name;
|
||||
|
||||
public:
|
||||
ParkSetNameAction() {}
|
||||
ParkSetNameAction(const std::string& name)
|
||||
: _name(name)
|
||||
{
|
||||
}
|
||||
|
||||
uint16 GetActionFlags() const override
|
||||
{
|
||||
return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED;
|
||||
}
|
||||
|
||||
void Serialise(DataSerialiser& stream) override
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
stream << _name;
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
{
|
||||
if (_name.empty())
|
||||
{
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_RIDE_ATTRACTION_NAME);
|
||||
}
|
||||
|
||||
// Ensure user string space.
|
||||
rct_string_id stringId = user_string_allocate(USER_STRING_HIGH_ID_NUMBER, _name.c_str());
|
||||
if (stringId != 0)
|
||||
{
|
||||
user_string_free(stringId);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_INVALID_NAME_FOR_PARK);
|
||||
}
|
||||
|
||||
return MakeResult();
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Execute() const override
|
||||
{
|
||||
rct_string_id stringId = user_string_allocate(USER_STRING_HIGH_ID_NUMBER, _name.c_str());
|
||||
if (stringId == 0)
|
||||
{
|
||||
return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_INVALID_NAME_FOR_PARK);
|
||||
}
|
||||
|
||||
// Free the old park name.
|
||||
user_string_free(gParkName);
|
||||
gParkName = stringId;
|
||||
|
||||
gfx_invalidate_screen();
|
||||
|
||||
return MakeResult();
|
||||
}
|
||||
};
|
||||
121
src/openrct2/actions/SignSetNameAction.hpp
Normal file
121
src/openrct2/actions/SignSetNameAction.hpp
Normal file
@@ -0,0 +1,121 @@
|
||||
#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 "../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();
|
||||
}
|
||||
};
|
||||
@@ -2093,7 +2093,7 @@ bool Network::LoadMap(IStream * stream)
|
||||
gCheatsDisableRideValueAging = stream->ReadValue<uint8>() != 0;
|
||||
gConfigGeneral.show_real_names_of_guests = stream->ReadValue<uint8>() != 0;
|
||||
gCheatsIgnoreResearchStatus = stream->ReadValue<uint8>() != 0;
|
||||
|
||||
|
||||
gLastAutoSaveUpdate = AUTOSAVE_PAUSE;
|
||||
result = true;
|
||||
}
|
||||
@@ -2206,7 +2206,7 @@ void Network::Client_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPa
|
||||
|
||||
if (player_id == action->GetPlayer())
|
||||
{
|
||||
// Only execute callbacks that belong to us,
|
||||
// Only execute callbacks that belong to us,
|
||||
// clients can have identical network ids assigned.
|
||||
auto itr = _gameActionCallbacks.find(action->GetNetworkId());
|
||||
if (itr != _gameActionCallbacks.end())
|
||||
|
||||
@@ -285,71 +285,6 @@ static money32 BannerPlace(sint16 x, sint16 y, uint8 pathBaseHeight, uint8 direc
|
||||
return bannerEntry->banner.price;
|
||||
}
|
||||
|
||||
static money32 BannerSetName(uint8 bannerIndex,
|
||||
uint16 nameChunkIndex,
|
||||
uint32 nameChunk1,
|
||||
uint32 nameChunk2,
|
||||
uint32 nameChunk3,
|
||||
uint8 flags)
|
||||
{
|
||||
static char newName[128];
|
||||
|
||||
if (bannerIndex >= MAX_BANNERS)
|
||||
{
|
||||
log_warning("Invalid game command for setting banner name, banner id = %d", bannerIndex);
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
rct_banner* banner = &gBanners[bannerIndex];
|
||||
|
||||
gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS;
|
||||
size_t indexToOffset[3] = { 24, 0, 12 };
|
||||
|
||||
if (nameChunkIndex > Util::CountOf(indexToOffset))
|
||||
{
|
||||
log_warning("Invalid chunk index for setting banner name, banner id = %d, index = %d", bannerIndex, nameChunkIndex);
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
size_t nameChunkOffset = std::min<size_t>(indexToOffset[nameChunkIndex], Util::CountOf(newName) - 12);
|
||||
std::memcpy(&newName[0 + nameChunkOffset], &nameChunk1, sizeof(uint32));
|
||||
std::memcpy(&newName[4 + nameChunkOffset], &nameChunk2, sizeof(uint32));
|
||||
std::memcpy(&newName[8 + nameChunkOffset], &nameChunk3, sizeof(uint32));
|
||||
|
||||
if (nameChunkIndex != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(flags & GAME_COMMAND_FLAG_APPLY))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
utf8 *buffer = gCommonStringFormatBuffer;
|
||||
utf8 *dst = buffer;
|
||||
dst = utf8_write_codepoint(dst, FORMAT_COLOUR_CODE_START + banner->text_colour);
|
||||
String::Set(dst, 256, newName, 32);
|
||||
|
||||
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 money32 BannerSetStyle(uint8 bannerIndex, uint8 colour, uint8 textColour, uint8 bannerFlags, uint8 flags)
|
||||
{
|
||||
if (bannerIndex >= MAX_BANNERS)
|
||||
@@ -662,18 +597,6 @@ void game_command_place_banner(sint32* eax, sint32* ebx, sint32* ecx, sint32* ed
|
||||
);
|
||||
}
|
||||
|
||||
void game_command_set_banner_name(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp)
|
||||
{
|
||||
*ebx = BannerSetName(
|
||||
*ecx & 0xFF,
|
||||
*eax & 0xFFFF,
|
||||
*edx,
|
||||
*ebp,
|
||||
*edi,
|
||||
*ebx & 0xFF
|
||||
);
|
||||
}
|
||||
|
||||
void game_command_set_banner_style(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp)
|
||||
{
|
||||
*ebx = BannerSetStyle(
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "Sprite.h"
|
||||
#include "../windows/Intent.h"
|
||||
#include "../Context.h"
|
||||
#include "../actions/ParkSetNameAction.hpp"
|
||||
|
||||
rct_string_id gParkName;
|
||||
uint32 gParkNameArgs;
|
||||
@@ -778,93 +779,8 @@ void update_park_fences_around_tile(sint32 x, sint32 y)
|
||||
|
||||
void park_set_name(const char *name)
|
||||
{
|
||||
// Required else the pointer arithmetic in the game commands below could cause an access violation
|
||||
char* newName = (char *)malloc(USER_STRING_MAX_LENGTH + 5);
|
||||
strncpy(newName, name, USER_STRING_MAX_LENGTH);
|
||||
|
||||
gGameCommandErrorTitle = STR_CANT_RENAME_PARK;
|
||||
game_do_command(1, GAME_COMMAND_FLAG_APPLY, 0, *((sint32*)(newName + 0)), GAME_COMMAND_SET_PARK_NAME, *((sint32*)(newName + 8)), *((sint32*)(newName + 4)));
|
||||
game_do_command(2, GAME_COMMAND_FLAG_APPLY, 0, *((sint32*)(newName + 12)), GAME_COMMAND_SET_PARK_NAME, *((sint32*)(newName + 20)), *((sint32*)(newName + 16)));
|
||||
game_do_command(0, GAME_COMMAND_FLAG_APPLY, 0, *((sint32*)(newName + 24)), GAME_COMMAND_SET_PARK_NAME, *((sint32*)(newName + 32)), *((sint32*)(newName + 28)));
|
||||
|
||||
free(newName);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00669C6D
|
||||
*/
|
||||
void game_command_set_park_name(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp)
|
||||
{
|
||||
rct_string_id newUserStringId;
|
||||
char oldName[128];
|
||||
static char newName[128];
|
||||
|
||||
sint32 nameChunkIndex = *eax & 0xFFFF;
|
||||
|
||||
gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING;
|
||||
//if (*ebx & GAME_COMMAND_FLAG_APPLY) { // this check seems to be useless and causes problems in multiplayer
|
||||
sint32 nameChunkOffset = nameChunkIndex - 1;
|
||||
if (nameChunkOffset < 0)
|
||||
nameChunkOffset = 2;
|
||||
nameChunkOffset *= 12;
|
||||
nameChunkOffset = Math::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;
|
||||
}
|
||||
|
||||
format_string(oldName, 128, gParkName, &gParkNameArgs);
|
||||
if (strcmp(oldName, newName) == 0) {
|
||||
*ebx = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (newName[0] == 0) {
|
||||
gGameCommandErrorText = STR_INVALID_RIDE_ATTRACTION_NAME;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
newUserStringId = user_string_allocate(USER_STRING_HIGH_ID_NUMBER, newName);
|
||||
if (newUserStringId == 0) {
|
||||
gGameCommandErrorText = STR_INVALID_NAME_FOR_PARK;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
|
||||
// Log park rename command if we are in multiplayer and logging is enabled
|
||||
if ((network_get_mode() == NETWORK_MODE_CLIENT || network_get_mode() == NETWORK_MODE_SERVER) && gConfigNetwork.log_server_actions) {
|
||||
// Get player name
|
||||
int player_index = network_get_player_index(game_command_playerid);
|
||||
const char* player_name = network_get_player_name(player_index);
|
||||
|
||||
char log_msg[256];
|
||||
char* args[3] = {
|
||||
(char *) player_name,
|
||||
oldName,
|
||||
newName
|
||||
};
|
||||
format_string(log_msg, 256, STR_LOG_PARK_NAME, args);
|
||||
network_append_server_log(log_msg);
|
||||
}
|
||||
|
||||
// Free the old ride name
|
||||
user_string_free(gParkName);
|
||||
gParkName = newUserStringId;
|
||||
|
||||
gfx_invalidate_screen();
|
||||
} else {
|
||||
user_string_free(newUserStringId);
|
||||
}
|
||||
|
||||
*ebx = 0;
|
||||
auto parkSetNameAction = ParkSetNameAction(name);
|
||||
GameActions::Execute(&parkSetNameAction);
|
||||
}
|
||||
|
||||
static money32 map_buy_land_rights_for_tile(sint32 x, sint32 y, sint32 setting, sint32 flags) {
|
||||
|
||||
@@ -110,7 +110,6 @@ sint32 map_buy_land_rights(sint32 x0, sint32 y0, sint32 x1, sint32 y1, sint32 se
|
||||
|
||||
void game_command_set_park_entrance_fee(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp);
|
||||
void game_command_set_park_open(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp);
|
||||
void game_command_set_park_name(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp);
|
||||
void game_command_buy_land_rights(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp);
|
||||
|
||||
money16 park_get_entrance_fee();
|
||||
|
||||
Reference in New Issue
Block a user