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

Fix #6228: Track design queue connections not preserved when built

This commit is contained in:
mix
2025-11-03 01:05:23 +00:00
committed by Gymnasiast
parent 49ef6768c5
commit 195de3b258
5 changed files with 59 additions and 9 deletions

View File

@@ -1,6 +1,7 @@
0.4.29 (in development)
------------------------------------------------------------------------
- Improved: [#25426] Building the track designs index is now quicker.
- Fix: [#6228] The saved queue line path connections are not preserved when placing track designs (original bug).
- Fix: [#14365] Track designs with scenery below the lowest track piece do not preview correctly.
- Fix: [#25451] Dropdown item tooltips stay open if the mouse is moved over an empty space.
- Fix: [#25461] Path connections in raised track designs are sometimes broken when placed.

View File

@@ -327,13 +327,14 @@ public:
// in the station array. e.g. if only slot 0 and 2 are in use, index 2 returns 2 instead of 3.
StationIndex::UnderlyingType getStationNumber(StationIndex in) const;
void chainQueues() const;
private:
void update();
void updateQueueLength(StationIndex stationIndex);
ResultWithMessage createVehicles(const CoordsXYE& element, bool isApplying, bool isSimulating);
void moveTrainsToBlockBrakes(const CoordsXYZ& firstBlockPosition, OpenRCT2::TrackElement& firstBlock);
money64 calculateIncomePerHour() const;
void chainQueues() const;
void constructMissingEntranceOrExit() const;
ResultWithMessage changeStatusDoStationChecks(StationIndex& stationIndex);

View File

@@ -1229,12 +1229,6 @@ static GameActions::Result TrackDesignPlaceSceneryElement(
return GameActions::Result();
}
if (tds.placeOperation == TrackPlaceOperation::place)
{
FootpathQueueChainReset();
FootpathRemoveEdgesAt(mapCoord, reinterpret_cast<TileElement*>(pathElement));
}
flags = GAME_COMMAND_FLAG_APPLY;
if (tds.placeOperation == TrackPlaceOperation::placeTrackPreview)
{
@@ -1252,8 +1246,11 @@ static GameActions::Result TrackDesignPlaceSceneryElement(
if (tds.placeOperation == TrackPlaceOperation::place)
{
FootpathConnectEdges(mapCoord, reinterpret_cast<TileElement*>(pathElement), flags);
FootpathUpdateQueueChains();
if (!pathElement->IsQueue() || FootpathQueueCountConnections(mapCoord, *pathElement) < 2)
{
FootpathRemoveEdgesAt(mapCoord, reinterpret_cast<TileElement*>(pathElement));
FootpathConnectEdges(mapCoord, reinterpret_cast<TileElement*>(pathElement), flags);
}
}
return GameActions::Result();
@@ -1807,6 +1804,11 @@ static GameActions::Result TrackDesignPlaceVirtual(
return sceneryPlaceRes;
}
if (tds.placeOperation == TrackPlaceOperation::place || tds.placeOperation == TrackPlaceOperation::placeTrackPreview)
{
ride.chainQueues();
}
// 0x6D0FE6
if (tds.placeOperation == TrackPlaceOperation::drawOutlines)
{

View File

@@ -955,6 +955,51 @@ void FootpathUpdateQueueChains()
}
}
int32_t FootpathQueueCountConnections(const CoordsXY& position, const PathElement& pathElement)
{
int32_t connectionCount = 0;
for (const Direction direction : kAllDirections)
{
const uint8_t edge = 1 << direction;
if (pathElement.GetEdges() & edge)
{
const CoordsXY adjacentPathPosition = position + CoordsDirectionDelta[direction];
const int32_t z = pathElement.GetBaseZ();
const TileElement* tileElement = FootpathGetElement({ adjacentPathPosition, z, z + kLandHeightStep }, direction);
if (tileElement == nullptr)
{
tileElement = FootpathGetElement({ adjacentPathPosition, z - kLandHeightStep, z }, direction);
if (tileElement == nullptr)
{
const EntranceElement* entrance = MapGetRideEntranceElementAt(CoordsXYZ{ adjacentPathPosition, z }, true);
if (entrance == nullptr)
{
entrance = MapGetRideEntranceElementAt(CoordsXYZ{ adjacentPathPosition, z + kLandHeightStep }, true);
if (entrance == nullptr)
continue;
}
if (entrance_has_direction(*entrance, direction + entrance->GetDirection()))
{
connectionCount++;
}
continue;
}
}
const PathElement& adjacentPath = *tileElement->AsPath();
if (adjacentPath.GetEdges() & Numerics::rol4(edge, 2))
{
connectionCount++;
}
}
}
return connectionCount;
}
/**
*
* rct2: 0x0069ADBD

View File

@@ -189,6 +189,7 @@ const OpenRCT2::FootpathRailingsObject* GetPathRailingsEntry(OpenRCT2::ObjectEnt
void FootpathQueueChainReset();
void FootpathQueueChainPush(RideId rideIndex);
int32_t FootpathQueueCountConnections(const CoordsXY& position, const OpenRCT2::PathElement& pathElement);
bool FootpathIsZAndDirectionValid(const OpenRCT2::PathElement& tileElement, int32_t currentZ, int32_t currentDirection);
FootpathPlacementResult FootpathGetOnTerrainPlacement(const TileCoordsXY& location);