1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 11:03:00 +01:00

Fix #11617: Zero clearance ghost track design paths break connections (#25685)

This commit is contained in:
mix
2025-12-27 13:29:49 +00:00
committed by GitHub
parent f4c43f5a39
commit 8ce8eec426
3 changed files with 2 additions and 57 deletions

View File

@@ -13,6 +13,7 @@
- Change: [#25485] Make the enlarged pressed swatch sprite more pronounced.
- Change: [#25544] The default game window size is now 1280×720px instead of 640×480px.
- Fix: [#9895] Stand-up coaster gets wrong intensity boost from the synchronisation bonus.
- Fix: [#11617] Path corner connections are broken when hovering track design ghosts with paths over them in zero clearances.
- Fix: [#22484] Lingering ghost entrance after placing park entrance.
- Fix: [#24952] Duplicate track designs when running via Steam without having RCT1 linked.
- Fix: [#25187] On-ride photo platform does not render as ghost when placing track design.

View File

@@ -47,7 +47,7 @@
// It is used for making sure only compatible builds get connected, even within
// single OpenRCT2 version.
constexpr uint8_t kStreamVersion = 5;
constexpr uint8_t kStreamVersion = 6;
const std::string kStreamID = std::string(kOpenRCT2Version) + "-" + std::to_string(kStreamVersion);

View File

@@ -1722,49 +1722,6 @@ bool TileElementWantsPathConnectionTowards(const TileCoordsXYZD& coords, const T
return false;
}
// fix up the corners around the given path element that gets removed
static void FootpathFixCornersAround(const TileCoordsXY& footpathPos, TileElement* pathElement)
{
// A mask for the paths' corners of each possible neighbour
static constexpr uint8_t cornersTouchingTile[3][3] = {
{ 0b0010, 0b0011, 0b0001 },
{ 0b0110, 0b0000, 0b1001 },
{ 0b0100, 0b1100, 0b1000 },
};
// Sloped paths don't create filled corners, so no need to remove any
if (pathElement->GetType() == TileElementType::Path && pathElement->AsPath()->IsSloped())
return;
for (int32_t xOffset = -1; xOffset <= 1; xOffset++)
{
for (int32_t yOffset = -1; yOffset <= 1; yOffset++)
{
// Skip self
if (xOffset == 0 && yOffset == 0)
continue;
TileElement* tileElement = MapGetFirstElementAt(
TileCoordsXY{ footpathPos.x + xOffset, footpathPos.y + yOffset }.ToCoordsXY());
if (tileElement == nullptr)
continue;
do
{
if (tileElement->GetType() != TileElementType::Path)
continue;
if (tileElement->AsPath()->IsSloped())
continue;
if (tileElement->BaseHeight != pathElement->BaseHeight)
continue;
const int32_t ix = xOffset + 1;
const int32_t iy = yOffset + 1;
tileElement->AsPath()->SetCorners(tileElement->AsPath()->GetCorners() & ~(cornersTouchingTile[iy][ix]));
} while (!(tileElement++)->IsLastForTile());
}
}
}
/**
*
* rct2: 0x006A6AA7
@@ -1786,7 +1743,6 @@ void FootpathRemoveEdgesAt(const CoordsXY& footpathPos, TileElement* tileElement
FootpathUpdateQueueEntranceBanner(footpathPos, tileElement);
bool fixCorners = false;
for (uint8_t direction = 0; direction < kNumOrthogonalDirections; direction++)
{
int32_t z1 = tileElement->BaseHeight;
@@ -1814,18 +1770,6 @@ void FootpathRemoveEdgesAt(const CoordsXY& footpathPos, TileElement* tileElement
FootpathRemoveEdgesTowards(
{ footpathPos + CoordsDirectionDelta[direction], z0 * kCoordsZStep, z1 * kCoordsZStep }, direction, isQueue);
}
else
{
// A footpath may stay connected, but its edges must be fixed later on when another edge does get removed.
fixCorners = true;
}
}
// Only fix corners when needed, to avoid changing corners that have been set for its looks.
if (fixCorners && tileElement->IsGhost())
{
auto tileFootpathPos = TileCoordsXY{ footpathPos };
FootpathFixCornersAround(tileFootpathPos, tileElement);
}
if (tileElement->GetType() == TileElementType::Path)