train_cmd.c
changeset 4870 0ee22ed51ada
parent 4856 3ed01482b9de
child 4996 c20caeeb1aed
equal deleted inserted replaced
4869:cded5f3a83c9 4870:0ee22ed51ada
  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) {