(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).

pull/155/head
KUDr 18 years ago
parent 3625d6f06b
commit 13f8fa8ba9

@ -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

@ -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),

@ -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",

@ -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 */

@ -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

@ -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 {

@ -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)

@ -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;
}

Loading…
Cancel
Save