Loading

Revision differences

Old revision #phoeeb6paNew revision #pubn57tm0
1Index: src/pathfinder/follow_track.hpp    
2===================================================================    
3--- src/pathfinder/follow_track.hpp    (revision 27829)    
4+++ src/pathfinder/follow_track.hpp    (working copy)    
5@@ -438,6 +438,21 @@    
6                 return true;    
7             }    
8         }    
9+    
10+        if (IsWaterTT()) {    
11+            /* if we reached a dead end, we can reverse the ship and continue moving */    
12+            m_exitdir = ReverseDiagDir(m_exitdir);    
13+            /* new tile will be the same as old one */    
14+            m_new_tile = m_old_tile;    
15+            /* set new trackdir bits to all reachable trackdirs */    
16+            QueryNewTileTrackStatus();    
17+            m_new_td_bits &= DiagdirReachesTrackdirs(m_exitdir);    
18+            if (m_new_td_bits != TRACKDIR_BIT_NONE) {    
19+                /* we have some trackdirs reachable after reversal */    
20+                return true;    
21+            }    
22+        }    
23+    
24         m_err = EC_NO_WAY;    
25         return false;    
26     }    
27Index: src/pathfinder/yapf/yapf.h  1Index: src/pathfinder/yapf/yapf.h  
28===================================================================  2===================================================================  
29--- src/pathfinder/yapf/yapf.h    (revision 27829)  3--- src/pathfinder/yapf/yapf.h    (revision 27829)  
  
73===================================================================  47===================================================================  
74--- src/pathfinder/yapf/yapf_ship.cpp    (revision 27829)  48--- src/pathfinder/yapf/yapf_ship.cpp    (revision 27829)  
75+++ src/pathfinder/yapf/yapf_ship.cpp    (working copy)  49+++ src/pathfinder/yapf/yapf_ship.cpp    (working copy)  
76@@ -139,6 +139,31 @@  76@@ -139,6 +139,43 @@
77         assert(best_trackdir == td1 || best_trackdir == td2);  51         assert(best_trackdir == td1 || best_trackdir == td2);  
78         return best_trackdir == td2;  52         return best_trackdir == td2;  
79     }  53     }  
  54+  
  55+    static bool stFindNearestDepot(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2, TileIndex *depot_tile, bool *reversed)  
  56+    {  
  57+        Tpf pf;  
  58+        bool result = pf.FindNearestDepot(v, tile, td1, td2, depot_tile, reversed);  
  59+        return result;  
  60+    }  
80+  61+  
81+    /**  62+    /**  
82+     * Find the best depot for a ship.  63+     * Find the best depot for a ship.  
83+     * @param v Vehicle  64+     * @param v Vehicle  
84+     * @param tile Tile of the vehicle.  65+     * @param tile Tile of the vehicle.  
85+     * @param td Trackdir of the vehicle.  85+     * @param td1 Trackdir of the vehicle.
86+     * @param max_distance max length (penalty) for paths.  86+     * @param td2 reversed Trackdir of the vehicle.
87+     * @todo max_distance not used by YAPF for ships.  87+     * @param depot_tile the tile of the depot.
88+     *       It can be removed or copy the SetMaxCost() strategy  88+     * @param reversed whether the path to depot was found on reversed Trackdir.
89+     *       applied in YAPF for rail. The best depot can be at    
90+     *       a distance greater than max_distance.    
91+     */  70+     */  
92+    static FindDepotData FindNearestDepot(const Ship *v, TileIndex tile, Trackdir td, int max_distance)  71+    inline bool FindNearestDepot(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2, TileIndex *depot_tile, bool *reversed)
93+    {  72+    {
94+        Tpf pf;  73+        Tpf pf1;
   74+        Tpf pf2;
95+        /* Set origin. */  75+        /* Set origin. */  
96+        pf.SetOrigin(tile, TrackdirToTrackdirBits(td));  76+        pf1.SetOrigin(tile, TrackdirToTrackdirBits(td1));
97+  77+        pf2.SetOrigin(tile, TrackdirToTrackdirBits(td2));
98+        /* Find the best path and return if no depot is found. */  78+
99+        if (!pf.FindPath(v)) return FindDepotData();  79+        bool path_found1 = pf1.FindPath(v);
100+  80+        bool path_found2 = pf2.FindPath(v);
101+        /* Return the cost of the best path and its depot. */  81+        if (!path_found1 && !path_found2) return false;
102+        Node *n = pf.GetBestNode();  82+
103+        return FindDepotData(n->m_segment_last_tile, n->m_cost);  83+        Node *n;
   84+        if (path_found1 || path_found2) {
   85+            n = path_found1 ? pf1.GetBestNode() : pf2.GetBestNode();
   86+            *depot_tile = n->m_segment_last_tile;
   87+            *reversed = !path_found1 && path_found2;
   88+        }
   89+        return true;
104+    }  90+    }  
105 };  91 };  
106   92   
107 /** Cost Provider module of YAPF for ships */  93 /** Cost Provider module of YAPF for ships */  
108@@ -188,15 +213,53 @@  108@@ -188,15 +225,53 @@
109     }  95     }  
110 };  96 };  
111   97   
  
161   147   
162     /** Tpf - pathfinder type */  148     /** Tpf - pathfinder type */  
163     typedef Tpf_                              Tpf;  149     typedef Tpf_                              Tpf;  
164@@ -215,12 +278,16 @@  164@@ -215,12 +290,16 @@
165 };  151 };  
166   152   
167 /* YAPF type 1 - uses TileIndex/Trackdir as Node key, allows 90-deg turns */  153 /* YAPF type 1 - uses TileIndex/Trackdir as Node key, allows 90-deg turns */  
  
181 /** Ship controller helper - path finder invoker */  167 /** Ship controller helper - path finder invoker */  
182 Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found)  168 Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found)  
183 {  169 {  
184@@ -239,6 +306,27 @@  184@@ -239,6 +318,30 @@
185     return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK;  171     return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK;  
186 }  172 }  
187   173   
188+FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance)  188+FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_penalty)
189+{  175+{  
  176+    FindDepotData fdd;  
  177+  
  178+    Trackdir td = v->GetVehicleTrackdir();  
  179+    Trackdir td_rev = ReverseTrackdir(td);  
190+    TileIndex tile = v->tile;  180+    TileIndex tile = v->tile;  
191+    Trackdir trackdir = v->GetVehicleTrackdir();  191+
192+    if ((TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0)) & TrackdirToTrackdirBits(trackdir)) == 0) {    
193+        return FindDepotData();    
194+    }    
195+    /* default is YAPF type 2 */  182+    /* default is YAPF type 2 */  
196+    typedef FindDepotData(*PfnFindNearestDepot)(const Ship*, TileIndex, Trackdir, int);  196+    typedef bool(*PfnFindNearestDepot)(const Ship*, TileIndex, Trackdir, Trackdir, TileIndex*, bool*);
197+    PfnFindNearestDepot pfnFindNearestDepot = &CYapfShipAnyDepot2::FindNearestDepot;  197+    PfnFindNearestDepot pfnFindNearestDepot = &CYapfShipAnyDepot2::stFindNearestDepot;
198+  185+  
199+    /* check if non-default YAPF type should be used */  186+    /* check if non-default YAPF type should be used */  
200+    if (_settings_game.pf.forbid_90_deg) {  187+    if (_settings_game.pf.forbid_90_deg) {  
201+        pfnFindNearestDepot = &CYapfShipAnyDepot3::FindNearestDepot; // Trackdir, forbid 90-deg  201+        pfnFindNearestDepot = &CYapfShipAnyDepot3::stFindNearestDepot; // Trackdir, forbid 90-deg
202+    } else if (_settings_game.pf.yapf.disable_node_optimization) {  189+    } else if (_settings_game.pf.yapf.disable_node_optimization) {  
203+        pfnFindNearestDepot = &CYapfShipAnyDepot1::FindNearestDepot; // Trackdir, allow 90-deg  190+        pfnFindNearestDepot = &CYapfShipAnyDepot1::stFindNearestDepot; // Trackdir, allow 90-deg
204+    }  191+    }
205+  192+
206+    return pfnFindNearestDepot(v, tile, trackdir, max_distance);  193+    bool ret = pfnFindNearestDepot(v, tile, td, td_rev, &fdd.tile, &fdd.reverse);
   194+    fdd.best_length = ret ? max_penalty / 2 : UINT_MAX; // some fake distance or NOT_FOUND
   195+    return fdd;
207+}  196+}  
208+  197+  
209 bool YapfShipCheckReverse(const Ship *v)  198 bool YapfShipCheckReverse(const Ship *v)  
  
280 bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)  269 bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)  
281 {  270 {  
282-    const Depot *depot = FindClosestShipDepot(this, 0);  271-    const Depot *depot = FindClosestShipDepot(this, 0);  
283+    FindDepotData rfdd = FindClosestReachableShipDepot(this, 0);  283+    FindDepotData sfdd = FindClosestReachableShipDepot(this, 0);
284+    if (rfdd.best_length == UINT_MAX) return false;  284+    if (sfdd.best_length == UINT_MAX) return false;
285   274   
286-    if (depot == NULL) return false;  275-    if (depot == NULL) return false;  
287+    if (location != NULL) *location = rfdd.tile;  287+    if (location != NULL) *location = sfdd.tile;
288+    if (destination != NULL) *destination = GetDepotIndex(rfdd.tile);  288+    if (destination != NULL) *destination = GetDepotIndex(sfdd.tile);
289   278   
290-    if (location    != NULL) *location    = depot->xy;  279-    if (location    != NULL) *location    = depot->xy;  
291-    if (destination != NULL) *destination = depot->index;  280-    if (destination != NULL) *destination = depot->index;