2276 /* choose a track */ |
2276 /* choose a track */ |
2277 static byte ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirbits) |
2277 static byte ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirbits) |
2278 { |
2278 { |
2279 TrainTrackFollowerData fd; |
2279 TrainTrackFollowerData fd; |
2280 uint best_track; |
2280 uint best_track; |
|
2281 // pathfinders are able to tell that route was only 'guessed' |
|
2282 bool path_not_found = false; |
|
2283 |
2281 #ifdef PF_BENCHMARK |
2284 #ifdef PF_BENCHMARK |
2282 TIC() |
2285 TIC() |
2283 #endif |
2286 #endif |
2284 |
2287 |
2285 assert((trackdirbits & ~0x3F) == 0); |
2288 assert((trackdirbits & ~0x3F) == 0); |
2286 |
2289 |
2287 /* quick return in case only one possible track is available */ |
2290 /* quick return in case only one possible track is available */ |
2288 if (KILL_FIRST_BIT(trackdirbits) == 0) return FIND_FIRST_BIT(trackdirbits); |
2291 if (KILL_FIRST_BIT(trackdirbits) == 0) return FIND_FIRST_BIT(trackdirbits); |
2289 |
2292 |
2290 if (_patches.yapf.rail_use_yapf) { |
2293 if (_patches.yapf.rail_use_yapf) { |
2291 Trackdir trackdir = YapfChooseRailTrack(v, tile, enterdir, trackdirbits); |
2294 Trackdir trackdir = YapfChooseRailTrack(v, tile, enterdir, trackdirbits, &path_not_found); |
2292 if (trackdir != INVALID_TRACKDIR) { |
2295 if (trackdir != INVALID_TRACKDIR) { |
2293 best_track = TrackdirToTrack(trackdir); |
2296 best_track = TrackdirToTrack(trackdir); |
2294 } else { |
2297 } else { |
2295 best_track = FIND_FIRST_BIT(TrackdirBitsToTrackBits(trackdirbits)); |
2298 best_track = FIND_FIRST_BIT(TrackdirBitsToTrackBits(trackdirbits)); |
2296 } |
2299 } |
2317 } else { |
2320 } else { |
2318 /* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains |
2321 /* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains |
2319 the direction we need to take to get there, if ftd.best_bird_dist is not 0, |
2322 the direction we need to take to get there, if ftd.best_bird_dist is not 0, |
2320 we did not find our target, but ftd.best_trackdir contains the direction leading |
2323 we did not find our target, but ftd.best_trackdir contains the direction leading |
2321 to the tile closest to our target. */ |
2324 to the tile closest to our target. */ |
|
2325 if (ftd.best_bird_dist != 0) path_not_found = true; |
2322 /* Discard enterdir information, making it a normal track */ |
2326 /* Discard enterdir information, making it a normal track */ |
2323 best_track = TrackdirToTrack(ftd.best_trackdir); |
2327 best_track = TrackdirToTrack(ftd.best_trackdir); |
2324 } |
2328 } |
2325 |
2329 |
2326 time = NpfEndInterval(perf); |
2330 time = NpfEndInterval(perf); |
2337 fd.best_track = 0xFF; |
2341 fd.best_track = 0xFF; |
2338 |
2342 |
2339 NewTrainPathfind(tile - TileOffsByDiagDir(enterdir), v->dest_tile, |
2343 NewTrainPathfind(tile - TileOffsByDiagDir(enterdir), v->dest_tile, |
2340 v->u.rail.compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd); |
2344 v->u.rail.compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd); |
2341 |
2345 |
|
2346 // check whether the path was found or only 'guessed' |
|
2347 if (fd.best_bird_dist != 0) path_not_found = true; |
|
2348 |
2342 if (fd.best_track == 0xff) { |
2349 if (fd.best_track == 0xff) { |
2343 // blaha |
2350 // blaha |
2344 best_track = FIND_FIRST_BIT(trackdirbits); |
2351 best_track = FIND_FIRST_BIT(trackdirbits); |
2345 } else { |
2352 } else { |
2346 best_track = fd.best_track & 7; |
2353 best_track = fd.best_track & 7; |
2347 } |
2354 } |
2348 |
2355 |
2349 time = NpfEndInterval(perf); |
2356 time = NpfEndInterval(perf); |
2350 DEBUG(yapf, 4)("[YAPF][NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0); |
2357 DEBUG(yapf, 4)("[YAPF][NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0); |
|
2358 } |
|
2359 // handle "path not found" state |
|
2360 if (path_not_found) { |
|
2361 // PF didn't find the route |
|
2362 if (!HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) { |
|
2363 // it is first time the problem occurred, set the "path not found" flag |
|
2364 SETBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION); |
|
2365 // and notify user about the event |
|
2366 if (_patches.lost_train_warn) { |
|
2367 SetDParam(0, v->unitnumber); |
|
2368 AddNewsItem( |
|
2369 STR_TRAIN_IS_LOST, |
|
2370 NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), |
|
2371 v->index, |
|
2372 0); |
|
2373 } |
|
2374 } |
|
2375 } else { |
|
2376 // route found, is the train marked with "path not found" flag? |
|
2377 if (HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) { |
|
2378 // clear the flag as the PF's problem was solved |
|
2379 CLRBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION); |
|
2380 // can we also delete the "News" item somehow? |
|
2381 } |
2351 } |
2382 } |
2352 |
2383 |
2353 #ifdef PF_BENCHMARK |
2384 #ifdef PF_BENCHMARK |
2354 TOC("PF time = ", 1) |
2385 TOC("PF time = ", 1) |
2355 #endif |
2386 #endif |
3577 CheckVehicleBreakdown(v); |
3608 CheckVehicleBreakdown(v); |
3578 AgeVehicle(v); |
3609 AgeVehicle(v); |
3579 |
3610 |
3580 CheckIfTrainNeedsService(v); |
3611 CheckIfTrainNeedsService(v); |
3581 |
3612 |
3582 // check if train hasn't advanced in its order list for a set number of days |
|
3583 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) { |
|
3584 v->u.rail.days_since_order_progr = 0; |
|
3585 SetDParam(0, v->unitnumber); |
|
3586 AddNewsItem( |
|
3587 STR_TRAIN_IS_LOST, |
|
3588 NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), |
|
3589 v->index, |
|
3590 0); |
|
3591 } |
|
3592 |
|
3593 CheckOrders(v); |
3613 CheckOrders(v); |
3594 |
3614 |
3595 /* update destination */ |
3615 /* update destination */ |
3596 if (v->current_order.type == OT_GOTO_STATION && |
3616 if (v->current_order.type == OT_GOTO_STATION && |
3597 (tile = GetStation(v->current_order.dest)->train_tile) != 0) { |
3617 (tile = GetStation(v->current_order.dest)->train_tile) != 0) { |