diff options
-rw-r--r-- | src/roadveh_cmd.cpp | 212 | ||||
-rw-r--r-- | src/ship_cmd.cpp | 126 | ||||
-rw-r--r-- | src/train_cmd.cpp | 319 |
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)); } |