8 #include "yapf_node_rail.hpp" |
8 #include "yapf_node_rail.hpp" |
9 #include "yapf_costrail.hpp" |
9 #include "yapf_costrail.hpp" |
10 #include "yapf_destrail.hpp" |
10 #include "yapf_destrail.hpp" |
11 #include "../vehicle_func.h" |
11 #include "../vehicle_func.h" |
12 #include "../pbs.h" |
12 #include "../pbs.h" |
|
13 #include "../functions.h" |
13 |
14 |
14 #define DEBUG_YAPF_CACHE 0 |
15 #define DEBUG_YAPF_CACHE 0 |
15 |
16 |
16 int _total_pf_time_us = 0; |
17 int _total_pf_time_us = 0; |
17 |
18 |
44 return false; // Stop iterating segment |
45 return false; // Stop iterating segment |
45 } |
46 } |
46 return true; |
47 return true; |
47 } |
48 } |
48 |
49 |
|
50 /** Reserve a railway platform. Tile contains the failed tile on abort. */ |
|
51 bool ReserveRailwayStationPlatform(TileIndex &tile, DiagDirection dir) |
|
52 { |
|
53 TileIndex start = tile; |
|
54 TileIndexDiff diff = TileOffsByDiagDir(dir); |
|
55 |
|
56 do { |
|
57 if (GetRailwayStationReservation(tile)) return false; |
|
58 SetRailwayStationReservation(tile, true); |
|
59 MarkTileDirtyByTile(tile); |
|
60 tile = TILE_ADD(tile, diff); |
|
61 } while (IsCompatibleTrainStationTile(tile, start)); |
|
62 |
|
63 return true; |
|
64 } |
|
65 |
|
66 /** Try to reserve a single track/platform. */ |
49 bool ReserveSingleTrack(TileIndex tile, Trackdir td) |
67 bool ReserveSingleTrack(TileIndex tile, Trackdir td) |
50 { |
68 { |
51 if (!TryReserveRailTrack(tile, TrackdirToTrack(td))) { |
69 if (IsRailwayStationTile(tile)) { |
52 /* Tile couldn't be reserved, undo. */ |
70 if (!ReserveRailwayStationPlatform(tile, TrackdirToExitdir(ReverseTrackdir(td)))) { |
53 m_res_fail_tile = tile; |
71 /* Platform could not be reserved, undo. */ |
54 m_res_fail_td = td; |
72 m_res_fail_tile = tile; |
55 return false; |
73 m_res_fail_td = td; |
56 } |
74 } |
57 /* YAPF can sometimes skip parts of a station, so make sure we |
75 } else { |
58 * always reserve the whole platform. */ |
76 if (!TryReserveRailTrack(tile, TrackdirToTrack(td))) { |
59 if (IsRailwayStationTile(tile)) SetRailwayStationPlatformReservation(tile, TrackdirToExitdir(ReverseTrackdir(td)), true); |
77 /* Tile couldn't be reserved, undo. */ |
|
78 m_res_fail_tile = tile; |
|
79 m_res_fail_td = td; |
|
80 return false; |
|
81 } |
|
82 } |
|
83 |
60 return tile != m_res_dest; |
84 return tile != m_res_dest; |
61 } |
85 } |
62 |
86 |
|
87 /** Unreserve a single track/platform. Stops when the previous failer is reached. */ |
63 bool UnreserveSingleTrack(TileIndex tile, Trackdir td) |
88 bool UnreserveSingleTrack(TileIndex tile, Trackdir td) |
64 { |
89 { |
65 if (tile != m_res_fail_tile || td != m_res_fail_td) UnreserveRailTrack(tile, TrackdirToTrack(td)); |
90 if (IsRailwayStationTile(tile)) { |
|
91 TileIndex start = tile; |
|
92 TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(td))); |
|
93 while ((tile != m_res_fail_tile || td != m_res_fail_td) && IsCompatibleTrainStationTile(tile, start)) { |
|
94 SetRailwayStationReservation(tile, false); |
|
95 tile = TILE_ADD(tile, diff); |
|
96 } |
|
97 } else if (tile != m_res_fail_tile || td != m_res_fail_td) { |
|
98 UnreserveRailTrack(tile, TrackdirToTrack(td)); |
|
99 } |
66 return tile != m_res_dest && (tile != m_res_fail_tile || td != m_res_fail_td); |
100 return tile != m_res_dest && (tile != m_res_fail_tile || td != m_res_fail_td); |
67 } |
101 } |
68 |
102 |
69 public: |
103 public: |
70 /** Set the target to where the reservation should be extended. */ |
104 /** Set the target to where the reservation should be extended. */ |