src/train_cmd.cpp
changeset 6151 0986553bca91
parent 6150 98af28cf9665
child 6152 6f9fbee77a47
equal deleted inserted replaced
6150:98af28cf9665 6151:0986553bca91
  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;