1
0
Fork 0

Add: Adapt pathfinding in YAPF and NPF for depots.

pull/8480/head
J0anJosep 2023-03-04 10:27:39 +01:00
parent 438d272cd1
commit 7017fcc676
3 changed files with 62 additions and 1 deletions

View File

@ -12,6 +12,7 @@
#include "../tile_cmd.h" #include "../tile_cmd.h"
#include "../waypoint_base.h" #include "../waypoint_base.h"
#include "../depot_base.h"
/** /**
* Calculates the tile of given station that is closest to a given tile * Calculates the tile of given station that is closest to a given tile
@ -47,6 +48,37 @@ inline TileIndex CalcClosestStationTile(StationID station, TileIndex tile, Stati
return TileXY(x, y); return TileXY(x, y);
} }
/**
* Calculates the tile of a depot that is closest to a given tile.
* @param depot_id The depot to calculate the distance to.
* @param tile The tile from where to calculate the distance.
* @return The closest depot tile to the given tile.
*/
static inline TileIndex CalcClosestDepotTile(DepotID depot_id, TileIndex tile)
{
assert(Depot::IsValidID(depot_id));
const Depot *dep = Depot::Get(depot_id);
/* If tile area is empty, use the xy tile. */
if (dep->ta.tile == INVALID_TILE) {
assert(dep->xy != INVALID_TILE);
return dep->xy;
}
TileIndex best_tile = INVALID_TILE;
uint best_distance = UINT_MAX;
for (auto const &depot_tile : dep->depot_tiles) {
uint new_distance = DistanceManhattan(depot_tile, tile);
if (new_distance < best_distance) {
best_tile = depot_tile;
best_distance = new_distance;
}
}
return best_tile;
}
/** /**
* Wrapper around GetTileTrackStatus() and TrackStatusToTrackdirBits(), as for * Wrapper around GetTileTrackStatus() and TrackStatusToTrackdirBits(), as for
* single tram bits GetTileTrackStatus() returns 0. The reason for this is * single tram bits GetTileTrackStatus() returns 0. The reason for this is

View File

@ -118,6 +118,7 @@ protected:
TileIndex m_destTile; TileIndex m_destTile;
TrackdirBits m_destTrackdirs; TrackdirBits m_destTrackdirs;
StationID m_dest_station_id; StationID m_dest_station_id;
DepotID m_dest_depot_id;
bool m_any_depot; bool m_any_depot;
/** to access inherited path finder */ /** to access inherited path finder */
@ -149,14 +150,25 @@ public:
break; break;
case OT_GOTO_DEPOT: case OT_GOTO_DEPOT:
m_dest_station_id = INVALID_STATION;
if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) { if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
m_any_depot = true; m_any_depot = true;
m_dest_depot_id = INVALID_DEPOT;
m_destTile = v->dest_tile;
m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0));
} else {
m_dest_depot_id = v->current_order.GetDestination();
assert(Depot::IsValidID(m_dest_depot_id));
m_destTile = CalcClosestDepotTile(m_dest_depot_id, v->tile);
m_destTrackdirs = INVALID_TRACKDIR_BIT;
} }
[[fallthrough]]; break;
default: default:
m_destTile = v->dest_tile; m_destTile = v->dest_tile;
m_dest_station_id = INVALID_STATION; m_dest_station_id = INVALID_STATION;
m_dest_depot_id = INVALID_DEPOT;
m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0)); m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0));
break; break;
} }
@ -176,6 +188,10 @@ public:
return HasStationTileRail(tile) return HasStationTileRail(tile)
&& (GetStationIndex(tile) == m_dest_station_id) && (GetStationIndex(tile) == m_dest_station_id)
&& (GetRailStationTrack(tile) == TrackdirToTrack(td)); && (GetRailStationTrack(tile) == TrackdirToTrack(td));
} else if (m_dest_depot_id != INVALID_DEPOT) {
return IsRailDepotTile(tile)
&& (GetDepotIndex(tile) == m_dest_depot_id)
&& (GetRailDepotTrack(tile) == TrackdirToTrack(td));
} }
if (m_any_depot) { if (m_any_depot) {

View File

@ -234,7 +234,9 @@ protected:
TileIndex m_destTile; TileIndex m_destTile;
TrackdirBits m_destTrackdirs; TrackdirBits m_destTrackdirs;
StationID m_dest_station; StationID m_dest_station;
DepotID m_dest_depot;
StationType m_station_type; StationType m_station_type;
bool m_bus;
bool m_non_artic; bool m_non_artic;
public: public:
@ -252,8 +254,14 @@ public:
m_destTile = CalcClosestStationTile(m_dest_station, v->tile, m_station_type); m_destTile = CalcClosestStationTile(m_dest_station, v->tile, m_station_type);
m_non_artic = !v->HasArticulatedPart(); m_non_artic = !v->HasArticulatedPart();
m_destTrackdirs = INVALID_TRACKDIR_BIT; m_destTrackdirs = INVALID_TRACKDIR_BIT;
} else if (v->current_order.IsType(OT_GOTO_DEPOT)) {
m_dest_station = INVALID_STATION;
m_dest_depot = v->current_order.GetDestination();
m_destTile = CalcClosestDepotTile(m_dest_depot, v->tile);
m_destTrackdirs = INVALID_TRACKDIR_BIT;
} else { } else {
m_dest_station = INVALID_STATION; m_dest_station = INVALID_STATION;
m_dest_depot = INVALID_DEPOT;
m_destTile = v->dest_tile; m_destTile = v->dest_tile;
m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype))); m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype)));
} }
@ -287,6 +295,11 @@ public:
(m_non_artic || IsDriveThroughStopTile(tile)); (m_non_artic || IsDriveThroughStopTile(tile));
} }
if (m_dest_depot != INVALID_DEPOT) {
return IsRoadDepotTile(tile) &&
GetDepotIndex(tile) == m_dest_depot;
}
return tile == m_destTile && HasTrackdir(m_destTrackdirs, trackdir); return tile == m_destTile && HasTrackdir(m_destTrackdirs, trackdir);
} }