summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lang/english.txt3
-rw-r--r--settings.c2
-rw-r--r--settings_gui.c2
-rw-r--r--train_cmd.c44
-rw-r--r--variables.h2
-rw-r--r--vehicle.h3
-rw-r--r--yapf/yapf.h5
-rw-r--r--yapf/yapf_rail.cpp18
8 files changed, 53 insertions, 26 deletions
diff --git a/lang/english.txt b/lang/english.txt
index d55e88d91..bf64c92e9 100644
--- a/lang/english.txt
+++ b/lang/english.txt
@@ -1026,8 +1026,7 @@ STR_CONFIG_PATCHES_NEW_PATHFINDING_ALL :{LTBLUE}New glo
STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Always allow small airports: {ORANGE}{STRING1}
-STR_CONFIG_PATCHES_LOST_TRAIN_DAYS :{LTBLUE}A train is lost if no progress is made for: {ORANGE}{STRING1} days
-STR_CONFIG_PATCHES_LOST_TRAIN_DAYS_DISABLED :{LTBLUE}A train is lost if no progress is made for: {ORANGE}disabled
+STR_CONFIG_PATCHES_WARN_LOST_TRAIN :{LTBLUE}Warn if train is lost: {ORANGE}{STRING1}
STR_CONFIG_PATCHES_ORDER_REVIEW :{LTBLUE}Review vehicles' orders: {ORANGE}{STRING1}
STR_CONFIG_PATCHES_ORDER_REVIEW_OFF :no
STR_CONFIG_PATCHES_ORDER_REVIEW_EXDEPOT :yes, but exclude stopped vehicles
diff --git a/settings.c b/settings.c
index 06a4870ba..6ffc63dbf 100644
--- a/settings.c
+++ b/settings.c
@@ -1290,7 +1290,7 @@ const SettingDesc _patch_settings[] = {
SDT_BOOL(Patches, train_income_warn, S, 0, true, STR_CONFIG_PATCHES_WARN_INCOME_LESS, NULL),
SDT_VAR(Patches, order_review_system,SLE_UINT8, S,MS, 2, 0, 2, 0, STR_CONFIG_PATCHES_ORDER_REVIEW, NULL),
SDT_BOOL(Patches, never_expire_vehicles, 0, 0, false, STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES,NULL),
- SDT_VAR(Patches, lost_train_days, SLE_UINT16, S,D0, 180, 180, 720, 0, STR_CONFIG_PATCHES_LOST_TRAIN_DAYS, NULL),
+ SDT_BOOL(Patches, lost_train_warn, S, 0, true, STR_CONFIG_PATCHES_WARN_LOST_TRAIN, NULL),
SDT_BOOL(Patches, autorenew, S, 0, false, STR_CONFIG_PATCHES_AUTORENEW_VEHICLE, EngineRenewUpdate),
SDT_VAR(Patches, autorenew_months, SLE_INT16, S, 0, 6, -12, 12, 0, STR_CONFIG_PATCHES_AUTORENEW_MONTHS, EngineRenewMonthsUpdate),
SDT_VAR(Patches, autorenew_money, SLE_UINT, S,CR,100000, 0, 2000000, 0, STR_CONFIG_PATCHES_AUTORENEW_MONEY, EngineRenewMoneyUpdate),
diff --git a/settings_gui.c b/settings_gui.c
index b93a480c8..95b381f79 100644
--- a/settings_gui.c
+++ b/settings_gui.c
@@ -631,7 +631,7 @@ static const char *_patches_vehicles[] = {
"train_income_warn",
"order_review_system",
"never_expire_vehicles",
- "lost_train_days",
+ "lost_train_warn",
"autorenew",
"autorenew_months",
"autorenew_money",
diff --git a/train_cmd.c b/train_cmd.c
index 4ae854bba..01849cb7e 100644
--- a/train_cmd.c
+++ b/train_cmd.c
@@ -2278,6 +2278,9 @@ static byte ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir,
{
TrainTrackFollowerData fd;
uint best_track;
+ // pathfinders are able to tell that route was only 'guessed'
+ bool path_not_found = false;
+
#ifdef PF_BENCHMARK
TIC()
#endif
@@ -2288,7 +2291,7 @@ static byte ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir,
if (KILL_FIRST_BIT(trackdirbits) == 0) return FIND_FIRST_BIT(trackdirbits);
if (_patches.yapf.rail_use_yapf) {
- Trackdir trackdir = YapfChooseRailTrack(v, tile, enterdir, trackdirbits);
+ Trackdir trackdir = YapfChooseRailTrack(v, tile, enterdir, trackdirbits, &path_not_found);
if (trackdir != INVALID_TRACKDIR) {
best_track = TrackdirToTrack(trackdir);
} else {
@@ -2319,6 +2322,7 @@ static byte ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir,
the direction we need to take to get there, if ftd.best_bird_dist is not 0,
we did not find our target, but ftd.best_trackdir contains the direction leading
to the tile closest to our target. */
+ if (ftd.best_bird_dist != 0) path_not_found = true;
/* Discard enterdir information, making it a normal track */
best_track = TrackdirToTrack(ftd.best_trackdir);
}
@@ -2339,6 +2343,9 @@ static byte ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir,
NewTrainPathfind(tile - TileOffsByDiagDir(enterdir), v->dest_tile,
v->u.rail.compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd);
+ // check whether the path was found or only 'guessed'
+ if (fd.best_bird_dist != 0) path_not_found = true;
+
if (fd.best_track == 0xff) {
// blaha
best_track = FIND_FIRST_BIT(trackdirbits);
@@ -2349,6 +2356,30 @@ static byte ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir,
time = NpfEndInterval(perf);
DEBUG(yapf, 4)("[YAPF][NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0);
}
+ // handle "path not found" state
+ if (path_not_found) {
+ // PF didn't find the route
+ if (!HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
+ // it is first time the problem occurred, set the "path not found" flag
+ SETBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
+ // and notify user about the event
+ if (_patches.lost_train_warn) {
+ SetDParam(0, v->unitnumber);
+ AddNewsItem(
+ STR_TRAIN_IS_LOST,
+ NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0),
+ v->index,
+ 0);
+ }
+ }
+ } else {
+ // route found, is the train marked with "path not found" flag?
+ if (HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
+ // clear the flag as the PF's problem was solved
+ CLRBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
+ // can we also delete the "News" item somehow?
+ }
+ }
#ifdef PF_BENCHMARK
TOC("PF time = ", 1)
@@ -3579,17 +3610,6 @@ void OnNewDay_Train(Vehicle *v)
CheckIfTrainNeedsService(v);
- // check if train hasn't advanced in its order list for a set number of days
- if (_patches.lost_train_days && v->num_orders && !(v->vehstatus & (VS_STOPPED | VS_CRASHED) ) && ++v->u.rail.days_since_order_progr >= _patches.lost_train_days && v->owner == _local_player) {
- v->u.rail.days_since_order_progr = 0;
- SetDParam(0, v->unitnumber);
- AddNewsItem(
- STR_TRAIN_IS_LOST,
- NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0),
- v->index,
- 0);
- }
-
CheckOrders(v);
/* update destination */
diff --git a/variables.h b/variables.h
index ef3d04b42..3c222ad1a 100644
--- a/variables.h
+++ b/variables.h
@@ -97,7 +97,7 @@ typedef struct Patches {
bool build_rawmaterial_ind; // allow building raw material industries
bool multiple_industry_per_town; // allow many industries of the same type per town
bool same_industry_close; // allow same type industries to be built close to each other
- uint16 lost_train_days; // if a train doesn't switch order in this amount of days, a train is lost warning is shown
+ bool lost_train_warn; // if a train can't find its destination, show a warning
uint8 order_review_system;
bool train_income_warn; // if train is generating little income, show a warning
bool status_long_date; // always show long date in status bar
diff --git a/vehicle.h b/vehicle.h
index 80b31b30d..fc6645ff1 100644
--- a/vehicle.h
+++ b/vehicle.h
@@ -92,6 +92,9 @@ enum {
// used to reverse the visible direction of the vehicle
VRF_REVERSE_DIRECTION = 4,
+
+ // used to mark train as lost because PF can't find the route
+ VRF_NO_PATH_TO_DESTINATION = 5,
};
typedef struct VehicleAir {
diff --git a/yapf/yapf.h b/yapf/yapf.h
index 55b9f73ca..3bf8468e9 100644
--- a/yapf/yapf.h
+++ b/yapf/yapf.h
@@ -27,10 +27,11 @@ Trackdir YapfChooseRoadTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir)
* @param v the train that needs to find a path
* @param tile the tile to find the path from (should be next tile the train is about to enter)
* @param enterdir diagonal direction which the RV will enter this new tile from
- * @param tracks available tracks on the new tile (to choose from)
+ * @param trackdirs available trackdirs on the new tile (to choose from)
+ * @param no_path_found [out] true is returned if no path can be found (returned Trackdir is only a 'guess')
* @return the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found
*/
-Trackdir YapfChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs);
+Trackdir YapfChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool *path_not_found);
/** Used by RV multistop feature to find the nearest road stop that has a free slot.
* @param v RV (its current tile will be the origin)
diff --git a/yapf/yapf_rail.cpp b/yapf/yapf_rail.cpp
index e80614662..0dc596927 100644
--- a/yapf/yapf_rail.cpp
+++ b/yapf/yapf_rail.cpp
@@ -103,21 +103,25 @@ public:
/// return debug report character to identify the transportation type
FORCEINLINE char TransportTypeChar() const {return 't';}
- static Trackdir stChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs)
+ static Trackdir stChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool *path_not_found)
{
// create pathfinder instance
Tpf pf;
- return pf.ChooseRailTrack(v, tile, enterdir, trackdirs);
+ return pf.ChooseRailTrack(v, tile, enterdir, trackdirs, path_not_found);
}
- FORCEINLINE Trackdir ChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs)
+ FORCEINLINE Trackdir ChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool *path_not_found)
{
// set origin and destination nodes
Yapf().SetOrigin(v->tile, GetVehicleTrackdir(v), INVALID_TILE, INVALID_TRACKDIR, 1, true);
Yapf().SetDestination(v);
// find the best path
- Yapf().FindPath(v);
+ bool path_found = Yapf().FindPath(v);
+ if (!path_found && path_not_found != NULL) {
+ // tell controller that the path was only 'guessed'
+ *path_not_found = !path_found;
+ }
// if path not found - return INVALID_TRACKDIR
Trackdir next_trackdir = INVALID_TRACKDIR;
@@ -195,10 +199,10 @@ struct CYapfAnyDepotRail2 : CYapfT<CYapfRail_TypesT<CYapfAnyDepotRail2, CFollowT
struct CYapfAnyDepotRail3 : CYapfT<CYapfRail_TypesT<CYapfAnyDepotRail3, CFollowTrackRailNo90, CRailNodeListTrackDir, CYapfDestinationAnyDepotRailT , CYapfFollowAnyDepotRailT> > {};
-Trackdir YapfChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs)
+Trackdir YapfChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool *path_not_found)
{
// default is YAPF type 2
- typedef Trackdir (*PfnChooseRailTrack)(Vehicle*, TileIndex, DiagDirection, TrackdirBits);
+ typedef Trackdir (*PfnChooseRailTrack)(Vehicle*, TileIndex, DiagDirection, TrackdirBits, bool*);
PfnChooseRailTrack pfnChooseRailTrack = &CYapfRail2::stChooseRailTrack;
// check if non-default YAPF type needed
@@ -207,7 +211,7 @@ Trackdir YapfChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir,
else if (_patches.yapf.disable_node_optimization)
pfnChooseRailTrack = &CYapfRail1::stChooseRailTrack; // Trackdir, allow 90-deg
- Trackdir td_ret = pfnChooseRailTrack(v, tile, enterdir, trackdirs);
+ Trackdir td_ret = pfnChooseRailTrack(v, tile, enterdir, trackdirs, path_not_found);
return td_ret;
}