FindDepotData OPFShipFindNearestDepot(const Ship *v, int max_distance)
{
FindDepotData fdd;
Trackdir trackdir = v->GetVehicleTrackdir();
/* Argument values for FindShipTrack below, for the current ship direction */
DiagDirection enterdir = TrackdirToExitdir(trackdir);
TileIndex tile = TILE_ADD(v->tile, TileOffsByDiagDir(enterdir));
TrackBits tracks = TrackdirBitsToTrackBits(DiagdirReachesTrackdirs(enterdir));
/* Argument values for FindShipTrack below, for the reversed ship direction */
DiagDirection enterdir_rev = ReverseDiagDir(enterdir);
TileIndex tile_rev = v->tile;
TrackBits tracks_rev = TrackStatusToTrackBits(GetTileTrackStatus(tile_rev, TRANSPORT_WATER, 0)) & DiagdirReachesTracks(enterdir_rev) & TrackdirBitsToTrackBits(TrackdirToTrackdirBits(trackdir));
Track track; // initialized, but unused
if (max_distance == 0) max_distance = INT_MAX;
uint best_length = UINT_MAX;
Depot *depot;
FOR_ALL_DEPOTS(depot) {
TileIndex depottile = depot->xy;
if (IsShipDepotTile(depottile) && IsTileOwner(depottile, v->owner)) {
uint distdepot = DistanceManhattan(v->tile, depottile);
if (distdepot <= (uint)max_distance && distdepot < best_length) {
/* Let's find the length it would be if we would reverse first */
uint length_rev = UINT_MAX;
if (tracks_rev != 0) {
length_rev = FindShipTrack(v, tile_rev, enterdir_rev, tracks_rev, tile, &track, depottile); //
if (length_rev != UINT_MAX) length_rev++; // penalty for reversing
}
/* And if we would not reverse? */
uint length = FindShipTrack(v, tile, enterdir, tracks, 0, &track, depottile);
/* Get the shortest length */
uint min_length = minu(length_rev, length);
if (min_length < best_length) {
best_length = min_length;
fdd.tile = depottile; // tile location of ship depot
fdd.best_length = distdepot; // distance manhattan from ship to depot
fdd.reverse = !(length <= length_rev);
}
}
}
}
return fdd;
}