diff options
Diffstat (limited to 'src/pathfinder/yapf')
-rw-r--r-- | src/pathfinder/yapf/yapf.h | 7 | ||||
-rw-r--r-- | src/pathfinder/yapf/yapf_ship.cpp | 57 |
2 files changed, 64 insertions, 0 deletions
diff --git a/src/pathfinder/yapf/yapf.h b/src/pathfinder/yapf/yapf.h index b02d9d0ee..00eb7e562 100644 --- a/src/pathfinder/yapf/yapf.h +++ b/src/pathfinder/yapf/yapf.h @@ -29,6 +29,13 @@ Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found); /** + * Returns true if it is better to reverse the ship before leaving depot using YAPF. + * @param v the ship leaving the depot + * @return true if reversing is better + */ +bool YapfShipCheckReverse(const Ship *v); + +/** * Finds the best path for given road vehicle using YAPF. * @param v the RV that needs to find a path * @param tile the tile to find the path from (should be next tile the RV is about to enter) diff --git a/src/pathfinder/yapf/yapf_ship.cpp b/src/pathfinder/yapf/yapf_ship.cpp index dfcda3858..a4113144e 100644 --- a/src/pathfinder/yapf/yapf_ship.cpp +++ b/src/pathfinder/yapf/yapf_ship.cpp @@ -98,6 +98,42 @@ public: } return next_trackdir; } + + /** + * Check whether a ship should reverse to reach its destination. + * Called when leaving depot. + * @param v Ship + * @param tile Current position + * @param td1 Forward direction + * @param td2 Reverse direction + * @return true if the reverse direction is better + */ + static bool CheckShipReverse(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2) + { + /* get available trackdirs on the destination tile */ + TrackdirBits dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER, 0)); + + /* create pathfinder instance */ + Tpf pf; + /* set origin and destination nodes */ + pf.SetOrigin(tile, TrackdirToTrackdirBits(td1) | TrackdirToTrackdirBits(td2)); + pf.SetDestination(v->dest_tile, dest_trackdirs); + /* find best path */ + if (!pf.FindPath(v)) return false; + + Node *pNode = pf.GetBestNode(); + if (pNode == NULL) return false; + + /* path was found + * walk through the path back to the origin */ + while (pNode->m_parent != NULL) { + pNode = pNode->m_parent; + } + + Trackdir best_trackdir = pNode->GetTrackdir(); + assert(best_trackdir == td1 || best_trackdir == td2); + return best_trackdir == td2; + } }; /** Cost Provider module of YAPF for ships */ @@ -197,3 +233,24 @@ Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, Trackdir td_ret = pfnChooseShipTrack(v, tile, enterdir, tracks, path_found); return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK; } + +bool YapfShipCheckReverse(const Ship *v) +{ + Trackdir td = v->GetVehicleTrackdir(); + Trackdir td_rev = ReverseTrackdir(td); + TileIndex tile = v->tile; + + typedef bool (*PfnCheckReverseShip)(const Ship*, TileIndex, Trackdir, Trackdir); + PfnCheckReverseShip pfnCheckReverseShip = CYapfShip2::CheckShipReverse; // default: ExitDir, allow 90-deg + + /* check if non-default YAPF type needed */ + if (_settings_game.pf.forbid_90_deg) { + pfnCheckReverseShip = &CYapfShip3::CheckShipReverse; // Trackdir, forbid 90-deg + } else if (_settings_game.pf.yapf.disable_node_optimization) { + pfnCheckReverseShip = &CYapfShip1::CheckShipReverse; // Trackdir, allow 90-deg + } + + bool reverse = pfnCheckReverseShip(v, tile, td, td_rev); + + return reverse; +} |