664 InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train); // updates the replace Train window |
664 InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train); // updates the replace Train window |
665 |
665 |
666 return value; |
666 return value; |
667 } |
667 } |
668 |
668 |
669 static bool IsTunnelTile(TileIndex tile) |
|
670 { |
|
671 return IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0x80) == 0; |
|
672 } |
|
673 |
|
674 |
669 |
675 /* Check if all the wagons of the given train are in a depot, returns the |
670 /* Check if all the wagons of the given train are in a depot, returns the |
676 * number of cars (including loco) then. If not, sets the error message to |
671 * number of cars (including loco) then. If not, sets the error message to |
677 * STR_881A_TRAINS_CAN_ONLY_BE_ALTERED and returns -1 */ |
672 * STR_881A_TRAINS_CAN_ONLY_BE_ALTERED and returns -1 */ |
678 int CheckTrainStoppedInDepot(const Vehicle *v) |
673 int CheckTrainStoppedInDepot(const Vehicle *v) |
1567 * value is unused when new depot finding and NPF are both disabled |
1560 * value is unused when new depot finding and NPF are both disabled |
1568 */ |
1561 */ |
1569 bool reverse; |
1562 bool reverse; |
1570 } TrainFindDepotData; |
1563 } TrainFindDepotData; |
1571 |
1564 |
1572 static bool TrainFindDepotEnumProc(TileIndex tile, TrainFindDepotData *tfdd, int track, uint length, byte *state) |
1565 static bool NtpCallbFindDepot(TileIndex tile, TrainFindDepotData *tfdd, int track, uint length) |
1573 { |
1566 { |
1574 if (IsTileType(tile, MP_RAILWAY) && IsTileOwner(tile, tfdd->owner)) { |
1567 if (IsTileType(tile, MP_RAILWAY) && IsTileOwner(tile, tfdd->owner)) { |
1575 if ((_m[tile].m5 & ~0x3) == 0xC0) { |
1568 if ((_m[tile].m5 & ~0x3) == 0xC0) { |
1576 if (length < tfdd->best_length) { |
1569 tfdd->best_length = length; |
1577 tfdd->best_length = length; |
1570 tfdd->tile = tile; |
1578 tfdd->tile = tile; |
|
1579 } |
|
1580 return true; |
1571 return true; |
1581 } |
1572 } |
1582 |
1573 } |
1583 // make sure the train doesn't run against a oneway signal |
1574 |
1584 if ((_m[tile].m5 & 0xC0) == 0x40) { |
1575 return false; |
1585 if (!(_m[tile].m3 & SignalAlongTrackdir(track)) && _m[tile].m3 & SignalAgainstTrackdir(track)) |
|
1586 return true; |
|
1587 } |
|
1588 } |
|
1589 |
|
1590 // stop searching if we've found a destination that is closer already. |
|
1591 return length >= tfdd->best_length; |
|
1592 } |
1576 } |
1593 |
1577 |
1594 // returns the tile of a depot to goto to. The given vehicle must not be |
1578 // returns the tile of a depot to goto to. The given vehicle must not be |
1595 // crashed! |
1579 // crashed! |
1596 static TrainFindDepotData FindClosestTrainDepot(Vehicle *v) |
1580 static TrainFindDepotData FindClosestTrainDepot(Vehicle *v) |
1630 * is removed. */ |
1614 * is removed. */ |
1631 tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH; |
1615 tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH; |
1632 if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) |
1616 if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) |
1633 tfdd.reverse = true; |
1617 tfdd.reverse = true; |
1634 } |
1618 } |
1635 } else if (!_patches.new_depot_finding) { |
|
1636 // search in all directions |
|
1637 for(i=0; i!=4; i++) |
|
1638 NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL); |
|
1639 } else { |
1619 } else { |
1640 // search in the forward direction first. |
1620 // search in the forward direction first. |
1641 i = v->direction >> 1; |
1621 i = v->direction >> 1; |
1642 if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = (i - 1) & 3; } |
1622 if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = (i - 1) & 3; } |
1643 NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL); |
1623 NewTrainPathfind(tile, 0, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd); |
1644 if (tfdd.best_length == (uint)-1){ |
1624 if (tfdd.best_length == (uint)-1){ |
1645 tfdd.reverse = true; |
1625 tfdd.reverse = true; |
1646 // search in backwards direction |
1626 // search in backwards direction |
1647 i = (v->direction^4) >> 1; |
1627 i = (v->direction^4) >> 1; |
1648 if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = (i - 1) & 3; } |
1628 if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = (i - 1) & 3; } |
1649 NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL); |
1629 NewTrainPathfind(tile, 0, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd); |
1650 } |
1630 } |
1651 } |
1631 } |
1652 |
1632 |
1653 return tfdd; |
1633 return tfdd; |
1654 } |
1634 } |
1885 uint best_bird_dist; |
1865 uint best_bird_dist; |
1886 uint best_track_dist; |
1866 uint best_track_dist; |
1887 byte best_track; |
1867 byte best_track; |
1888 } TrainTrackFollowerData; |
1868 } TrainTrackFollowerData; |
1889 |
1869 |
1890 static bool TrainTrackFollower(TileIndex tile, TrainTrackFollowerData *ttfd, int track, uint length, byte *state) |
1870 static bool NtpCallbFindStation(TileIndex tile, TrainTrackFollowerData *ttfd, int track, uint length) |
1891 { |
1871 { |
1892 // heading for nowhere? |
1872 // heading for nowhere? |
1893 if (ttfd->dest_coords == 0) |
1873 if (ttfd->dest_coords == 0) |
1894 return false; |
1874 return false; |
1895 |
1875 |
1898 (IsTileType(tile, MP_STATION) && IS_BYTE_INSIDE(_m[tile].m5, 0, 8) && _m[tile].m2 == ttfd->station_index)) { |
1878 (IsTileType(tile, MP_STATION) && IS_BYTE_INSIDE(_m[tile].m5, 0, 8) && _m[tile].m2 == ttfd->station_index)) { |
1899 /* We do not check for dest_coords if we have a station_index, |
1879 /* We do not check for dest_coords if we have a station_index, |
1900 * because in that case the dest_coords are just an |
1880 * because in that case the dest_coords are just an |
1901 * approximation of where the station is */ |
1881 * approximation of where the station is */ |
1902 // found station |
1882 // found station |
1903 ttfd->best_bird_dist = 0; |
1883 ttfd->best_track = track; |
1904 if (length < ttfd->best_track_dist) { |
|
1905 ttfd->best_track_dist = length; |
|
1906 ttfd->best_track = state[1]; |
|
1907 } |
|
1908 return true; |
1884 return true; |
1909 } else { |
1885 } else { |
1910 uint dist; |
1886 uint dist; |
1911 |
1887 |
1912 // we've actually found the destination already. no point searching in directions longer than this. |
1888 // didn't find station, keep track of the best path so far. |
1913 if (ttfd->best_track_dist != (uint)-1) |
|
1914 return length >= ttfd->best_track_dist; |
|
1915 |
|
1916 // didn't find station |
|
1917 dist = DistanceManhattan(tile, ttfd->dest_coords); |
1889 dist = DistanceManhattan(tile, ttfd->dest_coords); |
1918 if (dist < ttfd->best_bird_dist) { |
1890 if (dist < ttfd->best_bird_dist) { |
1919 ttfd->best_bird_dist = dist; |
1891 ttfd->best_bird_dist = dist; |
1920 ttfd->best_track = state[1]; |
1892 ttfd->best_track = track; |
1921 } |
1893 } |
1922 return false; |
1894 return false; |
1923 } |
1895 } |
1924 } |
1896 } |
1925 |
1897 |
2044 /* New train pathfinding */ |
2016 /* New train pathfinding */ |
2045 fd.best_bird_dist = (uint)-1; |
2017 fd.best_bird_dist = (uint)-1; |
2046 fd.best_track_dist = (uint)-1; |
2018 fd.best_track_dist = (uint)-1; |
2047 fd.best_track = 0xFF; |
2019 fd.best_track = 0xFF; |
2048 |
2020 |
2049 NewTrainPathfind(tile - TileOffsByDir(enterdir), enterdir, (TPFEnumProc*)TrainTrackFollower, &fd, NULL); |
2021 NewTrainPathfind(tile - TileOffsByDir(enterdir), v->dest_tile, |
|
2022 enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd); |
2050 |
2023 |
2051 if (fd.best_track == 0xff) { |
2024 if (fd.best_track == 0xff) { |
2052 // blaha |
2025 // blaha |
2053 best_track = FIND_FIRST_BIT(trackdirbits); |
2026 best_track = FIND_FIRST_BIT(trackdirbits); |
2054 } else { |
2027 } else { |
2116 } else { |
2089 } else { |
2117 while(true) { |
2090 while(true) { |
2118 fd.best_bird_dist = (uint)-1; |
2091 fd.best_bird_dist = (uint)-1; |
2119 fd.best_track_dist = (uint)-1; |
2092 fd.best_track_dist = (uint)-1; |
2120 |
2093 |
2121 NewTrainPathfind(v->tile, reverse ^ i, (TPFEnumProc*)TrainTrackFollower, &fd, NULL); |
2094 NewTrainPathfind(v->tile, v->dest_tile, reverse ^ i, (NTPEnumProc*)NtpCallbFindStation, &fd); |
2122 |
2095 |
2123 if (best_track != -1) { |
2096 if (best_track != -1) { |
2124 if (best_bird_dist != 0) { |
2097 if (best_bird_dist != 0) { |
2125 if (fd.best_bird_dist != 0) { |
2098 if (fd.best_bird_dist != 0) { |
2126 /* neither reached the destination, pick the one with the smallest bird dist */ |
2099 /* neither reached the destination, pick the one with the smallest bird dist */ |
2859 } |
2832 } |
2860 } else { |
2833 } else { |
2861 /* in tunnel */ |
2834 /* in tunnel */ |
2862 GetNewVehiclePos(v, &gp); |
2835 GetNewVehiclePos(v, &gp); |
2863 |
2836 |
2864 if (IsTileType(gp.new_tile, MP_TUNNELBRIDGE) && |
2837 // Check if to exit the tunnel... |
2865 !(_m[gp.new_tile].m5 & 0xF0)) { |
2838 if (!IsTunnelTile(gp.new_tile) || |
2866 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); |
2839 !(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y)&0x4) ) { |
2867 if (r & 0x4) goto common; |
2840 v->x_pos = gp.x; |
2868 } |
2841 v->y_pos = gp.y; |
2869 |
2842 VehiclePositionChanged(v); |
2870 v->x_pos = gp.x; |
2843 continue; |
2871 v->y_pos = gp.y; |
2844 } |
2872 VehiclePositionChanged(v); |
2845 } |
2873 continue; |
|
2874 } |
|
2875 common:; |
|
2876 |
2846 |
2877 /* update image of train, as well as delta XY */ |
2847 /* update image of train, as well as delta XY */ |
2878 newdir = GetNewVehicleDirection(v, gp.x, gp.y); |
2848 newdir = GetNewVehicleDirection(v, gp.x, gp.y); |
2879 UpdateTrainDeltaXY(v, newdir); |
2849 UpdateTrainDeltaXY(v, newdir); |
2880 v->cur_image = GetTrainImage(v, newdir); |
2850 v->cur_image = GetTrainImage(v, newdir); |