Loading

Revision differences

Old revision #ppqwyyw9sNew revision #pubn57tm0
47===================================================================  47===================================================================  
48--- src/pathfinder/yapf/yapf_ship.cpp    (revision 27829)  48--- src/pathfinder/yapf/yapf_ship.cpp    (revision 27829)  
49+++ src/pathfinder/yapf/yapf_ship.cpp    (working copy)  49+++ src/pathfinder/yapf/yapf_ship.cpp    (working copy)  
50@@ -139,6 +139,31 @@  50@@ -139,6 +139,43 @@
51         assert(best_trackdir == td1 || best_trackdir == td2);  51         assert(best_trackdir == td1 || best_trackdir == td2);  
52         return best_trackdir == td2;  52         return best_trackdir == td2;  
53     }  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+    }  
54+  61+  
55+    /**  62+    /**  
56+     * Find the best depot for a ship.  63+     * Find the best depot for a ship.  
57+     * @param v Vehicle  64+     * @param v Vehicle  
58+     * @param tile Tile of the vehicle.  65+     * @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+     */  70+     */  
66+    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)
67+    {  72+    {
68+        Tpf pf;  73+        Tpf pf1;
   74+        Tpf pf2;
69+        /* Set origin. */  75+        /* Set origin. */  
70+        pf.SetOrigin(tile, TrackdirToTrackdirBits(td));  76+        pf1.SetOrigin(tile, TrackdirToTrackdirBits(td1));
71+  77+        pf2.SetOrigin(tile, TrackdirToTrackdirBits(td2));
72+        /* Find the best path and return if no depot is found. */  78+
73+        if (!pf.FindPath(v)) return FindDepotData();  79+        bool path_found1 = pf1.FindPath(v);
74+  80+        bool path_found2 = pf2.FindPath(v);
75+        /* Return the cost of the best path and its depot. */  81+        if (!path_found1 && !path_found2) return false;
76+        Node *n = pf.GetBestNode();  82+
77+        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;
78+    }  90+    }  
79 };  91 };  
80   92   
81 /** Cost Provider module of YAPF for ships */  93 /** Cost Provider module of YAPF for ships */  
82@@ -188,15 +213,53 @@  82@@ -188,15 +225,53 @@
83     }  95     }  
84 };  96 };  
85   97   
  
101+    /** Called by YAPF to detect if node ends in the desired destination */  113+    /** Called by YAPF to detect if node ends in the desired destination */  
102+    inline bool PfDetectDestination(Node &n)  114+    inline bool PfDetectDestination(Node &n)  
103+    {  115+    {  
104+        bool bDest = IsShipDepotTile(n.m_segment_last_tile);  104+        bool bDest = IsShipDepotTile(n.m_segment_last_tile) && GetShipDepotPart(n.m_segment_last_tile) == DEPOT_PART_NORTH;
105+        return bDest;  117+        return bDest;  
106+    }  118+    }  
107+  119+  
108+    inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir)  120+    inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir)  
109+    {  121+    {  
110+        return IsShipDepotTile(tile);  110+        return IsShipDepotTile(n.m_segment_last_tile) && GetShipDepotPart(n.m_segment_last_tile) == DEPOT_PART_NORTH;
111+    }  123+    }  
112+  124+  
113+    /**  125+    /**  
  
135   147   
136     /** Tpf - pathfinder type */  148     /** Tpf - pathfinder type */  
137     typedef Tpf_                              Tpf;  149     typedef Tpf_                              Tpf;  
138@@ -215,12 +278,16 @@  138@@ -215,12 +290,16 @@
139 };  151 };  
140   152   
141 /* 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 */  
  
155 /** Ship controller helper - path finder invoker */  167 /** Ship controller helper - path finder invoker */  
156 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)  
157 {  169 {  
158@@ -239,6 +306,27 @@  158@@ -239,6 +318,30 @@
159     return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK;  171     return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK;  
160 }  172 }  
161   173   
162+FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance)  162+FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_penalty)
163+{  175+{  
  176+    FindDepotData fdd;  
  177+  
  178+    Trackdir td = v->GetVehicleTrackdir();  
  179+    Trackdir td_rev = ReverseTrackdir(td);  
164+    TileIndex tile = v->tile;  180+    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 */  182+    /* default is YAPF type 2 */  
170+    typedef FindDepotData(*PfnFindNearestDepot)(const Ship*, TileIndex, Trackdir, int);  170+    typedef bool(*PfnFindNearestDepot)(const Ship*, TileIndex, Trackdir, Trackdir, TileIndex*, bool*);
171+    PfnFindNearestDepot pfnFindNearestDepot = &CYapfShipAnyDepot2::FindNearestDepot;  171+    PfnFindNearestDepot pfnFindNearestDepot = &CYapfShipAnyDepot2::stFindNearestDepot;
172+  185+  
173+    /* check if non-default YAPF type should be used */  186+    /* check if non-default YAPF type should be used */  
174+    if (_settings_game.pf.forbid_90_deg) {  187+    if (_settings_game.pf.forbid_90_deg) {  
175+        pfnFindNearestDepot = &CYapfShipAnyDepot3::FindNearestDepot; // Trackdir, forbid 90-deg  175+        pfnFindNearestDepot = &CYapfShipAnyDepot3::stFindNearestDepot; // Trackdir, forbid 90-deg
176+    } else if (_settings_game.pf.yapf.disable_node_optimization) {  189+    } else if (_settings_game.pf.yapf.disable_node_optimization) {  
177+        pfnFindNearestDepot = &CYapfShipAnyDepot1::FindNearestDepot; // Trackdir, allow 90-deg  190+        pfnFindNearestDepot = &CYapfShipAnyDepot1::stFindNearestDepot; // Trackdir, allow 90-deg
178+    }  191+    }
179+  192+
180+    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;
181+}  196+}  
182+  197+  
183 bool YapfShipCheckReverse(const Ship *v)  198 bool YapfShipCheckReverse(const Ship *v)  
  
203-     * other hand if we have set a maximum distance, any depot  218-     * other hand if we have set a maximum distance, any depot  
204-     * further away than max_distance can safely be ignored. */  219-     * further away than max_distance can safely be ignored. */  
205-    uint best_dist = max_distance == 0 ? UINT_MAX : max_distance + 1;  220-    uint best_dist = max_distance == 0 ? UINT_MAX : max_distance + 1;  
206+    if (IsShipDepotTile(v->tile)) return FindDepotData(v->tile, 0);  206+    if (IsShipDepotTile(v->tile) && GetShipDepotPart(v->tile) == DEPOT_PART_NORTH) return FindDepotData(v->tile, 0);
207   222   
208-    FOR_ALL_DEPOTS(depot) {  223-    FOR_ALL_DEPOTS(depot) {  
209-        TileIndex tile = depot->xy;  224-        TileIndex tile = depot->xy;  
  
254 bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)  269 bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)  
255 {  270 {  
256-    const Depot *depot = FindClosestShipDepot(this, 0);  271-    const Depot *depot = FindClosestShipDepot(this, 0);  
257+    FindDepotData rfdd = FindClosestReachableShipDepot(this, 0);  257+    FindDepotData sfdd = FindClosestReachableShipDepot(this, 0);
258+    if (rfdd.best_length == UINT_MAX) return false;  258+    if (sfdd.best_length == UINT_MAX) return false;
259   274   
260-    if (depot == NULL) return false;  275-    if (depot == NULL) return false;  
261+    if (location != NULL) *location = rfdd.tile;  261+    if (location != NULL) *location = sfdd.tile;
262+    if (destination != NULL) *destination = GetDepotIndex(rfdd.tile);  262+    if (destination != NULL) *destination = GetDepotIndex(sfdd.tile);
263   278   
264-    if (location    != NULL) *location    = depot->xy;  279-    if (location    != NULL) *location    = depot->xy;  
265-    if (destination != NULL) *destination = depot->index;  280-    if (destination != NULL) *destination = depot->index;