src/signal.cpp
changeset 9775 22e256c3bf46
parent 9652 0405e98d8e96
child 9791 7bcdf05e5e5b
equal deleted inserted replaced
9774:190734cb1113 9775:22e256c3bf46
   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 				}