* Returns direction to for a road vehicle to take or * INVALID_TRACKDIR if the direction is currently blocked * @param v the Vehicle to do the pathfinding for * @param tile the where to start the pathfinding * @param enterdir the direction the vehicle enters the tile from * @return the Trackdir to take */
| 886 | * @return the Trackdir to take |
| 887 | */ |
| 888 | static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection enterdir) |
| 889 | { |
| 890 | #define return_track(x) { best_track = (Trackdir)x; goto found_best_track; } |
| 891 | |
| 892 | TileIndex desttile; |
| 893 | Trackdir best_track; |
| 894 | bool path_found = true; |
| 895 | |
| 896 | TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype)); |
| 897 | TrackdirBits red_signals = TrackStatusToRedSignals(ts); // crossing |
| 898 | TrackdirBits trackdirs = TrackStatusToTrackdirBits(ts); |
| 899 | |
| 900 | if (IsTileType(tile, MP_ROAD)) { |
| 901 | if (IsRoadDepot(tile) && (!IsTileOwner(tile, v->owner) || GetRoadDepotDirection(tile) == enterdir)) { |
| 902 | /* Road depot owned by another company or with the wrong orientation */ |
| 903 | trackdirs = TRACKDIR_BIT_NONE; |
| 904 | } |
| 905 | } else if (IsTileType(tile, MP_STATION) && IsBayRoadStopTile(tile)) { |
| 906 | /* Standard road stop (drive-through stops are treated as normal road) */ |
| 907 | |
| 908 | if (!IsTileOwner(tile, v->owner) || GetBayRoadStopDir(tile) == enterdir || v->HasArticulatedPart()) { |
| 909 | /* different station owner or wrong orientation or the vehicle has articulated parts */ |
| 910 | trackdirs = TRACKDIR_BIT_NONE; |
| 911 | } else { |
| 912 | /* Our station */ |
| 913 | RoadStopType rstype = v->IsBus() ? RoadStopType::Bus : RoadStopType::Truck; |
| 914 | |
| 915 | if (GetRoadStopType(tile) != rstype) { |
| 916 | /* Wrong station type */ |
| 917 | trackdirs = TRACKDIR_BIT_NONE; |
| 918 | } else { |
| 919 | /* Proper station type, check if there is free loading bay */ |
| 920 | if (!_settings_game.pf.roadveh_queue && IsBayRoadStopTile(tile) && |
| 921 | !RoadStop::GetByTile(tile, rstype)->HasFreeBay()) { |
| 922 | /* Station is full and RV queuing is off */ |
| 923 | trackdirs = TRACKDIR_BIT_NONE; |
| 924 | } |
| 925 | } |
| 926 | } |
| 927 | } |
| 928 | /* The above lookups should be moved to GetTileTrackStatus in the |
| 929 | * future, but that requires more changes to the pathfinder and other |
| 930 | * stuff, probably even more arguments to GTTS. |
| 931 | */ |
| 932 | |
| 933 | /* Remove tracks unreachable from the enter dir */ |
| 934 | trackdirs &= DiagdirReachesTrackdirs(enterdir); |
| 935 | if (trackdirs == TRACKDIR_BIT_NONE) { |
| 936 | /* If vehicle expected a path, it no longer exists, so invalidate it. */ |
| 937 | if (!v->path.empty()) v->path.clear(); |
| 938 | /* No reachable tracks, so we'll reverse */ |
| 939 | return_track(_road_reverse_table[enterdir]); |
| 940 | } |
| 941 | |
| 942 | if (v->reverse_ctr != 0) { |
| 943 | bool reverse = true; |
| 944 | if (RoadTypeIsTram(v->roadtype)) { |
| 945 | /* Trams may only reverse on a tile if it contains at least the straight |
no test coverage detected