* Checks for line end. Also, bars crossing at next tile if needed * * @param v vehicle we are checking * @param reverse Set to false to not execute the vehicle reversing. This does not change any other logic. * @return true iff we did NOT have to reverse */
| 3894 | * @return true iff we did NOT have to reverse |
| 3895 | */ |
| 3896 | static bool TrainCheckIfLineEnds(Train *v, bool reverse) |
| 3897 | { |
| 3898 | /* First, handle broken down train */ |
| 3899 | |
| 3900 | int t = v->breakdown_ctr; |
| 3901 | if (t > 1) { |
| 3902 | v->vehstatus.Set(VehState::TrainSlowing); |
| 3903 | |
| 3904 | uint16_t break_speed = _breakdown_speeds[GB(~t, 4, 4)]; |
| 3905 | if (break_speed < v->cur_speed) v->cur_speed = break_speed; |
| 3906 | } else { |
| 3907 | v->vehstatus.Reset(VehState::TrainSlowing); |
| 3908 | } |
| 3909 | |
| 3910 | if (!TrainCanLeaveTile(v)) return true; |
| 3911 | |
| 3912 | /* Determine the non-diagonal direction in which we will exit this tile */ |
| 3913 | DiagDirection dir = VehicleExitDir(v->direction, v->track); |
| 3914 | /* Calculate next tile */ |
| 3915 | TileIndex tile = v->tile + TileOffsByDiagDir(dir); |
| 3916 | |
| 3917 | /* Determine the track status on the next tile */ |
| 3918 | TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0, ReverseDiagDir(dir)); |
| 3919 | TrackdirBits reachable_trackdirs = DiagdirReachesTrackdirs(dir); |
| 3920 | |
| 3921 | TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts) & reachable_trackdirs; |
| 3922 | TrackdirBits red_signals = TrackStatusToRedSignals(ts) & reachable_trackdirs; |
| 3923 | |
| 3924 | /* We are sure the train is not entering a depot, it is detected above */ |
| 3925 | |
| 3926 | /* mask unreachable track bits if we are forbidden to do 90deg turns */ |
| 3927 | TrackBits bits = TrackdirBitsToTrackBits(trackdirbits); |
| 3928 | if (Rail90DegTurnDisallowed(GetTileRailType(v->tile), GetTileRailType(tile))) { |
| 3929 | bits &= ~TrackCrossesTracks(FindFirstTrack(v->track)); |
| 3930 | } |
| 3931 | |
| 3932 | /* no suitable trackbits at all || unusable rail (wrong type or owner) */ |
| 3933 | if (bits == TRACK_BIT_NONE || !CheckCompatibleRail(v, tile)) { |
| 3934 | return TrainApproachingLineEnd(v, false, reverse); |
| 3935 | } |
| 3936 | |
| 3937 | /* approaching red signal */ |
| 3938 | if ((trackdirbits & red_signals) != 0) return TrainApproachingLineEnd(v, true, reverse); |
| 3939 | |
| 3940 | /* approaching a rail/road crossing? then make it red */ |
| 3941 | if (IsLevelCrossingTile(tile)) MaybeBarCrossingWithSound(tile); |
| 3942 | |
| 3943 | return true; |
| 3944 | } |
| 3945 | |
| 3946 | |
| 3947 | static bool TrainLocoHandler(Train *v, bool mode) |
no test coverage detected