summaryrefslogtreecommitdiff
path: root/src/yapf/yapf_rail.cpp
diff options
context:
space:
mode:
authormichi_cc <michi_cc@openttd.org>2008-09-09 19:21:22 +0000
committermichi_cc <michi_cc@openttd.org>2008-09-09 19:21:22 +0000
commit1b7de43e8081b39cf8bd9250b5f675917229dd4b (patch)
treed92d586fd462cda23ebf65398113df03d48093f9 /src/yapf/yapf_rail.cpp
parentfa3f2ae035a2ad1bcb83b6bbc1e05b21911b5844 (diff)
downloadopenttd-1b7de43e8081b39cf8bd9250b5f675917229dd4b.tar.xz
(svn r14286) -Fix [FS#2265]: If a change of conventional/electric rail coincided with the start of a station platform, stale reservations could be left behind.
Diffstat (limited to 'src/yapf/yapf_rail.cpp')
-rw-r--r--src/yapf/yapf_rail.cpp52
1 files changed, 43 insertions, 9 deletions
diff --git a/src/yapf/yapf_rail.cpp b/src/yapf/yapf_rail.cpp
index 88fe70f80..619e0177b 100644
--- a/src/yapf/yapf_rail.cpp
+++ b/src/yapf/yapf_rail.cpp
@@ -10,6 +10,7 @@
#include "yapf_destrail.hpp"
#include "../vehicle_func.h"
#include "../pbs.h"
+#include "../functions.h"
#define DEBUG_YAPF_CACHE 0
@@ -46,23 +47,56 @@ private:
return true;
}
+ /** Reserve a railway platform. Tile contains the failed tile on abort. */
+ bool ReserveRailwayStationPlatform(TileIndex &tile, DiagDirection dir)
+ {
+ TileIndex start = tile;
+ TileIndexDiff diff = TileOffsByDiagDir(dir);
+
+ do {
+ if (GetRailwayStationReservation(tile)) return false;
+ SetRailwayStationReservation(tile, true);
+ MarkTileDirtyByTile(tile);
+ tile = TILE_ADD(tile, diff);
+ } while (IsCompatibleTrainStationTile(tile, start));
+
+ return true;
+ }
+
+ /** Try to reserve a single track/platform. */
bool ReserveSingleTrack(TileIndex tile, Trackdir td)
{
- if (!TryReserveRailTrack(tile, TrackdirToTrack(td))) {
- /* Tile couldn't be reserved, undo. */
- m_res_fail_tile = tile;
- m_res_fail_td = td;
- return false;
+ if (IsRailwayStationTile(tile)) {
+ if (!ReserveRailwayStationPlatform(tile, TrackdirToExitdir(ReverseTrackdir(td)))) {
+ /* Platform could not be reserved, undo. */
+ m_res_fail_tile = tile;
+ m_res_fail_td = td;
+ }
+ } else {
+ if (!TryReserveRailTrack(tile, TrackdirToTrack(td))) {
+ /* Tile couldn't be reserved, undo. */
+ m_res_fail_tile = tile;
+ m_res_fail_td = td;
+ return false;
+ }
}
- /* YAPF can sometimes skip parts of a station, so make sure we
- * always reserve the whole platform. */
- if (IsRailwayStationTile(tile)) SetRailwayStationPlatformReservation(tile, TrackdirToExitdir(ReverseTrackdir(td)), true);
+
return tile != m_res_dest;
}
+ /** Unreserve a single track/platform. Stops when the previous failer is reached. */
bool UnreserveSingleTrack(TileIndex tile, Trackdir td)
{
- if (tile != m_res_fail_tile || td != m_res_fail_td) UnreserveRailTrack(tile, TrackdirToTrack(td));
+ if (IsRailwayStationTile(tile)) {
+ TileIndex start = tile;
+ TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(td)));
+ while ((tile != m_res_fail_tile || td != m_res_fail_td) && IsCompatibleTrainStationTile(tile, start)) {
+ SetRailwayStationReservation(tile, false);
+ tile = TILE_ADD(tile, diff);
+ }
+ } else if (tile != m_res_fail_tile || td != m_res_fail_td) {
+ UnreserveRailTrack(tile, TrackdirToTrack(td));
+ }
return tile != m_res_dest && (tile != m_res_fail_tile || td != m_res_fail_td);
}