From a12cf878fae77a7298021062a80cad6d8a313aa9 Mon Sep 17 00:00:00 2001 From: mix <167040362+mixiate@users.noreply.github.com> Date: Wed, 11 Jun 2025 13:02:42 +0100 Subject: [PATCH] Fix #17365: Surface slope wrong on x axis when expanding map size --- distribution/changelog.txt | 1 + src/openrct2/world/Map.cpp | 72 ++++++++++++++++++++++++++------------ 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index b464c405f5..710a4b7c4c 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -6,6 +6,7 @@ - Change: [objects#383] Disable all base colours on non-remappable WWTT vehicles, change black to light_blue. - Change: [objects#384] Remove erroneously enabled WWTT third remaps. - Fix: [#15846] Rightclicking on track piece when there is construction below does not work. +- Fix: [#17365] The slope of new land surfaces is only correct on one side when shifting and resizing the map. - Fix: [#24456] Zoomed out vehicles on the ride window tab can sometimes draw incorrectly. - Fix: [#24458] Vehicles in the ride window vehicle tab are offset differently than vanilla RCT2, and the sprites are cut off at the bottom. - Fix: [#24576] It is possible to edit open rides in certain circumstances. diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index b5c95dc9fa..b09a2f1687 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -1341,7 +1341,8 @@ void MapRemoveOutOfRangeElements() gameState.cheats.buildInPauseMode = buildState; } -static void MapExtendBoundarySurfaceExtendTile(const SurfaceElement& sourceTile, SurfaceElement& destTile) +static void MapExtendBoundarySurfaceExtendTile( + const SurfaceElement& sourceTile, SurfaceElement& destTile, const Direction direction) { destTile.SetSurfaceObjectIndex(sourceTile.GetSurfaceObjectIndex()); destTile.SetEdgeObjectIndex(sourceTile.GetEdgeObjectIndex()); @@ -1350,18 +1351,20 @@ static void MapExtendBoundarySurfaceExtendTile(const SurfaceElement& sourceTile, destTile.SetWaterHeight(sourceTile.GetWaterHeight()); auto z = sourceTile.BaseHeight; - auto slope = sourceTile.GetSlope() & kTileSlopeNWSideUp; + const auto originalSlope = Numerics::rol4(sourceTile.GetSlope(), direction) + | (sourceTile.GetSlope() & kTileSlopeDiagonalFlag); + auto slope = originalSlope & kTileSlopeNWSideUp; if (slope == kTileSlopeNWSideUp) { z += 2; slope = kTileSlopeFlat; - if (sourceTile.GetSlope() & kTileSlopeDiagonalFlag) + if (originalSlope & kTileSlopeDiagonalFlag) { slope = kTileSlopeNCornerUp; - if (sourceTile.GetSlope() & kTileSlopeSCornerUp) + if (originalSlope & kTileSlopeSCornerUp) { slope = kTileSlopeWCornerUp; - if (sourceTile.GetSlope() & kTileSlopeECornerUp) + if (originalSlope & kTileSlopeECornerUp) { slope = kTileSlopeFlat; } @@ -1373,7 +1376,7 @@ static void MapExtendBoundarySurfaceExtendTile(const SurfaceElement& sourceTile, if (slope & kTileSlopeWCornerUp) slope |= kTileSlopeSCornerUp; - destTile.SetSlope(slope); + destTile.SetSlope(Numerics::ror4(slope, direction)); destTile.BaseHeight = z; destTile.ClearanceHeight = z; } @@ -1391,7 +1394,7 @@ void MapExtendBoundarySurfaceY() if (existingTileElement != nullptr && newTileElement != nullptr) { - MapExtendBoundarySurfaceExtendTile(*existingTileElement, *newTileElement); + MapExtendBoundarySurfaceExtendTile(*existingTileElement, *newTileElement, 0); } Park::UpdateFences({ x << 5, y << 5 }); @@ -1410,12 +1413,46 @@ void MapExtendBoundarySurfaceX() auto newTileElement = MapGetSurfaceElementAt(TileCoordsXY{ x, y }); if (existingTileElement != nullptr && newTileElement != nullptr) { - MapExtendBoundarySurfaceExtendTile(*existingTileElement, *newTileElement); + MapExtendBoundarySurfaceExtendTile(*existingTileElement, *newTileElement, 3); } Park::UpdateFences({ x << 5, y << 5 }); } } +static void MapExtendBoundarySurfaceShiftX(const int32_t amount, const int32_t mapSizeY) +{ + for (int32_t y = 1; y < mapSizeY - 1; y++) + { + for (int32_t x = amount; x > 0; x--) + { + const auto* const existingTileElement = MapGetSurfaceElementAt(TileCoordsXY{ x + 1, y }); + auto* const newTileElement = MapGetSurfaceElementAt(TileCoordsXY{ x, y }); + if (existingTileElement != nullptr && newTileElement != nullptr) + { + MapExtendBoundarySurfaceExtendTile(*existingTileElement, *newTileElement, 1); + } + Park::UpdateFences(TileCoordsXY{ x, y }.ToCoordsXY()); + } + } +} + +static void MapExtendBoundarySurfaceShiftY(const int32_t amount, const int32_t mapSizeX) +{ + for (int32_t x = 1; x < mapSizeX - 1; x++) + { + for (int32_t y = amount; y > 0; y--) + { + const auto* const existingTileElement = MapGetSurfaceElementAt(TileCoordsXY{ x, y + 1 }); + auto* const newTileElement = MapGetSurfaceElementAt(TileCoordsXY{ x, y }); + if (existingTileElement != nullptr && newTileElement != nullptr) + { + MapExtendBoundarySurfaceExtendTile(*existingTileElement, *newTileElement, 2); + } + Park::UpdateFences(TileCoordsXY{ x, y }.ToCoordsXY()); + } + } +} + /** * Clears the provided element properly from a certain tile, and updates * the pointer (when needed) passed to this function to point to the next element. @@ -2232,21 +2269,7 @@ void ShiftMap(const TileCoordsXY& amount) } else { - auto copyX = std::clamp(srcX, 1, gameState.mapSize.x - 2); - auto copyY = std::clamp(srcY, 1, gameState.mapSize.y - 2); - auto srcTile = MapGetSurfaceElementAt(TileCoordsXY(copyX, copyY)); - if (srcTile != nullptr) - { - auto tileEl = *srcTile; - tileEl.SetOwner(OWNERSHIP_UNOWNED); - tileEl.SetParkFences(0); - tileEl.SetLastForTile(true); - newElements.push_back(*reinterpret_cast(&tileEl)); - } - else - { - newElements.push_back(GetDefaultSurfaceElement()); - } + newElements.push_back(GetDefaultSurfaceElement()); } } } @@ -2254,6 +2277,9 @@ void ShiftMap(const TileCoordsXY& amount) SetTileElements(gameState, std::move(newElements)); MapRemoveOutOfRangeElements(); + MapExtendBoundarySurfaceShiftX(amount.x, gameState.mapSize.y); + MapExtendBoundarySurfaceShiftY(amount.y, gameState.mapSize.x); + for (auto& spawn : gameState.peepSpawns) shiftIfNotNull(spawn, amountToMove);