summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichi_cc <michi_cc@openttd.org>2011-12-17 02:02:28 +0000
committermichi_cc <michi_cc@openttd.org>2011-12-17 02:02:28 +0000
commit24b7be856bb6200f234f8ac2e6d3d365a4cf6aad (patch)
treebca8997d15fa8e03c6edbfa082054736346db09a
parent719b4707dc7f04dec672d6b5d643100670c78f47 (diff)
downloadopenttd-24b7be856bb6200f234f8ac2e6d3d365a4cf6aad.tar.xz
(svn r23564) -Fix [FS#4888]: Extending a path reservation starting at a partially reserved rail station could fail.
-rw-r--r--src/pathfinder/yapf/yapf_rail.cpp10
-rw-r--r--src/pbs.cpp16
2 files changed, 21 insertions, 5 deletions
diff --git a/src/pathfinder/yapf/yapf_rail.cpp b/src/pathfinder/yapf/yapf_rail.cpp
index d6776f75d..5c7509899 100644
--- a/src/pathfinder/yapf/yapf_rail.cpp
+++ b/src/pathfinder/yapf/yapf_rail.cpp
@@ -58,6 +58,7 @@ private:
Node *m_res_node; ///< The reservation target node
TileIndex m_res_fail_tile; ///< The tile where the reservation failed
Trackdir m_res_fail_td; ///< The trackdir where the reservation failed
+ TileIndex m_origin_tile; ///< Tile our reservation will originate from
bool FindSafePositionProc(TileIndex tile, Trackdir td)
{
@@ -80,7 +81,7 @@ private:
SetRailStationReservation(tile, true);
MarkTileDirtyByTile(tile);
tile = TILE_ADD(tile, diff);
- } while (IsCompatibleTrainStationTile(tile, start));
+ } while (IsCompatibleTrainStationTile(tile, start) && tile != m_origin_tile);
return true;
}
@@ -145,9 +146,10 @@ public:
}
/** Try to reserve the path till the reservation target. */
- bool TryReservePath(PBSTileInfo *target)
+ bool TryReservePath(PBSTileInfo *target, TileIndex origin)
{
m_res_fail_tile = INVALID_TILE;
+ m_origin_tile = origin;
if (target != NULL) {
target->tile = m_res_dest;
@@ -359,7 +361,7 @@ public:
this->FindSafePositionOnNode(pPrev);
}
- return dont_reserve || this->TryReservePath(NULL);
+ return dont_reserve || this->TryReservePath(NULL, pNode->GetLastTile());
}
};
@@ -452,7 +454,7 @@ public:
Node& best_next_node = *pPrev;
next_trackdir = best_next_node.GetTrackdir();
- if (reserve_track && path_found) this->TryReservePath(target);
+ if (reserve_track && path_found) this->TryReservePath(target, pNode->GetLastTile());
}
/* Treat the path as found if stopped on the first two way signal(s). */
diff --git a/src/pbs.cpp b/src/pbs.cpp
index 5c6a0fbcb..01e7b2f37 100644
--- a/src/pbs.cpp
+++ b/src/pbs.cpp
@@ -191,7 +191,21 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra
TrackdirBits reserved = ft.m_new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(ft.m_new_tile));
/* No reservation --> path end found */
- if (reserved == TRACKDIR_BIT_NONE) break;
+ if (reserved == TRACKDIR_BIT_NONE) {
+ if (ft.m_is_station) {
+ /* Check skipped station tiles as well, maybe our reservation ends inside the station. */
+ TileIndexDiff diff = TileOffsByDiagDir(ft.m_exitdir);
+ while (ft.m_tiles_skipped-- > 0) {
+ ft.m_new_tile -= diff;
+ if (HasStationReservation(ft.m_new_tile)) {
+ tile = ft.m_new_tile;
+ trackdir = DiagDirToDiagTrackdir(ft.m_exitdir);
+ break;
+ }
+ }
+ }
+ break;
+ }
/* Can't have more than one reserved trackdir */
Trackdir new_trackdir = FindFirstTrackdir(reserved);