(svn r12132) -Cleanup: convert pathfinder selection from if/else to switch/case at many places
authorsmatz
Wed, 13 Feb 2008 17:54:11 +0000
changeset 9050 c9b3ceb09413
parent 9049 7e716ad214c6
child 9051 0becfc1d0c09
(svn r12132) -Cleanup: convert pathfinder selection from if/else to switch/case at many places
src/roadveh_cmd.cpp
src/ship_cmd.cpp
src/train_cmd.cpp
--- a/src/roadveh_cmd.cpp	Wed Feb 13 16:49:25 2008 +0000
+++ b/src/roadveh_cmd.cpp	Wed Feb 13 17:54:11 2008 +0000
@@ -414,38 +414,36 @@
 
 static const Depot* FindClosestRoadDepot(const Vehicle* v)
 {
-	TileIndex tile = v->tile;
-
-	if (_patches.pathfinder_for_roadvehs == VPF_YAPF) { /* YAPF is being used */
-		Depot* ret = YapfFindNearestRoadDepot(v);
-		return ret;
-	} else if (_patches.pathfinder_for_roadvehs == VPF_NPF) { /* NPF is being used */
-		NPFFoundTargetData ftd;
-		/* See where we are now */
-		Trackdir trackdir = GetVehicleTrackdir(v);
+	switch (_patches.pathfinder_for_roadvehs) {
+		case VPF_YAPF: /* YAPF */
+			return YapfFindNearestRoadDepot(v);
 
-		ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, v->tile, ReverseTrackdir(trackdir), false, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPES, 0);
-		if (ftd.best_bird_dist == 0) {
-			return GetDepotByTile(ftd.node.tile); /* Target found */
-		} else {
-			return NULL; /* Target not found */
-		}
-		/* We do not search in two directions here, why should we? We can't reverse right now can we? */
-	} else { /* OPF is being used */
-		RoadFindDepotData rfdd;
+		case VPF_NPF: { /* NPF */
+			/* See where we are now */
+			Trackdir trackdir = GetVehicleTrackdir(v);
 
-		rfdd.owner = v->owner;
-		rfdd.best_length = (uint)-1;
+			NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, v->tile, ReverseTrackdir(trackdir), false, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPES, 0);
 
-		/* search in all directions */
-		for (DiagDirection i = DIAGDIR_BEGIN; i != DIAGDIR_END; i++) {
-			FollowTrack(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, i, EnumRoadSignalFindDepot, NULL, &rfdd);
-		}
+			if (ftd.best_bird_dist == 0) return GetDepotByTile(ftd.node.tile); /* Target found */
+		} break;
 
-		if (rfdd.best_length == (uint)-1) return NULL;
+		default:
+		case VPF_OPF: { /* OPF */
+			RoadFindDepotData rfdd;
 
-		return GetDepotByTile(rfdd.tile);
+			rfdd.owner = v->owner;
+			rfdd.best_length = UINT_MAX;
+
+			/* search in all directions */
+			for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
+				FollowTrack(v->tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, d, EnumRoadSignalFindDepot, NULL, &rfdd);
+			}
+
+			if (rfdd.best_length != UINT_MAX) return GetDepotByTile(rfdd.tile);
+		} break;
 	}
+
+	return NULL; /* Target not found */
 }
 
 /** Send a road vehicle to the depot.
@@ -1217,77 +1215,82 @@
 		return_track(FindFirstBit2x64(trackdirs));
 	}
 
-	if (_patches.pathfinder_for_roadvehs == VPF_YAPF) { /* YAPF */
-		Trackdir trackdir = YapfChooseRoadTrack(v, tile, enterdir);
-		if (trackdir != INVALID_TRACKDIR) return_track(trackdir);
-		return_track(PickRandomBit(trackdirs));
-	} else if (_patches.pathfinder_for_roadvehs == VPF_NPF) { /* NPF */
-		NPFFindStationOrTileData fstd;
-		NPFFoundTargetData ftd;
-		Trackdir trackdir;
-
-		NPFFillWithOrderData(&fstd, v);
-		trackdir = DiagdirToDiagTrackdir(enterdir);
-		//debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir);
+	switch (_patches.pathfinder_for_roadvehs) {
+		case VPF_YAPF: { /* YAPF */
+			Trackdir trackdir = YapfChooseRoadTrack(v, tile, enterdir);
+			if (trackdir != INVALID_TRACKDIR) return_track(trackdir);
+			return_track(PickRandomBit(trackdirs));
+		} break;
 
-		ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPES);
-		if (ftd.best_trackdir == INVALID_TRACKDIR) {
-			/* We are already at our target. Just do something
-			 * @todo: maybe display error?
-			 * @todo: go straight ahead if possible? */
-			return_track(FindFirstBit2x64(trackdirs));
-		} else {
-			/* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
-			the direction we need to take to get there, if ftd.best_bird_dist is not 0,
-			we did not find our target, but ftd.best_trackdir contains the direction leading
-			to the tile closest to our target. */
-			return_track(ftd.best_trackdir);
-		}
-	} else { /* OPF */
-		DiagDirection dir;
+		case VPF_NPF: { /* NPF */
+			NPFFindStationOrTileData fstd;
 
-		if (IsTileType(desttile, MP_ROAD)) {
-			if (GetRoadTileType(desttile) == ROAD_TILE_DEPOT) {
-				dir = GetRoadDepotDirection(desttile);
-				goto do_it;
+			NPFFillWithOrderData(&fstd, v);
+			Trackdir trackdir = DiagdirToDiagTrackdir(enterdir);
+			//debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir);
+
+			NPFFoundTargetData ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPES);
+			if (ftd.best_trackdir == INVALID_TRACKDIR) {
+				/* We are already at our target. Just do something
+				 * @todo: maybe display error?
+				 * @todo: go straight ahead if possible? */
+				return_track(FindFirstBit2x64(trackdirs));
+			} else {
+				/* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
+				 * the direction we need to take to get there, if ftd.best_bird_dist is not 0,
+				 * we did not find our target, but ftd.best_trackdir contains the direction leading
+				 * to the tile closest to our target. */
+				return_track(ftd.best_trackdir);
 			}
-		} else if (IsTileType(desttile, MP_STATION)) {
-			/* For drive-through stops we can head for the actual station tile */
-			if (IsStandardRoadStopTile(desttile)) {
-				dir = GetRoadStopDir(desttile);
+		} break;
+
+		default:
+		case VPF_OPF: { /* OPF */
+			DiagDirection dir;
+
+			if (IsTileType(desttile, MP_ROAD)) {
+				if (GetRoadTileType(desttile) == ROAD_TILE_DEPOT) {
+					dir = GetRoadDepotDirection(desttile);
+					goto do_it;
+				}
+			} else if (IsTileType(desttile, MP_STATION)) {
+				/* For drive-through stops we can head for the actual station tile */
+				if (IsStandardRoadStopTile(desttile)) {
+					dir = GetRoadStopDir(desttile);
 do_it:;
-				/* When we are heading for a depot or station, we just
-				 * pretend we are heading for the tile in front, we'll
-				 * see from there */
-				desttile += TileOffsByDiagDir(dir);
-				if (desttile == tile && trackdirs & _road_exit_dir_to_incoming_trackdirs[dir]) {
-					/* If we are already in front of the
-					 * station/depot and we can get in from here,
-					 * we enter */
-					return_track(FindFirstBit2x64(trackdirs & _road_exit_dir_to_incoming_trackdirs[dir]));
+					/* When we are heading for a depot or station, we just
+					 * pretend we are heading for the tile in front, we'll
+					 * see from there */
+					desttile += TileOffsByDiagDir(dir);
+					if (desttile == tile && trackdirs & _road_exit_dir_to_incoming_trackdirs[dir]) {
+						/* If we are already in front of the
+						 * station/depot and we can get in from here,
+						 * we enter */
+						return_track(FindFirstBit2x64(trackdirs & _road_exit_dir_to_incoming_trackdirs[dir]));
+					}
 				}
 			}
-		}
-		/* Do some pathfinding */
-		frd.dest = desttile;
+			/* Do some pathfinding */
+			frd.dest = desttile;
 
-		best_track = INVALID_TRACKDIR;
-		uint best_dist = (uint)-1;
-		uint best_maxlen = (uint)-1;
-		uint bitmask = (uint)trackdirs;
-		uint i;
-		FOR_EACH_SET_BIT(i, bitmask) {
-			if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track
-			frd.maxtracklen = (uint)-1;
-			frd.mindist = (uint)-1;
-			FollowTrack(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd);
+			best_track = INVALID_TRACKDIR;
+			uint best_dist = UINT_MAX;
+			uint best_maxlen = UINT_MAX;
+			uint bitmask = (uint)trackdirs;
+			uint i;
+			FOR_EACH_SET_BIT(i, bitmask) {
+				if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track
+				frd.maxtracklen = UINT_MAX;
+				frd.mindist = UINT_MAX;
+				FollowTrack(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd);
 
-			if (frd.mindist < best_dist || (frd.mindist == best_dist && frd.maxtracklen < best_maxlen)) {
-				best_dist = frd.mindist;
-				best_maxlen = frd.maxtracklen;
-				best_track = (Trackdir)i;
+				if (frd.mindist < best_dist || (frd.mindist == best_dist && frd.maxtracklen < best_maxlen)) {
+					best_dist = frd.mindist;
+					best_maxlen = frd.maxtracklen;
+					best_track = (Trackdir)i;
+				}
 			}
-		}
+		} break;
 	}
 
 found_best_track:;
@@ -1299,24 +1302,23 @@
 
 static uint RoadFindPathToStop(const Vehicle *v, TileIndex tile)
 {
-	uint dist;
 	if (_patches.pathfinder_for_roadvehs == VPF_YAPF) {
 		/* use YAPF */
-		dist = YapfRoadVehDistanceToTile(v, tile);
-	} else {
-		/* use NPF */
-		NPFFindStationOrTileData fstd;
-		Trackdir trackdir = GetVehicleTrackdir(v);
-		assert(trackdir != INVALID_TRACKDIR);
+		return YapfRoadVehDistanceToTile(v, tile);
+	}
 
-		fstd.dest_coords = tile;
-		fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station
+	/* use NPF */
+	Trackdir trackdir = GetVehicleTrackdir(v);
+	assert(trackdir != INVALID_TRACKDIR);
 
-		dist = NPFRouteToStationOrTile(v->tile, trackdir, false, &fstd, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPES).best_path_dist;
-		/* change units from NPF_TILE_LENGTH to # of tiles */
-		if (dist != UINT_MAX)
-			dist = (dist + NPF_TILE_LENGTH - 1) / NPF_TILE_LENGTH;
-	}
+	NPFFindStationOrTileData fstd;
+	fstd.dest_coords = tile;
+	fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station
+
+	uint dist = NPFRouteToStationOrTile(v->tile, trackdir, false, &fstd, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPES).best_path_dist;
+	/* change units from NPF_TILE_LENGTH to # of tiles */
+	if (dist != UINT_MAX) dist = (dist + NPF_TILE_LENGTH - 1) / NPF_TILE_LENGTH;
+
 	return dist;
 }
 
--- a/src/ship_cmd.cpp	Wed Feb 13 16:49:25 2008 +0000
+++ b/src/ship_cmd.cpp	Wed Feb 13 17:54:11 2008 +0000
@@ -113,34 +113,32 @@
 
 static const Depot* FindClosestShipDepot(const Vehicle* v)
 {
+	if (_patches.pathfinder_for_ships == VPF_NPF) { /* NPF is used */
+		Trackdir trackdir = GetVehicleTrackdir(v);
+		NPFFoundTargetData ftd = NPFRouteToDepotTrialError(v->tile, trackdir, false, TRANSPORT_WATER, 0, v->owner, INVALID_RAILTYPES);
+
+		if (ftd.best_bird_dist == 0) return GetDepotByTile(ftd.node.tile); /* Found target */
+
+		return NULL; /* Did not find target */
+	}
+
+	/* OPF or YAPF - find the closest depot */
+
 	const Depot* depot;
 	const Depot* best_depot = NULL;
-	uint dist;
-	uint best_dist = (uint)-1;
-	TileIndex tile;
-	TileIndex tile2 = v->tile;
+	uint best_dist = UINT_MAX;
 
-	if (_patches.pathfinder_for_ships == VPF_NPF) { /* NPF is used */
-		NPFFoundTargetData ftd;
-		Trackdir trackdir = GetVehicleTrackdir(v);
-		ftd = NPFRouteToDepotTrialError(v->tile, trackdir, false, TRANSPORT_WATER, 0, v->owner, INVALID_RAILTYPES);
-		if (ftd.best_bird_dist == 0) {
-			best_depot = GetDepotByTile(ftd.node.tile); /* Found target */
-		} else {
-			best_depot = NULL; /* Did not find target */
-		}
-	} else { /* OPF or YAPF */
-		FOR_ALL_DEPOTS(depot) {
-			tile = depot->xy;
-			if (IsTileDepotType(tile, TRANSPORT_WATER) && IsTileOwner(tile, v->owner)) {
-				dist = DistanceManhattan(tile, tile2);
-				if (dist < best_dist) {
-					best_dist = dist;
-					best_depot = depot;
-				}
+	FOR_ALL_DEPOTS(depot) {
+		TileIndex tile = depot->xy;
+		if (IsTileDepotType(tile, TRANSPORT_WATER) && IsTileOwner(tile, v->owner)) {
+			uint dist = DistanceManhattan(tile, v->tile);
+			if (dist < best_dist) {
+				best_dist = dist;
+				best_depot = depot;
 			}
 		}
 	}
+
 	return best_depot;
 }
 
@@ -525,52 +523,52 @@
  * direction in which we are entering the tile */
 static Track ChooseShipTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks)
 {
-	assert(enterdir >= 0 && enterdir <= 3);
+	assert(IsValidDiagDirection(enterdir));
 
-	if (_patches.pathfinder_for_ships == VPF_YAPF) { /* YAPF */
-		Trackdir trackdir = YapfChooseShipTrack(v, tile, enterdir, tracks);
-		return (trackdir != INVALID_TRACKDIR) ? TrackdirToTrack(trackdir) : INVALID_TRACK;
-	} else if (_patches.pathfinder_for_ships == VPF_NPF) { /* NPF */
-		NPFFindStationOrTileData fstd;
-		NPFFoundTargetData ftd;
-		Trackdir trackdir = GetVehicleTrackdir(v);
-		assert(trackdir != INVALID_TRACKDIR); // Check that we are not in a depot
+	switch (_patches.pathfinder_for_ships) {
+		case VPF_YAPF: { /* YAPF */
+			Trackdir trackdir = YapfChooseShipTrack(v, tile, enterdir, tracks);
+			if (trackdir != INVALID_TRACKDIR) return TrackdirToTrack(trackdir);
+		} break;
 
-		NPFFillWithOrderData(&fstd, v);
+		case VPF_NPF: { /* NPF */
+			NPFFindStationOrTileData fstd;
+			Trackdir trackdir = GetVehicleTrackdir(v);
+			assert(trackdir != INVALID_TRACKDIR); // Check that we are not in a depot
 
-		ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_WATER, v->owner, INVALID_RAILTYPES);
+			NPFFillWithOrderData(&fstd, v);
 
-		if (ftd.best_trackdir != 0xff) {
+			NPFFoundTargetData ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_WATER, v->owner, INVALID_RAILTYPES);
+
 			/* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
-			the direction we need to take to get there, if ftd.best_bird_dist is not 0,
-			we did not find our target, but ftd.best_trackdir contains the direction leading
-			to the tile closest to our target. */
-			return TrackdirToTrack(ftd.best_trackdir); /* TODO: Wrapper function? */
-		} else {
-			return INVALID_TRACK; /* Already at target, reverse? */
-		}
-	} else { /* OPF */
-		uint tot_dist, dist;
-		Track track;
-		TileIndex tile2;
+			 * the direction we need to take to get there, if ftd.best_bird_dist is not 0,
+			 * we did not find our target, but ftd.best_trackdir contains the direction leading
+			 * to the tile closest to our target. */
+			if (ftd.best_trackdir != 0xff) return TrackdirToTrack(ftd.best_trackdir); /* TODO: Wrapper function? */
+		} break;
 
-		tile2 = TILE_ADD(tile, -TileOffsByDiagDir(enterdir));
-		tot_dist = (uint)-1;
+		default:
+		case VPF_OPF: { /* OPF */
+			TileIndex tile2 = TILE_ADD(tile, -TileOffsByDiagDir(enterdir));
+			Track track;
 
-		/* Let's find out how far it would be if we would reverse first */
-		TrackBits b = GetTileShipTrackStatus(tile2) & _ship_sometracks[ReverseDiagDir(enterdir)] & v->u.ship.state;
-		if (b != 0) {
-			dist = FindShipTrack(v, tile2, ReverseDiagDir(enterdir), b, tile, &track);
-			if (dist != (uint)-1)
-				tot_dist = dist + 1;
-		}
-		/* And if we would not reverse? */
-		dist = FindShipTrack(v, tile, enterdir, tracks, 0, &track);
-		if (dist > tot_dist)
-			/* We could better reverse */
-			return INVALID_TRACK;
-		return track;
+			/* Let's find out how far it would be if we would reverse first */
+			TrackBits b = GetTileShipTrackStatus(tile2) & _ship_sometracks[ReverseDiagDir(enterdir)] & v->u.ship.state;
+
+			uint distr = UINT_MAX; // distance if we reversed
+			if (b != 0) {
+				distr = FindShipTrack(v, tile2, ReverseDiagDir(enterdir), b, tile, &track);
+				if (distr != UINT_MAX) distr++; // penalty for reversing
+			}
+
+			/* And if we would not reverse? */
+			uint dist = FindShipTrack(v, tile, enterdir, tracks, 0, &track);
+
+			if (dist <= distr) return track;
+		} break;
 	}
+
+	return INVALID_TRACK; /* We could better reverse */
 }
 
 static const Direction _new_vehicle_direction_table[] = {
--- a/src/train_cmd.cpp	Wed Feb 13 16:49:25 2008 +0000
+++ b/src/train_cmd.cpp	Wed Feb 13 17:54:11 2008 +0000
@@ -2000,7 +2000,7 @@
 
 	TrainFindDepotData tfdd;
 	tfdd.owner = v->owner;
-	tfdd.best_length = (uint)-1;
+	tfdd.best_length = UINT_MAX;
 	tfdd.reverse = false;
 
 	TileIndex tile = v->tile;
@@ -2010,36 +2010,43 @@
 		return tfdd;
 	}
 
-	if (_patches.pathfinder_for_trains == VPF_YAPF) { /* YAPF is selected */
-		bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse);
-		tfdd.best_length = found ? max_distance / 2 : -1; // some fake distance or NOT_FOUND
-	} else if (_patches.pathfinder_for_trains == VPF_NPF) { /* NPF is selected */
-		Vehicle* last = GetLastVehicleInChain(v);
-		Trackdir trackdir = GetVehicleTrackdir(v);
-		Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
-
-		assert(trackdir != INVALID_TRACKDIR);
-		NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY);
-		if (ftd.best_bird_dist == 0) {
-			/* Found target */
-			tfdd.tile = ftd.node.tile;
-			/* Our caller expects a number of tiles, so we just approximate that
-			 * number by this. It might not be completely what we want, but it will
-			 * work for now :-) We can possibly change this when the old pathfinder
-			 * is removed. */
-			tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH;
-			if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) tfdd.reverse = true;
-		}
-	} else { /* NTP */
-		/* search in the forward direction first. */
-		DiagDirection i = TrainExitDir(v->direction, v->u.rail.track);
-		NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
-		if (tfdd.best_length == (uint)-1){
-			tfdd.reverse = true;
-			/* search in backwards direction */
-			i = TrainExitDir(ReverseDir(v->direction), v->u.rail.track);
+	switch (_patches.pathfinder_for_trains) {
+		case VPF_YAPF: { /* YAPF */
+			bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse);
+			tfdd.best_length = found ? max_distance / 2 : UINT_MAX; // some fake distance or NOT_FOUND
+		} break;
+
+		case VPF_NPF: { /* NPF */
+			Vehicle* last = GetLastVehicleInChain(v);
+			Trackdir trackdir = GetVehicleTrackdir(v);
+			Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
+
+			assert(trackdir != INVALID_TRACKDIR);
+			NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY);
+			if (ftd.best_bird_dist == 0) {
+				/* Found target */
+				tfdd.tile = ftd.node.tile;
+				/* Our caller expects a number of tiles, so we just approximate that
+				* number by this. It might not be completely what we want, but it will
+				* work for now :-) We can possibly change this when the old pathfinder
+				* is removed. */
+				tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH;
+				if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) tfdd.reverse = true;
+			}
+		} break;
+
+		default:
+		case VPF_NTP: { /* NTP */
+			/* search in the forward direction first. */
+			DiagDirection i = TrainExitDir(v->direction, v->u.rail.track);
 			NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
-		}
+			if (tfdd.best_length == UINT_MAX){
+				tfdd.reverse = true;
+				/* search in backwards direction */
+				i = TrainExitDir(ReverseDir(v->direction), v->u.rail.track);
+				NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
+			}
+		} break;
 	}
 
 	return tfdd;
@@ -2358,68 +2365,76 @@
 	/* quick return in case only one possible track is available */
 	if (KillFirstBit(tracks) == TRACK_BIT_NONE) return FindFirstTrack(tracks);
 
-	if (_patches.pathfinder_for_trains == VPF_YAPF) { /* YAPF is selected */
-		Trackdir trackdir = YapfChooseRailTrack(v, tile, enterdir, tracks, &path_not_found);
-		if (trackdir != INVALID_TRACKDIR) {
-			best_track = TrackdirToTrack(trackdir);
-		} else {
-			best_track = FindFirstTrack(tracks);
-		}
-	} else if (_patches.pathfinder_for_trains == VPF_NPF) { /* NPF is selected */
-		void* perf = NpfBeginInterval();
-
-		NPFFindStationOrTileData fstd;
-		NPFFillWithOrderData(&fstd, v);
-		/* The enterdir for the new tile, is the exitdir for the old tile */
-		Trackdir trackdir = GetVehicleTrackdir(v);
-		assert(trackdir != 0xff);
-
-		NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes);
-
-		if (ftd.best_trackdir == 0xff) {
-			/* We are already at our target. Just do something
-			 * @todo maybe display error?
-			 * @todo: go straight ahead if possible? */
-			best_track = FindFirstTrack(tracks);
-		} else {
-			/* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
-			the direction we need to take to get there, if ftd.best_bird_dist is not 0,
-			we did not find our target, but ftd.best_trackdir contains the direction leading
-			to the tile closest to our target. */
-			if (ftd.best_bird_dist != 0) path_not_found = true;
-			/* Discard enterdir information, making it a normal track */
-			best_track = TrackdirToTrack(ftd.best_trackdir);
-		}
-
-		int time = NpfEndInterval(perf);
-		DEBUG(yapf, 4, "[NPFT] %d us - %d rounds - %d open - %d closed -- ", time, 0, _aystar_stats_open_size, _aystar_stats_closed_size);
-	} else { /* NTP is selected */
-		void* perf = NpfBeginInterval();
-
-		TrainTrackFollowerData fd;
-		FillWithStationData(&fd, v);
-
-		/* New train pathfinding */
-		fd.best_bird_dist = (uint)-1;
-		fd.best_track_dist = (uint)-1;
-		fd.best_track = INVALID_TRACKDIR;
-
-		NewTrainPathfind(tile - TileOffsByDiagDir(enterdir), v->dest_tile,
-			v->u.rail.compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd);
-
-		/* check whether the path was found or only 'guessed' */
-		if (fd.best_bird_dist != 0) path_not_found = true;
-
-		if (fd.best_track == 0xff) {
-			/* blaha */
-			best_track = FindFirstTrack(tracks);
-		} else {
-			best_track = TrackdirToTrack(fd.best_track);
-		}
-
-		int time = NpfEndInterval(perf);
-		DEBUG(yapf, 4, "[NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0);
+	switch (_patches.pathfinder_for_trains) {
+		case VPF_YAPF: { /* YAPF */
+			Trackdir trackdir = YapfChooseRailTrack(v, tile, enterdir, tracks, &path_not_found);
+			if (trackdir != INVALID_TRACKDIR) {
+				best_track = TrackdirToTrack(trackdir);
+			} else {
+				best_track = FindFirstTrack(tracks);
+			}
+		} break;
+
+		case VPF_NPF: { /* NPF */
+			void *perf = NpfBeginInterval();
+
+			NPFFindStationOrTileData fstd;
+			NPFFillWithOrderData(&fstd, v);
+			/* The enterdir for the new tile, is the exitdir for the old tile */
+			Trackdir trackdir = GetVehicleTrackdir(v);
+			assert(trackdir != INVALID_TRACKDIR);
+
+			NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes);
+
+			if (ftd.best_trackdir == INVALID_TRACKDIR) {
+				/* We are already at our target. Just do something
+				 * @todo maybe display error?
+				 * @todo: go straight ahead if possible? */
+				best_track = FindFirstTrack(tracks);
+			} else {
+				/* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
+				 * the direction we need to take to get there, if ftd.best_bird_dist is not 0,
+				 * we did not find our target, but ftd.best_trackdir contains the direction leading
+				 * to the tile closest to our target. */
+				if (ftd.best_bird_dist != 0) path_not_found = true;
+				/* Discard enterdir information, making it a normal track */
+				best_track = TrackdirToTrack(ftd.best_trackdir);
+			}
+
+			int time = NpfEndInterval(perf);
+			DEBUG(yapf, 4, "[NPFT] %d us - %d rounds - %d open - %d closed -- ", time, 0, _aystar_stats_open_size, _aystar_stats_closed_size);
+		} break;
+
+		default:
+		case VPF_NTP: { /* NTP */
+			void *perf = NpfBeginInterval();
+
+			TrainTrackFollowerData fd;
+			FillWithStationData(&fd, v);
+
+			/* New train pathfinding */
+			fd.best_bird_dist = UINT_MAX;
+			fd.best_track_dist = UINT_MAX;
+			fd.best_track = INVALID_TRACKDIR;
+
+			NewTrainPathfind(tile - TileOffsByDiagDir(enterdir), v->dest_tile,
+				v->u.rail.compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd);
+
+			/* check whether the path was found or only 'guessed' */
+			if (fd.best_bird_dist != 0) path_not_found = true;
+
+			if (fd.best_track == INVALID_TRACKDIR) {
+				/* blaha */
+				best_track = FindFirstTrack(tracks);
+			} else {
+				best_track = TrackdirToTrack(fd.best_track);
+			}
+
+			int time = NpfEndInterval(perf);
+			DEBUG(yapf, 4, "[NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0);
+		} break;
 	}
+
 	/* handle "path not found" state */
 	if (path_not_found) {
 		/* PF didn't find the route */
@@ -2469,81 +2484,87 @@
 
 	int i = _search_directions[FIND_FIRST_BIT(v->u.rail.track)][DirToDiagDir(v->direction)];
 
-	if (_patches.pathfinder_for_trains == VPF_YAPF) { /* YAPF is selected */
-		reverse_best = YapfCheckReverseTrain(v);
-	} else if (_patches.pathfinder_for_trains == VPF_NPF) { /* NPF if selected for trains */
-		NPFFindStationOrTileData fstd;
-		NPFFoundTargetData ftd;
-		Trackdir trackdir, trackdir_rev;
-		Vehicle* last = GetLastVehicleInChain(v);
-
-		NPFFillWithOrderData(&fstd, v);
-
-		trackdir = GetVehicleTrackdir(v);
-		trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
-		assert(trackdir != 0xff);
-		assert(trackdir_rev != 0xff);
-
-		ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes);
-		if (ftd.best_bird_dist != 0) {
-			/* We didn't find anything, just keep on going straight ahead */
-			reverse_best = false;
-		} else {
-			if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) {
-				reverse_best = true;
+	switch (_patches.pathfinder_for_trains) {
+		case VPF_YAPF: { /* YAPF */
+			reverse_best = YapfCheckReverseTrain(v);
+		} break;
+
+		case VPF_NPF: { /* NPF */
+			NPFFindStationOrTileData fstd;
+			NPFFoundTargetData ftd;
+			Vehicle* last = GetLastVehicleInChain(v);
+
+			NPFFillWithOrderData(&fstd, v);
+
+			Trackdir trackdir = GetVehicleTrackdir(v);
+			Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
+			assert(trackdir != INVALID_TRACKDIR);
+			assert(trackdir_rev != INVALID_TRACKDIR);
+
+			ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes);
+			if (ftd.best_bird_dist != 0) {
+				/* We didn't find anything, just keep on going straight ahead */
+				reverse_best = false;
 			} else {
-				reverse_best = false;
+				if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) {
+					reverse_best = true;
+				} else {
+					reverse_best = false;
+				}
 			}
-		}
-	} else { /* NTP is selected */
-		int best_track = -1;
-		uint reverse = 0;
-		uint best_bird_dist  = 0;
-		uint best_track_dist = 0;
-
-		for (;;) {
-			fd.best_bird_dist = (uint)-1;
-			fd.best_track_dist = (uint)-1;
-
-			NewTrainPathfind(v->tile, v->dest_tile, v->u.rail.compatible_railtypes, (DiagDirection)(reverse ^ i), (NTPEnumProc*)NtpCallbFindStation, &fd);
-
-			if (best_track != -1) {
-				if (best_bird_dist != 0) {
-					if (fd.best_bird_dist != 0) {
-						/* neither reached the destination, pick the one with the smallest bird dist */
-						if (fd.best_bird_dist > best_bird_dist) goto bad;
-						if (fd.best_bird_dist < best_bird_dist) goto good;
+		} break;
+
+		default:
+		case VPF_NTP: { /* NTP */
+			int best_track = -1;
+			uint reverse = 0;
+			uint best_bird_dist  = 0;
+			uint best_track_dist = 0;
+
+			for (;;) {
+				fd.best_bird_dist = UINT_MAX;
+				fd.best_track_dist = UINT_MAX;
+
+				NewTrainPathfind(v->tile, v->dest_tile, v->u.rail.compatible_railtypes, (DiagDirection)(reverse ^ i), (NTPEnumProc*)NtpCallbFindStation, &fd);
+
+				if (best_track != -1) {
+					if (best_bird_dist != 0) {
+						if (fd.best_bird_dist != 0) {
+							/* neither reached the destination, pick the one with the smallest bird dist */
+							if (fd.best_bird_dist > best_bird_dist) goto bad;
+							if (fd.best_bird_dist < best_bird_dist) goto good;
+						} else {
+							/* we found the destination for the first time */
+							goto good;
+						}
 					} else {
-						/* we found the destination for the first time */
-						goto good;
+						if (fd.best_bird_dist != 0) {
+							/* didn't find destination, but we've found the destination previously */
+							goto bad;
+						} else {
+							/* both old & new reached the destination, compare track length */
+							if (fd.best_track_dist > best_track_dist) goto bad;
+							if (fd.best_track_dist < best_track_dist) goto good;
+						}
 					}
-				} else {
-					if (fd.best_bird_dist != 0) {
-						/* didn't find destination, but we've found the destination previously */
-						goto bad;
-					} else {
-						/* both old & new reached the destination, compare track length */
-						if (fd.best_track_dist > best_track_dist) goto bad;
-						if (fd.best_track_dist < best_track_dist) goto good;
-					}
+
+					/* if we reach this position, there's two paths of equal value so far.
+					 * pick one randomly. */
+					int r = GB(Random(), 0, 8);
+					if (_pick_track_table[i] == (v->direction & 3)) r += 80;
+					if (_pick_track_table[best_track] == (v->direction & 3)) r -= 80;
+					if (r <= 127) goto bad;
 				}
-
-				/* if we reach this position, there's two paths of equal value so far.
-				 * pick one randomly. */
-				int r = GB(Random(), 0, 8);
-				if (_pick_track_table[i] == (v->direction & 3)) r += 80;
-				if (_pick_track_table[best_track] == (v->direction & 3)) r -= 80;
-				if (r <= 127) goto bad;
+good:;
+				best_track = i;
+				best_bird_dist = fd.best_bird_dist;
+				best_track_dist = fd.best_track_dist;
+				reverse_best = reverse;
+bad:;
+				if (reverse != 0) break;
+				reverse = 2;
 			}
-good:;
-			best_track = i;
-			best_bird_dist = fd.best_bird_dist;
-			best_track_dist = fd.best_track_dist;
-			reverse_best = reverse;
-bad:;
-			if (reverse != 0) break;
-			reverse = 2;
-		}
+		} break;
 	}
 
 	return reverse_best != 0;
@@ -3025,7 +3046,7 @@
 				 * the signal status. */
 				uint32 tracks = ts | (ts >> 8);
 				TrackBits bits = (TrackBits)(tracks & TRACK_BIT_MASK);
-				if ((_patches.pathfinder_for_trains != VPF_NTP) && _patches.forbid_90_deg && prev == NULL) {
+				if (_patches.pathfinder_for_trains != VPF_NTP && _patches.forbid_90_deg && prev == NULL) {
 					/* We allow wagons to make 90 deg turns, because forbid_90_deg
 					 * can be switched on halfway a turn */
 					bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
@@ -3459,7 +3480,7 @@
 
 	/* mask unreachable track bits if we are forbidden to do 90deg turns */
 	TrackBits bits = (TrackBits)((ts | (ts >> 8)) & TRACK_BIT_MASK);
-	if ((_patches.pathfinder_for_trains != VPF_NTP) && _patches.forbid_90_deg) {
+	if (_patches.pathfinder_for_trains != VPF_NTP && _patches.forbid_90_deg) {
 		bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
 	}