1327 |
1327 |
1328 typedef struct TrainFindDepotData { |
1328 typedef struct TrainFindDepotData { |
1329 uint best_length; |
1329 uint best_length; |
1330 uint tile; |
1330 uint tile; |
1331 byte owner; |
1331 byte owner; |
|
1332 /** |
|
1333 * true if reversing is necesarry for the train to get to this depot This |
|
1334 * value is unused when new depot finding and NPF are both disabled |
|
1335 */ |
|
1336 bool reverse; |
1332 } TrainFindDepotData; |
1337 } TrainFindDepotData; |
1333 |
1338 |
1334 static bool TrainFindDepotEnumProc(uint tile, TrainFindDepotData *tfdd, int track, uint length, byte *state) |
1339 static bool TrainFindDepotEnumProc(uint tile, TrainFindDepotData *tfdd, int track, uint length, byte *state) |
1335 { |
1340 { |
1336 if (IsTileType(tile, MP_RAILWAY) && _map_owner[tile] == tfdd->owner) { |
1341 if (IsTileType(tile, MP_RAILWAY) && _map_owner[tile] == tfdd->owner) { |
1363 |
1368 |
1364 assert(!(v->vehstatus & VS_CRASHED)); |
1369 assert(!(v->vehstatus & VS_CRASHED)); |
1365 |
1370 |
1366 tfdd.owner = v->owner; |
1371 tfdd.owner = v->owner; |
1367 tfdd.best_length = (uint)-1; |
1372 tfdd.best_length = (uint)-1; |
|
1373 tfdd.reverse = false; |
1368 |
1374 |
1369 if (IsTileDepotType(tile, TRANSPORT_RAIL)){ |
1375 if (IsTileDepotType(tile, TRANSPORT_RAIL)){ |
1370 tfdd.tile = tile; |
1376 tfdd.tile = tile; |
1371 tfdd.best_length = 0; |
1377 tfdd.best_length = 0; |
1372 return tfdd; |
1378 return tfdd; |
1374 |
1380 |
1375 if (v->u.rail.track == 0x40) { tile = GetVehicleOutOfTunnelTile(v); } |
1381 if (v->u.rail.track == 0x40) { tile = GetVehicleOutOfTunnelTile(v); } |
1376 |
1382 |
1377 if (_patches.new_pathfinding_all) { |
1383 if (_patches.new_pathfinding_all) { |
1378 NPFFoundTargetData ftd; |
1384 NPFFoundTargetData ftd; |
|
1385 Vehicle* last = GetLastVehicleInChain(v); |
1379 byte trackdir = GetVehicleTrackdir(v); |
1386 byte trackdir = GetVehicleTrackdir(v); |
|
1387 byte trackdir_rev = REVERSE_TRACKDIR(GetVehicleTrackdir(last)); |
|
1388 |
1380 assert (trackdir != 0xFF); |
1389 assert (trackdir != 0xFF); |
1381 ftd = NPFRouteToDepotBreadthFirst(v->tile, trackdir, TRANSPORT_RAIL, v->owner); |
1390 ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, NPF_INFINITE_PENALTY); |
1382 if (ftd.best_bird_dist == 0) { |
1391 if (ftd.best_bird_dist == 0) { |
1383 /* Found target */ |
1392 /* Found target */ |
1384 tfdd.tile = ftd.node.tile; |
1393 tfdd.tile = ftd.node.tile; |
1385 tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH; |
|
1386 /* Our caller expects a number of tiles, so we just approximate that |
1394 /* Our caller expects a number of tiles, so we just approximate that |
1387 * number by this. It might not be completely what we want, but it will |
1395 * number by this. It might not be completely what we want, but it will |
1388 * work for now :-) We can possibly change this when the old pathfinder |
1396 * work for now :-) We can possibly change this when the old pathfinder |
1389 * is removed. */ |
1397 * is removed. */ |
|
1398 tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH; |
|
1399 if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) |
|
1400 tfdd.reverse = true; |
1390 } |
1401 } |
1391 } else if (!_patches.new_depot_finding) { |
1402 } else if (!_patches.new_depot_finding) { |
1392 // search in all directions |
1403 // search in all directions |
1393 for(i=0; i!=4; i++) |
1404 for(i=0; i!=4; i++) |
1394 NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL); |
1405 NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL); |
1396 // search in the forward direction first. |
1407 // search in the forward direction first. |
1397 i = v->direction >> 1; |
1408 i = v->direction >> 1; |
1398 if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = (i - 1) & 3; } |
1409 if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = (i - 1) & 3; } |
1399 NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL); |
1410 NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL); |
1400 if (tfdd.best_length == (uint)-1){ |
1411 if (tfdd.best_length == (uint)-1){ |
|
1412 tfdd.reverse = true; |
1401 // search in backwards direction |
1413 // search in backwards direction |
1402 i = (v->direction^4) >> 1; |
1414 i = (v->direction^4) >> 1; |
1403 if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = (i - 1) & 3; } |
1415 if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = (i - 1) & 3; } |
1404 NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL); |
1416 NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL); |
1405 } |
1417 } |
1445 v->dest_tile = tfdd.tile; |
1457 v->dest_tile = tfdd.tile; |
1446 v->current_order.type = OT_GOTO_DEPOT; |
1458 v->current_order.type = OT_GOTO_DEPOT; |
1447 v->current_order.flags = OF_NON_STOP | OF_FULL_LOAD; |
1459 v->current_order.flags = OF_NON_STOP | OF_FULL_LOAD; |
1448 v->current_order.station = GetDepotByTile(tfdd.tile)->index; |
1460 v->current_order.station = GetDepotByTile(tfdd.tile)->index; |
1449 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
1461 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
|
1462 /* If there is no depot in front, reverse automatically */ |
|
1463 if (tfdd.reverse) |
|
1464 DoCommandByTile(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION); |
1450 } |
1465 } |
1451 |
1466 |
1452 return 0; |
1467 return 0; |
1453 } |
1468 } |
1454 |
1469 |
1866 Vehicle* last = GetLastVehicleInChain(v); |
1881 Vehicle* last = GetLastVehicleInChain(v); |
1867 |
1882 |
1868 NPFFillWithOrderData(&fstd, v); |
1883 NPFFillWithOrderData(&fstd, v); |
1869 |
1884 |
1870 trackdir = GetVehicleTrackdir(v); |
1885 trackdir = GetVehicleTrackdir(v); |
1871 trackdir_rev = REVERSE_TRACKDIR(GetVehicleTrackdir(v)); |
1886 trackdir_rev = REVERSE_TRACKDIR(GetVehicleTrackdir(last)); |
1872 assert(trackdir != 0xff); |
1887 assert(trackdir != 0xff); |
1873 assert(trackdir_rev != 0xff); |
1888 assert(trackdir_rev != 0xff); |
1874 |
1889 |
1875 ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner); |
1890 ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner); |
1876 if (ftd.best_bird_dist != 0) { |
1891 if (ftd.best_bird_dist != 0) { |