| 1056 | } |
| 1057 | |
| 1058 | static Trackdir FollowPreviousRoadVehicle(const RoadVehicle *v, const RoadVehicle *prev, TileIndex tile, DiagDirection entry_dir, bool already_reversed) |
| 1059 | { |
| 1060 | if (prev->tile == v->tile && !already_reversed) { |
| 1061 | /* If the previous vehicle is on the same tile as this vehicle is |
| 1062 | * then it must have reversed. */ |
| 1063 | return _road_reverse_table[entry_dir]; |
| 1064 | } |
| 1065 | |
| 1066 | uint8_t prev_state = prev->state; |
| 1067 | Trackdir dir; |
| 1068 | |
| 1069 | if (prev_state == RVSB_WORMHOLE || prev_state == RVSB_IN_DEPOT) { |
| 1070 | DiagDirection diag_dir = INVALID_DIAGDIR; |
| 1071 | |
| 1072 | if (IsTileType(tile, MP_TUNNELBRIDGE)) { |
| 1073 | diag_dir = GetTunnelBridgeDirection(tile); |
| 1074 | } else if (IsRoadDepotTile(tile)) { |
| 1075 | diag_dir = ReverseDiagDir(GetRoadDepotDirection(tile)); |
| 1076 | } |
| 1077 | |
| 1078 | if (diag_dir == INVALID_DIAGDIR) return INVALID_TRACKDIR; |
| 1079 | dir = DiagDirToDiagTrackdir(diag_dir); |
| 1080 | } else { |
| 1081 | if (already_reversed && (prev->tile != tile || (prev_state < TRACKDIR_END && IsReversingRoadTrackdir(static_cast<Trackdir>(prev_state))))) { |
| 1082 | /* |
| 1083 | * The vehicle has reversed, but did not go straight back. |
| 1084 | * It immediately turn onto another tile. This means that |
| 1085 | * the roadstate of the previous vehicle cannot be used |
| 1086 | * as the direction we have to go with this vehicle. |
| 1087 | * |
| 1088 | * Next table is build in the following way: |
| 1089 | * - first row for when the vehicle in front went to the northern or |
| 1090 | * western tile, second for southern and eastern. |
| 1091 | * - columns represent the entry direction. |
| 1092 | * - cell values are determined by the Trackdir one has to take from |
| 1093 | * the entry dir (column) to the tile in north or south by only |
| 1094 | * going over the trackdirs used for turning 90 degrees, i.e. |
| 1095 | * TRACKDIR_{UPPER,RIGHT,LOWER,LEFT}_{N,E,S,W}. |
| 1096 | */ |
| 1097 | bool north; |
| 1098 | if (prev->tile != tile) { |
| 1099 | north = prev->tile < tile; |
| 1100 | } else { |
| 1101 | north = (prev_state == TRACKDIR_RVREV_NW || prev_state == TRACKDIR_RVREV_NE); |
| 1102 | } |
| 1103 | static const Trackdir reversed_turn_lookup[2][DIAGDIR_END] = { |
| 1104 | { TRACKDIR_UPPER_W, TRACKDIR_RIGHT_N, TRACKDIR_LEFT_N, TRACKDIR_UPPER_E }, |
| 1105 | { TRACKDIR_RIGHT_S, TRACKDIR_LOWER_W, TRACKDIR_LOWER_E, TRACKDIR_LEFT_S }}; |
| 1106 | dir = reversed_turn_lookup[north ? 0 : 1][ReverseDiagDir(entry_dir)]; |
| 1107 | } else if (HasBit(prev_state, RVS_IN_DT_ROAD_STOP)) { |
| 1108 | dir = (Trackdir)(prev_state & RVSB_ROAD_STOP_TRACKDIR_MASK); |
| 1109 | } else if (prev_state < TRACKDIR_END) { |
| 1110 | dir = (Trackdir)prev_state; |
| 1111 | } else { |
| 1112 | return INVALID_TRACKDIR; |
| 1113 | } |
| 1114 | } |
| 1115 |
no test coverage detected