| Old revision #ppqwyyw9s | New revision #pbcgoaplf | ||
|---|---|---|---|
| 1 | Index: src/pathfinder/npf/npf.cpp | ||
| 2 | =================================================================== | ||
| 3 | --- src/pathfinder/npf/npf.cpp (revision 27833) | ||
| 4 | +++ src/pathfinder/npf/npf.cpp (working copy) | ||
| 5 | @@ -536,8 +536,13 @@ | ||
| 6 | AyStarUserData *user = (AyStarUserData *)as->user_data; | ||
| 7 | /* It's not worth caching the result with NPF_FLAG_IS_TARGET here as below, | ||
| 8 | * since checking the cache not that much faster than the actual check */ | ||
| 9 | - return IsDepotTypeTile(current->path.node.tile, user->type) ? | ||
| 10 | - AYSTAR_FOUND_END_NODE : AYSTAR_DONE; | ||
| 11 | + if (user->type != TRANSPORT_WATER) { | ||
| 12 | + return IsDepotTypeTile(current->path.node.tile, user->type) ? | ||
| 13 | + AYSTAR_FOUND_END_NODE : AYSTAR_DONE; | ||
| 14 | + } else { | ||
| 15 | + return IsShipDepotTile(current->path.node.tile) && GetShipDepotPart(current->path.node.tile) == DEPOT_PART_NORTH && IsTileOwner(current->path.node.tile, user->owner) ? | ||
| 16 | + AYSTAR_FOUND_END_NODE : AYSTAR_DONE; | ||
| 17 | + } | ||
| 18 | } | ||
| 19 | |||
| 20 | /** Find any safe and free tile. */ | ||
| 21 | @@ -1161,6 +1166,24 @@ | ||
| 22 | |||
| 23 | /*** Ships ***/ | ||
| 24 | |||
| 25 | +FindDepotData NPFShipFindNearestDepot(const Ship *v, int max_distance) | ||
| 26 | +{ | ||
| 27 | + Trackdir trackdir = v->GetVehicleTrackdir(); | ||
| 28 | + Trackdir trackdir_rev = ReverseTrackdir(trackdir); | ||
| 29 | + NPFFindStationOrTileData fstd; | ||
| 30 | + fstd.v = v; | ||
| 31 | + fstd.reserve_path = false; | ||
| 32 | + | ||
| 33 | + assert(trackdir != INVALID_TRACKDIR); | ||
| 34 | + AyStarUserData user = { v->owner, TRANSPORT_WATER, INVALID_RAILTYPES, ROADTYPES_NONE }; | ||
| 35 | + NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, v->tile, trackdir_rev, false, &fstd, &user, NPF_INFINITE_PENALTY); | ||
| 36 | + if (ftd.best_bird_dist != 0) return FindDepotData(); | ||
| 37 | + | ||
| 38 | + /* Found target */ | ||
| 39 | + /* Our caller wants the distance to depot. We provide it in distance manhattan */ | ||
| 40 | + return FindDepotData(ftd.node.tile, DistanceManhattan(v->tile, ftd.node.tile), NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)); | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | Track NPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found) | ||
| 44 | { | ||
| 45 | NPFFindStationOrTileData fstd; | ||
| 46 | Index: src/pathfinder/npf/npf_func.h | ||
| 47 | =================================================================== | ||
| 48 | --- src/pathfinder/npf/npf_func.h (revision 27833) | ||
| 49 | +++ src/pathfinder/npf/npf_func.h (working copy) | ||
| 50 | @@ -39,6 +39,14 @@ | ||
| 51 | Trackdir NPFRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found); | ||
| 52 | |||
| 53 | /** | ||
| 54 | + * Used when user sends ship to the nearest depot or if ship needs servicing using NPF | ||
| 55 | + * @param v ship that needs to go to some depot | ||
| 56 | + * @param max_distance not used | ||
| 57 | + * @return the data about the depot | ||
| 58 | + */ | ||
| 59 | +FindDepotData NPFShipFindNearestDepot(const Ship *v, int max_distance); | ||
| 60 | + | ||
| 61 | +/** | ||
| 62 | * Finds the best path for given ship using NPF. | ||
| 63 | * @param v the ship that needs to find a path | ||
| 64 | * @param tile the tile to find the path from (should be next tile the ship is about to enter) | ||
| 65 | Index: src/pathfinder/opf/opf_ship.cpp | ||
| 66 | =================================================================== | ||
| 67 | --- src/pathfinder/opf/opf_ship.cpp (revision 27833) | ||
| 68 | +++ src/pathfinder/opf/opf_ship.cpp (working copy) | ||
| 69 | @@ -14,6 +14,7 @@ | ||
| 70 | #include "../../tunnelbridge.h" | ||
| 71 | #include "../../ship.h" | ||
| 72 | #include "../../core/random_func.hpp" | ||
| 73 | +#include "../pathfinder_type.h" | ||
| 74 | |||
| 75 | #include "../../safeguards.h" | ||
| 76 | |||
| 77 | @@ -212,3 +213,8 @@ | ||
| 78 | if (dist <= distr) return track; | ||
| 79 | return INVALID_TRACK; // We could better reverse | ||
| 80 | } | ||
| 81 | + | ||
| 82 | +FindDepotData OPFShipFindNearestDepot(const Ship *v, int max_distance) // todo | ||
| 83 | +{ | ||
| 84 | + return FindDepotData(); | ||
| 85 | +} | ||
| 86 | Index: src/pathfinder/opf/opf_ship.h | ||
| 87 | =================================================================== | ||
| 88 | --- src/pathfinder/opf/opf_ship.h (revision 27833) | ||
| 89 | +++ src/pathfinder/opf/opf_ship.h (working copy) | ||
| 90 | @@ -28,4 +28,13 @@ | ||
| 91 | */ | ||
| 92 | Track OPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found); | ||
| 93 | |||
| 94 | +/** | ||
| 95 | + * Used when user sends ship to the nearest depot or if ship needs servicing using OPF. | ||
| 96 | + * @todo this is just a placeholder, it's currently not implemented | ||
| 97 | + * @param v vehicle that needs to go to some depot | ||
| 98 | + * @param max_distance not used | ||
| 99 | + * @return the data about the depot | ||
| 100 | + */ | ||
| 101 | +FindDepotData OPFShipFindNearestDepot(const Ship *v, int max_distance); | ||
| 102 | + | ||
| 103 | #endif /* OPF_SHIP_H */ | ||
| 1 | Index: src/pathfinder/yapf/yapf.h | 104 | Index: src/pathfinder/yapf/yapf.h |
| 2 | =================================================================== | 105 | =================================================================== |
| 3 | --- src/pathfinder/yapf/yapf.h (revision 278 | 3 | --- src/pathfinder/yapf/yapf.h (revision 27833) |
| 4 | +++ src/pathfinder/yapf/yapf.h (working copy) | 107 | +++ src/pathfinder/yapf/yapf.h (working copy) |
| 5 | @@ -97,4 +97,1 | 5 | @@ -97,4 +97,12 @@ |
| 6 | */ | 109 | */ |
| 7 | bool YapfTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir td, bool override_railtype); | 110 | bool YapfTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir td, bool override_railtype); |
| 8 | 111 | ||
| 9 | +/** | 112 | +/** |
| 10 | + * Used when user sends ship to the nearest depot or if ship needs servicing using YAPF. | 113 | + * Used when user sends ship to the nearest depot or if ship needs servicing using YAPF. |
| 11 | + * @param v vehicle that needs to go to some depot | 114 | + * @param v vehicle that needs to go to some depot |
| 12 | + * @param max_distance max distance (in pathfinder penalty) from the current vehicle position | 12 | + * @param max_distance not used |
| 13 | + * (used also as optimization - the pathfinder can stop path finding if max_penalty | ||
| 14 | + * was reached and no depot was seen) | ||
| 15 | + * @return the data about the depot | 116 | + * @return the data about the depot |
| 16 | + */ | 117 | + */ |
| 17 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance); | 118 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance); |
| 18 | + | 119 | + |
| 19 | #endif /* YAPF_H */ | 120 | #endif /* YAPF_H */ |
| 20 | |||
| 21 | |||
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | |||
| 26 | |||
| 27 | |||
| 28 | |||
| 29 | |||
| 30 | |||
| 31 | |||
| 32 | |||
| 33 | |||
| 34 | |||
| 35 | |||
| 36 | |||
| 37 | |||
| 38 | |||
| 39 | |||
| 40 | |||
| 41 | |||
| 42 | |||
| 43 | |||
| 44 | |||
| 45 | |||
| 46 | Index: src/pathfinder/yapf/yapf_ship.cpp | 121 | Index: src/pathfinder/yapf/yapf_ship.cpp |
| 47 | =================================================================== | 122 | =================================================================== |
| 48 | --- src/pathfinder/yapf/yapf_ship.cpp (revision 278 | 48 | --- src/pathfinder/yapf/yapf_ship.cpp (revision 27833) |
| 49 | +++ src/pathfinder/yapf/yapf_ship.cpp (working copy) | 124 | +++ src/pathfinder/yapf/yapf_ship.cpp (working copy) |
| 50 | @@ -139,6 +139, | 50 | @@ -139,6 +139,48 @@ |
| 51 | assert(best_trackdir == td1 || best_trackdir == td2); | 126 | assert(best_trackdir == td1 || best_trackdir == td2); |
| 52 | return best_trackdir == td2; | 127 | return best_trackdir == td2; |
| 53 | } | 128 | } |
| 129 | + | ||
| 130 | + static bool stFindNearestDepot(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2, TileIndex *depot_tile, bool *reversed) | ||
| 131 | + { | ||
| 132 | + Tpf pf; | ||
| 133 | + bool result = pf.FindNearestDepot(v, tile, td1, td2, depot_tile, reversed); | ||
| 134 | + return result; | ||
| 135 | + } | ||
| 54 | + | 136 | + |
| 55 | + /** | 137 | + /** |
| 56 | + * Find the best depot for a ship. | 138 | + * Find the best depot for a ship. |
| 57 | + * @param v Vehicle | 139 | + * @param v Vehicle |
| 58 | + * @param tile Tile of the vehicle. | 140 | + * @param tile Tile of the vehicle. |
| 59 | + * @param td Trackdir of the vehicle. | 59 | + * @param td1 Trackdir of the vehicle. |
| 60 | + * @param max_distance max length (penalty) for paths. | 60 | + * @param td2 reversed Trackdir of the vehicle. |
| 61 | + * @todo max_distance not used by YAPF for ships. | 61 | + * @param depot_tile the tile of the depot. |
| 62 | + * It can be removed or copy the SetMaxCost() strategy | 62 | + * @param reversed whether the path to depot was found on reversed Trackdir. |
| 63 | + * applied in YAPF for rail. The best depot can be at | ||
| 64 | + * a distance greater than max_distance. | ||
| 65 | + */ | 145 | + */ |
| 66 | + | 66 | + inline bool FindNearestDepot(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2, TileIndex *depot_tile, bool *reversed) |
| 67 | + { | 147 | + { |
| 68 | + Tpf pf; | 148 | + Tpf pf; |
| 69 | + /* Set origin. */ | 149 | + /* Set origin. */ |
| 70 | + pf.SetOrigin(tile, TrackdirToTrackdirBits(td)); | 150 | + pf.SetOrigin(tile, TrackdirToTrackdirBits(td1) | TrackdirToTrackdirBits(td2)); |
| 71 | + | 151 | + |
| 72 | + /* Find the best path and return if no depot is found. */ | 152 | + /* find the best path */ |
| 73 | + if (!pf.FindPath(v)) return FindDepotData(); | 153 | + bool bFound = pf.FindPath(v); |
| 74 | + | 154 | + if (!bFound) return false; |
| 75 | + /* Return the cost of the best path and its depot. */ | 155 | + |
| 156 | + /* some path found | ||
| 157 | + * get found depot tile */ | ||
| 76 | + Node *n = pf.GetBestNode(); | 158 | + Node *n = pf.GetBestNode(); |
| 77 | + return FindDepotData(n->m_segment_last_tile, n->m_cost); | 159 | + *depot_tile = n->m_key.m_tile; |
| 160 | + | ||
| 161 | + /* walk through the path back to the origin */ | ||
| 162 | + Node *pNode = n; | ||
| 163 | + while (pNode->m_parent != NULL) { | ||
| 164 | + pNode = pNode->m_parent; | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + /* if the origin node is the ship's Trackdir then we didn't reverse */ | ||
| 168 | + *reversed = (pNode->m_key.m_td != td1); | ||
| 169 | + return true; | ||
| 78 | + } | 170 | + } |
| 79 | }; | 171 | }; |
| 80 | 172 | ||
| 81 | /** Cost Provider module of YAPF for ships */ | 173 | /** Cost Provider module of YAPF for ships */ |
| 82 | @@ -188,15 +2 | 82 | @@ -188,15 +230,54 @@ |
| 83 | } | 175 | } |
| 84 | }; | 176 | }; |
| 85 | 177 | … | … |
| 101 | + /** Called by YAPF to detect if node ends in the desired destination */ | 193 | + /** Called by YAPF to detect if node ends in the desired destination */ |
| 102 | + inline bool PfDetectDestination(Node &n) | 194 | + inline bool PfDetectDestination(Node &n) |
| 103 | + { | 195 | + { |
| 104 | + bool bDest = IsShipDepotTile(n.m_segment_last_tile); | 196 | + |
| 197 | + bool bDest = (IsShipDepotTile(n.m_key.m_tile) && GetShipDepotPart(n.m_key.m_tile) == DEPOT_PART_NORTH) && IsTileOwner(n.m_key.m_tile, Yapf().GetVehicle()->owner); | ||
| 105 | + return bDest; | 198 | + return bDest; |
| 106 | + } | 199 | + } |
| 107 | + | 200 | + |
| 108 | + inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir) | 201 | + inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir) |
| 109 | + { | 202 | + { |
| 110 | + return | 110 | + return (IsShipDepotTile(n.m_key.m_tile) && GetShipDepotPart(n.m_key.m_tile) == DEPOT_PART_NORTH) && IsTileOwner(n.m_key.m_tile, Yapf().GetVehicle()->owner); |
| 111 | + } | 204 | + } |
| 112 | + | 205 | + |
| 113 | + /** | 206 | + /** | … | … |
| 135 | 228 | ||
| 136 | /** Tpf - pathfinder type */ | 229 | /** Tpf - pathfinder type */ |
| 137 | typedef Tpf_ Tpf; | 230 | typedef Tpf_ Tpf; |
| 138 | @@ -215,12 +2 | 138 | @@ -215,12 +296,16 @@ |
| 139 | }; | 232 | }; |
| 140 | 233 | ||
| 141 | /* YAPF type 1 - uses TileIndex/Trackdir as Node key, allows 90-deg turns */ | 234 | /* YAPF type 1 - uses TileIndex/Trackdir as Node key, allows 90-deg turns */ |
| 142 | -struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1, CFollowTrackWater , CShipNodeListTrackDir> > {}; | 235 | -struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1, CFollowTrackWater , CShipNodeListTrackDir> > {}; |
| 143 | +struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1 , CFollowTrackWater , CShipNodeListTrackDir, CYapfDestinationTileT | 143 | +struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1 , CFollowTrackWater , CShipNodeListTrackDir, CYapfDestinationTileT> > {}; |
| 144 | /* YAPF type 2 - uses TileIndex/DiagDirection as Node key, allows 90-deg turns */ | 237 | /* YAPF type 2 - uses TileIndex/DiagDirection as Node key, allows 90-deg turns */ |
| 145 | -struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2, CFollowTrackWater , CShipNodeListExitDir > > {}; | 238 | -struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2, CFollowTrackWater , CShipNodeListExitDir > > {}; |
| 146 | +struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2 , CFollowTrackWater , CShipNodeListExitDir , CYapfDestinationTileT | 146 | +struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2 , CFollowTrackWater , CShipNodeListExitDir , CYapfDestinationTileT> > {}; |
| 147 | /* YAPF type 3 - uses TileIndex/Trackdir as Node key, forbids 90-deg turns */ | 240 | /* YAPF type 3 - uses TileIndex/Trackdir as Node key, forbids 90-deg turns */ |
| 148 | -struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3, CFollowTrackWaterNo90, CShipNodeListTrackDir> > {}; | 241 | -struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3, CFollowTrackWaterNo90, CShipNodeListTrackDir> > {}; |
| 149 | +struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3 , CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationTileT | 149 | +struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3 , CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationTileT> > {}; |
| 150 |
| 150 | |
| 151 | +struct CYapfShipAnyDepot1 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot1, CFollowTrackWater , CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT | 151 | +struct CYapfShipAnyDepot1 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot1, CFollowTrackWater , CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT> > {}; |
| 152 | +struct CYapfShipAnyDepot2 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot2, CFollowTrackWater , CShipNodeListExitDir , CYapfDestinationAnyDepotShipT | 152 | +struct CYapfShipAnyDepot2 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot2, CFollowTrackWater , CShipNodeListExitDir , CYapfDestinationAnyDepotShipT> > {}; |
| 153 | +struct CYapfShipAnyDepot3 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot3, CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT | 153 | +struct CYapfShipAnyDepot3 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot3, CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT> > {}; |
| 154 | + | 247 | + |
| 155 | /** Ship controller helper - path finder invoker */ | 248 | /** Ship controller helper - path finder invoker */ |
| 156 | Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found) | 249 | Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found) |
| 157 | { | 250 | { |
| 158 | @@ -239,6 +3 | 158 | @@ -239,6 +324,31 @@ |
| 159 | return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK; | 252 | return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK; |
| 160 | } | 253 | } |
| 161 | 254 | ||
| 162 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance) | 255 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance) |
| 163 | +{ | 256 | +{ |
| 257 | + FindDepotData fdd; | ||
| 258 | + | ||
| 259 | + Trackdir td = v->GetVehicleTrackdir(); | ||
| 260 | + Trackdir td_rev = ReverseTrackdir(td); | ||
| 164 | + TileIndex tile = v->tile; | 261 | + TileIndex tile = v->tile; |
| 165 | + Trackdir trackdir = v->GetVehicleTrackdir(); | 165 | + |
| 166 | + if ((TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0)) & TrackdirToTrackdirBits(trackdir)) == 0) { | ||
| 167 | + return FindDepotData(); | ||
| 168 | + } | ||
| 169 | + /* default is YAPF type 2 */ | 263 | + /* default is YAPF type 2 */ |
| 170 | + typedef | 170 | + typedef bool(*PfnFindNearestDepot)(const Ship*, TileIndex, Trackdir, Trackdir, TileIndex*, bool*); |
| 171 | + PfnFindNearestDepot pfnFindNearestDepot = &CYapfShipAnyDepot2:: | 171 | + PfnFindNearestDepot pfnFindNearestDepot = &CYapfShipAnyDepot2::stFindNearestDepot; |
| 172 | + | 266 | + |
| 173 | + /* check if non-default YAPF type should be used */ | 267 | + /* check if non-default YAPF type should be used */ |
| 174 | + if (_settings_game.pf.forbid_90_deg) { | 268 | + if (_settings_game.pf.forbid_90_deg) { |
| 175 | + pfnFindNearestDepot = &CYapfShipAnyDepot3:: | 175 | + pfnFindNearestDepot = &CYapfShipAnyDepot3::stFindNearestDepot; // Trackdir, forbid 90-deg |
| 176 | + } else if (_settings_game.pf.yapf.disable_node_optimization) { | 270 | + } else if (_settings_game.pf.yapf.disable_node_optimization) { |
| 177 | + pfnFindNearestDepot = &CYapfShipAnyDepot1::FindNearestDepot; // Trackdir, allow 90-deg | 271 | + pfnFindNearestDepot = &CYapfShipAnyDepot1::stFindNearestDepot; // Trackdir, allow 90-deg |
| 178 | + } | 272 | + } |
| 179 | + | 273 | + |
| 180 | + return pfnFindNearestDepot(v, tile, trackdir, max_distance); | 274 | + bool ret = pfnFindNearestDepot(v, tile, td, td_rev, &fdd.tile, &fdd.reverse); |
| 275 | + | ||
| 276 | + fdd.best_length = ret ? DistanceManhattan(tile, fdd.tile) : UINT_MAX; // distance manhattan or NOT_FOUND | ||
| 277 | + return fdd; | ||
| 181 | +} | 278 | +} |
| 182 | + | 279 | + |
| 183 | bool YapfShipCheckReverse(const Ship *v) | 280 | bool YapfShipCheckReverse(const Ship *v) | … | … |
| 185 | Trackdir td = v->GetVehicleTrackdir(); | 282 | Trackdir td = v->GetVehicleTrackdir(); |
| 186 | Index: src/ship_cmd.cpp | 283 | Index: src/ship_cmd.cpp |
| 187 | =================================================================== | 284 | =================================================================== |
| 188 | --- src/ship_cmd.cpp (revision 278 | 188 | --- src/ship_cmd.cpp (revision 27833) |
| 189 | +++ src/ship_cmd.cpp (working copy) | 286 | +++ src/ship_cmd.cpp (working copy) |
| 190 | @@ -138, | 190 | @@ -138,7 +138,7 @@ |
| 191 | result->Set(_ship_sprites[spritenum] + direction); | 288 | result->Set(_ship_sprites[spritenum] + direction); |
| 192 | } | 289 | } |
| 193 | 290 | ||
| 194 | -static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance) | 291 | -static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance) |
| 292 | +static FindDepotData FindClosestShipDepot(const Ship *v, uint max_distance) | ||
| 293 | { | ||
| 294 | /* Find the closest depot */ | ||
| 295 | const Depot *depot; | ||
| 296 | @@ -161,9 +161,27 @@ | ||
| 297 | } | ||
| 298 | } | ||
| 299 | |||
| 300 | - return best_depot; | ||
| 301 | + FindDepotData fdd; | ||
| 302 | + if (best_depot != NULL) { | ||
| 303 | + fdd.best_length = best_dist; | ||
| 304 | + fdd.tile = best_depot->xy; | ||
| 305 | + } | ||
| 306 | + return fdd; | ||
| 307 | } | ||
| 308 | |||
| 195 | +static FindDepotData FindClosestReachableShipDepot(const Ship *v, int max_distance) | 309 | +static FindDepotData FindClosestReachableShipDepot(const Ship *v, int max_distance) |
| 196 | { | 196 | +{ |
| 197 | - /* Find the closest depot */ | 197 | + if ((IsShipDepotTile(v->tile) && GetShipDepotPart(v->tile) == DEPOT_PART_NORTH) && IsTileOwner(v->tile, v->owner)) return FindDepotData(v->tile, 0); |
| 198 | - const Depot *depot; | 198 | + |
| 199 | - const Depot *best_depot = NULL; | ||
| 200 | - /* If we don't have a maximum distance, i.e. distance = 0, | ||
| 201 | - * we want to find any depot so the best distance of no | ||
| 202 | - * depot must be more than any correct distance. On the | ||
| 203 | - * other hand if we have set a maximum distance, any depot | ||
| 204 | - * further away than max_distance can safely be ignored. */ | ||
| 205 | - uint best_dist = max_distance == 0 ? UINT_MAX : max_distance + 1; | ||
| 206 | + if (IsShipDepotTile(v->tile)) return FindDepotData(v->tile, 0); | ||
| 207 | |||
| 208 | - FOR_ALL_DEPOTS(depot) { | ||
| 209 | - TileIndex tile = depot->xy; | ||
| 210 | - if (IsShipDepotTile(tile) && IsTileOwner(tile, v->owner)) { | ||
| 211 | - uint dist = DistanceManhattan(tile, v->tile); | ||
| 212 | - if (dist < best_dist) { | ||
| 213 | - best_dist = dist; | ||
| 214 | - best_depot = depot; | ||
| 215 | - } | ||
| 216 | - } | ||
| 217 | + switch (_settings_game.pf.pathfinder_for_ships) { | 313 | + switch (_settings_game.pf.pathfinder_for_ships) { |
| 218 | + | 218 | + case VPF_OPF: return OPFShipFindNearestDepot(v, max_distance); |
| 219 | + | 219 | + case VPF_NPF: return NPFShipFindNearestDepot(v, max_distance); |
| 220 | + case VPF_YAPF: return YapfShipFindNearestDepot(v, max_distance); | 316 | + case VPF_YAPF: return YapfShipFindNearestDepot(v, max_distance); |
| 221 | + | 317 | + |
| 222 | + default: NOT_REACHED(); | 318 | + default: NOT_REACHED(); |
| 223 | } | 223 | + } |
| 224 | - | 224 | +} |
| 225 | - return best_depot; | 225 | + |
| 226 | } | ||
| 227 | |||
| 228 | static void CheckIfShipNeedsService(Vehicle *v) | 322 | static void CheckIfShipNeedsService(Vehicle *v) |
| 229 | @@ -180,9 +167,9 @@ | 323 | { |
| 324 | if (Company::Get(v->owner)->settings.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return; | ||
| 325 | @@ -180,9 +198,9 @@ | ||
| 230 | default: NOT_REACHED(); | 326 | default: NOT_REACHED(); |
| 231 | } | 327 | } |
| 232 | 328 | ||
| 233 | - const Depot *depot = FindClosestShipDepot(v, max_distance); | 329 | - const Depot *depot = FindClosestShipDepot(v, max_distance); |
| 234 | + const FindDepotData | 234 | + const FindDepotData sfdd = FindClosestReachableShipDepot(Ship::From(v), max_distance); |
| 235 | 331 | ||
| 236 | - if (depot == NULL) { | 332 | - if (depot == NULL) { |
| 237 | + if ( | 237 | + if (sfdd.best_length == UINT_MAX || sfdd.best_length >= max_distance) { |
| 238 | if (v->current_order.IsType(OT_GOTO_DEPOT)) { | 334 | if (v->current_order.IsType(OT_GOTO_DEPOT)) { |
| 239 | v->current_order.MakeDummy(); | 335 | v->current_order.MakeDummy(); |
| 240 | SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); | 336 | SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); |
| 241 | @@ -190,8 + | 241 | @@ -190,8 +208,8 @@ |
| 242 | return; | 338 | return; |
| 243 | } | 339 | } |
| 244 | 340 | ||
| 245 | - v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE); | 341 | - v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE); |
| 246 | - v->dest_tile = depot->xy; | 342 | - v->dest_tile = depot->xy; |
| 247 | + v->current_order.MakeGoToDepot(GetDepotIndex( | 247 | + v->current_order.MakeGoToDepot(GetDepotIndex(sfdd.tile), ODTFB_SERVICE); |
| 248 | + v->dest_tile = | 248 | + v->dest_tile = sfdd.tile; |
| 249 | SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); | 345 | SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); |
| 250 | } | 346 | } |
| 251 | 347 | ||
| 252 | @@ -712,12 + | 252 | @@ -712,12 +730,15 @@ |
| 253 | 349 | ||
| 254 | bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) | 350 | bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) |
| 255 | { | 351 | { |
| 256 | - const Depot *depot = FindClosestShipDepot(this, 0); | 352 | - const Depot *depot = FindClosestShipDepot(this, 0); |
| 257 | + FindDepotData rfdd = FindClosestReachableShipDepot(this, 0); | 353 | + FindDepotData sfdd = FindClosestReachableShipDepot(this, 0); |
| 258 | + if (rfdd.best_length == UINT_MAX) return false; | 354 | + if (sfdd.best_length == UINT_MAX) { |
| 355 | + sfdd = FindClosestShipDepot(this, 0); | ||
| 356 | + if (sfdd.best_length == UINT_MAX) return false; | ||
| 357 | + } | ||
| 259 | 358 | ||
| 260 | - if (depot == NULL) return false; | 359 | - if (depot == NULL) return false; |
| 261 | + if (location != NULL) *location = rfdd.tile; | 360 | + if (location != NULL) *location = sfdd.tile; |
| 262 | + if (destination != NULL) *destination = GetDepotIndex(rfdd.tile); | 361 | + if (destination != NULL) *destination = GetDepotIndex(sfdd.tile); |
| 362 | + if (reverse != NULL) *reverse = sfdd.reverse; | ||
| 263 | 363 | ||
| 264 | - if (location != NULL) *location = depot->xy; | 364 | - if (location != NULL) *location = depot->xy; |
| 265 | - if (destination != NULL) *destination = depot->index; | 365 | - if (destination != NULL) *destination = depot->index; |