diff options
author | rubidium <rubidium@openttd.org> | 2009-12-02 09:57:17 +0000 |
---|---|---|
committer | rubidium <rubidium@openttd.org> | 2009-12-02 09:57:17 +0000 |
commit | 9165c195b9609bb9db77cc23ff424802eb4ab128 (patch) | |
tree | 1a8b2370e076ace6dd5b6087e94d37bf3a5e2f78 | |
parent | ef8cc49175ae8f97c6659c3acd13fdb4434cd535 (diff) | |
download | openttd-9165c195b9609bb9db77cc23ff424802eb4ab128.tar.xz |
(svn r18371) -Codechange: unify calling of the train pathfinders
-rw-r--r-- | src/pathfinder/npf/npf.cpp | 120 | ||||
-rw-r--r-- | src/pathfinder/npf/npf.h | 9 | ||||
-rw-r--r-- | src/pathfinder/npf/npf_func.h | 45 | ||||
-rw-r--r-- | src/pathfinder/pathfinder_type.h | 35 | ||||
-rw-r--r-- | src/pathfinder/yapf/yapf.h | 44 | ||||
-rw-r--r-- | src/pathfinder/yapf/yapf_rail.cpp | 22 | ||||
-rw-r--r-- | src/train_cmd.cpp | 171 |
7 files changed, 241 insertions, 205 deletions
diff --git a/src/pathfinder/npf/npf.cpp b/src/pathfinder/npf/npf.cpp index 13410a0f5..f50106fb2 100644 --- a/src/pathfinder/npf/npf.cpp +++ b/src/pathfinder/npf/npf.cpp @@ -21,6 +21,7 @@ #include "../../train.h" #include "../../ship.h" #include "../pathfinder_func.h" +#include "../pathfinder_type.h" #include "npf.h" static AyStar _npf_aystar; @@ -1059,30 +1060,6 @@ NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, return best_result; } -NPFFoundTargetData NPFRouteToSafeTile(const Train *v, TileIndex tile, Trackdir trackdir, bool override_railtype) -{ - assert(v->type == VEH_TRAIN); - - NPFFindStationOrTileData fstd; - fstd.v = v; - fstd.reserve_path = true; - - AyStarNode start1; - start1.tile = tile; - /* We set this in case the target is also the start tile, we will just - * return a not found then */ - start1.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR; - start1.direction = trackdir; - NPFSetFlag(&start1, NPF_FLAG_IGNORE_RESERVED, true); - - RailTypes railtypes = v->compatible_railtypes; - if (override_railtype) railtypes |= GetRailTypeInfo(v->railtype)->compatible_railtypes; - - /* perform a breadth first search. Target is NULL, - * since we are just looking for any safe tile...*/ - return NPFRouteInternal(&start1, true, NULL, false, &fstd, NPFFindSafeTile, NPFCalcZero, TRANSPORT_RAIL, 0, v->owner, railtypes, 0); -} - void InitializeNPF() { static bool first_init = true; @@ -1139,3 +1116,98 @@ Track NPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, if (ftd.best_trackdir == 0xff) return INVALID_TRACK; return TrackdirToTrack(ftd.best_trackdir); } + +/*** Trains ***/ + +FindDepotData NPFTrainFindNearestDepot(const Train *v, int max_distance) +{ + const Train *last = v->Last(); + Trackdir trackdir = v->GetVehicleTrackdir(); + Trackdir trackdir_rev = ReverseTrackdir(last->GetVehicleTrackdir()); + + assert(trackdir != INVALID_TRACKDIR); + NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, TRANSPORT_RAIL, 0, v->owner, v->compatible_railtypes, NPF_INFINITE_PENALTY); + if (ftd.best_bird_dist != 0) FindDepotData(); + + /* Found target */ + /* 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. */ + return FindDepotData(ftd.node.tile, ftd.best_path_dist / NPF_TILE_LENGTH, NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)); +} + +bool NPFTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir trackdir, bool override_railtype) +{ + assert(v->type == VEH_TRAIN); + + NPFFindStationOrTileData fstd; + fstd.v = v; + fstd.reserve_path = true; + + AyStarNode start1; + start1.tile = tile; + /* We set this in case the target is also the start tile, we will just + * return a not found then */ + start1.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR; + start1.direction = trackdir; + NPFSetFlag(&start1, NPF_FLAG_IGNORE_RESERVED, true); + + RailTypes railtypes = v->compatible_railtypes; + if (override_railtype) railtypes |= GetRailTypeInfo(v->railtype)->compatible_railtypes; + + /* perform a breadth first search. Target is NULL, + * since we are just looking for any safe tile...*/ + return NPFRouteInternal(&start1, true, NULL, false, &fstd, NPFFindSafeTile, NPFCalcZero, TRANSPORT_RAIL, 0, v->owner, railtypes, 0).res_okay; +} + +bool NPFTrainCheckReverse(const Train *v) +{ + NPFFindStationOrTileData fstd; + NPFFoundTargetData ftd; + const Train *last = v->Last(); + + NPFFillWithOrderData(&fstd, v); + + Trackdir trackdir = v->GetVehicleTrackdir(); + Trackdir trackdir_rev = ReverseTrackdir(last->GetVehicleTrackdir()); + 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->compatible_railtypes); + /* If we didn't find anything, just keep on going straight ahead, otherwise take the reverse flag */ + return ftd.best_bird_dist != 0 && NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE); +} + +Track NPFTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool *path_not_found, bool reserve_track, struct PBSTileInfo *target) +{ + NPFFindStationOrTileData fstd; + NPFFillWithOrderData(&fstd, v, reserve_track); + + PBSTileInfo origin = FollowTrainReservation(v); + assert(IsValidTrackdir(origin.trackdir)); + + NPFFoundTargetData ftd = NPFRouteToStationOrTile(origin.tile, origin.trackdir, true, &fstd, TRANSPORT_RAIL, 0, v->owner, v->compatible_railtypes); + + if (target != NULL) { + target->tile = ftd.node.tile; + target->trackdir = (Trackdir)ftd.node.direction; + target->okay = ftd.res_okay; + } + + 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? */ + if (path_not_found) *path_not_found = false; + return FindFirstTrack(tracks); + } + + /* 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 (path_not_found != NULL) *path_not_found = (ftd.best_bird_dist != 0); + /* Discard enterdir information, making it a normal track */ + return TrackdirToTrack(ftd.best_trackdir); +} diff --git a/src/pathfinder/npf/npf.h b/src/pathfinder/npf/npf.h index fcd75db4d..fb10c07ec 100644 --- a/src/pathfinder/npf/npf.h +++ b/src/pathfinder/npf/npf.h @@ -38,7 +38,8 @@ enum { }; enum { - /** This penalty is the equivalent of "inifite", which means that paths that + /** + * This penalty is the equivalent of "infite", which means that paths that * get this penalty will be chosen, but only if there is no other route * without it. Be careful with not applying this penalty to often, or the * total path cost might overflow.. @@ -119,12 +120,6 @@ NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir t * of choices and accurate heuristics, such as water. */ NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, bool ignore_start_tile, TransportType type, uint sub_type, Owner owner, RailTypes railtypes); -/** - * Search for any safe tile using a breadth first search and try to reserve a path. - */ -NPFFoundTargetData NPFRouteToSafeTile(const struct Train *v, TileIndex tile, Trackdir trackdir, bool override_railtype); - - void NPFFillWithOrderData(NPFFindStationOrTileData *fstd, const Vehicle *v, bool reserve_path = false); diff --git a/src/pathfinder/npf/npf_func.h b/src/pathfinder/npf/npf_func.h index ef3b1001c..027e8c794 100644 --- a/src/pathfinder/npf/npf_func.h +++ b/src/pathfinder/npf/npf_func.h @@ -12,6 +12,10 @@ #ifndef NPF_FUNC_H #define NPF_FUNC_H +#include "../../track_type.h" +#include "../../direction_type.h" +#include "../pathfinder_type.h" + /** * Finds the best path for given ship using NPF. * @param v the ship that needs to find a path @@ -22,4 +26,45 @@ */ Track NPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks); +/** + * Used when user sends train to the nearest depot or if train needs servicing using NPF + * @param v train that needs to go to some depot + * @param max_distance max distance (number of track tiles) from the current train position + * (used also as optimization - the pathfinder can stop path finding if max_distance + * was reached and no depot was seen) + * @return the data about the depot + */ +FindDepotData NPFTrainFindNearestDepot(const Train *v, int max_distance); + +/** + * Try to extend the reserved path of a train to the nearest safe tile using NPF. + * + * @param v The train that needs to find a safe tile. + * @param tile Last tile of the current reserved path. + * @param td Last trackdir of the current reserved path. + * @param override_railtype Should all physically compatible railtypes be searched, even if the vehicle can't run on them on its own? + * @return True if the path could be extended to a safe tile. + */ +bool NPFTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir td, bool override_railtype); + +/** + * Returns true if it is better to reverse the train before leaving station using NPF. + * @param v the train leaving the station + * @return true if reversing is better + */ +bool NPFTrainCheckReverse(const Train *v); + +/** + * Finds the best path for given train using NPF. + * @param v the train that needs to find a path + * @param tile the tile to find the path from (should be next tile the train is about to enter) + * @param enterdir diagonal direction which the RV will enter this new tile from + * @param tracks available trackdirs on the new tile (to choose from) + * @param path_not_found [out] true is returned if no path can be found (returned Trackdir is only a 'guess') + * @param reserve_track indicates whether YAPF should try to reserve the found path + * @param target [out] the target tile of the reservation, free is set to true if path was reserved + * @return the best track for next turn + */ +Track NPFTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool *path_not_found, bool reserve_track, struct PBSTileInfo *target); + #endif /* NPF_FUNC_H */ diff --git a/src/pathfinder/pathfinder_type.h b/src/pathfinder/pathfinder_type.h new file mode 100644 index 000000000..95daf533e --- /dev/null +++ b/src/pathfinder/pathfinder_type.h @@ -0,0 +1,35 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>. + */ + +/** @file pathfinder_type.h General types related to pathfinders. */ + +#ifndef PATHFINDER_TYPE_H +#define PATHFINDER_TYPE_H + +/** + * Helper container to find a depot + */ +struct FindDepotData { + TileIndex tile; ///< The tile of the depot + uint best_length; ///< The distance towards the depot, or UINT_MAX if not found + bool reverse; ///< True if reversing is necessary for the train to get to this depot + + /** + * Create an instance of this structure. + * @param tile the tile of the depot + * @param best_length the distance towards the depot, or UINT_MAX if not found + * @param reverse whether we need to reverse first. + */ + FindDepotData(TileIndex tile = INVALID_TILE, uint best_length = UINT_MAX, bool reverse = false) : + tile(tile), best_length(best_length), reverse(reverse) + { + } +}; + +#endif /* PATHFINDER_TYPE_H */ diff --git a/src/pathfinder/yapf/yapf.h b/src/pathfinder/yapf/yapf.h index 2f39cd6c5..bfb442a2a 100644 --- a/src/pathfinder/yapf/yapf.h +++ b/src/pathfinder/yapf/yapf.h @@ -14,6 +14,7 @@ #include "../../direction_type.h" #include "../../station_type.h" +#include "../pathfinder_type.h" /** * Finds the best path for given ship using YAPF. @@ -33,7 +34,8 @@ Track YapfChooseShipTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, */ Trackdir YapfChooseRoadTrack(const Vehicle *v, TileIndex tile, DiagDirection enterdir); -/** Finds the best path for given train. +/** + * Finds the best path for given train using YAPF. * @param v the train that needs to find a path * @param tile the tile to find the path from (should be next tile the train is about to enter) * @param enterdir diagonal direction which the RV will enter this new tile from @@ -41,9 +43,9 @@ Trackdir YapfChooseRoadTrack(const Vehicle *v, TileIndex tile, DiagDirection ent * @param path_not_found [out] true is returned if no path can be found (returned Trackdir is only a 'guess') * @param reserve_track indicates whether YAPF should try to reserve the found path * @param target [out] the target tile of the reservation, free is set to true if path was reserved - * @return the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found + * @return the best track for next turn */ -Trackdir YapfChooseRailTrack(const Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool *path_not_found, bool reserve_track, struct PBSTileInfo *target); +Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool *path_not_found, bool reserve_track, struct PBSTileInfo *target); /** Used by RV multistop feature to find the nearest road stop that has a free slot. * @param v RV (its current tile will be the origin) @@ -70,31 +72,33 @@ bool YapfFindNearestRoadVehicleCompatibleStop(const RoadVehicle *v, StationID st */ bool YapfFindNearestRoadDepot(const Vehicle *v, int max_distance, TileIndex *depot_tile); -/** Used when user sends train to the nearest depot or if train needs servicing. +/** + * Used when user sends train to the nearest depot or if train needs servicing using YAPF. * @param v train that needs to go to some depot * @param max_distance max distance (number of track tiles) from the current train position * (used also as optimization - the pathfinder can stop path finding if max_distance * was reached and no depot was seen) - * @param reverse_penalty penalty that should be added for the path that requires reversing the train first - * @param depot_tile receives the depot tile if depot was found - * @param reversed receives true if train needs to reversed first - * @return true if depot was found. + * @return the data about the depot */ -bool YapfFindNearestRailDepotTwoWay(const Vehicle *v, int max_distance, int reverse_penalty, TileIndex *depot_tile, bool *reversed); +FindDepotData YapfTrainFindNearestDepot(const Train *v, int max_distance); -/** Returns true if it is better to reverse the train before leaving station */ -bool YapfCheckReverseTrain(const Vehicle *v); +/** + * Returns true if it is better to reverse the train before leaving station using YAPF. + * @param v the train leaving the station + * @return true if reversing is better + */ +bool YapfTrainCheckReverse(const Train *v); /** - * Try to extend the reserved path of a train to the nearest safe tile. + * Try to extend the reserved path of a train to the nearest safe tile using YAPF. * * @param v The train that needs to find a safe tile. * @param tile Last tile of the current reserved path. * @param td Last trackdir of the current reserved path. - * @param override_railtype Should all physically compabtible railtypes be searched, even if the vehicle can't on them on it own? + * @param override_railtype Should all physically compatible railtypes be searched, even if the vehicle can't run on them on its own? * @return True if the path could be extended to a safe tile. */ -bool YapfRailFindNearestSafeTile(const Vehicle *v, TileIndex tile, Trackdir td, bool override_railtype); +bool YapfTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir td, bool override_railtype); /** Use this function to notify YAPF that track layout (or signal configuration) has change */ void YapfNotifyTrackLayoutChange(TileIndex tile, Track track); @@ -111,7 +115,17 @@ extern int _aystar_stats_closed_size; /** Base tile length units */ enum { YAPF_TILE_LENGTH = 100, - YAPF_TILE_CORNER_LENGTH = 71 + YAPF_TILE_CORNER_LENGTH = 71, + + /** + * This penalty is the equivalent of "infite", which means that paths that + * get this penalty will be chosen, but only if there is no other route + * without it. Be careful with not applying this penalty to often, or the + * total path cost might overflow.. + * For now, this is just a Very Big Penalty, we might actually implement + * this in a nicer way :-) + */ + YAPF_INFINITE_PENALTY = 1000 * YAPF_TILE_LENGTH, }; #endif /* YAPF_H */ diff --git a/src/pathfinder/yapf/yapf_rail.cpp b/src/pathfinder/yapf/yapf_rail.cpp index f17b90262..54ea1a916 100644 --- a/src/pathfinder/yapf/yapf_rail.cpp +++ b/src/pathfinder/yapf/yapf_rail.cpp @@ -524,7 +524,7 @@ struct CYapfAnySafeTileRail1 : CYapfT<CYapfRail_TypesT<CYapfAnySafeTileRail1, CF struct CYapfAnySafeTileRail2 : CYapfT<CYapfRail_TypesT<CYapfAnySafeTileRail2, CFollowTrackFreeRailNo90, CRailNodeListTrackDir, CYapfDestinationAnySafeTileRailT , CYapfFollowAnySafeTileRailT> > {}; -Trackdir YapfChooseRailTrack(const Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool *path_not_found, bool reserve_track, PBSTileInfo *target) +Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool *path_not_found, bool reserve_track, PBSTileInfo *target) { /* default is YAPF type 2 */ typedef Trackdir (*PfnChooseRailTrack)(const Vehicle*, TileIndex, DiagDirection, TrackBits, bool*, bool, PBSTileInfo*); @@ -536,13 +536,11 @@ Trackdir YapfChooseRailTrack(const Vehicle *v, TileIndex tile, DiagDirection ent } Trackdir td_ret = pfnChooseRailTrack(v, tile, enterdir, tracks, path_not_found, reserve_track, target); - - return td_ret; + return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : FindFirstTrack(tracks); } -bool YapfCheckReverseTrain(const Vehicle *vt) +bool YapfTrainCheckReverse(const Train *v) { - const Train *v = Train::From(vt); const Train *last_veh = v->Last(); /* get trackdirs of both ends */ @@ -600,12 +598,11 @@ bool YapfCheckReverseTrain(const Vehicle *vt) return reverse; } -bool YapfFindNearestRailDepotTwoWay(const Vehicle *v, int max_distance, int reverse_penalty, TileIndex *depot_tile, bool *reversed) +FindDepotData YapfTrainFindNearestDepot(const Train *v, int max_distance) { - *depot_tile = INVALID_TILE; - *reversed = false; + FindDepotData fdd; - const Vehicle *last_veh = v->Last(); + const Train *last_veh = v->Last(); PBSTileInfo origin = FollowTrainReservation(Train::From(v)); TileIndex last_tile = last_veh->tile; @@ -619,11 +616,12 @@ bool YapfFindNearestRailDepotTwoWay(const Vehicle *v, int max_distance, int reve pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail2::stFindNearestDepotTwoWay; // Trackdir, forbid 90-deg } - bool ret = pfnFindNearestDepotTwoWay(v, origin.tile, origin.trackdir, last_tile, td_rev, max_distance, reverse_penalty, depot_tile, reversed); - return ret; + bool ret = pfnFindNearestDepotTwoWay(v, origin.tile, origin.trackdir, last_tile, td_rev, max_distance, YAPF_INFINITE_PENALTY, &fdd.tile, &fdd.reverse); + fdd.best_length = ret ? max_distance / 2 : UINT_MAX; // some fake distance or NOT_FOUND + return fdd; } -bool YapfRailFindNearestSafeTile(const Vehicle *v, TileIndex tile, Trackdir td, bool override_railtype) +bool YapfTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir td, bool override_railtype) { typedef bool (*PfnFindNearestSafeTile)(const Vehicle*, TileIndex, Trackdir, bool); PfnFindNearestSafeTile pfnFindNearestSafeTile = CYapfAnySafeTileRail1::stFindNearestSafeTile; diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 0ce9685de..e6d67abd1 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -13,7 +13,7 @@ #include "gui.h" #include "articulated_vehicles.h" #include "command_func.h" -#include "pathfinder/npf/npf.h" +#include "pathfinder/npf/npf_func.h" #include "news_func.h" #include "company_func.h" #include "vehicle_gui.h" @@ -2138,77 +2138,28 @@ CommandCost CmdRefitRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, return cost; } -struct TrainFindDepotData { - uint best_length; - TileIndex tile; - Owner owner; - /** - * true if reversing is necessary for the train to get to this depot - * This value is unused when new depot finding and NPF are both disabled - */ - bool reverse; -}; - /** returns the tile of a depot to goto to. The given vehicle must not be * crashed! */ -static TrainFindDepotData FindClosestTrainDepot(Train *v, int max_distance) +static FindDepotData FindClosestTrainDepot(Train *v, int max_distance) { assert(!(v->vehstatus & VS_CRASHED)); - TrainFindDepotData tfdd; - tfdd.owner = v->owner; - tfdd.reverse = false; - - if (IsRailDepotTile(v->tile)) { - tfdd.tile = v->tile; - tfdd.best_length = 0; - return tfdd; - } + if (IsRailDepotTile(v->tile)) return FindDepotData(v->tile, 0); PBSTileInfo origin = FollowTrainReservation(v); - if (IsRailDepotTile(origin.tile)) { - tfdd.tile = origin.tile; - tfdd.best_length = 0; - return tfdd; - } - - tfdd.best_length = UINT_MAX; + if (IsRailDepotTile(origin.tile)) return FindDepotData(origin.tile, 0); switch (_settings_game.pf.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: return NPFTrainFindNearestDepot(v, max_distance); + case VPF_YAPF: return YapfTrainFindNearestDepot(v, max_distance); - case VPF_NPF: { // NPF - const Vehicle *last = v->Last(); - Trackdir trackdir = v->GetVehicleTrackdir(); - Trackdir trackdir_rev = ReverseTrackdir(last->GetVehicleTrackdir()); - - assert(trackdir != INVALID_TRACKDIR); - NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, TRANSPORT_RAIL, 0, v->owner, v->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: - NOT_REACHED(); + default: NOT_REACHED(); } - - return tfdd; } bool Train::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) { - TrainFindDepotData tfdd = FindClosestTrainDepot(this, 0); + FindDepotData tfdd = FindClosestTrainDepot(this, 0); if (tfdd.best_length == UINT_MAX) return false; if (location != NULL) *location = tfdd.tile; @@ -2556,71 +2507,14 @@ static const byte _initial_tile_subcoord[6][4][3] = { * @param dest [out] State and destination of the requested path * @return The best track the train should follow */ -static Track DoTrainPathfind(Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool *path_not_found, bool do_track_reservation, PBSTileInfo *dest) +static Track DoTrainPathfind(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool *path_not_found, bool do_track_reservation, PBSTileInfo *dest) { - Track best_track; - -#ifdef PF_BENCHMARK - TIC() -#endif - - if (path_not_found) *path_not_found = false; - switch (_settings_game.pf.pathfinder_for_trains) { - case VPF_YAPF: { // YAPF - Trackdir trackdir = YapfChooseRailTrack(v, tile, enterdir, tracks, path_not_found, do_track_reservation, dest); - 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, do_track_reservation); + case VPF_NPF: return NPFTrainChooseTrack(v, tile, enterdir, tracks, path_not_found, do_track_reservation, dest); + case VPF_YAPF: return YapfTrainChooseTrack(v, tile, enterdir, tracks, path_not_found, do_track_reservation, dest); - PBSTileInfo origin = FollowTrainReservation(v); - assert(IsValidTrackdir(origin.trackdir)); - - NPFFoundTargetData ftd = NPFRouteToStationOrTile(origin.tile, origin.trackdir, true, &fstd, TRANSPORT_RAIL, 0, v->owner, v->compatible_railtypes); - - if (dest != NULL) { - dest->tile = ftd.node.tile; - dest->trackdir = (Trackdir)ftd.node.direction; - dest->okay = ftd.res_okay; - } - - 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 != NULL) *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: - NOT_REACHED(); + default: NOT_REACHED(); } - -#ifdef PF_BENCHMARK - TOC("PF time = ", 1) -#endif - - return best_track; } /** @@ -2717,15 +2611,16 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, TrackBits *new_tracks, * @param v The vehicle. * @param tile The tile the search should start from. * @param td The trackdir the search should start from. - * @param override_tailtype Whether all physically compatible railtypes should be followed. + * @param override_railtype Whether all physically compatible railtypes should be followed. * @return True if a path to a safe stopping tile could be reserved. */ static bool TryReserveSafeTrack(const Train *v, TileIndex tile, Trackdir td, bool override_tailtype) { - if (_settings_game.pf.pathfinder_for_trains == VPF_YAPF) { - return YapfRailFindNearestSafeTile(v, tile, td, override_tailtype); - } else { - return NPFRouteToSafeTile(v, tile, td, override_tailtype).res_okay; + switch (_settings_game.pf.pathfinder_for_trains) { + case VPF_NPF: return NPFTrainFindNearestSafeTile(v, tile, td, override_tailtype); + case VPF_YAPF: return YapfTrainFindNearestSafeTile(v, tile, td, override_tailtype); + + default: NOT_REACHED(); } } @@ -3069,7 +2964,7 @@ bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay) } -static bool CheckReverseTrain(Train *v) +static bool CheckReverseTrain(const Train *v) { if (_settings_game.difficulty.line_reverse_mode != 0 || v->track == TRACK_BIT_DEPOT || v->track == TRACK_BIT_WORMHOLE || @@ -3077,31 +2972,13 @@ static bool CheckReverseTrain(Train *v) return false; } - assert(v->track); + assert(v->track != TRACK_BIT_NONE); switch (_settings_game.pf.pathfinder_for_trains) { - case VPF_YAPF: // YAPF - return YapfCheckReverseTrain(v); - - case VPF_NPF: { // NPF - NPFFindStationOrTileData fstd; - NPFFoundTargetData ftd; - Vehicle *last = v->Last(); + case VPF_NPF: return NPFTrainCheckReverse(v); + case VPF_YAPF: return YapfTrainCheckReverse(v); - NPFFillWithOrderData(&fstd, v); - - Trackdir trackdir = v->GetVehicleTrackdir(); - Trackdir trackdir_rev = ReverseTrackdir(last->GetVehicleTrackdir()); - 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->compatible_railtypes); - /* If we didn't find anything, just keep on going straight ahead, otherwise take the reverse flag */ - return ftd.best_bird_dist != 0 && NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE); - } break; - - default: - NOT_REACHED(); + default: NOT_REACHED(); } } @@ -4313,7 +4190,7 @@ static void CheckIfTrainNeedsService(Train *v) return; } - TrainFindDepotData tfdd = FindClosestTrainDepot(v, MAX_ACCEPTABLE_DEPOT_DIST); + FindDepotData tfdd = FindClosestTrainDepot(v, MAX_ACCEPTABLE_DEPOT_DIST); /* Only go to the depot if it is not too far out of our way. */ if (tfdd.best_length == UINT_MAX || tfdd.best_length > MAX_ACCEPTABLE_DEPOT_DIST) { if (v->current_order.IsType(OT_GOTO_DEPOT)) { |