1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-12 10:32:26 +01:00

Refactor map_get_footpath_element() and fix #10486

This commit is contained in:
Gymnasiast
2019-12-31 10:08:36 +01:00
parent 37110f386d
commit 0d09a645fc
10 changed files with 22 additions and 21 deletions

View File

@@ -3616,13 +3616,12 @@ void ride_construction_toolupdate_construct(ScreenCoordsXY screenCoords)
&& ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) && ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP))
{ {
TileElement* pathsByDir[4]; TileElement* pathsByDir[4];
constexpr TileCoordsXY DirOffsets[4] = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } };
bool keepOrientation = false; bool keepOrientation = false;
for (int8_t i = 0; i < 4; i++) for (int8_t i = 0; i < 4; i++)
{ {
pathsByDir[i] = map_get_footpath_element( pathsByDir[i] = map_get_footpath_element({ mapCoords->x + (DirectionOffsets[i].x * COORDS_XY_STEP),
(mapCoords->x >> 5) + DirOffsets[i].x, (mapCoords->y >> 5) + DirOffsets[i].y, z >> 3); mapCoords->y + (DirectionOffsets[i].y * COORDS_XY_STEP), z });
if (pathsByDir[i] && (pathsByDir[i])->AsPath()->IsSloped() && (pathsByDir[i])->AsPath()->GetSlopeDirection() != i) if (pathsByDir[i] && (pathsByDir[i])->AsPath()->IsSloped() && (pathsByDir[i])->AsPath()->GetSlopeDirection() != i)
{ {
@@ -3632,8 +3631,9 @@ void ride_construction_toolupdate_construct(ScreenCoordsXY screenCoords)
// Sloped path on the level below // Sloped path on the level below
if (!pathsByDir[i]) if (!pathsByDir[i])
{ {
pathsByDir[i] = map_get_footpath_element( pathsByDir[i] = map_get_footpath_element({ mapCoords->x + (DirectionOffsets[i].x * COORDS_XY_STEP),
(mapCoords->x >> 5) + DirOffsets[i].x, (mapCoords->y >> 5) + DirOffsets[i].y, (z >> 3) - 2); mapCoords->y + (DirectionOffsets[i].y * COORDS_XY_STEP),
z - PATH_HEIGHT_STEP });
if (pathsByDir[i] if (pathsByDir[i]
&& (!(pathsByDir[i])->AsPath()->IsSloped() && (!(pathsByDir[i])->AsPath()->IsSloped()

View File

@@ -413,10 +413,10 @@ private:
{ {
auto direction = pathElement->GetSlopeDirection(); auto direction = pathElement->GetSlopeDirection();
int32_t z = pathElement->GetBaseZ(); int32_t z = pathElement->GetBaseZ();
wall_remove_intersecting_walls({ _loc, z, z + (6 * 8) }, direction_reverse(direction)); wall_remove_intersecting_walls({ _loc, z, z + (6 * COORDS_Z_STEP) }, direction_reverse(direction));
wall_remove_intersecting_walls({ _loc, z, z + (6 * 8) }, direction); wall_remove_intersecting_walls({ _loc, z, z + (6 * COORDS_Z_STEP) }, direction);
// Removing walls may have made the pointer invalid, so find it again // Removing walls may have made the pointer invalid, so find it again
auto tileElement = map_get_footpath_element(_loc.x / 32, _loc.y / 32, z); auto tileElement = map_get_footpath_element(CoordsXYZ(_loc, z));
if (tileElement == nullptr) if (tileElement == nullptr)
{ {
log_error("Something went wrong. Could not refind footpath."); log_error("Something went wrong. Could not refind footpath.");

View File

@@ -111,7 +111,7 @@ private:
{ {
bool getGhostPath = GetFlags() & GAME_COMMAND_FLAG_GHOST; bool getGhostPath = GetFlags() & GAME_COMMAND_FLAG_GHOST;
TileElement* tileElement = map_get_footpath_element(_loc.x / 32, _loc.y / 32, _loc.z / 8); TileElement* tileElement = map_get_footpath_element(_loc);
TileElement* footpathElement = nullptr; TileElement* footpathElement = nullptr;
if (tileElement != nullptr) if (tileElement != nullptr)
{ {

View File

@@ -73,7 +73,7 @@ public:
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE, STR_TOO_HIGH); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_POSITION_THIS_HERE, STR_TOO_HIGH);
} }
auto tileElement = map_get_footpath_element(_loc.x / 32, _loc.y / 32, _loc.z / 8); auto tileElement = map_get_footpath_element(_loc);
if (tileElement == nullptr) if (tileElement == nullptr)
{ {
log_error("Could not find path element."); log_error("Could not find path element.");
@@ -143,7 +143,7 @@ public:
res->Position = _loc; res->Position = _loc;
res->Expenditure = ExpenditureType::Landscaping; res->Expenditure = ExpenditureType::Landscaping;
auto tileElement = map_get_footpath_element(_loc.x / 32, _loc.y / 32, _loc.z / 8); auto tileElement = map_get_footpath_element(_loc);
auto pathElement = tileElement->AsPath(); auto pathElement = tileElement->AsPath();
if (pathElement == nullptr) if (pathElement == nullptr)

View File

@@ -67,7 +67,7 @@ public:
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_REMOVE_THIS, STR_TOO_HIGH); 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 tileElement = map_get_footpath_element(_loc);
if (tileElement == nullptr) if (tileElement == nullptr)
{ {
log_warning("Could not find path element."); log_warning("Could not find path element.");
@@ -94,7 +94,7 @@ public:
GameActionResult::Ptr Execute() const override GameActionResult::Ptr Execute() const override
{ {
auto tileElement = map_get_footpath_element(_loc.x / 32, _loc.y / 32, _loc.z / 8); auto tileElement = map_get_footpath_element(_loc);
auto pathElement = tileElement->AsPath(); auto pathElement = tileElement->AsPath();
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST)) if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST))

View File

@@ -1175,7 +1175,8 @@ void ride_clear_blocked_tiles(Ride* ride)
if (element->GetType() == TILE_ELEMENT_TYPE_TRACK && element->AsTrack()->GetRideIndex() == ride->id) if (element->GetType() == TILE_ELEMENT_TYPE_TRACK && element->AsTrack()->GetRideIndex() == ride->id)
{ {
// Unblock footpath element that is at same position // Unblock footpath element that is at same position
auto footpathElement = map_get_footpath_element(x, y, element->base_height); auto footpathElement = map_get_footpath_element(
TileCoordsXYZ{ x, y, element->base_height }.ToCoordsXYZ());
if (footpathElement != nullptr) if (footpathElement != nullptr)
{ {
footpathElement->AsPath()->SetIsBlockedByVehicle(false); footpathElement->AsPath()->SetIsBlockedByVehicle(false);

View File

@@ -111,14 +111,14 @@ static bool entrance_has_direction(TileElement* tileElement, int32_t direction)
return entrance_get_directions(tileElement) & (1 << (direction & 3)); return entrance_get_directions(tileElement) & (1 << (direction & 3));
} }
TileElement* map_get_footpath_element(int32_t x, int32_t y, int32_t z) TileElement* map_get_footpath_element(CoordsXYZ coords)
{ {
TileElement* tileElement = map_get_first_element_at(TileCoordsXY{ x, y }.ToCoordsXY()); TileElement* tileElement = map_get_first_element_at(coords);
do do
{ {
if (tileElement == nullptr) if (tileElement == nullptr)
break; break;
if (tileElement->GetType() == TILE_ELEMENT_TYPE_PATH && tileElement->base_height == z) if (tileElement->GetType() == TILE_ELEMENT_TYPE_PATH && tileElement->GetBaseZ() == coords.z)
return tileElement; return tileElement;
} while (!(tileElement++)->IsLastForTile()); } while (!(tileElement++)->IsLastForTile());

View File

@@ -174,7 +174,7 @@ extern const CoordsXY DirectionOffsets[NumOrthogonalDirections];
extern const LocationXY16 BinUseOffsets[NumOrthogonalDirections]; extern const LocationXY16 BinUseOffsets[NumOrthogonalDirections];
extern const LocationXY16 BenchUseOffsets[NumOrthogonalDirections * 2]; extern const LocationXY16 BenchUseOffsets[NumOrthogonalDirections * 2];
TileElement* map_get_footpath_element(int32_t x, int32_t y, int32_t z); TileElement* map_get_footpath_element(CoordsXYZ coords);
struct PathElement; struct PathElement;
PathElement* map_get_footpath_element_slope(int32_t x, int32_t y, int32_t z, int32_t slope); PathElement* map_get_footpath_element_slope(int32_t x, int32_t y, int32_t z, int32_t slope);
void footpath_interrupt_peeps(int32_t x, int32_t y, int32_t z); void footpath_interrupt_peeps(int32_t x, int32_t y, int32_t z);

View File

@@ -117,7 +117,7 @@ protected:
// Check that the peep is still on a footpath. Use next_z instead of pos->z here because pos->z will change // Check that the peep is still on a footpath. Use next_z instead of pos->z here because pos->z will change
// when the peep is halfway up a slope, but next_z will not change until they move to the next tile. // when the peep is halfway up a slope, but next_z will not change until they move to the next tile.
EXPECT_NE(map_get_footpath_element(pos->x, pos->y, peep->next_z), nullptr); EXPECT_NE(map_get_footpath_element(TileCoordsXYZ{ pos->x, pos->y, peep->next_z }.ToCoordsXYZ()), nullptr);
} }
// Clean up the peep, because we're reusing this loaded context for all tests. // Clean up the peep, because we're reusing this loaded context for all tests.

View File

@@ -51,7 +51,7 @@ std::shared_ptr<IContext> TileElementWantsFootpathConnection::_context;
TEST_F(TileElementWantsFootpathConnection, FlatPath) TEST_F(TileElementWantsFootpathConnection, FlatPath)
{ {
// Flat paths want to connect to other paths in any direction // Flat paths want to connect to other paths in any direction
const TileElement* const pathElement = map_get_footpath_element(19, 18, 14); const TileElement* const pathElement = map_get_footpath_element(TileCoordsXYZ{ 19, 18, 14 }.ToCoordsXYZ());
ASSERT_NE(pathElement, nullptr); ASSERT_NE(pathElement, nullptr);
EXPECT_TRUE(tile_element_wants_path_connection_towards({ 19, 18, 14, 0 }, nullptr)); EXPECT_TRUE(tile_element_wants_path_connection_towards({ 19, 18, 14, 0 }, nullptr));
EXPECT_TRUE(tile_element_wants_path_connection_towards({ 19, 18, 14, 1 }, nullptr)); EXPECT_TRUE(tile_element_wants_path_connection_towards({ 19, 18, 14, 1 }, nullptr));
@@ -63,7 +63,7 @@ TEST_F(TileElementWantsFootpathConnection, FlatPath)
TEST_F(TileElementWantsFootpathConnection, SlopedPath) TEST_F(TileElementWantsFootpathConnection, SlopedPath)
{ {
// Sloped paths only want to connect in two directions, of which is one at a higher offset // Sloped paths only want to connect in two directions, of which is one at a higher offset
const TileElement* const slopedPathElement = map_get_footpath_element(18, 18, 14); const TileElement* const slopedPathElement = map_get_footpath_element(TileCoordsXYZ{ 18, 18, 14 }.ToCoordsXYZ());
ASSERT_NE(slopedPathElement, nullptr); ASSERT_NE(slopedPathElement, nullptr);
ASSERT_TRUE(slopedPathElement->AsPath()->IsSloped()); ASSERT_TRUE(slopedPathElement->AsPath()->IsSloped());
// Bottom and top of sloped path want a path connection // Bottom and top of sloped path want a path connection