Merge branch 'master' into jgrpp

# Conflicts:
#	src/group_gui.cpp
#	src/lang/german.txt
#	src/lang/korean.txt
#	src/lang/traditional_chinese.txt
#	src/pathfinder/yapf/yapf_rail.cpp
#	src/saveload/vehicle_sl.cpp
#	src/window.cpp
This commit is contained in:
Jonathan G Rennison
2017-04-04 19:22:56 +01:00
5 changed files with 40 additions and 32 deletions

View File

@@ -541,6 +541,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;
@@ -554,9 +556,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
@@ -615,7 +624,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
/* Finish if we already exceeded the maximum path cost (i.e. when
* searching for the nearest depot). */
if (m_max_cost > 0 && (parent_cost + segment_entry_cost + segment_cost) > m_max_cost) {
end_segment_reason |= ESRB_PATH_TOO_LONG;
end_segment_reason |= ESRB_MAX_COST_EXCEEDED;
}
/* Move to the next tile/trackdir. */
@@ -691,6 +700,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_MAX_COST_EXCEEDED) return false;
bool target_seen = false;
if ((end_segment_reason & ESRB_POSSIBLE_TARGET) != ESRB_NONE) {
/* Depot, station or waypoint. */

View File

@@ -288,7 +288,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;
/*
@@ -301,16 +301,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_yapfdesync_level > 0 || _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, 0, "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, 0, "CACHE ERROR: FindNearestDepotTwoWay() = [%s, %s]",
result1.tile != INVALID_TILE ? "T" : "F",
result2.tile != INVALID_TILE ? "T" : "F");
DumpState(pf1, pf2);
}
}
@@ -318,7 +318,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);
@@ -326,13 +326,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;
@@ -342,9 +339,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);
}
};
@@ -684,15 +679,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 */
@@ -700,9 +693,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)

View File

@@ -19,6 +19,7 @@ enum EndSegmentReason {
ESR_RAIL_TYPE, ///< the next tile has a different rail type than our tiles
ESR_INFINITE_LOOP, ///< infinite loop detected
ESR_SEGMENT_TOO_LONG, ///< the segment is too long (possible infinite loop)
ESR_MAX_COST_EXCEEDED, ///< maximum cost is exceeded
ESR_CHOICE_FOLLOWS, ///< the next tile contains a choice (the track splits to more than one segments)
ESR_DEPOT, ///< stop in the depot (could be a target next time)
ESR_WAYPOINT, ///< waypoint encountered (could be a target next time)
@@ -43,6 +44,7 @@ enum EndSegmentReasonBits {
ESRB_RAIL_TYPE = 1 << ESR_RAIL_TYPE,
ESRB_INFINITE_LOOP = 1 << ESR_INFINITE_LOOP,
ESRB_SEGMENT_TOO_LONG = 1 << ESR_SEGMENT_TOO_LONG,
ESRB_MAX_COST_EXCEEDED = 1 << ESR_MAX_COST_EXCEEDED,
ESRB_CHOICE_FOLLOWS = 1 << ESR_CHOICE_FOLLOWS,
ESRB_DEPOT = 1 << ESR_DEPOT,
ESRB_WAYPOINT = 1 << ESR_WAYPOINT,
@@ -63,7 +65,7 @@ enum EndSegmentReasonBits {
ESRB_CACHED_MASK = ESRB_DEAD_END | ESRB_RAIL_TYPE | ESRB_INFINITE_LOOP | ESRB_SEGMENT_TOO_LONG | ESRB_CHOICE_FOLLOWS | ESRB_DEPOT | ESRB_WAYPOINT | ESRB_STATION | ESRB_SAFE_TILE,
/* Reasons to abort pathfinding in this direction. */
ESRB_ABORT_PF_MASK = ESRB_DEAD_END | ESRB_PATH_TOO_LONG | ESRB_INFINITE_LOOP | ESRB_FIRST_TWO_WAY_RED,
ESRB_ABORT_PF_MASK = ESRB_DEAD_END | ESRB_PATH_TOO_LONG | ESRB_MAX_COST_EXCEEDED | ESRB_INFINITE_LOOP | ESRB_FIRST_TWO_WAY_RED,
};
DECLARE_ENUM_AS_BIT_SET(EndSegmentReasonBits)
@@ -71,7 +73,7 @@ DECLARE_ENUM_AS_BIT_SET(EndSegmentReasonBits)
inline CStrA ValueStr(EndSegmentReasonBits bits)
{
static const char * const end_segment_reason_names[] = {
"DEAD_END", "RAIL_TYPE", "INFINITE_LOOP", "SEGMENT_TOO_LONG", "CHOICE_FOLLOWS",
"DEAD_END", "RAIL_TYPE", "INFINITE_LOOP", "SEGMENT_TOO_LONG", "MAX_COST_EXCEEDED", "CHOICE_FOLLOWS",
"DEPOT", "WAYPOINT", "STATION", "SAFE_TILE",
"PATH_TOO_LONG", "FIRST_TWO_WAY_RED", "LOOK_AHEAD_END", "TARGET_REACHED"
};