MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / FollowReservation

Function FollowReservation

src/pbs.cpp:191–253  ·  view source on GitHub ↗

Follow a reservation starting from a specific tile to the end. */

Source from the content-addressed store, hash-verified

189
190/** Follow a reservation starting from a specific tile to the end. */
191static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Trackdir trackdir, bool ignore_oneway = false)
192{
193 TileIndex start_tile = tile;
194 Trackdir start_trackdir = trackdir;
195 bool first_loop = true;
196
197 /* Start track not reserved? This can happen if two trains
198 * are on the same tile. The reservation on the next tile
199 * is not ours in this case, so exit. */
200 if (!HasReservedTracks(tile, TrackToTrackBits(TrackdirToTrack(trackdir)))) return PBSTileInfo(tile, trackdir, false);
201
202 /* Do not disallow 90 deg turns as the setting might have changed between reserving and now. */
203 CFollowTrackRail ft(o, rts);
204 while (ft.Follow(tile, trackdir)) {
205 TrackdirBits reserved = ft.new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(ft.new_tile));
206
207 /* No reservation --> path end found */
208 if (reserved == TRACKDIR_BIT_NONE) {
209 if (ft.is_station) {
210 /* Check skipped station tiles as well, maybe our reservation ends inside the station. */
211 TileIndexDiff diff = TileOffsByDiagDir(ft.exitdir);
212 while (ft.tiles_skipped-- > 0) {
213 ft.new_tile -= diff;
214 if (HasStationReservation(ft.new_tile)) {
215 tile = ft.new_tile;
216 trackdir = DiagDirToDiagTrackdir(ft.exitdir);
217 break;
218 }
219 }
220 }
221 break;
222 }
223
224 /* Can't have more than one reserved trackdir */
225 Trackdir new_trackdir = FindFirstTrackdir(reserved);
226
227 /* One-way signal against us. The reservation can't be ours as it is not
228 * a safe position from our direction and we can never pass the signal. */
229 if (!ignore_oneway && HasOnewaySignalBlockingTrackdir(ft.new_tile, new_trackdir)) break;
230
231 tile = ft.new_tile;
232 trackdir = new_trackdir;
233
234 if (first_loop) {
235 /* Update the start tile after we followed the track the first
236 * time. This is necessary because the track follower can skip
237 * tiles (in stations for example) which means that we might
238 * never visit our original starting tile again. */
239 start_tile = tile;
240 start_trackdir = trackdir;
241 first_loop = false;
242 } else {
243 /* Loop encountered? */
244 if (tile == start_tile && trackdir == start_trackdir) break;
245 }
246 /* Depot tile? Can't continue. */
247 if (IsRailDepotTile(tile)) break;
248 /* Non-pbs signal? Reservation can't continue. */

Callers 2

FollowTrainReservationFunction · 0.85
GetTrainForReservationFunction · 0.85

Calls 15

HasReservedTracksFunction · 0.85
TrackToTrackBitsFunction · 0.85
TrackdirToTrackFunction · 0.85
TrackBitsToTrackdirBitsFunction · 0.85
GetReservedTrackbitsFunction · 0.85
TileOffsByDiagDirFunction · 0.85
HasStationReservationFunction · 0.85
DiagDirToDiagTrackdirFunction · 0.85
FindFirstTrackdirFunction · 0.85
IsRailDepotTileFunction · 0.85
IsTileTypeFunction · 0.85

Tested by

no test coverage detected