diff options
author | michi_cc <michi_cc@openttd.org> | 2008-09-09 19:21:22 +0000 |
---|---|---|
committer | michi_cc <michi_cc@openttd.org> | 2008-09-09 19:21:22 +0000 |
commit | 1b7de43e8081b39cf8bd9250b5f675917229dd4b (patch) | |
tree | d92d586fd462cda23ebf65398113df03d48093f9 | |
parent | fa3f2ae035a2ad1bcb83b6bbc1e05b21911b5844 (diff) | |
download | openttd-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.
-rw-r--r-- | src/yapf/yapf_node_rail.hpp | 12 | ||||
-rw-r--r-- | src/yapf/yapf_rail.cpp | 52 |
2 files changed, 43 insertions, 21 deletions
diff --git a/src/yapf/yapf_node_rail.hpp b/src/yapf/yapf_node_rail.hpp index 192bce2ed..0d7e5d4d9 100644 --- a/src/yapf/yapf_node_rail.hpp +++ b/src/yapf/yapf_node_rail.hpp @@ -193,18 +193,6 @@ struct CYapfRailNodeT cur = ft.m_new_tile; assert(KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE); cur_td = FindFirstTrackdir(ft.m_new_td_bits); - - /* Did we skip tiles because of a station? */ - if (ft.m_is_station && ft.m_tiles_skipped > 0) { - TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(cur_td)); - TileIndex tile = TILE_ADD(cur, -diff * ft.m_tiles_skipped); - - /* Call func for all tiles in between. */ - for (int i = 0; i < ft.m_tiles_skipped; ++i) { - if (!(obj.*func)(tile, cur_td)) return false; - tile = TILE_ADD(tile, diff); - } - } } return (obj.*func)(cur, cur_td); 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); } |