mirror of https://github.com/OpenRCT2/OpenRCT2.git
Simplify game action by creating seperate function for track design ptd1
This commit is contained in:
parent
6081aa4720
commit
27046c2468
|
@ -9,16 +9,18 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../actions/RideEntranceExitRemoveAction.hpp"
|
||||
#include "../ride/Ride.h"
|
||||
#include "../ride/Station.h"
|
||||
#include "../world/Entrance.h"
|
||||
#include "../actions/RideEntranceExitRemoveAction.hpp"
|
||||
#include "../world/MapAnimation.h"
|
||||
#include "GameAction.h"
|
||||
|
||||
DEFINE_GAME_ACTION(RideEntranceExitPlaceAction, GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, GameActionResult)
|
||||
{
|
||||
private:
|
||||
CoordsXYZD _loc;
|
||||
CoordsXY _loc;
|
||||
Direction _direction;
|
||||
NetworkRideId_t _rideIndex;
|
||||
uint8_t _stationNum;
|
||||
bool _isExit;
|
||||
|
@ -26,8 +28,9 @@ private:
|
|||
public:
|
||||
RideEntranceExitPlaceAction() = default;
|
||||
|
||||
RideEntranceExitPlaceAction(CoordsXYZD loc, ride_id_t rideIndex, uint8_t stationNum, bool isExit)
|
||||
RideEntranceExitPlaceAction(CoordsXY loc, Direction direction, ride_id_t rideIndex, uint8_t stationNum, bool isExit)
|
||||
: _loc(loc)
|
||||
, _direction(direction)
|
||||
, _rideIndex(rideIndex)
|
||||
, _stationNum(stationNum)
|
||||
, _isExit(isExit)
|
||||
|
@ -48,158 +51,125 @@ public:
|
|||
|
||||
GameActionResult::Ptr Query() const override
|
||||
{
|
||||
// Remember when in unknown station num mode rideIndex is unknown and z is set
|
||||
// When in known station num mode rideIndex is known and z is unknown
|
||||
auto errorTitle = _isExit ? STR_CANT_BUILD_MOVE_EXIT_FOR_THIS_RIDE_ATTRACTION:
|
||||
STR_CANT_BUILD_MOVE_ENTRANCE_FOR_THIS_RIDE_ATTRACTION;
|
||||
auto errorTitle = _isExit ? STR_CANT_BUILD_MOVE_EXIT_FOR_THIS_RIDE_ATTRACTION
|
||||
: STR_CANT_BUILD_MOVE_ENTRANCE_FOR_THIS_RIDE_ATTRACTION;
|
||||
if (!map_check_free_elements_and_reorganise(1))
|
||||
{
|
||||
return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, errorTitle);
|
||||
}
|
||||
|
||||
if (_stationNum == 0xFF)
|
||||
if (_rideIndex >= MAX_RIDES || _rideIndex == RIDE_ID_NULL)
|
||||
{
|
||||
auto z = _loc.z * 16;
|
||||
log_warning("Invalid game command for ride %u", _rideIndex);
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, errorTitle);
|
||||
}
|
||||
|
||||
if (!gCheatsSandboxMode && !map_is_location_owned(_loc.x, _loc.y, z))
|
||||
{
|
||||
return MakeResult(GA_ERROR::NOT_OWNED, errorTitle);
|
||||
}
|
||||
Ride* ride = get_ride(_rideIndex);
|
||||
if (ride == nullptr || ride->type == RIDE_TYPE_NULL)
|
||||
{
|
||||
log_warning("Invalid game command for ride %u", _rideIndex);
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, errorTitle);
|
||||
}
|
||||
|
||||
int16_t clear_z = z / 8 + (_isExit ? 5 : 7);
|
||||
auto cost = MONEY32_UNDEFINED;
|
||||
if (!map_can_construct_with_clear_at(
|
||||
_loc.x, _loc.y, z / 8, clear_z, &map_place_non_scenery_clear_func, { 0b1111, 0 }, GetFlags(), &cost,
|
||||
CREATE_CROSSING_MODE_NONE))
|
||||
{
|
||||
return MakeResult(GA_ERROR::NO_CLEARANCE, errorTitle, gGameCommandErrorText, gCommonFormatArgs);
|
||||
}
|
||||
if (_stationNum > MAX_STATIONS)
|
||||
{
|
||||
log_warning("Invalid station number for ride. stationNum: %u", _stationNum);
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, errorTitle);
|
||||
}
|
||||
|
||||
if (gMapGroundFlags & ELEMENT_IS_UNDERWATER)
|
||||
{
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle, STR_RIDE_CANT_BUILD_THIS_UNDERWATER);
|
||||
}
|
||||
if (ride->status != RIDE_STATUS_CLOSED)
|
||||
{
|
||||
return MakeResult(GA_ERROR::NOT_CLOSED, errorTitle, STR_MUST_BE_CLOSED_FIRST);
|
||||
}
|
||||
|
||||
if (z / 8 > 244)
|
||||
if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK)
|
||||
{
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle, STR_NOT_ALLOWED_TO_MODIFY_STATION);
|
||||
}
|
||||
|
||||
ride_clear_for_construction(ride);
|
||||
ride_remove_peeps(ride);
|
||||
|
||||
bool requiresRemove = false;
|
||||
LocationXY16 removeCoord = { 0, 0 };
|
||||
|
||||
if (_isExit)
|
||||
{
|
||||
const auto exit = ride_get_exit_location(ride, _stationNum);
|
||||
if (!exit.isNull())
|
||||
{
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle, STR_TOO_HIGH);
|
||||
if (GetFlags() & GAME_COMMAND_FLAG_GHOST)
|
||||
{
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle);
|
||||
}
|
||||
|
||||
removeCoord.x = exit.x * 32;
|
||||
removeCoord.y = exit.y * 32;
|
||||
requiresRemove = true;
|
||||
}
|
||||
auto res = MakeResult();
|
||||
res->Position.x = _loc.x + 16;
|
||||
res->Position.y = _loc.y + 16;
|
||||
res->Position.z = tile_element_height(_loc.x, _loc.y);
|
||||
res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
return res;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rideIndex >= MAX_RIDES || _rideIndex == RIDE_ID_NULL)
|
||||
const auto entrance = ride_get_entrance_location(ride, _stationNum);
|
||||
if (!entrance.isNull())
|
||||
{
|
||||
log_warning("Invalid game command for ride %u", _rideIndex);
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, errorTitle);
|
||||
}
|
||||
|
||||
Ride* ride = get_ride(_rideIndex);
|
||||
if (ride == nullptr || ride->type == RIDE_TYPE_NULL)
|
||||
{
|
||||
log_warning("Invalid game command for ride %u", _rideIndex);
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, errorTitle);
|
||||
}
|
||||
|
||||
if (ride->status != RIDE_STATUS_CLOSED)
|
||||
{
|
||||
return MakeResult(GA_ERROR::NOT_CLOSED, errorTitle, STR_MUST_BE_CLOSED_FIRST);
|
||||
}
|
||||
|
||||
if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK)
|
||||
{
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle, STR_NOT_ALLOWED_TO_MODIFY_STATION);
|
||||
}
|
||||
|
||||
ride_clear_for_construction(ride);
|
||||
ride_remove_peeps(ride);
|
||||
|
||||
bool requiresRemove = false;
|
||||
LocationXY16 removeCoord = { 0, 0 };
|
||||
|
||||
if (_isExit)
|
||||
{
|
||||
const auto exit = ride_get_exit_location(ride, _stationNum);
|
||||
if (!exit.isNull())
|
||||
if (GetFlags() & GAME_COMMAND_FLAG_GHOST)
|
||||
{
|
||||
if (GetFlags() & GAME_COMMAND_FLAG_GHOST)
|
||||
{
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle);
|
||||
}
|
||||
|
||||
removeCoord.x = exit.x * 32;
|
||||
removeCoord.y = exit.y * 32;
|
||||
requiresRemove = true;
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle);
|
||||
}
|
||||
|
||||
removeCoord.x = entrance.x * 32;
|
||||
removeCoord.y = entrance.y * 32;
|
||||
requiresRemove = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto entrance = ride_get_entrance_location(ride, _stationNum);
|
||||
if (!entrance.isNull())
|
||||
{
|
||||
if (GetFlags() & GAME_COMMAND_FLAG_GHOST)
|
||||
{
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle);
|
||||
}
|
||||
|
||||
removeCoord.x = entrance.x * 32;
|
||||
removeCoord.y = entrance.y * 32;
|
||||
requiresRemove = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (requiresRemove)
|
||||
{
|
||||
auto rideEntranceExitRemove = RideEntranceExitRemoveAction(
|
||||
{ removeCoord.x, removeCoord.y }, _rideIndex, _stationNum, _isExit);
|
||||
rideEntranceExitRemove.SetFlags(GetFlags());
|
||||
|
||||
auto result = GameActions::QueryNested(&rideEntranceExitRemove);
|
||||
if (result->Error != GA_ERROR::OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
auto z = ride->stations[_stationNum].Height * 8;
|
||||
gCommandPosition.z = z;
|
||||
|
||||
if (!gCheatsSandboxMode && !map_is_location_owned(_loc.x, _loc.y, z))
|
||||
{
|
||||
return MakeResult(GA_ERROR::NOT_OWNED, errorTitle);
|
||||
}
|
||||
|
||||
int8_t clear_z = (z / 8) + (_isExit ? 5 : 7);
|
||||
auto cost = MONEY32_UNDEFINED;
|
||||
if (!map_can_construct_with_clear_at(
|
||||
_loc.x, _loc.y, z / 8, clear_z, &map_place_non_scenery_clear_func, { 0b1111, 0 }, GetFlags(), &cost,
|
||||
CREATE_CROSSING_MODE_NONE))
|
||||
{
|
||||
return MakeResult(GA_ERROR::NO_CLEARANCE, errorTitle, gGameCommandErrorText, gCommonFormatArgs);
|
||||
}
|
||||
|
||||
if (gMapGroundFlags & ELEMENT_IS_UNDERWATER)
|
||||
{
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle, STR_RIDE_CANT_BUILD_THIS_UNDERWATER);
|
||||
}
|
||||
|
||||
if (z / 8 > 244)
|
||||
{
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle, STR_TOO_HIGH);
|
||||
}
|
||||
|
||||
auto res = MakeResult();
|
||||
res->Position.x = _loc.x + 16;
|
||||
res->Position.y = _loc.y + 16;
|
||||
res->Position.z = tile_element_height(_loc.x, _loc.y);
|
||||
res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
return res;
|
||||
}
|
||||
|
||||
if (requiresRemove)
|
||||
{
|
||||
auto rideEntranceExitRemove = RideEntranceExitRemoveAction(
|
||||
{ removeCoord.x, removeCoord.y }, _rideIndex, _stationNum, _isExit);
|
||||
rideEntranceExitRemove.SetFlags(GetFlags());
|
||||
|
||||
auto result = GameActions::QueryNested(&rideEntranceExitRemove);
|
||||
if (result->Error != GA_ERROR::OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
auto z = ride->stations[_stationNum].Height * 8;
|
||||
gCommandPosition.z = z;
|
||||
|
||||
if (!gCheatsSandboxMode && !map_is_location_owned(_loc.x, _loc.y, z))
|
||||
{
|
||||
return MakeResult(GA_ERROR::NOT_OWNED, errorTitle);
|
||||
}
|
||||
|
||||
int8_t clear_z = (z / 8) + (_isExit ? 5 : 7);
|
||||
auto cost = MONEY32_UNDEFINED;
|
||||
if (!map_can_construct_with_clear_at(
|
||||
_loc.x, _loc.y, z / 8, clear_z, &map_place_non_scenery_clear_func, { 0b1111, 0 }, GetFlags(), &cost,
|
||||
CREATE_CROSSING_MODE_NONE))
|
||||
{
|
||||
return MakeResult(GA_ERROR::NO_CLEARANCE, errorTitle, gGameCommandErrorText, gCommonFormatArgs);
|
||||
}
|
||||
|
||||
if (gMapGroundFlags & ELEMENT_IS_UNDERWATER)
|
||||
{
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle, STR_RIDE_CANT_BUILD_THIS_UNDERWATER);
|
||||
}
|
||||
|
||||
if (z / 8 > 244)
|
||||
{
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle, STR_TOO_HIGH);
|
||||
}
|
||||
|
||||
auto res = MakeResult();
|
||||
res->Position.x = _loc.x + 16;
|
||||
res->Position.y = _loc.y + 16;
|
||||
res->Position.z = tile_element_height(_loc.x, _loc.y);
|
||||
res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
return res;
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Execute() const override
|
||||
|
@ -208,126 +178,159 @@ public:
|
|||
// When in known station num mode rideIndex is known and z is unknown
|
||||
auto errorTitle = _isExit ? STR_CANT_BUILD_MOVE_EXIT_FOR_THIS_RIDE_ATTRACTION
|
||||
: STR_CANT_BUILD_MOVE_ENTRANCE_FOR_THIS_RIDE_ATTRACTION;
|
||||
if (_stationNum == 0xFF)
|
||||
Ride* ride = get_ride(_rideIndex);
|
||||
if (ride == nullptr || ride->type == RIDE_TYPE_NULL)
|
||||
{
|
||||
return MakeResult(GA_ERROR::UNKNOWN, errorTitle);
|
||||
log_warning("Invalid game command for ride %u", _rideIndex);
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, errorTitle);
|
||||
}
|
||||
|
||||
ride_clear_for_construction(ride);
|
||||
ride_remove_peeps(ride);
|
||||
|
||||
bool requiresRemove = false;
|
||||
LocationXY16 removeCoord = { 0, 0 };
|
||||
|
||||
if (_isExit)
|
||||
{
|
||||
const auto exit = ride_get_exit_location(ride, _stationNum);
|
||||
if (!exit.isNull())
|
||||
{
|
||||
removeCoord.x = exit.x * 32;
|
||||
removeCoord.y = exit.y * 32;
|
||||
requiresRemove = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Ride* ride = get_ride(_rideIndex);
|
||||
if (ride == nullptr || ride->type == RIDE_TYPE_NULL)
|
||||
const auto entrance = ride_get_entrance_location(ride, _stationNum);
|
||||
if (!entrance.isNull())
|
||||
{
|
||||
log_warning("Invalid game command for ride %u", _rideIndex);
|
||||
return MakeResult(GA_ERROR::INVALID_PARAMETERS, errorTitle);
|
||||
removeCoord.x = entrance.x * 32;
|
||||
removeCoord.y = entrance.y * 32;
|
||||
requiresRemove = true;
|
||||
}
|
||||
|
||||
ride_clear_for_construction(ride);
|
||||
ride_remove_peeps(ride);
|
||||
|
||||
bool requiresRemove = false;
|
||||
LocationXY16 removeCoord = { 0, 0 };
|
||||
|
||||
if (_isExit)
|
||||
{
|
||||
const auto exit = ride_get_exit_location(ride, _stationNum);
|
||||
if (!exit.isNull())
|
||||
{
|
||||
removeCoord.x = exit.x * 32;
|
||||
removeCoord.y = exit.y * 32;
|
||||
requiresRemove = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto entrance = ride_get_entrance_location(ride, _stationNum);
|
||||
if (!entrance.isNull())
|
||||
{
|
||||
removeCoord.x = entrance.x * 32;
|
||||
removeCoord.y = entrance.y * 32;
|
||||
requiresRemove = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (requiresRemove)
|
||||
{
|
||||
auto rideEntranceExitRemove = RideEntranceExitRemoveAction(
|
||||
{ removeCoord.x, removeCoord.y }, _rideIndex, _stationNum, _isExit);
|
||||
rideEntranceExitRemove.SetFlags(GetFlags());
|
||||
|
||||
auto result = GameActions::ExecuteNested(&rideEntranceExitRemove);
|
||||
if (result->Error != GA_ERROR::OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
auto z = ride->stations[_stationNum].Height * 8;
|
||||
gCommandPosition.z = z;
|
||||
|
||||
if (!(GetFlags() & GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED)
|
||||
&& !(GetFlags() & GAME_COMMAND_FLAG_GHOST))
|
||||
{
|
||||
footpath_remove_litter(_loc.x, _loc.y, z);
|
||||
wall_remove_at_z(_loc.x, _loc.y, z);
|
||||
}
|
||||
|
||||
int8_t clear_z = (z / 8) + (_isExit ? 5 : 7);
|
||||
auto cost = MONEY32_UNDEFINED;
|
||||
if (!map_can_construct_with_clear_at(
|
||||
_loc.x, _loc.y, z / 8, clear_z, &map_place_non_scenery_clear_func, { 0b1111, 0 }, GetFlags(), &cost,
|
||||
CREATE_CROSSING_MODE_NONE))
|
||||
{
|
||||
return MakeResult(GA_ERROR::NO_CLEARANCE, errorTitle, gGameCommandErrorText, gCommonFormatArgs);
|
||||
}
|
||||
|
||||
auto res = MakeResult();
|
||||
res->Position.x = _loc.x + 16;
|
||||
res->Position.y = _loc.y + 16;
|
||||
res->Position.z = tile_element_height(_loc.x, _loc.y);
|
||||
res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
|
||||
TileElement* tileElement = tile_element_insert(_loc.x / 32, _loc.y / 32, z / 8, 0b1111);
|
||||
assert(tileElement != nullptr);
|
||||
tileElement->SetType(TILE_ELEMENT_TYPE_ENTRANCE);
|
||||
tileElement->SetDirection(_loc.direction);
|
||||
tileElement->clearance_height = clear_z;
|
||||
tileElement->AsEntrance()->SetEntranceType(_isExit ? ENTRANCE_TYPE_RIDE_EXIT : ENTRANCE_TYPE_RIDE_ENTRANCE);
|
||||
tileElement->AsEntrance()->SetStationIndex(_stationNum);
|
||||
tileElement->AsEntrance()->SetRideIndex(_rideIndex);
|
||||
|
||||
if (GetFlags() & GAME_COMMAND_FLAG_GHOST)
|
||||
{
|
||||
tileElement->SetGhost(true);
|
||||
}
|
||||
|
||||
if (_isExit)
|
||||
{
|
||||
ride_set_exit_location(
|
||||
ride, _stationNum, { _loc.x / 32, _loc.y / 32, z / 8, (uint8_t)tileElement->GetDirection() });
|
||||
}
|
||||
else
|
||||
{
|
||||
ride_set_entrance_location(
|
||||
ride, _stationNum, { _loc.x / 32, _loc.y / 32, z / 8, (uint8_t)tileElement->GetDirection() });
|
||||
ride->stations[_stationNum].LastPeepInQueue = SPRITE_INDEX_NULL;
|
||||
ride->stations[_stationNum].QueueLength = 0;
|
||||
|
||||
map_animation_create(MAP_ANIMATION_TYPE_RIDE_ENTRANCE, _loc.x, _loc.y, z / 8);
|
||||
}
|
||||
|
||||
footpath_queue_chain_reset();
|
||||
|
||||
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST))
|
||||
{
|
||||
maze_entrance_hedge_removal(_loc.x, _loc.y, tileElement);
|
||||
}
|
||||
|
||||
footpath_connect_edges(_loc.x, _loc.y, tileElement, GetFlags());
|
||||
footpath_update_queue_chains();
|
||||
|
||||
map_invalidate_tile_full(_loc.x, _loc.y);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
if (requiresRemove)
|
||||
{
|
||||
auto rideEntranceExitRemove = RideEntranceExitRemoveAction(
|
||||
{ removeCoord.x, removeCoord.y }, _rideIndex, _stationNum, _isExit);
|
||||
rideEntranceExitRemove.SetFlags(GetFlags());
|
||||
|
||||
auto result = GameActions::ExecuteNested(&rideEntranceExitRemove);
|
||||
if (result->Error != GA_ERROR::OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
auto z = ride->stations[_stationNum].Height * 8;
|
||||
gCommandPosition.z = z;
|
||||
|
||||
if (!(GetFlags() & GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED) && !(GetFlags() & GAME_COMMAND_FLAG_GHOST))
|
||||
{
|
||||
footpath_remove_litter(_loc.x, _loc.y, z);
|
||||
wall_remove_at_z(_loc.x, _loc.y, z);
|
||||
}
|
||||
|
||||
int8_t clear_z = (z / 8) + (_isExit ? 5 : 7);
|
||||
auto cost = MONEY32_UNDEFINED;
|
||||
if (!map_can_construct_with_clear_at(
|
||||
_loc.x, _loc.y, z / 8, clear_z, &map_place_non_scenery_clear_func, { 0b1111, 0 }, GetFlags(), &cost,
|
||||
CREATE_CROSSING_MODE_NONE))
|
||||
{
|
||||
return MakeResult(GA_ERROR::NO_CLEARANCE, errorTitle, gGameCommandErrorText, gCommonFormatArgs);
|
||||
}
|
||||
|
||||
auto res = MakeResult();
|
||||
res->Position.x = _loc.x + 16;
|
||||
res->Position.y = _loc.y + 16;
|
||||
res->Position.z = tile_element_height(_loc.x, _loc.y);
|
||||
res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
|
||||
TileElement* tileElement = tile_element_insert(_loc.x / 32, _loc.y / 32, z / 8, 0b1111);
|
||||
assert(tileElement != nullptr);
|
||||
tileElement->SetType(TILE_ELEMENT_TYPE_ENTRANCE);
|
||||
tileElement->SetDirection(_direction);
|
||||
tileElement->clearance_height = clear_z;
|
||||
tileElement->AsEntrance()->SetEntranceType(_isExit ? ENTRANCE_TYPE_RIDE_EXIT : ENTRANCE_TYPE_RIDE_ENTRANCE);
|
||||
tileElement->AsEntrance()->SetStationIndex(_stationNum);
|
||||
tileElement->AsEntrance()->SetRideIndex(_rideIndex);
|
||||
|
||||
if (GetFlags() & GAME_COMMAND_FLAG_GHOST)
|
||||
{
|
||||
tileElement->SetGhost(true);
|
||||
}
|
||||
|
||||
if (_isExit)
|
||||
{
|
||||
ride_set_exit_location(
|
||||
ride, _stationNum, { _loc.x / 32, _loc.y / 32, z / 8, (uint8_t)tileElement->GetDirection() });
|
||||
}
|
||||
else
|
||||
{
|
||||
ride_set_entrance_location(
|
||||
ride, _stationNum, { _loc.x / 32, _loc.y / 32, z / 8, (uint8_t)tileElement->GetDirection() });
|
||||
ride->stations[_stationNum].LastPeepInQueue = SPRITE_INDEX_NULL;
|
||||
ride->stations[_stationNum].QueueLength = 0;
|
||||
|
||||
map_animation_create(MAP_ANIMATION_TYPE_RIDE_ENTRANCE, _loc.x, _loc.y, z / 8);
|
||||
}
|
||||
|
||||
footpath_queue_chain_reset();
|
||||
|
||||
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST))
|
||||
{
|
||||
maze_entrance_hedge_removal(_loc.x, _loc.y, tileElement);
|
||||
}
|
||||
|
||||
footpath_connect_edges(_loc.x, _loc.y, tileElement, GetFlags());
|
||||
footpath_update_queue_chains();
|
||||
|
||||
map_invalidate_tile_full(_loc.x, _loc.y);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static GameActionResult::Ptr TrackPlaceQuery(const CoordsXYZ loc, const bool isExit)
|
||||
{
|
||||
auto errorTitle = isExit ? STR_CANT_BUILD_MOVE_EXIT_FOR_THIS_RIDE_ATTRACTION
|
||||
: STR_CANT_BUILD_MOVE_ENTRANCE_FOR_THIS_RIDE_ATTRACTION;
|
||||
if (!map_check_free_elements_and_reorganise(1))
|
||||
{
|
||||
return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, errorTitle);
|
||||
}
|
||||
|
||||
if (!gCheatsSandboxMode && !map_is_location_owned(loc.x, loc.y, loc.z))
|
||||
{
|
||||
return MakeResult(GA_ERROR::NOT_OWNED, errorTitle);
|
||||
}
|
||||
|
||||
int16_t baseZ = loc.z / 8;
|
||||
int16_t clearZ = baseZ + (isExit ? 5 : 7);
|
||||
auto cost = MONEY32_UNDEFINED;
|
||||
if (!map_can_construct_with_clear_at(
|
||||
loc.x, loc.y, baseZ, clearZ, &map_place_non_scenery_clear_func, { 0b1111, 0 }, 0, &cost,
|
||||
CREATE_CROSSING_MODE_NONE))
|
||||
{
|
||||
return MakeResult(GA_ERROR::NO_CLEARANCE, errorTitle, gGameCommandErrorText, gCommonFormatArgs);
|
||||
}
|
||||
|
||||
if (gMapGroundFlags & ELEMENT_IS_UNDERWATER)
|
||||
{
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle, STR_RIDE_CANT_BUILD_THIS_UNDERWATER);
|
||||
}
|
||||
|
||||
if (baseZ > 244)
|
||||
{
|
||||
return MakeResult(GA_ERROR::DISALLOWED, errorTitle, STR_TOO_HIGH);
|
||||
}
|
||||
auto res = MakeResult();
|
||||
res->Position.x = loc.x + 16;
|
||||
res->Position.y = loc.y + 16;
|
||||
res->Position.z = tile_element_height(loc.x, loc.y);
|
||||
res->ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "../Game.h"
|
||||
#include "../OpenRCT2.h"
|
||||
#include "../actions/LargeSceneryRemoveAction.hpp"
|
||||
#include "../actions/RideEntranceExitPlaceAction.hpp"
|
||||
#include "../actions/RideSetSetting.hpp"
|
||||
#include "../actions/RideSetVehiclesAction.hpp"
|
||||
#include "../actions/SmallSceneryPlaceAction.hpp"
|
||||
|
@ -1217,9 +1218,8 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y,
|
|||
|
||||
if (_trackDesignPlaceOperation == PTD_OPERATION_1)
|
||||
{
|
||||
cost = game_do_command(
|
||||
mapCoord.x, 0 | rotation << 8, mapCoord.y, (z / 16) & 0xFF,
|
||||
GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, -1, 0);
|
||||
auto res = RideEntranceExitPlaceAction::TrackPlaceQuery({mapCoord.x, mapCoord.y, z}, false);
|
||||
cost = res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1251,9 +1251,8 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y,
|
|||
|
||||
if (_trackDesignPlaceOperation == PTD_OPERATION_1)
|
||||
{
|
||||
cost = game_do_command(
|
||||
mapCoord.x, 0 | rotation << 8, mapCoord.y, ((z / 16) & 0xFF) | (1 << 8),
|
||||
GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, -1, 0);
|
||||
auto res = RideEntranceExitPlaceAction::TrackPlaceQuery({ mapCoord.x, mapCoord.y, z }, true);
|
||||
cost = res->Error == GA_ERROR::OK ? res->Cost : MONEY32_UNDEFINED;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1635,19 +1634,16 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in
|
|||
z = (entrance->z == (int8_t)(uint8_t)0x80) ? -1 : entrance->z;
|
||||
z *= 8;
|
||||
z += gTrackPreviewOrigin.z;
|
||||
z >>= 4;
|
||||
|
||||
gGameCommandErrorTitle = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE;
|
||||
money32 cost = game_do_command(
|
||||
x, 0 | (rotation << 8), y, z | (isExit << 8), GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, -1, 0);
|
||||
if (cost == MONEY32_UNDEFINED)
|
||||
auto res = RideEntranceExitPlaceAction::TrackPlaceQuery({ x, y, z }, false);
|
||||
if (res->Error != GA_ERROR::OK)
|
||||
{
|
||||
_trackDesignPlaceCost = cost;
|
||||
_trackDesignPlaceCost = MONEY32_UNDEFINED;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_trackDesignPlaceCost += cost;
|
||||
_trackDesignPlaceCost += res->Cost;
|
||||
_trackDesignPlaceStateEntranceExitPlaced = true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue