190 static SmallSet<DiagDirection, SIG_TBD_SIZE> _tbdset("_tbdset"); ///< set of open nodes in current signal block |
190 static SmallSet<DiagDirection, SIG_TBD_SIZE> _tbdset("_tbdset"); ///< set of open nodes in current signal block |
191 static SmallSet<DiagDirection, SIG_GLOB_SIZE> _globset("_globset"); ///< set of places to be updated in following runs |
191 static SmallSet<DiagDirection, SIG_GLOB_SIZE> _globset("_globset"); ///< set of places to be updated in following runs |
192 |
192 |
193 |
193 |
194 /** Check whether there is a train on rail, not in a depot */ |
194 /** Check whether there is a train on rail, not in a depot */ |
195 static void *TrainOnTileEnum(Vehicle *v, void *) |
195 static Vehicle *TrainOnTileEnum(Vehicle *v, void *) |
196 { |
196 { |
197 if (v->type != VEH_TRAIN || v->u.rail.track == TRACK_BIT_DEPOT) return NULL; |
197 if (v->type != VEH_TRAIN || v->u.rail.track == TRACK_BIT_DEPOT) return NULL; |
198 |
198 |
199 return v; |
199 return v; |
200 } |
200 } |
282 case MP_RAILWAY: { |
282 case MP_RAILWAY: { |
283 if (GetTileOwner(tile) != owner) continue; // do not propagate signals on others' tiles (remove for tracksharing) |
283 if (GetTileOwner(tile) != owner) continue; // do not propagate signals on others' tiles (remove for tracksharing) |
284 |
284 |
285 if (IsRailDepot(tile)) { |
285 if (IsRailDepot(tile)) { |
286 if (enterdir == INVALID_DIAGDIR) { // from 'inside' - train just entered or left the depot |
286 if (enterdir == INVALID_DIAGDIR) { // from 'inside' - train just entered or left the depot |
287 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; |
287 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum) != NULL) flags |= SF_TRAIN; |
288 exitdir = GetRailDepotDirection(tile); |
288 exitdir = GetRailDepotDirection(tile); |
289 tile += TileOffsByDiagDir(exitdir); |
289 tile += TileOffsByDiagDir(exitdir); |
290 enterdir = ReverseDiagDir(exitdir); |
290 enterdir = ReverseDiagDir(exitdir); |
291 break; |
291 break; |
292 } else if (enterdir == GetRailDepotDirection(tile)) { // entered a depot |
292 } else if (enterdir == GetRailDepotDirection(tile)) { // entered a depot |
293 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; |
293 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum) != NULL) flags |= SF_TRAIN; |
294 continue; |
294 continue; |
295 } else { |
295 } else { |
296 continue; |
296 continue; |
297 } |
297 } |
298 } |
298 } |
299 |
299 |
300 if (GetRailTileType(tile) == RAIL_TILE_WAYPOINT) { |
300 if (GetRailTileType(tile) == RAIL_TILE_WAYPOINT) { |
301 if (GetWaypointAxis(tile) != DiagDirToAxis(enterdir)) continue; |
301 if (GetWaypointAxis(tile) != DiagDirToAxis(enterdir)) continue; |
302 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; |
302 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum) != NULL) flags |= SF_TRAIN; |
303 tile += TileOffsByDiagDir(exitdir); |
303 tile += TileOffsByDiagDir(exitdir); |
304 /* enterdir and exitdir stay the same */ |
304 /* enterdir and exitdir stay the same */ |
305 break; |
305 break; |
306 } |
306 } |
307 |
307 |
308 TrackBits tracks = GetTrackBits(tile); // trackbits of tile |
308 TrackBits tracks = GetTrackBits(tile); // trackbits of tile |
309 TrackBits tracks_masked = (TrackBits)(tracks & _enterdir_to_trackbits[enterdir]); // only incidating trackbits |
309 TrackBits tracks_masked = (TrackBits)(tracks & _enterdir_to_trackbits[enterdir]); // only incidating trackbits |
310 |
310 |
311 if (tracks == TRACK_BIT_HORZ || tracks == TRACK_BIT_VERT) { // there is exactly one incidating track, no need to check |
311 if (tracks == TRACK_BIT_HORZ || tracks == TRACK_BIT_VERT) { // there is exactly one incidating track, no need to check |
312 tracks = tracks_masked; |
312 tracks = tracks_masked; |
313 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, &tracks, &EnsureNoTrainOnTrackProc)) flags |= SF_TRAIN; |
313 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, &tracks, &EnsureNoTrainOnTrackProc) != NULL) flags |= SF_TRAIN; |
314 } else { |
314 } else { |
315 if (tracks_masked == TRACK_BIT_NONE) continue; // no incidating track |
315 if (tracks_masked == TRACK_BIT_NONE) continue; // no incidating track |
316 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; |
316 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum) != NULL) flags |= SF_TRAIN; |
317 } |
317 } |
318 |
318 |
319 if (HasSignals(tile)) { // there is exactly one track - not zero, because there is exit from this tile |
319 if (HasSignals(tile)) { // there is exactly one track - not zero, because there is exit from this tile |
320 Track track = TrackBitsToTrack(tracks_masked); // mask TRACK_BIT_X and Y too |
320 Track track = TrackBitsToTrack(tracks_masked); // mask TRACK_BIT_X and Y too |
321 if (HasSignalOnTrack(tile, track)) { // now check whole track, not trackdir |
321 if (HasSignalOnTrack(tile, track)) { // now check whole track, not trackdir |
356 if (!IsRailwayStation(tile)) continue; |
356 if (!IsRailwayStation(tile)) continue; |
357 if (GetTileOwner(tile) != owner) continue; |
357 if (GetTileOwner(tile) != owner) continue; |
358 if (DiagDirToAxis(enterdir) != GetRailStationAxis(tile)) continue; // different axis |
358 if (DiagDirToAxis(enterdir) != GetRailStationAxis(tile)) continue; // different axis |
359 if (IsStationTileBlocked(tile)) continue; // 'eye-candy' station tile |
359 if (IsStationTileBlocked(tile)) continue; // 'eye-candy' station tile |
360 |
360 |
361 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; |
361 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum) != NULL) flags |= SF_TRAIN; |
362 tile += TileOffsByDiagDir(exitdir); |
362 tile += TileOffsByDiagDir(exitdir); |
363 break; |
363 break; |
364 |
364 |
365 case MP_ROAD: |
365 case MP_ROAD: |
366 if (!IsLevelCrossing(tile)) continue; |
366 if (!IsLevelCrossing(tile)) continue; |
367 if (GetTileOwner(tile) != owner) continue; |
367 if (GetTileOwner(tile) != owner) continue; |
368 if (DiagDirToAxis(enterdir) == GetCrossingRoadAxis(tile)) continue; // different axis |
368 if (DiagDirToAxis(enterdir) == GetCrossingRoadAxis(tile)) continue; // different axis |
369 |
369 |
370 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; |
370 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum) != NULL) flags |= SF_TRAIN; |
371 tile += TileOffsByDiagDir(exitdir); |
371 tile += TileOffsByDiagDir(exitdir); |
372 break; |
372 break; |
373 |
373 |
374 case MP_TUNNELBRIDGE: { |
374 case MP_TUNNELBRIDGE: { |
375 if (GetTileOwner(tile) != owner) continue; |
375 if (GetTileOwner(tile) != owner) continue; |
376 if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) continue; |
376 if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) continue; |
377 DiagDirection dir = GetTunnelBridgeDirection(tile); |
377 DiagDirection dir = GetTunnelBridgeDirection(tile); |
378 |
378 |
379 if (enterdir == INVALID_DIAGDIR) { // incoming from the wormhole |
379 if (enterdir == INVALID_DIAGDIR) { // incoming from the wormhole |
380 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; |
380 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum) != NULL) flags |= SF_TRAIN; |
381 enterdir = dir; |
381 enterdir = dir; |
382 exitdir = ReverseDiagDir(dir); |
382 exitdir = ReverseDiagDir(dir); |
383 tile += TileOffsByDiagDir(exitdir); // just skip to next tile |
383 tile += TileOffsByDiagDir(exitdir); // just skip to next tile |
384 } else { // NOT incoming from the wormhole! |
384 } else { // NOT incoming from the wormhole! |
385 if (ReverseDiagDir(enterdir) != dir) continue; |
385 if (ReverseDiagDir(enterdir) != dir) continue; |
386 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; |
386 if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum) != NULL) flags |= SF_TRAIN; |
387 tile = GetOtherTunnelBridgeEnd(tile); // just skip to exit tile |
387 tile = GetOtherTunnelBridgeEnd(tile); // just skip to exit tile |
388 enterdir = INVALID_DIAGDIR; |
388 enterdir = INVALID_DIAGDIR; |
389 exitdir = INVALID_DIAGDIR; |
389 exitdir = INVALID_DIAGDIR; |
390 } |
390 } |
391 } |
391 } |