changeset 18716:30959e70d2f7 draft

(svn r23564) -Fix [FS#4888]: Extending a path reservation starting at a partially reserved rail station could fail.
author michi_cc <michi_cc@openttd.org>
date Sat, 17 Dec 2011 02:02:28 +0000
parents e6411cf4e885
children e9e4e17e3e19
files src/pathfinder/yapf/yapf_rail.cpp src/pbs.cpp
diffstat 2 files changed, 21 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/pathfinder/yapf/yapf_rail.cpp
+++ b/src/pathfinder/yapf/yapf_rail.cpp
@@ -58,6 +58,7 @@
 	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 @@
 			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 @@
 	}
 
 	/** 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 @@
 			this->FindSafePositionOnNode(pPrev);
 		}
 
-		return dont_reserve || this->TryReservePath(NULL);
+		return dont_reserve || this->TryReservePath(NULL, pNode->GetLastTile());
 	}
 };
 
@@ -452,7 +454,7 @@
 			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). */
--- a/src/pbs.cpp
+++ b/src/pbs.cpp
@@ -191,7 +191,21 @@
 		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);