|
@@ -404,49 +404,49 @@ static int32 NPFRailPathCost(AyStar *as,
|
|
|
* that) */
|
|
|
cost += _settings_game.pf.npf.npf_rail_depot_reverse_penalty;
|
|
|
}
|
|
|
|
|
|
/* Check for occupied track */
|
|
|
cost += NPFReservedTrackCost(current);
|
|
|
|
|
|
NPFMarkTile(tile);
|
|
|
DEBUG(npf, 4, "Calculating G for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), cost);
|
|
|
return cost;
|
|
|
}
|
|
|
|
|
|
/* Will find any depot */
|
|
|
static int32 NPFFindDepot(AyStar *as, OpenListNode *current)
|
|
|
{
|
|
|
/* It's not worth caching the result with NPF_FLAG_IS_TARGET here as below,
|
|
|
* since checking the cache not that much faster than the actual check */
|
|
|
return IsDepotTypeTile(current->path.node.tile, (TransportType)as->user_data[NPF_TYPE]) ?
|
|
|
AYSTAR_FOUND_END_NODE : AYSTAR_DONE;
|
|
|
}
|
|
|
|
|
|
/** Find any safe and free tile. */
|
|
|
static int32 NPFFindSafeTile(AyStar *as, OpenListNode *current)
|
|
|
{
|
|
|
const Train *v = (Train *)((NPFFindStationOrTileData*)as->user_target)->v;
|
|
|
const Train *v = (const Train *)((NPFFindStationOrTileData*)as->user_target)->v;
|
|
|
|
|
|
return
|
|
|
IsSafeWaitingPosition(v, current->path.node.tile, current->path.node.direction, true, _settings_game.pf.forbid_90_deg) &&
|
|
|
IsWaitingPositionFree(v, current->path.node.tile, current->path.node.direction, _settings_game.pf.forbid_90_deg) ?
|
|
|
AYSTAR_FOUND_END_NODE : AYSTAR_DONE;
|
|
|
}
|
|
|
|
|
|
/* Will find a station identified using the NPFFindStationOrTileData */
|
|
|
static int32 NPFFindStationOrTile(AyStar *as, OpenListNode *current)
|
|
|
{
|
|
|
NPFFindStationOrTileData *fstd = (NPFFindStationOrTileData*)as->user_target;
|
|
|
AyStarNode *node = ¤t->path.node;
|
|
|
TileIndex tile = node->tile;
|
|
|
|
|
|
/* If GetNeighbours said we could get here, we assume the station type
|
|
|
* is correct */
|
|
|
if (
|
|
|
(fstd->station_index == INVALID_STATION && tile == fstd->dest_coords) || // We've found the tile, or
|
|
|
(IsTileType(tile, MP_STATION) && GetStationIndex(tile) == fstd->station_index) // the station
|
|
|
) {
|
|
|
return AYSTAR_FOUND_END_NODE;
|
|
|
} else {
|
|
|
return AYSTAR_DONE;
|
|
|
}
|
|
@@ -485,49 +485,49 @@ static void ClearPathReservation(const P
|
|
|
} else {
|
|
|
UnreserveRailTrack(start->node.tile, TrackdirToTrack(start->node.direction));
|
|
|
}
|
|
|
first_run = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* To be called when @p current contains the (shortest route to) the target node.
|
|
|
* Will fill the contents of the NPFFoundTargetData using
|
|
|
* AyStarNode[NPF_TRACKDIR_CHOICE]. If requested, path reservation
|
|
|
* is done here.
|
|
|
*/
|
|
|
static void NPFSaveTargetData(AyStar *as, OpenListNode *current)
|
|
|
{
|
|
|
NPFFoundTargetData *ftd = (NPFFoundTargetData*)as->user_path;
|
|
|
ftd->best_trackdir = (Trackdir)current->path.node.user_data[NPF_TRACKDIR_CHOICE];
|
|
|
ftd->best_path_dist = current->g;
|
|
|
ftd->best_bird_dist = 0;
|
|
|
ftd->node = current->path.node;
|
|
|
ftd->res_okay = false;
|
|
|
|
|
|
if (as->user_target != NULL && ((NPFFindStationOrTileData*)as->user_target)->reserve_path && as->user_data[NPF_TYPE] == TRANSPORT_RAIL) {
|
|
|
/* Path reservation is requested. */
|
|
|
const Train *v = (Train *)((NPFFindStationOrTileData*)as->user_target)->v;
|
|
|
const Train *v = (const Train *)((NPFFindStationOrTileData*)as->user_target)->v;
|
|
|
|
|
|
const PathNode *target = FindSafePosition(¤t->path, v);
|
|
|
ftd->node = target->node;
|
|
|
|
|
|
/* If the target is a station skip to platform end. */
|
|
|
if (IsRailwayStationTile(target->node.tile)) {
|
|
|
DiagDirection dir = TrackdirToExitdir(target->node.direction);
|
|
|
uint len = GetStationByTile(target->node.tile)->GetPlatformLength(target->node.tile, dir);
|
|
|
TileIndex end_tile = TILE_ADD(target->node.tile, (len - 1) * TileOffsByDiagDir(dir));
|
|
|
|
|
|
/* Update only end tile, trackdir of a station stays the same. */
|
|
|
ftd->node.tile = end_tile;
|
|
|
if (!IsWaitingPositionFree(v, end_tile, target->node.direction, _settings_game.pf.forbid_90_deg)) return;
|
|
|
SetRailwayStationPlatformReservation(target->node.tile, dir, true);
|
|
|
SetRailwayStationReservation(target->node.tile, false);
|
|
|
} else {
|
|
|
if (!IsWaitingPositionFree(v, target->node.tile, target->node.direction, _settings_game.pf.forbid_90_deg)) return;
|
|
|
}
|
|
|
|
|
|
for (const PathNode *cur = target; cur->parent != NULL; cur = cur->parent) {
|
|
|
if (!TryReserveRailTrack(cur->node.tile, TrackdirToTrack(cur->node.direction))) {
|
|
|
/* Reservation failed, undo. */
|
|
|
ClearPathReservation(target, cur);
|
|
|
return;
|