summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsmatz <smatz@openttd.org>2008-02-13 17:54:11 +0000
committersmatz <smatz@openttd.org>2008-02-13 17:54:11 +0000
commitfd51465c8bc1d86d67678adcef78aba5349dd492 (patch)
tree82f5077f05aaa2584b55ba43561c4004d6939e45 /src
parent480036254b7773352ea8e77ca03eb7ab7355e505 (diff)
downloadopenttd-fd51465c8bc1d86d67678adcef78aba5349dd492.tar.xz
(svn r12132) -Cleanup: convert pathfinder selection from if/else to switch/case at many places
Diffstat (limited to 'src')
-rw-r--r--src/roadveh_cmd.cpp212
-rw-r--r--src/ship_cmd.cpp126
-rw-r--r--src/train_cmd.cpp319
3 files changed, 339 insertions, 318 deletions
diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp
index 6c4db3316..f340a4b2b 100644
--- a/src/roadveh_cmd.cpp
+++ b/src/roadveh_cmd.cpp
@@ -414,38 +414,36 @@ static bool EnumRoadSignalFindDepot(TileIndex tile, void* data, Trackdir trackdi
static const Depot* FindClosestRoadDepot(const Vehicle* v)
{
- TileIndex tile = v->tile;
+ switch (_patches.pathfinder_for_roadvehs) {
+ case VPF_YAPF: /* YAPF */
+ return YapfFindNearestRoadDepot(v);
- 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);
-
- 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;
+
+ default:
+ case VPF_OPF: { /* OPF */
+ RoadFindDepotData rfdd;
+
+ rfdd.owner = v->owner;
+ rfdd.best_length = UINT_MAX;
- if (rfdd.best_length == (uint)-1) return NULL;
+ /* 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);
+ }
- return GetDepotByTile(rfdd.tile);
+ 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 @@ static Trackdir RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection ent
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);
-
- 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;
+ 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;
+
+ case VPF_NPF: { /* NPF */
+ NPFFindStationOrTileData fstd;
+
+ NPFFillWithOrderData(&fstd, v);
+ Trackdir trackdir = DiagdirToDiagTrackdir(enterdir);
+ //debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir);
- if (IsTileType(desttile, MP_ROAD)) {
- if (GetRoadTileType(desttile) == ROAD_TILE_DEPOT) {
- dir = GetRoadDepotDirection(desttile);
- goto do_it;
+ 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;
-
- 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);
-
- 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;
+ /* Do some pathfinding */
+ frd.dest = desttile;
+
+ 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;
+ }
}
- }
+ } break;
}
found_best_track:;
@@ -1299,24 +1302,23 @@ found_best_track:;
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);
+
+ 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;
- 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;
}
diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp
index 6b986c494..5c8fda196 100644
--- a/src/ship_cmd.cpp
+++ b/src/ship_cmd.cpp
@@ -113,34 +113,32 @@ int Ship::GetImage(Direction direction) const
static const Depot* FindClosestShipDepot(const Vehicle* v)
{
- const Depot* depot;
- const Depot* best_depot = NULL;
- uint dist;
- uint best_dist = (uint)-1;
- TileIndex tile;
- TileIndex tile2 = v->tile;
-
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;
- }
+ 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 best_dist = UINT_MAX;
+
+ 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 @@ static inline NPFFoundTargetData PerfNPFRouteToStationOrTile(TileIndex tile, Tra
* direction in which we are entering the tile */
static Track ChooseShipTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks)
{
- assert(enterdir >= 0 && enterdir <= 3);
-
- 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
+ assert(IsValidDiagDirection(enterdir));
- NPFFillWithOrderData(&fstd, v);
+ switch (_patches.pathfinder_for_ships) {
+ case VPF_YAPF: { /* YAPF */
+ Trackdir trackdir = YapfChooseShipTrack(v, tile, enterdir, tracks);
+ if (trackdir != INVALID_TRACKDIR) return TrackdirToTrack(trackdir);
+ } break;
- ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_WATER, v->owner, INVALID_RAILTYPES);
+ case VPF_NPF: { /* NPF */
+ NPFFindStationOrTileData fstd;
+ Trackdir trackdir = GetVehicleTrackdir(v);
+ assert(trackdir != INVALID_TRACKDIR); // Check that we are not in a depot
+
+ NPFFillWithOrderData(&fstd, v);
+
+ NPFFoundTargetData ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_WATER, v->owner, INVALID_RAILTYPES);
- if (ftd.best_trackdir != 0xff) {
/* 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;
-
- tile2 = TILE_ADD(tile, -TileOffsByDiagDir(enterdir));
- tot_dist = (uint)-1;
-
- /* 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;
+ * 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;
+
+ 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;
+
+ 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[] = {
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index 232c79e07..1cfb2feb9 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -2000,7 +2000,7 @@ static TrainFindDepotData FindClosestTrainDepot(Vehicle *v, int max_distance)
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 @@ static TrainFindDepotData FindClosestTrainDepot(Vehicle *v, int max_distance)
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 @@ static Track ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir
/* 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();
+ 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;
- 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);
+ case VPF_NPF: { /* NPF */
+ void *perf = NpfBeginInterval();
- NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes);
+ 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);
- 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);
- }
+ NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes);
- 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();
+ 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);
+ }
- TrainTrackFollowerData fd;
- FillWithStationData(&fd, v);
+ 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;
- /* New train pathfinding */
- fd.best_bird_dist = (uint)-1;
- fd.best_track_dist = (uint)-1;
- fd.best_track = INVALID_TRACKDIR;
+ default:
+ case VPF_NTP: { /* NTP */
+ void *perf = NpfBeginInterval();
- NewTrainPathfind(tile - TileOffsByDiagDir(enterdir), v->dest_tile,
- v->u.rail.compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd);
+ TrainTrackFollowerData fd;
+ FillWithStationData(&fd, v);
- /* check whether the path was found or only 'guessed' */
- if (fd.best_bird_dist != 0) path_not_found = true;
+ /* New train pathfinding */
+ fd.best_bird_dist = UINT_MAX;
+ fd.best_track_dist = UINT_MAX;
+ fd.best_track = INVALID_TRACKDIR;
- if (fd.best_track == 0xff) {
- /* blaha */
- best_track = FindFirstTrack(tracks);
- } else {
- best_track = TrackdirToTrack(fd.best_track);
- }
+ 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);
+ 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 @@ static bool CheckReverseTrain(Vehicle *v)
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;
- } 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;
+ switch (_patches.pathfinder_for_trains) {
+ case VPF_YAPF: { /* YAPF */
+ reverse_best = YapfCheckReverseTrain(v);
+ } break;
- for (;;) {
- fd.best_bird_dist = (uint)-1;
- fd.best_track_dist = (uint)-1;
+ case VPF_NPF: { /* NPF */
+ NPFFindStationOrTileData fstd;
+ NPFFoundTargetData ftd;
+ Vehicle* last = GetLastVehicleInChain(v);
- NewTrainPathfind(v->tile, v->dest_tile, v->u.rail.compatible_railtypes, (DiagDirection)(reverse ^ i), (NTPEnumProc*)NtpCallbFindStation, &fd);
+ NPFFillWithOrderData(&fstd, v);
- 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;
- }
+ 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 {
+ if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) {
+ reverse_best = true;
} else {
- if (fd.best_bird_dist != 0) {
- /* didn't find destination, but we've found the destination previously */
- goto bad;
+ reverse_best = false;
+ }
+ }
+ } 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 {
- /* 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 (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;
+ 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;
- }
+ if (reverse != 0) break;
+ reverse = 2;
+ }
+ } break;
}
return reverse_best != 0;
@@ -3025,7 +3046,7 @@ static void TrainController(Vehicle *v, bool update_image)
* 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 @@ static bool TrainCheckIfLineEnds(Vehicle *v)
/* 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));
}