1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-06 06:32:56 +01:00

Implement game action for park naming.

This commit is contained in:
ZehMatt
2018-03-24 05:17:23 +01:00
parent 199a3e33f4
commit b45609a278
6 changed files with 97 additions and 90 deletions

View File

@@ -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,

View File

@@ -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

View File

@@ -30,6 +30,7 @@
#include "PlacePeepSpawnAction.hpp"
#include "MazeSetTrackAction.hpp"
#include "SignSetNameAction.hpp"
#include "ParkSetNameAction.hpp"
namespace GameActions
{
@@ -50,5 +51,6 @@ namespace GameActions
Register<PlacePeepSpawnAction>();
Register<MazeSetTrackAction>();
Register<SignSetNameAction>();
Register<ParkSetNameAction>();
}
}

View File

@@ -0,0 +1,90 @@
#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/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();
}
};

View File

@@ -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) {

View File

@@ -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();