Fix #8264: Rides and scenery placeable outside of map with ZC and Sandbox mode enabled (#8715)

* Fix #8264: Rides and scenery placeable outside of map with ZC and Sandbox mode enabled

map_can_construct_with_clear_at first checks whether it is inside the map, and then checks gCheatsDisableClearanceChecks, making earlier checks for gCheatsDisableClearanceChecks unnecessary.

* Increase network version
This commit is contained in:
jensj12 2019-02-27 19:46:18 +01:00 committed by Duncan
parent 6d3200aacc
commit 89066759eb
8 changed files with 37 additions and 51 deletions

View File

@ -53,6 +53,7 @@
- Fix: [#8187] Cannot set land ownership over ride entrances or exits in sandbox mode.
- Fix: [#8200] Incorrect behaviour when removing entrances and exits that are on the same tile.
- Fix: [#8204] Crash when tile element has no surface elements.
- Fix: [#8264] Rides and scenery placeable outside of map with ZC and Sandbox mode enabled.
- Fix: [#8335] Rides with arbitrary ride types can crash the game when they break down.
- Fix: [#8358] Infinite loop when changing vehicle count on stopped ride.
- Fix: [#8402] Crash closing a window in some cases.

View File

@ -99,13 +99,9 @@ public:
entranceLoc.y += CoordsDirectionDelta[(_direction + 1) & 0x3].y * 2;
}
if (!gCheatsDisableClearanceChecks)
if (!map_can_construct_at(entranceLoc.x, entranceLoc.y, zLow, zHigh, { 0b1111, 0 }))
{
if (!map_can_construct_at(entranceLoc.x, entranceLoc.y, zLow, zHigh, { 0b1111, 0 }))
{
return std::make_unique<GameActionResult>(
GA_ERROR::NO_CLEARANCE, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_NONE);
}
return std::make_unique<GameActionResult>(GA_ERROR::NO_CLEARANCE, STR_CANT_BUILD_PARK_ENTRANCE_HERE, STR_NONE);
}
// Check that entrance element does not already exist at this location

View File

@ -235,19 +235,16 @@ public:
GA_ERROR::INVALID_PARAMETERS, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_TOO_HIGH);
}
if (!gCheatsDisableClearanceChecks || (GetFlags() & GAME_COMMAND_FLAG_GHOST))
uint8_t crossingMode = (ride->type == RIDE_TYPE_MINIATURE_RAILWAY && _trackType == TRACK_ELEM_FLAT)
? CREATE_CROSSING_MODE_TRACK_OVER_PATH
: CREATE_CROSSING_MODE_NONE;
if (!map_can_construct_with_clear_at(
mapLoc.x, mapLoc.y, baseZ, clearanceZ, &map_place_non_scenery_clear_func, quarterTile, GetFlags(), &cost,
crossingMode))
{
uint8_t crossingMode = (ride->type == RIDE_TYPE_MINIATURE_RAILWAY && _trackType == TRACK_ELEM_FLAT)
? CREATE_CROSSING_MODE_TRACK_OVER_PATH
: CREATE_CROSSING_MODE_NONE;
if (!map_can_construct_with_clear_at(
mapLoc.x, mapLoc.y, baseZ, clearanceZ, &map_place_non_scenery_clear_func, quarterTile, GetFlags(),
&cost, crossingMode))
{
return std::make_unique<GameActionResult>(
GA_ERROR::NO_CLEARANCE, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, gGameCommandErrorText,
gCommonFormatArgs);
}
return std::make_unique<GameActionResult>(
GA_ERROR::NO_CLEARANCE, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, gGameCommandErrorText,
gCommonFormatArgs);
}
uint8_t mapGroundFlags = gMapGroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND);
@ -479,19 +476,16 @@ public:
clearanceZ = (clearanceZ / 8) + baseZ;
if (!gCheatsDisableClearanceChecks || (GetFlags() & GAME_COMMAND_FLAG_GHOST))
uint8_t crossingMode = (ride->type == RIDE_TYPE_MINIATURE_RAILWAY && _trackType == TRACK_ELEM_FLAT)
? CREATE_CROSSING_MODE_TRACK_OVER_PATH
: CREATE_CROSSING_MODE_NONE;
if (!map_can_construct_with_clear_at(
mapLoc.x, mapLoc.y, baseZ, clearanceZ, &map_place_non_scenery_clear_func, quarterTile,
GetFlags() | GAME_COMMAND_FLAG_APPLY, &cost, crossingMode))
{
uint8_t crossingMode = (ride->type == RIDE_TYPE_MINIATURE_RAILWAY && _trackType == TRACK_ELEM_FLAT)
? CREATE_CROSSING_MODE_TRACK_OVER_PATH
: CREATE_CROSSING_MODE_NONE;
if (!map_can_construct_with_clear_at(
mapLoc.x, mapLoc.y, baseZ, clearanceZ, &map_place_non_scenery_clear_func, quarterTile,
GetFlags() | GAME_COMMAND_FLAG_APPLY, &cost, crossingMode))
{
return std::make_unique<GameActionResult>(
GA_ERROR::NO_CLEARANCE, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, gGameCommandErrorText,
gCommonFormatArgs);
}
return std::make_unique<GameActionResult>(
GA_ERROR::NO_CLEARANCE, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, gGameCommandErrorText,
gCommonFormatArgs);
}
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !gCheatsDisableClearanceChecks)

View File

@ -31,7 +31,7 @@
// This string specifies which version of network stream current build uses.
// It is used for making sure only compatible builds get connected, even within
// single OpenRCT2 version.
#define NETWORK_STREAM_VERSION "46"
#define NETWORK_STREAM_VERSION "47"
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
static rct_peep* _pickup_peep = nullptr;

View File

@ -122,10 +122,9 @@ static money32 RideEntranceExitPlace(
int16_t clear_z = z / 8 + (isExit ? 5 : 7);
if (!gCheatsDisableClearanceChecks
&& !map_can_construct_with_clear_at(
x, y, z / 8, clear_z, &map_place_non_scenery_clear_func, { 0b1111, 0 }, flags, &cost,
CREATE_CROSSING_MODE_NONE))
if (!map_can_construct_with_clear_at(
x, y, z / 8, clear_z, &map_place_non_scenery_clear_func, { 0b1111, 0 }, flags, &cost,
CREATE_CROSSING_MODE_NONE))
{
return MONEY32_UNDEFINED;
}
@ -236,10 +235,9 @@ static money32 RideEntranceExitPlace(
int8_t clear_z = (z / 8) + (isExit ? 5 : 7);
if (!gCheatsDisableClearanceChecks
&& !map_can_construct_with_clear_at(
x, y, z / 8, clear_z, &map_place_non_scenery_clear_func, { 0b1111, 0 }, flags, &cost,
CREATE_CROSSING_MODE_NONE))
if (!map_can_construct_with_clear_at(
x, y, z / 8, clear_z, &map_place_non_scenery_clear_func, { 0b1111, 0 }, flags, &cost,
CREATE_CROSSING_MODE_NONE))
{
return MONEY32_UNDEFINED;
}

View File

@ -240,7 +240,7 @@ static money32 footpath_element_insert(
uint8_t crossingMode = (type & FOOTPATH_ELEMENT_INSERT_QUEUE) || (slope != TILE_ELEMENT_SLOPE_FLAT)
? CREATE_CROSSING_MODE_NONE
: CREATE_CROSSING_MODE_PATH_OVER_TRACK;
if (!entrancePath && !gCheatsDisableClearanceChecks
if (!entrancePath
&& !map_can_construct_with_clear_at(
x, y, z, zHigh, &map_place_non_scenery_clear_func, quarterTile, flags, &gFootpathPrice, crossingMode))
return MONEY32_UNDEFINED;
@ -623,7 +623,7 @@ static money32 footpath_place_from_track(
uint8_t crossingMode = (type & FOOTPATH_ELEMENT_INSERT_QUEUE) || (slope != TILE_ELEMENT_SLOPE_FLAT)
? CREATE_CROSSING_MODE_NONE
: CREATE_CROSSING_MODE_PATH_OVER_TRACK;
if (!entrancePath && !gCheatsDisableClearanceChecks
if (!entrancePath
&& !map_can_construct_with_clear_at(
x, y, z, zHigh, &map_place_non_scenery_clear_func, quarterTile, flags, &gFootpathPrice, crossingMode))
return MONEY32_UNDEFINED;

View File

@ -2213,7 +2213,7 @@ void game_command_set_water_height(
zLow = temp;
}
if (gCheatsDisableClearanceChecks || map_can_construct_at(x, y, zLow, zHigh, { 0b1111, 0b1111 }))
if (map_can_construct_at(x, y, zLow, zHigh, { 0b1111, 0b1111 }))
{
if (tile_element->AsSurface()->HasTrackThatNeedsWater())
{
@ -2389,10 +2389,9 @@ void game_command_place_large_scenery(
int32_t zHigh = (tile->z_clearance / 8) + zLow;
QuarterTile quarterTile = QuarterTile{ static_cast<uint8_t>(tile->flags >> 12), 0 }.Rotate(rotation);
if (!gCheatsDisableClearanceChecks
&& !map_can_construct_with_clear_at(
curTile.x, curTile.y, zLow, zHigh, &map_place_scenery_clear_func, quarterTile, flags, &supportsCost,
CREATE_CROSSING_MODE_NONE))
if (!map_can_construct_with_clear_at(
curTile.x, curTile.y, zLow, zHigh, &map_place_scenery_clear_func, quarterTile, flags, &supportsCost,
CREATE_CROSSING_MODE_NONE))
{
*ebx = MONEY32_UNDEFINED;
return;
@ -3033,8 +3032,7 @@ bool map_can_construct_with_clear_at(
*/
int32_t map_can_construct_at(int32_t x, int32_t y, int32_t zLow, int32_t zHigh, QuarterTile bl)
{
return gCheatsDisableClearanceChecks
|| map_can_construct_with_clear_at(x, y, zLow, zHigh, nullptr, bl, 0, nullptr, CREATE_CROSSING_MODE_NONE);
return map_can_construct_with_clear_at(x, y, zLow, zHigh, nullptr, bl, 0, nullptr, CREATE_CROSSING_MODE_NONE);
}
/**

View File

@ -268,9 +268,8 @@ static money32 SmallSceneryPlace(
QuarterTile quarterTile = QuarterTile{ collisionQuadrants, supports }.Rotate(quadRotation);
if (!gCheatsDisableClearanceChecks
&& !map_can_construct_with_clear_at(
x, y, zLow, zHigh, &map_place_scenery_clear_func, quarterTile, flags, &clearCost, CREATE_CROSSING_MODE_NONE))
if (!map_can_construct_with_clear_at(
x, y, zLow, zHigh, &map_place_scenery_clear_func, quarterTile, flags, &clearCost, CREATE_CROSSING_MODE_NONE))
{
return MONEY32_UNDEFINED;
}