Create FootpathSceneryRemoveAction to split up footpath place

This commit is contained in:
duncanspumpkin 2019-03-01 09:50:50 +00:00
parent c479ada2ca
commit ef69c01da5
7 changed files with 208 additions and 13 deletions

View File

@ -19,6 +19,7 @@
#include <openrct2/actions/LargeSceneryRemoveAction.hpp>
#include <openrct2/actions/SmallSceneryRemoveAction.hpp>
#include <openrct2/actions/WallRemoveAction.hpp>
#include <openrct2/actions/FootpathSceneryRemoveAction.hpp>
#include <openrct2/localisation/Localisation.h>
#include <openrct2/ride/Ride.h>
#include <openrct2/ride/RideData.h>
@ -507,16 +508,8 @@ static void viewport_interaction_remove_footpath(TileElement* tileElement, int32
*/
static void viewport_interaction_remove_footpath_item(TileElement* tileElement, int32_t x, int32_t y)
{
int32_t type = tileElement->AsPath()->GetPathEntryIndex();
if (tileElement->AsPath()->IsQueue())
type |= 0x80;
int32_t slopeData = tileElement->AsPath()->GetSlopeDirection();
if (tileElement->AsPath()->IsSloped())
slopeData |= FOOTPATH_PROPERTIES_FLAG_IS_SLOPED;
gGameCommandErrorTitle = STR_CANT_REMOVE_THIS;
game_do_command(x, (slopeData << 8) | 1, y, (type << 8) | tileElement->base_height, GAME_COMMAND_PLACE_PATH, 0, 0);
auto footpathSceneryRemoveAction = FootpathSceneryRemoveAction({x, y, tileElement->base_height * 8});
GameActions::Execute(&footpathSceneryRemoveAction);
}
/**

View File

@ -94,6 +94,8 @@ enum GAME_COMMAND
GAME_COMMAND_SET_CLIMATE, // GA
GAME_COMMAND_SET_COLOUR_SCHEME, // GA
GAME_COMMAND_SET_STAFF_COSTUME, // GA
GAME_COMMAND_PLACE_FOOTPATH_SCENERY, // GA
GAME_COMMAND_REMOVE_FOOTPATH_SCENERY, // GA
GAME_COMMAND_COUNT,
};

View File

@ -0,0 +1,64 @@
/*****************************************************************************
* Copyright (c) 2014-2018 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 "../Cheats.h"
#include "../OpenRCT2.h"
#include "../core/MemoryStream.h"
#include "../interface/Window.h"
#include "../localisation/StringIds.h"
#include "../management/Finance.h"
#include "../world/Footpath.h"
#include "../world/Location.hpp"
#include "../world/Park.h"
#include "../world/Wall.h"
#include "GameAction.h"
DEFINE_GAME_ACTION(FootpathSceneryPlaceAction, GAME_COMMAND_PLACE_FOOTPATH_SCENERY, GameActionResult)
{
private:
int32_t _x;
int32_t _y;
int32_t _z;
public:
FootpathSceneryPlaceAction() = default;
FootpathSceneryPlaceAction(int32_t x, int32_t y, int32_t z)
: _x(x)
, _y(y)
, _z(z)
{
}
uint16_t GetActionFlags() const override
{
return GameAction::GetActionFlags();
}
void Serialise(DataSerialiser & stream) override
{
GameAction::Serialise(stream);
stream << DS_TAG(_x) << DS_TAG(_y) << DS_TAG(_z);
}
GameActionResult::Ptr Query() const override
{
GameActionResult::Ptr res = std::make_unique<GameActionResult>();
return res;
}
GameActionResult::Ptr Execute() const override
{
GameActionResult::Ptr res = std::make_unique<GameActionResult>();
return res;
}
};

View File

@ -0,0 +1,105 @@
/*****************************************************************************
* Copyright (c) 2014-2018 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 "../Cheats.h"
#include "../OpenRCT2.h"
#include "../core/MemoryStream.h"
#include "../interface/Window.h"
#include "../localisation/StringIds.h"
#include "../management/Finance.h"
#include "../world/Footpath.h"
#include "../world/Location.hpp"
#include "../world/Park.h"
#include "../world/Wall.h"
#include "GameAction.h"
DEFINE_GAME_ACTION(FootpathSceneryRemoveAction, GAME_COMMAND_REMOVE_FOOTPATH_SCENERY, GameActionResult)
{
private:
CoordsXYZ _loc;
public:
FootpathSceneryRemoveAction() = default;
FootpathSceneryRemoveAction(CoordsXYZ loc)
: _loc(loc)
{
}
uint16_t GetActionFlags() const override
{
return GameAction::GetActionFlags();
}
void Serialise(DataSerialiser & stream) override
{
GameAction::Serialise(stream);
stream << DS_TAG(_loc);
}
GameActionResult::Ptr Query() const override
{
if (!map_is_location_valid({_loc.x, _loc.y}))
{
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS, STR_OFF_EDGE_OF_MAP);
}
if (!((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode)
&& !map_is_location_owned(_loc.x, _loc.y, _loc.z / 8))
{
return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_REMOVE_THIS, STR_LAND_NOT_OWNED_BY_PARK);
}
if (_loc.z / 8 < 2)
{
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS, STR_TOO_LOW);
}
if (_loc.z / 8 > 248)
{
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS, STR_TOO_HIGH);
}
auto tileElement = map_get_footpath_element(_loc.x / 32, _loc.y / 32, _loc.z / 8);
auto pathElement = tileElement->AsPath();
if (pathElement == nullptr)
{
log_error("Could not find path element.");
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS);
}
auto res = MakeResult();
res->Cost = MONEY(0, 0);
return res;
}
GameActionResult::Ptr Execute() const override
{
auto tileElement = map_get_footpath_element(_loc.x / 32, _loc.y / 32, _loc.z / 8);
auto pathElement = tileElement->AsPath();
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST))
{
footpath_interrupt_peeps(_loc.x, _loc.y, _loc.z);
}
if (pathElement == nullptr)
{
log_error("Could not find path element.");
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS);
}
pathElement->SetAddition(0);
auto res = MakeResult();
res->Cost = MONEY(0, 0);
return res;
}
};

View File

@ -11,6 +11,8 @@
#include "ClearAction.hpp"
#include "ClimateSetAction.hpp"
#include "FootpathRemoveAction.hpp"
#include "FootpathSceneryPlaceAction.hpp"
#include "FootpathSceneryRemoveAction.hpp"
#include "GameAction.h"
#include "GuestSetNameAction.hpp"
#include "LandSetHeightAction.hpp"
@ -56,6 +58,8 @@ namespace GameActions
Register<BannerSetNameAction>();
Register<ClimateSetAction>();
Register<FootpathRemoveAction>();
Register<FootpathSceneryPlaceAction>();
Register<FootpathSceneryRemoveAction>();
Register<GuestSetNameAction>();
Register<MazeSetTrackAction>();
Register<ParkMarketingAction>();

View File

@ -343,6 +343,32 @@ template<> struct DataSerializerTraits<CoordsXY>
}
};
template<> struct DataSerializerTraits<CoordsXYZ>
{
static void encode(IStream* stream, const CoordsXYZ& coord)
{
stream->WriteValue(ByteSwapBE(coord.x));
stream->WriteValue(ByteSwapBE(coord.y));
stream->WriteValue(ByteSwapBE(coord.z));
}
static void decode(IStream* stream, CoordsXYZ& coord)
{
auto x = ByteSwapBE(stream->ReadValue<int32_t>());
auto y = ByteSwapBE(stream->ReadValue<int32_t>());
auto z = ByteSwapBE(stream->ReadValue<int32_t>());
coord = CoordsXYZ{ x, y, z };
}
static void log(IStream* stream, const CoordsXYZ& coord)
{
char msg[128] = {};
snprintf(
msg, sizeof(msg), "CoordsXYZ(x = %d, y = %d, z = %d)", coord.x, coord.y, coord.z);
stream->Write(msg, strlen(msg));
}
};
template<> struct DataSerializerTraits<CoordsXYZD>
{
static void encode(IStream* stream, const CoordsXYZD& coord)

View File

@ -14,6 +14,7 @@
#include "../Game.h"
#include "../actions/LargeSceneryRemoveAction.hpp"
#include "../actions/SmallSceneryRemoveAction.hpp"
#include "../actions/FootpathSceneryRemoveAction.hpp"
#include "../actions/WallRemoveAction.hpp"
#include "../common.h"
#include "../localisation/Localisation.h"
@ -205,9 +206,9 @@ void scenery_remove_ghost_tool_placement()
if (tileElement->base_height != z)
continue;
game_do_command(
x, 233 | (gSceneryPlacePathSlope << 8), y, z | (gSceneryPlacePathType << 8), GAME_COMMAND_PLACE_PATH,
gSceneryGhostPathObjectType & 0xFFFF0000, 0);
auto footpathSceneryRemoveAction = FootpathSceneryRemoveAction({x, y, z * 8});
footpathSceneryRemoveAction.SetFlags(GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_GHOST);
GameActions::Execute(&footpathSceneryRemoveAction);
break;
} while (!(tileElement++)->IsLastForTile());
}