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

Merge pull request #25467 from mixiate/fix-6228

Fix #6228: Exact saved track design queue connections not preserved. Fix track design preview path connections
This commit is contained in:
Michael Steenbeek
2025-11-07 22:07:47 +01:00
committed by GitHub
6 changed files with 63 additions and 11 deletions

View File

@@ -1,9 +1,11 @@
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.
- Fix: [#25467] Paths are not connected together correctly in track design previews.
- Fix: [#25476] When both RCT2 and RCT1 are present, autodetection fails.
0.4.28 (2025-11-01)

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 = 1;
constexpr uint8_t kStreamVersion = 2;
const std::string kStreamID = std::string(kOpenRCT2Version) + "-" + std::to_string(kStreamVersion);

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)
{
@@ -1250,10 +1244,14 @@ static GameActions::Result TrackDesignPlaceSceneryElement(
flags |= GAME_COMMAND_FLAG_REPLAY;
}
if (tds.placeOperation == TrackPlaceOperation::place)
if (tds.placeOperation == TrackPlaceOperation::placeTrackPreview
|| 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 +1805,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);