src/train_cmd.cpp
changeset 5994 a067afdb59b1
parent 5993 956d341d930e
child 5998 2bfbade143ac
equal deleted inserted replaced
5993:956d341d930e 5994:a067afdb59b1
  2993 
  2993 
  2994 static void TrainController(Vehicle *v, bool update_image)
  2994 static void TrainController(Vehicle *v, bool update_image)
  2995 {
  2995 {
  2996 	Vehicle *prev;
  2996 	Vehicle *prev;
  2997 	GetNewVehiclePosResult gp;
  2997 	GetNewVehiclePosResult gp;
  2998 	uint32 r, tracks,ts;
  2998 	uint32 r, tracks, ts;
  2999 	Trackdir i;
  2999 	Trackdir i;
  3000 	DiagDirection enterdir;
  3000 	DiagDirection enterdir;
  3001 	Direction dir;
  3001 	Direction dir;
  3002 	Direction newdir;
  3002 	Direction newdir;
  3003 	Direction chosen_dir;
  3003 	Direction chosen_dir;
  3011 		if (v->u.rail.track != TRACK_BIT_WORMHOLE) {
  3011 		if (v->u.rail.track != TRACK_BIT_WORMHOLE) {
  3012 			/* Not inside tunnel */
  3012 			/* Not inside tunnel */
  3013 			if (GetNewVehiclePos(v, &gp)) {
  3013 			if (GetNewVehiclePos(v, &gp)) {
  3014 				/* Staying in the old tile */
  3014 				/* Staying in the old tile */
  3015 				if (v->u.rail.track == TRACK_BIT_DEPOT) {
  3015 				if (v->u.rail.track == TRACK_BIT_DEPOT) {
  3016 					/* inside depot */
  3016 					/* Inside depot */
  3017 					gp.x = v->x_pos;
  3017 					gp.x = v->x_pos;
  3018 					gp.y = v->y_pos;
  3018 					gp.y = v->y_pos;
  3019 				} else {
  3019 				} else {
  3020 					/* is not inside depot */
  3020 					/* Not inside depot */
  3021 
  3021 
  3022 					if (IsFrontEngine(v) && !TrainCheckIfLineEnds(v)) return;
  3022 					if (IsFrontEngine(v) && !TrainCheckIfLineEnds(v)) return;
  3023 
  3023 
  3024 					r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  3024 					r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  3025 					if (HASBIT(r, VETS_CANNOT_ENTER)) {
  3025 					if (HASBIT(r, VETS_CANNOT_ENTER)) {
  3041 
  3041 
  3042 				TrackBits bits;
  3042 				TrackBits bits;
  3043 				/* Determine what direction we're entering the new tile from */
  3043 				/* Determine what direction we're entering the new tile from */
  3044 				dir = GetNewVehicleDirectionByTile(gp.new_tile, gp.old_tile);
  3044 				dir = GetNewVehicleDirectionByTile(gp.new_tile, gp.old_tile);
  3045 				enterdir = DirToDiagDir(dir);
  3045 				enterdir = DirToDiagDir(dir);
  3046 				assert(enterdir==0 || enterdir==1 || enterdir==2 || enterdir==3);
  3046 				assert(IsValidDiagDirection(enterdir));
  3047 
  3047 
  3048 				/* Get the status of the tracks in the new tile and mask
  3048 				/* Get the status of the tracks in the new tile and mask
  3049 				 * away the bits that aren't reachable. */
  3049 				 * away the bits that aren't reachable. */
  3050 				ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL) & _reachable_tracks[enterdir];
  3050 				ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL) & _reachable_tracks[enterdir];
  3051 
  3051 
  3058 					/* We allow wagons to make 90 deg turns, because forbid_90_deg
  3058 					/* We allow wagons to make 90 deg turns, because forbid_90_deg
  3059 					 * can be switched on halfway a turn */
  3059 					 * can be switched on halfway a turn */
  3060 					bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
  3060 					bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
  3061 				}
  3061 				}
  3062 
  3062 
  3063 				if (bits == TRACK_BIT_NONE) {
  3063 				if (bits == TRACK_BIT_NONE) goto invalid_rail;
  3064 					//debug("%x == 0", bits);
       
  3065 					goto invalid_rail;
       
  3066 				}
       
  3067 
  3064 
  3068 				/* Check if the new tile contrains tracks that are compatible
  3065 				/* Check if the new tile contrains tracks that are compatible
  3069 				 * with the current train, if not, bail out. */
  3066 				 * with the current train, if not, bail out. */
  3070 				if (!CheckCompatibleRail(v, gp.new_tile)) {
  3067 				if (!CheckCompatibleRail(v, gp.new_tile)) goto invalid_rail;
  3071 					//debug("!CheckCompatibleRail(%p, %x)", v, gp.new_tile);
       
  3072 					goto invalid_rail;
       
  3073 				}
       
  3074 
  3068 
  3075 				if (prev == NULL) {
  3069 				if (prev == NULL) {
  3076 					/* Currently the locomotive is active. Determine which one of the
  3070 					/* Currently the locomotive is active. Determine which one of the
  3077 					 * available tracks to choose */
  3071 					 * available tracks to choose */
  3078 					chosen_track = 1 << ChooseTrainTrack(v, gp.new_tile, enterdir, bits);
  3072 					chosen_track = 1 << ChooseTrainTrack(v, gp.new_tile, enterdir, bits);
  3079 					assert(chosen_track & tracks);
  3073 					assert(chosen_track & tracks);
  3080 
  3074 
  3081 					/* Check if it's a red signal and that force proceed is not clicked. */
  3075 					/* Check if it's a red signal and that force proceed is not clicked. */
  3082 					if ( (tracks>>16)&chosen_track && v->u.rail.force_proceed == 0) goto red_light;
  3076 					if ((tracks >> 16) & chosen_track && v->u.rail.force_proceed == 0) goto red_light;
  3083 				} else {
  3077 				} else {
  3084 					static byte _matching_tracks[8] = {0x30, 1, 0xC, 2, 0x30, 1, 0xC, 2};
  3078 					static const TrackBits _matching_tracks[8] = {
       
  3079 							TRACK_BIT_LEFT  | TRACK_BIT_RIGHT, TRACK_BIT_X,
       
  3080 							TRACK_BIT_UPPER | TRACK_BIT_LOWER, TRACK_BIT_Y,
       
  3081 							TRACK_BIT_LEFT  | TRACK_BIT_RIGHT, TRACK_BIT_X,
       
  3082 							TRACK_BIT_UPPER | TRACK_BIT_LOWER, TRACK_BIT_Y
       
  3083 					};
  3085 
  3084 
  3086 					/* The wagon is active, simply follow the prev vehicle. */
  3085 					/* The wagon is active, simply follow the prev vehicle. */
  3087 					chosen_track = (TrackBits)(byte)(_matching_tracks[GetDirectionToVehicle(prev, gp.x, gp.y)] & bits);
  3086 					chosen_track = (TrackBits)(byte)(_matching_tracks[GetDirectionToVehicle(prev, gp.x, gp.y)] & bits);
  3088 				}
  3087 				}
  3089 
  3088 
  3090 				/* make sure chosen track is a valid track */
  3089 				/* Make sure chosen track is a valid track */
  3091 				assert(chosen_track==1 || chosen_track==2 || chosen_track==4 || chosen_track==8 || chosen_track==16 || chosen_track==32);
  3090 				assert(
       
  3091 						chosen_track == TRACK_BIT_X     || chosen_track == TRACK_BIT_Y ||
       
  3092 						chosen_track == TRACK_BIT_UPPER || chosen_track == TRACK_BIT_LOWER ||
       
  3093 						chosen_track == TRACK_BIT_LEFT  || chosen_track == TRACK_BIT_RIGHT);
  3092 
  3094 
  3093 				/* Update XY to reflect the entrance to the new tile, and select the direction to use */
  3095 				/* Update XY to reflect the entrance to the new tile, and select the direction to use */
  3094 				{
  3096 				{
  3095 					const byte *b = _initial_tile_subcoord[FIND_FIRST_BIT(chosen_track)][enterdir];
  3097 					const byte *b = _initial_tile_subcoord[FIND_FIRST_BIT(chosen_track)][enterdir];
  3096 					gp.x = (gp.x & ~0xF) | b[0];
  3098 					gp.x = (gp.x & ~0xF) | b[0];
  3124 
  3126 
  3125 				if (IsFrontEngine(v)) TrainMovedChangeSignals(gp.new_tile, enterdir);
  3127 				if (IsFrontEngine(v)) TrainMovedChangeSignals(gp.new_tile, enterdir);
  3126 
  3128 
  3127 				/* Signals can only change when the first
  3129 				/* Signals can only change when the first
  3128 				 * (above) or the last vehicle moves. */
  3130 				 * (above) or the last vehicle moves. */
  3129 				if (v->next == NULL)
  3131 				if (v->next == NULL) TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir));
  3130 					TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir));
       
  3131 
  3132 
  3132 				if (prev == NULL) AffectSpeedByDirChange(v, chosen_dir);
  3133 				if (prev == NULL) AffectSpeedByDirChange(v, chosen_dir);
  3133 
  3134 
  3134 				v->direction = chosen_dir;
  3135 				v->direction = chosen_dir;
  3135 			}
  3136 			}
  3136 		} else {
  3137 		} else {
  3137 			/* in tunnel on on a bridge */
  3138 			/* In tunnel or on a bridge */
  3138 			GetNewVehiclePos(v, &gp);
  3139 			GetNewVehiclePos(v, &gp);
  3139 
  3140 
  3140 			SetSpeedLimitOnBridge(v);
  3141 			SetSpeedLimitOnBridge(v);
  3141 
  3142 
  3142 			if (!(IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) || !HASBIT(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
  3143 			if (!(IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) || !HASBIT(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {