From 13f8fa8ba99ad4b9cca8ef5c624b42dc719860c0 Mon Sep 17 00:00:00 2001 From: KUDr Date: Tue, 17 Oct 2006 16:16:19 +0000 Subject: (svn r6800) -Feature change: [train is lost] message is now generated immediately when pathfinder can't find the path. (thanks MeusH, peter1138 and Brianetta for ideas and help). --- lang/english.txt | 3 +-- settings.c | 2 +- settings_gui.c | 2 +- train_cmd.c | 44 ++++++++++++++++++++++++++++++++------------ variables.h | 2 +- vehicle.h | 3 +++ yapf/yapf.h | 5 +++-- yapf/yapf_rail.cpp | 18 +++++++++++------- 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 > {}; -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; } -- cgit v1.2.3-54-g00ecf