Merge branch 'save_ext' into enhanced_viewport_overlay

# Conflicts:
#	src/smallmap_gui.cpp
This commit is contained in:
Jonathan G Rennison
2017-09-04 01:04:04 +01:00
265 changed files with 4275 additions and 2654 deletions

View File

@@ -133,7 +133,7 @@ struct AyStar {
* everything */
void *user_path;
void *user_target;
uint user_data[10];
void *user_data;
byte loops_per_tick; ///< How many loops are there called before Main() gives control back to the caller. 0 = until done.
uint max_path_cost; ///< If the g-value goes over this number, it stops searching, 0 = infinite.

View File

@@ -38,11 +38,11 @@ struct NPFFindStationOrTileData {
};
/** Indices into AyStar.userdata[] */
enum AyStarUserDataType {
NPF_TYPE = 0, ///< Contains a TransportTypes value
NPF_SUB_TYPE, ///< Contains the sub transport type
NPF_OWNER, ///< Contains an Owner value
NPF_RAILTYPES, ///< Contains a bitmask the compatible RailTypes of the engine when NPF_TYPE == TRANSPORT_RAIL. Unused otherwise.
struct AyStarUserData {
Owner owner;
TransportType type;
RailTypes railtypes;
RoadTypes roadtypes;
};
/** Indices into AyStarNode.userdata[] */
@@ -157,13 +157,14 @@ static int32 NPFCalcStationOrTileHeuristic(AyStar *as, AyStarNode *current, Open
TileIndex from = current->tile;
TileIndex to = fstd->dest_coords;
uint dist;
AyStarUserData *user = (AyStarUserData *)as->user_data;
/* for train-stations, we are going to aim for the closest station tile */
if (as->user_data[NPF_TYPE] != TRANSPORT_WATER && fstd->station_index != INVALID_STATION) {
if (user->type != TRANSPORT_WATER && fstd->station_index != INVALID_STATION) {
to = CalcClosestStationTile(fstd->station_index, from, fstd->station_type);
}
if (as->user_data[NPF_TYPE] == TRANSPORT_ROAD) {
if (user->type == TRANSPORT_ROAD) {
/* Since roads only have diagonal pieces, we use manhattan distance here */
dist = DistanceManhattan(from, to) * NPF_TILE_LENGTH;
} else {
@@ -532,9 +533,10 @@ static int32 NPFRailPathCost(AyStar *as, AyStarNode *current, OpenListNode *pare
/* Will find any depot */
static int32 NPFFindDepot(AyStar *as, OpenListNode *current)
{
AyStarUserData *user = (AyStarUserData *)as->user_data;
/* 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]) ?
return IsDepotTypeTile(current->path.node.tile, user->type) ?
AYSTAR_FOUND_END_NODE : AYSTAR_DONE;
}
@@ -612,6 +614,7 @@ static void ClearPathReservation(const PathNode *start, const PathNode *end)
*/
static void NPFSaveTargetData(AyStar *as, OpenListNode *current)
{
AyStarUserData *user = (AyStarUserData *)as->user_data;
NPFFoundTargetData *ftd = (NPFFoundTargetData*)as->user_path;
ftd->best_trackdir = (Trackdir)current->path.node.user_data[NPF_TRACKDIR_CHOICE];
ftd->best_path_dist = current->g;
@@ -619,7 +622,7 @@ static void NPFSaveTargetData(AyStar *as, OpenListNode *current)
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) {
if (as->user_target != NULL && ((NPFFindStationOrTileData*)as->user_target)->reserve_path && user->type == TRANSPORT_RAIL) {
/* Path reservation is requested. */
const Train *v = Train::From(((NPFFindStationOrTileData *)as->user_target)->v);
@@ -767,28 +770,25 @@ static inline bool ForceReverse(TileIndex tile, DiagDirection dir, TransportType
*
* @param tile The tile of interest.
* @param dir The direction in which the vehicle drives onto a tile.
* @param type The transporttype of the vehicle.
* @param subtype For TRANSPORT_ROAD the compatible RoadTypes of the vehicle.
* @param railtypes For TRANSPORT_RAIL the compatible RailTypes of the vehicle.
* @param owner The owner of the vehicle.
* @param user Vehicle information.
* @return true iff the vehicle can enter the tile.
*/
static bool CanEnterTile(TileIndex tile, DiagDirection dir, TransportType type, uint subtype, RailTypes railtypes, Owner owner)
static bool CanEnterTile(TileIndex tile, DiagDirection dir, AyStarUserData *user)
{
/* Check tunnel entries and bridge ramps */
if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(tile) != dir) return false;
/* Test ownership */
if (!CanEnterTileOwnerCheck(owner, tile, dir)) return false;
if (!CanEnterTileOwnerCheck(user->owner, tile, dir)) return false;
/* check correct rail type (mono, maglev, etc) */
if (type == TRANSPORT_RAIL) {
if (user->type == TRANSPORT_RAIL) {
RailType rail_type = GetTileRailType(tile);
if (!HasBit(railtypes, rail_type)) return false;
if (!HasBit(user->railtypes, rail_type)) return false;
}
/* Depots, standard roadstops and single tram bits can only be entered from one direction */
DiagDirection single_entry = GetTileSingleEntry(tile, type, subtype);
DiagDirection single_entry = GetTileSingleEntry(tile, user->type, user->roadtypes);
if (single_entry != INVALID_DIAGDIR && single_entry != ReverseDiagDir(dir)) return false;
return true;
@@ -849,6 +849,7 @@ static TrackdirBits GetDriveableTrackdirBits(TileIndex dst_tile, Trackdir src_tr
* copy AyStarNode.user_data[NPF_NODE_FLAGS] from the parent */
static void NPFFollowTrack(AyStar *aystar, OpenListNode *current)
{
AyStarUserData *user = (AyStarUserData *)aystar->user_data;
/* We leave src_tile on track src_trackdir in direction src_exitdir */
Trackdir src_trackdir = current->path.node.direction;
TileIndex src_tile = current->path.node.tile;
@@ -860,8 +861,8 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current)
bool ignore_src_tile = (current->path.parent == NULL && NPFGetFlag(&current->path.node, NPF_FLAG_IGNORE_START_TILE));
/* Information about the vehicle: TransportType (road/rail/water) and SubType (compatible rail/road types) */
TransportType type = (TransportType)aystar->user_data[NPF_TYPE];
uint subtype = aystar->user_data[NPF_SUB_TYPE];
TransportType type = user->type;
uint subtype = user->roadtypes;
/* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */
aystar->num_neighbours = 0;
@@ -889,7 +890,7 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current)
/* We leave src_tile in src_exitdir and reach dst_tile */
dst_tile = AddTileIndexDiffCWrap(src_tile, TileIndexDiffCByDiagDir(src_exitdir));
if (dst_tile != INVALID_TILE && !CanEnterTile(dst_tile, src_exitdir, type, subtype, (RailTypes)aystar->user_data[NPF_RAILTYPES], (Owner)aystar->user_data[NPF_OWNER])) dst_tile = INVALID_TILE;
if (dst_tile != INVALID_TILE && !CanEnterTile(dst_tile, src_exitdir, user)) dst_tile = INVALID_TILE;
if (dst_tile == INVALID_TILE) {
/* We cannot enter the next tile. Road vehicles can reverse, others reach dead end */
@@ -960,7 +961,7 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current)
* multiple targets that are spread around, we should perform a breadth first
* search by specifiying CalcZero as our heuristic.
*/
static NPFFoundTargetData NPFRouteInternal(AyStarNode *start1, bool ignore_start_tile1, AyStarNode *start2, bool ignore_start_tile2, NPFFindStationOrTileData *target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, uint sub_type, Owner owner, RailTypes railtypes, uint reverse_penalty)
static NPFFoundTargetData NPFRouteInternal(AyStarNode *start1, bool ignore_start_tile1, AyStarNode *start2, bool ignore_start_tile2, NPFFindStationOrTileData *target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, AyStarUserData *user, uint reverse_penalty, bool ignore_reserved = false)
{
int r;
NPFFoundTargetData result;
@@ -970,7 +971,7 @@ static NPFFoundTargetData NPFRouteInternal(AyStarNode *start1, bool ignore_start
_npf_aystar.EndNodeCheck = target_proc;
_npf_aystar.FoundEndNode = NPFSaveTargetData;
_npf_aystar.GetNeighbours = NPFFollowTrack;
switch (type) {
switch (user->type) {
default: NOT_REACHED();
case TRANSPORT_RAIL: _npf_aystar.CalculateG = NPFRailPathCost; break;
case TRANSPORT_ROAD: _npf_aystar.CalculateG = NPFRoadPathCost; break;
@@ -981,12 +982,14 @@ static NPFFoundTargetData NPFRouteInternal(AyStarNode *start1, bool ignore_start
start1->user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
start1->user_data[NPF_NODE_FLAGS] = 0;
NPFSetFlag(start1, NPF_FLAG_IGNORE_START_TILE, ignore_start_tile1);
NPFSetFlag(start1, NPF_FLAG_IGNORE_RESERVED, ignore_reserved);
_npf_aystar.AddStartNode(start1, 0);
if (start2 != NULL) {
start2->user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
start2->user_data[NPF_NODE_FLAGS] = 0;
NPFSetFlag(start2, NPF_FLAG_IGNORE_START_TILE, ignore_start_tile2);
NPFSetFlag(start2, NPF_FLAG_REVERSE, true);
NPFSetFlag(start2, NPF_FLAG_IGNORE_RESERVED, ignore_reserved);
_npf_aystar.AddStartNode(start2, reverse_penalty);
}
@@ -1002,10 +1005,7 @@ static NPFFoundTargetData NPFRouteInternal(AyStarNode *start1, bool ignore_start
_npf_aystar.user_target = target;
/* Initialize user_data */
_npf_aystar.user_data[NPF_TYPE] = type;
_npf_aystar.user_data[NPF_SUB_TYPE] = sub_type;
_npf_aystar.user_data[NPF_OWNER] = owner;
_npf_aystar.user_data[NPF_RAILTYPES] = railtypes;
_npf_aystar.user_data = user;
/* GO! */
r = _npf_aystar.Main();
@@ -1026,29 +1026,25 @@ static NPFFoundTargetData NPFRouteInternal(AyStarNode *start1, bool ignore_start
/* Will search as below, but with two start nodes, the second being the
* reverse. Look at the NPF_FLAG_REVERSE flag in the result node to see which
* direction was taken (NPFGetFlag(result.node, NPF_FLAG_REVERSE)) */
static NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, bool ignore_start_tile1, TileIndex tile2, Trackdir trackdir2, bool ignore_start_tile2, NPFFindStationOrTileData *target, TransportType type, uint sub_type, Owner owner, RailTypes railtypes)
static NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, bool ignore_start_tile1, TileIndex tile2, Trackdir trackdir2, bool ignore_start_tile2, NPFFindStationOrTileData *target, AyStarUserData *user)
{
AyStarNode start1;
AyStarNode start2;
start1.tile = tile1;
start2.tile = tile2;
/* We set this in case the target is also the start tile, we will just
* return a not found then */
start1.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
start1.direction = trackdir1;
start2.direction = trackdir2;
start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
return NPFRouteInternal(&start1, ignore_start_tile1, (IsValidTile(tile2) ? &start2 : NULL), ignore_start_tile2, target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, sub_type, owner, railtypes, 0);
return NPFRouteInternal(&start1, ignore_start_tile1, (IsValidTile(tile2) ? &start2 : NULL), ignore_start_tile2, target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, user, 0);
}
/* Will search from the given tile and direction, for a route to the given
* station for the given transport type. See the declaration of
* NPFFoundTargetData above for the meaning of the result. */
static NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, bool ignore_start_tile, NPFFindStationOrTileData *target, TransportType type, uint sub_type, Owner owner, RailTypes railtypes)
static NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, bool ignore_start_tile, NPFFindStationOrTileData *target, AyStarUserData *user)
{
return NPFRouteToStationOrTileTwoWay(tile, trackdir, ignore_start_tile, INVALID_TILE, INVALID_TRACKDIR, false, target, type, sub_type, owner, railtypes);
return NPFRouteToStationOrTileTwoWay(tile, trackdir, ignore_start_tile, INVALID_TILE, INVALID_TRACKDIR, false, target, user);
}
/* Search using breadth first. Good for little track choice and inaccurate
@@ -1058,23 +1054,19 @@ static NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir track
* reverse_penalty applied (NPF_TILE_LENGTH is the equivalent of one full
* tile).
*/
static NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, bool ignore_start_tile1, TileIndex tile2, Trackdir trackdir2, bool ignore_start_tile2, NPFFindStationOrTileData *target, TransportType type, uint sub_type, Owner owner, RailTypes railtypes, uint reverse_penalty)
static NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, bool ignore_start_tile1, TileIndex tile2, Trackdir trackdir2, bool ignore_start_tile2, NPFFindStationOrTileData *target, AyStarUserData *user, uint reverse_penalty)
{
AyStarNode start1;
AyStarNode start2;
start1.tile = tile1;
start2.tile = tile2;
/* We set this in case the target is also the start tile, we will just
* return a not found then */
start1.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
start1.direction = trackdir1;
start2.direction = trackdir2;
start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
/* perform a breadth first search. Target is NULL,
* since we are just looking for any depot...*/
return NPFRouteInternal(&start1, ignore_start_tile1, (IsValidTile(tile2) ? &start2 : NULL), ignore_start_tile2, target, NPFFindDepot, NPFCalcZero, type, sub_type, owner, railtypes, reverse_penalty);
return NPFRouteInternal(&start1, ignore_start_tile1, (IsValidTile(tile2) ? &start2 : NULL), ignore_start_tile2, target, NPFFindDepot, NPFCalcZero, user, reverse_penalty);
}
void InitializeNPF()
@@ -1123,7 +1115,8 @@ FindDepotData NPFRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_penal
{
Trackdir trackdir = v->GetVehicleTrackdir();
NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, v->tile, ReverseTrackdir(trackdir), false, NULL, TRANSPORT_ROAD, v->compatible_roadtypes, v->owner, INVALID_RAILTYPES, 0);
AyStarUserData user = { v->owner, TRANSPORT_ROAD, INVALID_RAILTYPES, v->compatible_roadtypes };
NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, v->tile, ReverseTrackdir(trackdir), false, NULL, &user, 0);
if (ftd.best_bird_dist != 0) return FindDepotData();
@@ -1142,7 +1135,8 @@ Trackdir NPFRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDir
NPFFillWithOrderData(&fstd, v);
Trackdir trackdir = DiagDirToDiagTrackdir(enterdir);
NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_ROAD, v->compatible_roadtypes, v->owner, INVALID_RAILTYPES);
AyStarUserData user = { v->owner, TRANSPORT_ROAD, INVALID_RAILTYPES, v->compatible_roadtypes };
NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, &user);
if (ftd.best_trackdir == INVALID_TRACKDIR) {
/* We are already at our target. Just do something
* @todo: maybe display error?
@@ -1169,7 +1163,8 @@ Track NPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir,
NPFFillWithOrderData(&fstd, v);
NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_WATER, 0, v->owner, INVALID_RAILTYPES);
AyStarUserData user = { v->owner, TRANSPORT_WATER, INVALID_RAILTYPES, ROADTYPES_NONE };
NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, &user);
/* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
* the direction we need to take to get there, if ftd.best_bird_dist is not 0,
@@ -1192,7 +1187,8 @@ bool NPFShipCheckReverse(const Ship *v)
assert(trackdir != INVALID_TRACKDIR);
assert(trackdir_rev != INVALID_TRACKDIR);
ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, false, v->tile, trackdir_rev, false, &fstd, TRANSPORT_WATER, 0, v->owner, INVALID_RAILTYPES);
AyStarUserData user = { v->owner, TRANSPORT_WATER, INVALID_RAILTYPES, ROADTYPES_NONE };
ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, false, v->tile, trackdir_rev, false, &fstd, &user);
/* If we didn't find anything, just keep on going straight ahead, otherwise take the reverse flag */
return ftd.best_bird_dist == 0 && NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE);
}
@@ -1209,7 +1205,8 @@ FindDepotData NPFTrainFindNearestDepot(const Train *v, int max_penalty)
fstd.reserve_path = false;
assert(trackdir != INVALID_TRACKDIR);
NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, TRANSPORT_RAIL, 0, v->owner, v->compatible_railtypes, NPF_INFINITE_PENALTY);
AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE };
NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, &user, NPF_INFINITE_PENALTY);
if (ftd.best_bird_dist != 0) return FindDepotData();
/* Found target */
@@ -1230,18 +1227,15 @@ bool NPFTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir trackd
AyStarNode start1;
start1.tile = tile;
/* We set this in case the target is also the start tile, we will just
* return a not found then */
start1.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
start1.direction = trackdir;
NPFSetFlag(&start1, NPF_FLAG_IGNORE_RESERVED, true);
RailTypes railtypes = v->compatible_railtypes;
if (override_railtype) railtypes |= GetRailTypeInfo(v->railtype)->compatible_railtypes;
/* perform a breadth first search. Target is NULL,
* since we are just looking for any safe tile...*/
return NPFRouteInternal(&start1, true, NULL, false, &fstd, NPFFindSafeTile, NPFCalcZero, TRANSPORT_RAIL, 0, v->owner, railtypes, 0).res_okay;
AyStarUserData user = { v->owner, TRANSPORT_RAIL, railtypes, ROADTYPES_NONE };
return NPFRouteInternal(&start1, true, NULL, false, &fstd, NPFFindSafeTile, NPFCalcZero, &user, 0, true).res_okay;
}
bool NPFTrainCheckReverse(const Train *v)
@@ -1257,7 +1251,8 @@ bool NPFTrainCheckReverse(const Train *v)
assert(trackdir != INVALID_TRACKDIR);
assert(trackdir_rev != INVALID_TRACKDIR);
ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, TRANSPORT_RAIL, 0, v->owner, v->compatible_railtypes);
AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE };
ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, &user);
/* If we didn't find anything, just keep on going straight ahead, otherwise take the reverse flag */
return ftd.best_bird_dist == 0 && NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE);
}
@@ -1270,7 +1265,8 @@ Track NPFTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir
PBSTileInfo origin = FollowTrainReservation(v);
assert(IsValidTrackdir(origin.trackdir));
NPFFoundTargetData ftd = NPFRouteToStationOrTile(origin.tile, origin.trackdir, true, &fstd, TRANSPORT_RAIL, 0, v->owner, v->compatible_railtypes);
AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE };
NPFFoundTargetData ftd = NPFRouteToStationOrTile(origin.tile, origin.trackdir, true, &fstd, &user);
if (target != NULL) {
target->tile = ftd.node.tile;

View File

@@ -403,6 +403,8 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
/* Penalty for reversing in a depot. */
assert(IsRailDepot(cur.tile));
segment_cost += Yapf().PfGetSettings().rail_depot_reverse_penalty;
} else if (IsRailDepotTile(cur.tile)) {
/* We will end in this pass (depot is possible target) */
end_segment_reason |= ESRB_DEPOT;
@@ -416,9 +418,16 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
CFollowTrackRail ft(v);
TileIndex t = cur.tile;
Trackdir td = cur.td;
/* Arbitrary maximum tiles to follow to avoid infinite loops. */
uint max_tiles = 20;
while (ft.Follow(t, td)) {
assert(t != ft.m_new_tile);
t = ft.m_new_tile;
if (t == cur.tile || --max_tiles == 0) {
/* We looped back on ourself or found another loop, bail out. */
td = INVALID_TRACKDIR;
break;
}
if (KillFirstBit(ft.m_new_td_bits) != TRACKDIR_BIT_NONE) {
/* We encountered a junction; it's going to be too complex to
* handle this perfectly, so just bail out. There is no simple
@@ -553,6 +562,9 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
} // for (;;)
/* Don't consider path any further it if exceeded max_cost. */
if (end_segment_reason & ESRB_PATH_TOO_LONG) return false;
bool target_seen = false;
if ((end_segment_reason & ESRB_POSSIBLE_TARGET) != ESRB_NONE) {
/* Depot, station or waypoint. */

View File

@@ -140,7 +140,8 @@ public:
* waypoint. */
Yapf().DisableCache(true);
}
/* FALL THROUGH */
FALLTHROUGH;
case OT_GOTO_STATION:
m_destTile = CalcClosestStationTile(v->current_order.GetDestination(), v->tile, v->current_order.IsType(OT_GOTO_STATION) ? STATION_RAIL : STATION_WAYPOINT);
m_dest_station_id = v->current_order.GetDestination();

View File

@@ -223,7 +223,7 @@ public:
return 't';
}
static bool stFindNearestDepotTwoWay(const Train *v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2, int max_penalty, int reverse_penalty, TileIndex *depot_tile, bool *reversed)
static FindDepotData stFindNearestDepotTwoWay(const Train *v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2, int max_penalty, int reverse_penalty)
{
Tpf pf1;
/*
@@ -236,16 +236,16 @@ public:
* depot orders and you do not disable automatic servicing.
*/
if (max_penalty != 0) pf1.DisableCache(true);
bool result1 = pf1.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty, depot_tile, reversed);
FindDepotData result1 = pf1.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty);
if (_debug_desync_level >= 2) {
Tpf pf2;
TileIndex depot_tile2 = INVALID_TILE;
bool reversed2 = false;
pf2.DisableCache(true);
bool result2 = pf2.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty, &depot_tile2, &reversed2);
if (result1 != result2 || (result1 && (*depot_tile != depot_tile2 || *reversed != reversed2))) {
DEBUG(desync, 2, "CACHE ERROR: FindNearestDepotTwoWay() = [%s, %s]", result1 ? "T" : "F", result2 ? "T" : "F");
FindDepotData result2 = pf2.FindNearestDepotTwoWay(v, t1, td1, t2, td2, max_penalty, reverse_penalty);
if (result1.tile != result2.tile || (result1.reverse != result2.reverse)) {
DEBUG(desync, 2, "CACHE ERROR: FindNearestDepotTwoWay() = [%s, %s]",
result1.tile != INVALID_TILE ? "T" : "F",
result2.tile != INVALID_TILE ? "T" : "F");
DumpState(pf1, pf2);
}
}
@@ -253,7 +253,7 @@ public:
return result1;
}
inline bool FindNearestDepotTwoWay(const Train *v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2, int max_penalty, int reverse_penalty, TileIndex *depot_tile, bool *reversed)
inline FindDepotData FindNearestDepotTwoWay(const Train *v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2, int max_penalty, int reverse_penalty)
{
/* set origin and destination nodes */
Yapf().SetOrigin(t1, td1, t2, td2, reverse_penalty, true);
@@ -261,13 +261,10 @@ public:
Yapf().SetMaxCost(max_penalty);
/* find the best path */
bool bFound = Yapf().FindPath(v);
if (!bFound) return false;
if (!Yapf().FindPath(v)) return FindDepotData();
/* some path found
* get found depot tile */
/* Some path found. */
Node *n = Yapf().GetBestNode();
*depot_tile = n->GetLastTile();
/* walk through the path back to the origin */
Node *pNode = n;
@@ -277,9 +274,7 @@ public:
/* if the origin node is our front vehicle tile/Trackdir then we didn't reverse
* but we can also look at the cost (== 0 -> not reversed, == reverse_penalty -> reversed) */
*reversed = (pNode->m_cost != 0);
return true;
return FindDepotData(n->GetLastTile(), n->m_cost, pNode->m_cost != 0);
}
};
@@ -611,15 +606,13 @@ bool YapfTrainCheckReverse(const Train *v)
FindDepotData YapfTrainFindNearestDepot(const Train *v, int max_penalty)
{
FindDepotData fdd;
const Train *last_veh = v->Last();
PBSTileInfo origin = FollowTrainReservation(v);
TileIndex last_tile = last_veh->tile;
Trackdir td_rev = ReverseTrackdir(last_veh->GetVehicleTrackdir());
typedef bool (*PfnFindNearestDepotTwoWay)(const Train*, TileIndex, Trackdir, TileIndex, Trackdir, int, int, TileIndex*, bool*);
typedef FindDepotData (*PfnFindNearestDepotTwoWay)(const Train*, TileIndex, Trackdir, TileIndex, Trackdir, int, int);
PfnFindNearestDepotTwoWay pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail1::stFindNearestDepotTwoWay;
/* check if non-default YAPF type needed */
@@ -627,9 +620,7 @@ FindDepotData YapfTrainFindNearestDepot(const Train *v, int max_penalty)
pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail2::stFindNearestDepotTwoWay; // Trackdir, forbid 90-deg
}
bool ret = pfnFindNearestDepotTwoWay(v, origin.tile, origin.trackdir, last_tile, td_rev, max_penalty, YAPF_INFINITE_PENALTY, &fdd.tile, &fdd.reverse);
fdd.best_length = ret ? max_penalty / 2 : UINT_MAX; // some fake distance or NOT_FOUND
return fdd;
return pfnFindNearestDepotTwoWay(v, origin.tile, origin.trackdir, last_tile, td_rev, max_penalty, YAPF_INFINITE_PENALTY);
}
bool YapfTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir td, bool override_railtype)