2879 } |
2879 } |
2880 |
2880 |
2881 static void TrainController(Vehicle *v, bool update_image) |
2881 static void TrainController(Vehicle *v, bool update_image) |
2882 { |
2882 { |
2883 Vehicle *prev; |
2883 Vehicle *prev; |
2884 GetNewVehiclePosResult gp; |
|
2885 uint32 ts; |
|
2886 DiagDirection enterdir; |
|
2887 Direction dir; |
|
2888 |
2884 |
2889 /* For every vehicle after and including the given vehicle */ |
2885 /* For every vehicle after and including the given vehicle */ |
2890 for (prev = GetPrevVehicleInChain(v); v != NULL; prev = v, v = v->next) { |
2886 for (prev = GetPrevVehicleInChain(v); v != NULL; prev = v, v = v->next) { |
2891 BeginVehicleMove(v); |
2887 BeginVehicleMove(v); |
2892 |
2888 |
|
2889 GetNewVehiclePosResult gp; |
2893 if (v->u.rail.track != TRACK_BIT_WORMHOLE) { |
2890 if (v->u.rail.track != TRACK_BIT_WORMHOLE) { |
2894 /* Not inside tunnel */ |
2891 /* Not inside tunnel */ |
2895 if (GetNewVehiclePos(v, &gp)) { |
2892 if (GetNewVehiclePos(v, &gp)) { |
2896 /* Staying in the old tile */ |
2893 /* Staying in the old tile */ |
2897 if (v->u.rail.track == TRACK_BIT_DEPOT) { |
2894 if (v->u.rail.track == TRACK_BIT_DEPOT) { |
2919 } |
2916 } |
2920 } |
2917 } |
2921 } else { |
2918 } else { |
2922 /* A new tile is about to be entered. */ |
2919 /* A new tile is about to be entered. */ |
2923 |
2920 |
2924 TrackBits bits; |
|
2925 /* Determine what direction we're entering the new tile from */ |
2921 /* Determine what direction we're entering the new tile from */ |
2926 dir = GetNewVehicleDirectionByTile(gp.new_tile, gp.old_tile); |
2922 Direction dir = GetNewVehicleDirectionByTile(gp.new_tile, gp.old_tile); |
2927 enterdir = DirToDiagDir(dir); |
2923 DiagDirection enterdir = DirToDiagDir(dir); |
2928 assert(IsValidDiagDirection(enterdir)); |
2924 assert(IsValidDiagDirection(enterdir)); |
2929 |
2925 |
2930 /* Get the status of the tracks in the new tile and mask |
2926 /* Get the status of the tracks in the new tile and mask |
2931 * away the bits that aren't reachable. */ |
2927 * away the bits that aren't reachable. */ |
2932 ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL) & _reachable_tracks[enterdir]; |
2928 uint32 ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL) & _reachable_tracks[enterdir]; |
2933 |
2929 |
2934 /* Combine the from & to directions. |
2930 /* Combine the from & to directions. |
2935 * Now, the lower byte contains the track status, and the byte at bit 16 contains |
2931 * Now, the lower byte contains the track status, and the byte at bit 16 contains |
2936 * the signal status. */ |
2932 * the signal status. */ |
2937 uint32 tracks = ts | (ts >> 8); |
2933 uint32 tracks = ts | (ts >> 8); |
2938 bits = (TrackBits)(tracks & TRACK_BIT_MASK); |
2934 TrackBits bits = (TrackBits)(tracks & TRACK_BIT_MASK); |
2939 if ((_patches.new_pathfinding_all || _patches.yapf.rail_use_yapf) && _patches.forbid_90_deg && prev == NULL) { |
2935 if ((_patches.new_pathfinding_all || _patches.yapf.rail_use_yapf) && _patches.forbid_90_deg && prev == NULL) { |
2940 /* We allow wagons to make 90 deg turns, because forbid_90_deg |
2936 /* We allow wagons to make 90 deg turns, because forbid_90_deg |
2941 * can be switched on halfway a turn */ |
2937 * can be switched on halfway a turn */ |
2942 bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track)); |
2938 bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track)); |
2943 } |
2939 } |
2954 * available tracks to choose */ |
2950 * available tracks to choose */ |
2955 chosen_track = 1 << ChooseTrainTrack(v, gp.new_tile, enterdir, bits); |
2951 chosen_track = 1 << ChooseTrainTrack(v, gp.new_tile, enterdir, bits); |
2956 assert(chosen_track & tracks); |
2952 assert(chosen_track & tracks); |
2957 |
2953 |
2958 /* Check if it's a red signal and that force proceed is not clicked. */ |
2954 /* Check if it's a red signal and that force proceed is not clicked. */ |
2959 if ((tracks >> 16) & chosen_track && v->u.rail.force_proceed == 0) goto red_light; |
2955 if ((tracks >> 16) & chosen_track && v->u.rail.force_proceed == 0) { |
|
2956 // In front of a red signal |
|
2957 /* find the first set bit in ts. need to do it in 2 steps, since |
|
2958 * FIND_FIRST_BIT only handles 6 bits at a time. */ |
|
2959 Trackdir i = FindFirstTrackdir((TrackdirBits)(uint16)ts); |
|
2960 |
|
2961 if (!HasSignalOnTrackdir(gp.new_tile, ReverseTrackdir(i))) { |
|
2962 v->cur_speed = 0; |
|
2963 v->subspeed = 0; |
|
2964 v->progress = 255 - 100; |
|
2965 if (++v->load_unload_time_rem < _patches.wait_oneway_signal * 20) return; |
|
2966 } else if (HasSignalOnTrackdir(gp.new_tile, i)) { |
|
2967 v->cur_speed = 0; |
|
2968 v->subspeed = 0; |
|
2969 v->progress = 255-10; |
|
2970 if (++v->load_unload_time_rem < _patches.wait_twoway_signal * 73) { |
|
2971 TileIndex o_tile = gp.new_tile + TileOffsByDiagDir(enterdir); |
|
2972 VehicleAtSignalData vasd; |
|
2973 vasd.tile = o_tile; |
|
2974 vasd.direction = ReverseDir(dir); |
|
2975 |
|
2976 /* check if a train is waiting on the other side */ |
|
2977 if (VehicleFromPos(o_tile, &vasd, CheckVehicleAtSignal) == NULL) return; |
|
2978 } |
|
2979 } |
|
2980 goto reverse_train_direction; |
|
2981 } |
2960 } else { |
2982 } else { |
2961 static const TrackBits _matching_tracks[8] = { |
2983 static const TrackBits _matching_tracks[8] = { |
2962 TRACK_BIT_LEFT | TRACK_BIT_RIGHT, TRACK_BIT_X, |
2984 TRACK_BIT_LEFT | TRACK_BIT_RIGHT, TRACK_BIT_X, |
2963 TRACK_BIT_UPPER | TRACK_BIT_LOWER, TRACK_BIT_Y, |
2985 TRACK_BIT_UPPER | TRACK_BIT_LOWER, TRACK_BIT_Y, |
2964 TRACK_BIT_LEFT | TRACK_BIT_RIGHT, TRACK_BIT_X, |
2986 TRACK_BIT_LEFT | TRACK_BIT_RIGHT, TRACK_BIT_X, |
3052 return; |
3074 return; |
3053 |
3075 |
3054 invalid_rail: |
3076 invalid_rail: |
3055 /* We've reached end of line?? */ |
3077 /* We've reached end of line?? */ |
3056 if (prev != NULL) error("!Disconnecting train"); |
3078 if (prev != NULL) error("!Disconnecting train"); |
3057 goto reverse_train_direction; |
|
3058 |
|
3059 red_light: { |
|
3060 /* We're in front of a red signal ?? */ |
|
3061 /* find the first set bit in ts. need to do it in 2 steps, since |
|
3062 * FIND_FIRST_BIT only handles 6 bits at a time. */ |
|
3063 Trackdir i = FindFirstTrackdir((TrackdirBits)(uint16)ts); |
|
3064 |
|
3065 if (!HasSignalOnTrackdir(gp.new_tile, ReverseTrackdir(i))) { |
|
3066 v->cur_speed = 0; |
|
3067 v->subspeed = 0; |
|
3068 v->progress = 255 - 100; |
|
3069 if (++v->load_unload_time_rem < _patches.wait_oneway_signal * 20) return; |
|
3070 } else if (HasSignalOnTrackdir(gp.new_tile, i)){ |
|
3071 v->cur_speed = 0; |
|
3072 v->subspeed = 0; |
|
3073 v->progress = 255-10; |
|
3074 if (++v->load_unload_time_rem < _patches.wait_twoway_signal * 73) { |
|
3075 TileIndex o_tile = gp.new_tile + TileOffsByDiagDir(enterdir); |
|
3076 VehicleAtSignalData vasd; |
|
3077 vasd.tile = o_tile; |
|
3078 vasd.direction = ReverseDir(dir); |
|
3079 |
|
3080 /* check if a train is waiting on the other side */ |
|
3081 if (VehicleFromPos(o_tile, &vasd, CheckVehicleAtSignal) == NULL) return; |
|
3082 } |
|
3083 } |
|
3084 } |
|
3085 |
3079 |
3086 reverse_train_direction: |
3080 reverse_train_direction: |
3087 v->load_unload_time_rem = 0; |
3081 v->load_unload_time_rem = 0; |
3088 v->cur_speed = 0; |
3082 v->cur_speed = 0; |
3089 v->subspeed = 0; |
3083 v->subspeed = 0; |