src/train_cmd.cpp
branchNewGRF_ports
changeset 6872 1c4a4a609f85
parent 6871 5a9dc001e1ad
child 6877 889301acc299
equal deleted inserted replaced
6871:5a9dc001e1ad 6872:1c4a4a609f85
     4 
     4 
     5 #include "stdafx.h"
     5 #include "stdafx.h"
     6 #include "openttd.h"
     6 #include "openttd.h"
     7 #include "bridge_map.h"
     7 #include "bridge_map.h"
     8 #include "debug.h"
     8 #include "debug.h"
     9 #include "functions.h"
     9 #include "tile_cmd.h"
    10 #include "landscape.h"
    10 #include "landscape.h"
    11 #include "gui.h"
    11 #include "gui.h"
    12 #include "station_map.h"
    12 #include "station_map.h"
    13 #include "table/strings.h"
       
    14 #include "strings.h"
       
    15 #include "map.h"
       
    16 #include "tile.h"
       
    17 #include "tunnel_map.h"
    13 #include "tunnel_map.h"
    18 #include "vehicle.h"
       
    19 #include "timetable.h"
    14 #include "timetable.h"
    20 #include "articulated_vehicles.h"
    15 #include "articulated_vehicles.h"
    21 #include "command.h"
    16 #include "command_func.h"
    22 #include "pathfind.h"
    17 #include "pathfind.h"
    23 #include "npf.h"
    18 #include "npf.h"
    24 #include "station.h"
    19 #include "station.h"
    25 #include "table/train_cmd.h"
       
    26 #include "news.h"
    20 #include "news.h"
    27 #include "engine.h"
    21 #include "engine.h"
    28 #include "player.h"
    22 #include "player_func.h"
    29 #include "sound.h"
    23 #include "player_base.h"
    30 #include "depot.h"
    24 #include "depot.h"
    31 #include "waypoint.h"
    25 #include "waypoint.h"
    32 #include "vehicle_gui.h"
    26 #include "vehicle_gui.h"
    33 #include "train.h"
    27 #include "train.h"
    34 #include "bridge.h"
    28 #include "bridge.h"
    35 #include "newgrf_callbacks.h"
    29 #include "newgrf_callbacks.h"
    36 #include "newgrf_engine.h"
    30 #include "newgrf_engine.h"
    37 #include "newgrf_sound.h"
    31 #include "newgrf_sound.h"
    38 #include "newgrf_text.h"
    32 #include "newgrf_text.h"
    39 #include "direction.h"
    33 #include "direction_func.h"
    40 #include "yapf/yapf.h"
    34 #include "yapf/yapf.h"
    41 #include "date.h"
       
    42 #include "cargotype.h"
    35 #include "cargotype.h"
    43 #include "group.h"
    36 #include "group.h"
    44 #include "table/sprites.h"
    37 #include "table/sprites.h"
       
    38 #include "tunnelbridge_map.h"
       
    39 #include "strings_func.h"
       
    40 #include "functions.h"
       
    41 #include "window_func.h"
       
    42 #include "date_func.h"
       
    43 #include "vehicle_func.h"
       
    44 #include "sound_func.h"
       
    45 #include "signal_func.h"
       
    46 #include "variables.h"
       
    47 #include "autoreplace_gui.h"
       
    48 #include "gfx_func.h"
       
    49 #include "settings_type.h"
       
    50 
       
    51 #include "table/strings.h"
       
    52 #include "table/train_cmd.h"
    45 
    53 
    46 static bool TrainCheckIfLineEnds(Vehicle *v);
    54 static bool TrainCheckIfLineEnds(Vehicle *v);
    47 static void TrainController(Vehicle *v, bool update_image);
    55 static void TrainController(Vehicle *v, bool update_image);
       
    56 static TileIndex TrainApproachingCrossingTile(const Vehicle *v);
    48 
    57 
    49 static const byte _vehicle_initial_x_fract[4] = {10, 8, 4,  8};
    58 static const byte _vehicle_initial_x_fract[4] = {10, 8, 4,  8};
    50 static const byte _vehicle_initial_y_fract[4] = { 8, 4, 8, 10};
    59 static const byte _vehicle_initial_y_fract[4] = { 8, 4, 8, 10};
    51 static const TrackBits _state_dir_table[4] = { TRACK_BIT_RIGHT, TRACK_BIT_LOWER, TRACK_BIT_LEFT, TRACK_BIT_UPPER };
    60 
       
    61 
       
    62 /**
       
    63  * Determine the side in which the train will leave the tile
       
    64  *
       
    65  * @param direction vehicle direction
       
    66  * @param track vehicle track bits
       
    67  * @return side of tile the train will leave
       
    68  */
       
    69 static inline DiagDirection TrainExitDir(Direction direction, TrackBits track)
       
    70 {
       
    71 	static const TrackBits state_dir_table[DIAGDIR_END] = { TRACK_BIT_RIGHT, TRACK_BIT_LOWER, TRACK_BIT_LEFT, TRACK_BIT_UPPER };
       
    72 
       
    73 	DiagDirection diagdir = DirToDiagDir(direction);
       
    74 
       
    75 	/* Determine the diagonal direction in which we will exit this tile */
       
    76 	if (!HasBit(direction, 0) && track != state_dir_table[diagdir]) {
       
    77 		diagdir = ChangeDiagDir(diagdir, DIAGDIRDIFF_90LEFT);
       
    78 	}
       
    79 
       
    80 	return diagdir;
       
    81 }
    52 
    82 
    53 
    83 
    54 /** Return the cargo weight multiplier to use for a rail vehicle
    84 /** Return the cargo weight multiplier to use for a rail vehicle
    55  * @param cargo Cargo type to get multiplier for
    85  * @param cargo Cargo type to get multiplier for
    56  * @return Cargo weight multiplier
    86  * @return Cargo weight multiplier
   100 		if (total_power == 0) v->vehstatus |= VS_STOPPED;
   130 		if (total_power == 0) v->vehstatus |= VS_STOPPED;
   101 
   131 
   102 		v->u.rail.cached_power = total_power;
   132 		v->u.rail.cached_power = total_power;
   103 		v->u.rail.cached_max_te = max_te;
   133 		v->u.rail.cached_max_te = max_te;
   104 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
   134 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
   105 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   135 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   106 	}
   136 	}
   107 }
   137 }
   108 
   138 
   109 
   139 
   110 /**
   140 /**
   158 	assert(IsFrontEngine(v) || IsFreeWagon(v));
   188 	assert(IsFrontEngine(v) || IsFreeWagon(v));
   159 
   189 
   160 	const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type);
   190 	const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type);
   161 	EngineID first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE;
   191 	EngineID first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE;
   162 	v->u.rail.cached_total_length = 0;
   192 	v->u.rail.cached_total_length = 0;
   163 	v->u.rail.compatible_railtypes = 0;
   193 	v->u.rail.compatible_railtypes = RAILTYPES_NONE;
       
   194 
       
   195 	bool train_can_tilt = true;
   164 
   196 
   165 	for (Vehicle *u = v; u != NULL; u = u->Next()) {
   197 	for (Vehicle *u = v; u != NULL; u = u->Next()) {
   166 		const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
   198 		const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
   167 
   199 
   168 		/* Check the v->first cache. */
   200 		/* Check the v->first cache. */
   169 		assert(u->First() == v);
   201 		assert(u->First() == v);
       
   202 
       
   203 		if (!HasBit(EngInfo(u->engine_type)->misc_flags, EF_RAIL_TILTS)) train_can_tilt = false;
   170 
   204 
   171 		/* update the 'first engine' */
   205 		/* update the 'first engine' */
   172 		u->u.rail.first_engine = v == u ? INVALID_ENGINE : first_engine;
   206 		u->u.rail.first_engine = v == u ? INVALID_ENGINE : first_engine;
   173 		u->u.rail.railtype = rvi_u->railtype;
   207 		u->u.rail.railtype = rvi_u->railtype;
   174 
   208 
   219 
   253 
   220 			/* Some electric engines can be allowed to run on normal rail. It happens to all
   254 			/* Some electric engines can be allowed to run on normal rail. It happens to all
   221 			 * existing electric engines when elrails are disabled and then re-enabled */
   255 			 * existing electric engines when elrails are disabled and then re-enabled */
   222 			if (HasBit(u->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL)) {
   256 			if (HasBit(u->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL)) {
   223 				u->u.rail.railtype = RAILTYPE_RAIL;
   257 				u->u.rail.railtype = RAILTYPE_RAIL;
   224 				u->u.rail.compatible_railtypes |= (1 << RAILTYPE_RAIL);
   258 				u->u.rail.compatible_railtypes |= RAILTYPES_RAIL;
   225 			}
   259 			}
   226 
   260 
   227 			/* max speed is the minimum of the speed limits of all vehicles in the consist */
   261 			/* max speed is the minimum of the speed limits of all vehicles in the consist */
   228 			if ((rvi_u->railveh_type != RAILVEH_WAGON || _patches.wagon_speed_limits) && !UsesWagonOverride(u)) {
   262 			if ((rvi_u->railveh_type != RAILVEH_WAGON || _patches.wagon_speed_limits) && !UsesWagonOverride(u)) {
   229 				uint16 speed = GetVehicleProperty(u, 0x09, rvi_u->max_speed);
   263 				uint16 speed = GetVehicleProperty(u, 0x09, rvi_u->max_speed);
   249 		v->u.rail.cached_total_length += u->u.rail.cached_veh_length;
   283 		v->u.rail.cached_total_length += u->u.rail.cached_veh_length;
   250 	}
   284 	}
   251 
   285 
   252 	/* store consist weight/max speed in cache */
   286 	/* store consist weight/max speed in cache */
   253 	v->u.rail.cached_max_speed = max_speed;
   287 	v->u.rail.cached_max_speed = max_speed;
       
   288 	v->u.rail.cached_tilt = train_can_tilt;
   254 
   289 
   255 	/* recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added) */
   290 	/* recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added) */
   256 	TrainCargoChanged(v);
   291 	TrainCargoChanged(v);
   257 }
   292 }
   258 
       
   259 /* These two arrays are used for realistic acceleration. XXX: How should they
       
   260  * be interpreted? */
       
   261 static const byte _curve_neighbours45[8][2] = {
       
   262 	{7, 1},
       
   263 	{0, 2},
       
   264 	{1, 3},
       
   265 	{2, 4},
       
   266 	{3, 5},
       
   267 	{4, 6},
       
   268 	{5, 7},
       
   269 	{6, 0},
       
   270 };
       
   271 
       
   272 static const byte _curve_neighbours90[8][2] = {
       
   273 	{6, 2},
       
   274 	{7, 3},
       
   275 	{0, 4},
       
   276 	{1, 5},
       
   277 	{2, 6},
       
   278 	{3, 7},
       
   279 	{4, 0},
       
   280 	{5, 1},
       
   281 };
       
   282 
   293 
   283 enum AccelType {
   294 enum AccelType {
   284 	AM_ACCEL,
   295 	AM_ACCEL,
   285 	AM_BRAKE
   296 	AM_BRAKE
   286 };
   297 };
   291 	StationID sid = GetStationIndex(tile);
   302 	StationID sid = GetStationIndex(tile);
   292 
   303 
   293 	assert(v->type == VEH_TRAIN);
   304 	assert(v->type == VEH_TRAIN);
   294 	/* When does a train drive through a station
   305 	/* When does a train drive through a station
   295 	 * first we deal with the "new nonstop handling" */
   306 	 * first we deal with the "new nonstop handling" */
   296 	if (_patches.new_nonstop && o->flags & OF_NON_STOP && sid == o->dest) {
   307 	if (_patches.new_nonstop && o->flags & OFB_NON_STOP && sid == o->dest) {
   297 		return false;
   308 		return false;
   298 	}
   309 	}
   299 
   310 
   300 	if (v->last_station_visited == sid) return false;
   311 	if (v->last_station_visited == sid) return false;
   301 
   312 
   302 	if (sid != o->dest && (o->flags & OF_NON_STOP || _patches.new_nonstop)) {
   313 	if (sid != o->dest && (o->flags & OFB_NON_STOP || _patches.new_nonstop)) {
   303 		return false;
   314 		return false;
   304 	}
   315 	}
   305 
   316 
   306 	return true;
   317 	return true;
   307 }
   318 }
   308 
   319 
   309 /** new acceleration*/
   320 /** new acceleration*/
   310 static int GetTrainAcceleration(Vehicle *v, bool mode)
   321 static int GetTrainAcceleration(Vehicle *v, bool mode)
   311 {
   322 {
   312 	int max_speed = 2000;
   323 	static const int absolute_max_speed = 2000;
       
   324 	int max_speed = absolute_max_speed;
   313 	int speed = v->cur_speed * 10 / 16; // km-ish/h -> mp/h
   325 	int speed = v->cur_speed * 10 / 16; // km-ish/h -> mp/h
   314 	int curvecount[2] = {0, 0};
   326 	int curvecount[2] = {0, 0};
   315 
   327 
   316 	/*first find the curve speed limit */
   328 	/*first find the curve speed limit */
   317 	int numcurve = 0;
   329 	int numcurve = 0;
   318 	int sum = 0;
   330 	int sum = 0;
   319 	int pos = 0;
   331 	int pos = 0;
   320 	int lastpos = -1;
   332 	int lastpos = -1;
   321 	for (const Vehicle *u = v; u->Next() != NULL; u = u->Next(), pos++) {
   333 	for (const Vehicle *u = v; u->Next() != NULL; u = u->Next(), pos++) {
   322 		Direction dir = u->direction;
   334 		Direction this_dir = u->direction;
   323 		Direction ndir = u->Next()->direction;
   335 		Direction next_dir = u->Next()->direction;
   324 		int i;
   336 
   325 
   337 		DirDiff dirdiff = DirDifference(this_dir, next_dir);
   326 		for (i = 0; i < 2; i++) {
   338 		if (dirdiff == DIRDIFF_SAME) continue;
   327 			if ( _curve_neighbours45[dir][i] == ndir) {
   339 
   328 				curvecount[i]++;
   340 		if (dirdiff == DIRDIFF_45LEFT) curvecount[0]++;
   329 				if (lastpos != -1) {
   341 		if (dirdiff == DIRDIFF_45RIGHT) curvecount[1]++;
   330 					numcurve++;
   342 		if (dirdiff == DIRDIFF_45LEFT || dirdiff == DIRDIFF_45RIGHT) {
   331 					sum += pos - lastpos;
   343 			if (lastpos != -1) {
   332 					if (pos - lastpos == 1) {
   344 				numcurve++;
   333 						max_speed = 88;
   345 				sum += pos - lastpos;
   334 					}
   346 				if (pos - lastpos == 1) {
       
   347 					max_speed = 88;
   335 				}
   348 				}
   336 				lastpos = pos;
   349 			}
   337 			}
   350 			lastpos = pos;
   338 		}
   351 		}
   339 
   352 
   340 		/*if we have a 90 degree turn, fix the speed limit to 60 */
   353 		/*if we have a 90 degree turn, fix the speed limit to 60 */
   341 		if (_curve_neighbours90[dir][0] == ndir ||
   354 		if (dirdiff == DIRDIFF_90LEFT || dirdiff == DIRDIFF_90RIGHT) {
   342 				_curve_neighbours90[dir][1] == ndir) {
       
   343 			max_speed = 61;
   355 			max_speed = 61;
   344 		}
   356 		}
   345 	}
   357 	}
   346 
       
   347 	if (numcurve > 0) sum /= numcurve;
       
   348 
   358 
   349 	if ((curvecount[0] != 0 || curvecount[1] != 0) && max_speed > 88) {
   359 	if ((curvecount[0] != 0 || curvecount[1] != 0) && max_speed > 88) {
   350 		int total = curvecount[0] + curvecount[1];
   360 		int total = curvecount[0] + curvecount[1];
   351 
   361 
   352 		if (curvecount[0] == 1 && curvecount[1] == 1) {
   362 		if (curvecount[0] == 1 && curvecount[1] == 1) {
   353 			max_speed = 0xFFFF;
   363 			max_speed = absolute_max_speed;
   354 		} else if (total > 1) {
   364 		} else if (total > 1) {
       
   365 			if (numcurve > 0) sum /= numcurve;
   355 			max_speed = 232 - (13 - Clamp(sum, 1, 12)) * (13 - Clamp(sum, 1, 12));
   366 			max_speed = 232 - (13 - Clamp(sum, 1, 12)) * (13 - Clamp(sum, 1, 12));
   356 		}
   367 		}
   357 	}
   368 	}
   358 
   369 
   359 	max_speed += (max_speed / 2) * v->u.rail.railtype;
   370 	if (max_speed != absolute_max_speed) {
       
   371 		/* Apply the engine's rail type curve speed advantage, if it slowed by curves */
       
   372 		const RailtypeInfo *rti = GetRailTypeInfo(v->u.rail.railtype);
       
   373 		max_speed += (max_speed / 2) * rti->curve_speed;
       
   374 
       
   375 		if (v->u.rail.cached_tilt) {
       
   376 			/* Apply max_speed bonus of 20% for a tilting train */
       
   377 			max_speed += max_speed / 5;
       
   378 		}
       
   379 	}
   360 
   380 
   361 	if (IsTileType(v->tile, MP_STATION) && IsFrontEngine(v)) {
   381 	if (IsTileType(v->tile, MP_STATION) && IsFrontEngine(v)) {
   362 		if (TrainShouldStop(v, v->tile)) {
   382 		if (TrainShouldStop(v, v->tile)) {
   363 			int station_length = GetStationByTile(v->tile)->GetPlatformLength(v->tile, DirToDiagDir(v->direction));
   383 			int station_length = GetStationByTile(v->tile)->GetPlatformLength(v->tile, DirToDiagDir(v->direction));
   364 			int delta_v;
   384 
   365 
   385 			int st_max_speed = 120;
   366 			max_speed = 120;
   386 
   367 
   387 			int delta_v = v->cur_speed / (station_length + 1);
   368 			delta_v = v->cur_speed / (station_length + 1);
   388 			if (v->max_speed > (v->cur_speed - delta_v)) {
   369 			if (v->max_speed > (v->cur_speed - delta_v))
   389 				st_max_speed = v->cur_speed - (delta_v / 10);
   370 				max_speed = v->cur_speed - (delta_v / 10);
   390 			}
   371 
   391 
   372 			max_speed = max(max_speed, 25 * station_length);
   392 			st_max_speed = max(st_max_speed, 25 * station_length);
       
   393 			max_speed = min(max_speed, st_max_speed);
   373 		}
   394 		}
   374 	}
   395 	}
   375 
   396 
   376 	int mass = v->u.rail.cached_weight;
   397 	int mass = v->u.rail.cached_weight;
   377 	int power = v->u.rail.cached_power * 746;
   398 	int power = v->u.rail.cached_power * 746;
   466 	if (HasBit(this->u.rail.flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction);
   487 	if (HasBit(this->u.rail.flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction);
   467 
   488 
   468 	if (is_custom_sprite(img)) {
   489 	if (is_custom_sprite(img)) {
   469 		base = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img)));
   490 		base = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img)));
   470 		if (base != 0) return base;
   491 		if (base != 0) return base;
   471 		img = orig_rail_vehicle_info[this->engine_type].image_index;
   492 		img = _orig_rail_vehicle_info[this->engine_type].image_index;
   472 	}
   493 	}
   473 
   494 
   474 	base = _engine_sprite_base[img] + ((direction + _engine_sprite_add[img]) & _engine_sprite_and[img]);
   495 	base = _engine_sprite_base[img] + ((direction + _engine_sprite_add[img]) & _engine_sprite_and[img]);
   475 
   496 
   476 	if (this->cargo.Count() >= this->cargo_cap / 2U) base += _wagon_full_adder[img];
   497 	if (this->cargo.Count() >= this->cargo_cap / 2U) base += _wagon_full_adder[img];
   485 	SpriteID image = 0;
   506 	SpriteID image = 0;
   486 
   507 
   487 	if (is_custom_sprite(img)) {
   508 	if (is_custom_sprite(img)) {
   488 		image = GetCustomVehicleIcon(engine, DIR_W);
   509 		image = GetCustomVehicleIcon(engine, DIR_W);
   489 		if (image == 0) {
   510 		if (image == 0) {
   490 			img = orig_rail_vehicle_info[engine].image_index;
   511 			img = _orig_rail_vehicle_info[engine].image_index;
   491 		} else {
   512 		} else {
   492 			y += _traininfo_vehicle_pitch;
   513 			y += _traininfo_vehicle_pitch;
   493 		}
   514 		}
   494 	}
   515 	}
   495 	if (image == 0) {
   516 	if (image == 0) {
   500 		DrawSprite(image, pal, x - 14, y);
   521 		DrawSprite(image, pal, x - 14, y);
   501 		x += 15;
   522 		x += 15;
   502 		image = 0;
   523 		image = 0;
   503 		if (is_custom_sprite(img)) {
   524 		if (is_custom_sprite(img)) {
   504 			image = GetCustomVehicleIcon(engine, DIR_E);
   525 			image = GetCustomVehicleIcon(engine, DIR_E);
   505 			if (image == 0) img = orig_rail_vehicle_info[engine].image_index;
   526 			if (image == 0) img = _orig_rail_vehicle_info[engine].image_index;
   506 		}
   527 		}
   507 		if (image == 0) {
   528 		if (image == 0) {
   508 			image =
   529 			image =
   509 				((6 + _engine_sprite_add[img + 1]) & _engine_sprite_and[img + 1]) +
   530 				((6 + _engine_sprite_add[img + 1]) & _engine_sprite_and[img + 1]) +
   510 				_engine_sprite_base[img + 1];
   531 				_engine_sprite_base[img + 1];
   513 	DrawSprite(image, pal, x, y);
   534 	DrawSprite(image, pal, x, y);
   514 }
   535 }
   515 
   536 
   516 static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags)
   537 static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags)
   517 {
   538 {
   518 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
   519 
       
   520 	const RailVehicleInfo *rvi = RailVehInfo(engine);
   539 	const RailVehicleInfo *rvi = RailVehInfo(engine);
   521 	CommandCost value((GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8);
   540 	CommandCost value(EXPENSES_NEW_VEHICLES, (GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8);
   522 
   541 
   523 	uint num_vehicles = 1 + CountArticulatedParts(engine, false);
   542 	uint num_vehicles = 1 + CountArticulatedParts(engine, false);
   524 
   543 
   525 	if (!(flags & DC_QUERY_COST)) {
   544 	if (!(flags & DC_QUERY_COST)) {
   526 		/* Allow for the wagon and the articulated parts, plus one to "terminate" the list. */
   545 		/* Allow for the wagon and the articulated parts, plus one to "terminate" the list. */
   602 			}
   621 			}
   603 			GetPlayer(_current_player)->num_engines[engine]++;
   622 			GetPlayer(_current_player)->num_engines[engine]++;
   604 		}
   623 		}
   605 	}
   624 	}
   606 
   625 
   607 	return CommandCost(value);
   626 	return value;
   608 }
   627 }
   609 
   628 
   610 /** Move all free vehicles in the depot to the train */
   629 /** Move all free vehicles in the depot to the train */
   611 static void NormalizeTrainVehInDepot(const Vehicle* u)
   630 static void NormalizeTrainVehInDepot(const Vehicle* u)
   612 {
   631 {
   623 	}
   642 	}
   624 }
   643 }
   625 
   644 
   626 static CommandCost EstimateTrainCost(EngineID engine, const RailVehicleInfo* rvi)
   645 static CommandCost EstimateTrainCost(EngineID engine, const RailVehicleInfo* rvi)
   627 {
   646 {
   628 	return CommandCost(GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5);
   647 	return CommandCost(EXPENSES_NEW_VEHICLES, GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5);
   629 }
   648 }
   630 
   649 
   631 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
   650 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
   632 {
   651 {
   633 	u = new (u) Train();
   652 	u = new (u) Train();
   673 	if (!(flags & DC_QUERY_COST)) {
   692 	if (!(flags & DC_QUERY_COST)) {
   674 		if (!IsTileDepotType(tile, TRANSPORT_RAIL)) return CMD_ERROR;
   693 		if (!IsTileDepotType(tile, TRANSPORT_RAIL)) return CMD_ERROR;
   675 		if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
   694 		if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
   676 	}
   695 	}
   677 
   696 
   678 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
   679 
       
   680 	const RailVehicleInfo *rvi = RailVehInfo(p1);
   697 	const RailVehicleInfo *rvi = RailVehInfo(p1);
   681 
   698 
   682 	/* Check if depot and new engine uses the same kind of tracks */
   699 	/* Check if depot and new engine uses the same kind of tracks */
   683 	/* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
   700 	/* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
   684 	if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
   701 	if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
   734 			const Engine *e = GetEngine(p1);
   751 			const Engine *e = GetEngine(p1);
   735 			v->reliability = e->reliability;
   752 			v->reliability = e->reliability;
   736 			v->reliability_spd_dec = e->reliability_spd_dec;
   753 			v->reliability_spd_dec = e->reliability_spd_dec;
   737 			v->max_age = e->lifelength * 366;
   754 			v->max_age = e->lifelength * 366;
   738 
   755 
   739 			v->string_id = STR_SV_TRAIN_NAME;
   756 			v->name = NULL;
   740 			v->u.rail.railtype = rvi->railtype;
   757 			v->u.rail.railtype = rvi->railtype;
   741 			_new_vehicle_id = v->index;
   758 			_new_vehicle_id = v->index;
   742 
   759 
   743 			v->service_interval = _patches.servint_trains;
   760 			v->service_interval = _patches.servint_trains;
   744 			v->date_of_last_service = _date;
   761 			v->date_of_last_service = _date;
   883 {
   900 {
   884 	UnlinkWagon(v, v->First());
   901 	UnlinkWagon(v, v->First());
   885 	if (dest == NULL) return;
   902 	if (dest == NULL) return;
   886 
   903 
   887 	Vehicle *next = dest->Next();
   904 	Vehicle *next = dest->Next();
       
   905 	v->SetNext(NULL);
   888 	dest->SetNext(v);
   906 	dest->SetNext(v);
   889 	v->SetNext(next);
   907 	v->SetNext(next);
   890 	ClearFreeWagon(v);
   908 	ClearFreeWagon(v);
   891 	ClearFrontEngine(v);
   909 	ClearFrontEngine(v);
   892 }
   910 }
  1022 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
  1040 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
  1023 
  1041 
  1024 		if (flags & DC_EXEC) src->unitnumber = unit_num;
  1042 		if (flags & DC_EXEC) src->unitnumber = unit_num;
  1025 	}
  1043 	}
  1026 
  1044 
  1027 	if (dst_head != NULL) {
  1045 	/*
  1028 		/* Check NewGRF Callback 0x1D */
  1046 	 * Check whether the vehicles in the source chain are in the destination
  1029 		uint16 callback = GetVehicleCallbackParent(CBID_TRAIN_ALLOW_WAGON_ATTACH, 0, 0, dst_head->engine_type, src, dst_head);
  1047 	 * chain. This can easily be done by checking whether the first vehicle
  1030 		if (callback != CALLBACK_FAILED) {
  1048 	 * of the source chain is in the destination chain as the Next/Previous
  1031 			if (callback == 0xFD) return_cmd_error(STR_INCOMPATIBLE_RAIL_TYPES);
  1049 	 * pointers always make a doubly linked list of it where the assumption
  1032 			if (callback < 0xFD) {
  1050 	 * v->Next()->Previous() == v holds (assuming v->Next() != NULL).
  1033 				StringID error = GetGRFStringID(GetEngineGRFID(dst_head->engine_type), 0xD000 + callback);
  1051 	 */
  1034 				return_cmd_error(error);
  1052 	bool src_in_dst = false;
  1035 			}
  1053 	for (Vehicle *v = dst_head; !src_in_dst && v != NULL; v = v->Next()) src_in_dst = v == src;
  1036 		}
  1054 
       
  1055 	/*
       
  1056 	 * If the source chain is in the destination chain then the user is
       
  1057 	 * only reordering the vehicles, thus not attaching a new vehicle.
       
  1058 	 * Therefor the 'allow wagon attach' callback does not need to be
       
  1059 	 * called. If it would be called strange things would happen because
       
  1060 	 * one 'attaches' an already 'attached' vehicle causing more trouble
       
  1061 	 * than it actually solves (infinite loops and such).
       
  1062 	 */
       
  1063 	if (dst_head != NULL && !src_in_dst) {
       
  1064 		/*
       
  1065 		 * When performing the 'allow wagon attach' callback, we have to check
       
  1066 		 * that for each and every wagon, not only the first one. This means
       
  1067 		 * that we have to test one wagon, attach it to the train and then test
       
  1068 		 * the next wagon till we have reached the end. We have to restore it
       
  1069 		 * to the state it was before we 'tried' attaching the train when the
       
  1070 		 * attaching fails or succeeds because we are not 'only' doing this
       
  1071 		 * in the DC_EXEC state.
       
  1072 		 */
       
  1073 		Vehicle *dst_tail = dst_head;
       
  1074 		while (dst_tail->Next() != NULL) dst_tail = dst_tail->Next();
       
  1075 
       
  1076 		Vehicle *orig_tail = dst_tail;
       
  1077 		Vehicle *next_to_attach = src;
       
  1078 		Vehicle *src_previous = src->Previous();
       
  1079 
       
  1080 		while (next_to_attach != NULL) {
       
  1081 			/* Back up and clear the first_engine data to avoid using wagon override group */
       
  1082 			EngineID first_engine = next_to_attach->u.rail.first_engine;
       
  1083 			next_to_attach->u.rail.first_engine = INVALID_ENGINE;
       
  1084 
       
  1085 			uint16 callback = GetVehicleCallbackParent(CBID_TRAIN_ALLOW_WAGON_ATTACH, 0, 0, dst_head->engine_type, next_to_attach, dst_head);
       
  1086 
       
  1087 			/* Restore original first_engine data */
       
  1088 			next_to_attach->u.rail.first_engine = first_engine;
       
  1089 
       
  1090 			if (callback != CALLBACK_FAILED) {
       
  1091 				StringID error = STR_NULL;
       
  1092 
       
  1093 				if (callback == 0xFD) error = STR_INCOMPATIBLE_RAIL_TYPES;
       
  1094 				if (callback < 0xFD) error = GetGRFStringID(GetEngineGRFID(dst_head->engine_type), 0xD000 + callback);
       
  1095 
       
  1096 				if (error != STR_NULL) {
       
  1097 					/*
       
  1098 					 * The attaching is not allowed. In this case 'next_to_attach'
       
  1099 					 * can contain some vehicles of the 'source' and the destination
       
  1100 					 * train can have some too. We 'just' add the to-be added wagons
       
  1101 					 * to the chain and then split it where it was previously
       
  1102 					 * separated, i.e. the tail of the original destination train.
       
  1103 					 * Furthermore the 'previous' link of the original source vehicle needs
       
  1104 					 * to be restored, otherwise the train goes missing in the depot.
       
  1105 					 */
       
  1106 					dst_tail->SetNext(next_to_attach);
       
  1107 					orig_tail->SetNext(NULL);
       
  1108 					if (src_previous != NULL) src_previous->SetNext(src);
       
  1109 
       
  1110 					return_cmd_error(error);
       
  1111 				}
       
  1112 			}
       
  1113 
       
  1114 			/* Only check further wagons if told to move the chain */
       
  1115 			if (!HasBit(p2, 0)) break;
       
  1116 
       
  1117 			/*
       
  1118 			 * Adding a next wagon to the chain so we can test the other wagons.
       
  1119 			 * First 'take' the first wagon from 'next_to_attach' and move it
       
  1120 			 * to the next wagon. Then add that to the tail of the destination
       
  1121 			 * train and update the tail with the new vehicle.
       
  1122 			 */
       
  1123 			Vehicle *to_add = next_to_attach;
       
  1124 			next_to_attach = next_to_attach->Next();
       
  1125 
       
  1126 			to_add->SetNext(NULL);
       
  1127 			dst_tail->SetNext(to_add);
       
  1128 			dst_tail = dst_tail->Next();
       
  1129 		}
       
  1130 
       
  1131 		/*
       
  1132 		 * When we reach this the attaching is allowed. It also means that the
       
  1133 		 * chain of vehicles to attach is empty, so we do not need to merge that.
       
  1134 		 * This means only the splitting needs to be done.
       
  1135 		 * Furthermore the 'previous' link of the original source vehicle needs
       
  1136 		 * to be restored, otherwise the train goes missing in the depot.
       
  1137 		 */
       
  1138 		orig_tail->SetNext(NULL);
       
  1139 		if (src_previous != NULL) src_previous->SetNext(src);
  1037 	}
  1140 	}
  1038 
  1141 
  1039 	/* do it? */
  1142 	/* do it? */
  1040 	if (flags & DC_EXEC) {
  1143 	if (flags & DC_EXEC) {
  1041 		/* If we move the front Engine and if the second vehicle is not an engine
  1144 		/* If we move the front Engine and if the second vehicle is not an engine
  1142 			if (IsFrontEngine(src_head)) {
  1245 			if (IsFrontEngine(src_head)) {
  1143 				UpdateTrainAcceleration(src_head);
  1246 				UpdateTrainAcceleration(src_head);
  1144 				InvalidateWindow(WC_VEHICLE_DETAILS, src_head->index);
  1247 				InvalidateWindow(WC_VEHICLE_DETAILS, src_head->index);
  1145 				/* Update the refit button and window */
  1248 				/* Update the refit button and window */
  1146 				InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
  1249 				InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
  1147 				InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, 12);
  1250 				InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, VVW_WIDGET_REFIT_VEH);
  1148 			}
  1251 			}
  1149 			/* Update the depot window */
  1252 			/* Update the depot window */
  1150 			InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
  1253 			InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
  1151 		}
  1254 		}
  1152 
  1255 
  1156 			UpdateTrainGroupID(dst_head);
  1259 			UpdateTrainGroupID(dst_head);
  1157 			if (IsFrontEngine(dst_head)) {
  1260 			if (IsFrontEngine(dst_head)) {
  1158 				UpdateTrainAcceleration(dst_head);
  1261 				UpdateTrainAcceleration(dst_head);
  1159 				InvalidateWindow(WC_VEHICLE_DETAILS, dst_head->index);
  1262 				InvalidateWindow(WC_VEHICLE_DETAILS, dst_head->index);
  1160 				/* Update the refit button and window */
  1263 				/* Update the refit button and window */
  1161 				InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, 12);
  1264 				InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, VVW_WIDGET_REFIT_VEH);
  1162 				InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
  1265 				InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
  1163 			}
  1266 			}
  1164 			/* Update the depot window */
  1267 			/* Update the depot window */
  1165 			InvalidateWindow(WC_VEHICLE_DEPOT, dst_head->tile);
  1268 			InvalidateWindow(WC_VEHICLE_DEPOT, dst_head->tile);
  1166 		}
  1269 		}
  1199 		if (v->vehstatus & VS_STOPPED && v->u.rail.track == TRACK_BIT_DEPOT) {
  1302 		if (v->vehstatus & VS_STOPPED && v->u.rail.track == TRACK_BIT_DEPOT) {
  1200 			DeleteVehicleNews(p1, STR_8814_TRAIN_IS_WAITING_IN_DEPOT);
  1303 			DeleteVehicleNews(p1, STR_8814_TRAIN_IS_WAITING_IN_DEPOT);
  1201 		}
  1304 		}
  1202 
  1305 
  1203 		v->vehstatus ^= VS_STOPPED;
  1306 		v->vehstatus ^= VS_STOPPED;
  1204 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  1307 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  1205 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1308 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1206 	}
  1309 	}
  1207 	return CommandCost();
  1310 	return CommandCost();
  1208 }
  1311 }
  1209 
  1312 
  1229 
  1332 
  1230 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  1333 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  1231 
  1334 
  1232 	if (HASBITS(v->vehstatus, VS_CRASHED)) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE);
  1335 	if (HASBITS(v->vehstatus, VS_CRASHED)) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE);
  1233 
  1336 
  1234 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
  1235 
       
  1236 	while (IsArticulatedPart(v)) v = v->Previous();
  1337 	while (IsArticulatedPart(v)) v = v->Previous();
  1237 	Vehicle *first = v->First();
  1338 	Vehicle *first = v->First();
  1238 
  1339 
  1239 	/* make sure the vehicle is stopped in the depot */
  1340 	/* make sure the vehicle is stopped in the depot */
  1240 	if (CheckTrainStoppedInDepot(first) < 0) {
  1341 	if (CheckTrainStoppedInDepot(first) < 0) {
  1250 		}
  1351 		}
  1251 		InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
  1352 		InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
  1252 		RebuildVehicleLists();
  1353 		RebuildVehicleLists();
  1253 	}
  1354 	}
  1254 
  1355 
  1255 	CommandCost cost;
  1356 	CommandCost cost(EXPENSES_NEW_VEHICLES);
  1256 	switch (p2) {
  1357 	switch (p2) {
  1257 		case 0: case 2: { /* Delete given wagon */
  1358 		case 0: case 2: { /* Delete given wagon */
  1258 			bool switch_engine = false;    // update second wagon to engine?
  1359 			bool switch_engine = false;    // update second wagon to engine?
  1259 			byte ori_subtype = v->subtype; // backup subtype of deleted wagon in case DeleteVehicle() changes
  1360 			byte ori_subtype = v->subtype; // backup subtype of deleted wagon in case DeleteVehicle() changes
  1260 
  1361 
  1446 {
  1547 {
  1447 	int old = v->u.rail.last_speed;
  1548 	int old = v->u.rail.last_speed;
  1448 	if (spd != old) {
  1549 	if (spd != old) {
  1449 		v->u.rail.last_speed = spd;
  1550 		v->u.rail.last_speed = spd;
  1450 		if (_patches.vehicle_speed || (old == 0) != (spd == 0))
  1551 		if (_patches.vehicle_speed || (old == 0) != (spd == 0))
  1451 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  1552 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  1452 	}
  1553 	}
  1453 }
  1554 }
  1454 
  1555 
  1455 static void SwapTrainFlags(byte *swap_flag1, byte *swap_flag2)
  1556 static void SwapTrainFlags(byte *swap_flag1, byte *swap_flag2)
  1456 {
  1557 {
  1522 
  1623 
  1523 	/* Update train's power incase tiles were different rail type */
  1624 	/* Update train's power incase tiles were different rail type */
  1524 	TrainPowerChanged(v);
  1625 	TrainPowerChanged(v);
  1525 }
  1626 }
  1526 
  1627 
  1527 /* Check if the vehicle is a train and is on the tile we are testing */
  1628 
  1528 static void *TestTrainOnCrossing(Vehicle *v, void *data)
  1629 /**
  1529 {
  1630  * Check if the vehicle is a train
  1530 	if (v->tile != *(const TileIndex*)data || v->type != VEH_TRAIN) return NULL;
  1631  * @param v vehicle on tile
       
  1632  * @return v if it is a train, NULL otherwise
       
  1633  */
       
  1634 static void *TrainOnTileEnum(Vehicle *v, void *)
       
  1635 {
       
  1636 	return (v->type == VEH_TRAIN) ? v : NULL;
       
  1637 }
       
  1638 
       
  1639 
       
  1640 /**
       
  1641  * Checks if a train is approaching a rail-road crossing
       
  1642  * @param v vehicle on tile
       
  1643  * @param data tile with crossing we are testing
       
  1644  * @return v if it is approaching a crossing, NULL otherwise
       
  1645  */
       
  1646 static void *TrainApproachingCrossingEnum(Vehicle *v, void *data)
       
  1647 {
       
  1648 	/* not a train || not front engine || crashed */
       
  1649 	if (v->type != VEH_TRAIN || !IsFrontEngine(v) || v->vehstatus & VS_CRASHED) return NULL;
       
  1650 
       
  1651 	TileIndex tile = *(TileIndex*)data;
       
  1652 
       
  1653 	if (TrainApproachingCrossingTile(v) != tile) return NULL;
       
  1654 
  1531 	return v;
  1655 	return v;
  1532 }
  1656 }
  1533 
  1657 
  1534 static void DisableTrainCrossing(TileIndex tile)
  1658 
  1535 {
  1659 /**
  1536 	if (IsLevelCrossingTile(tile) &&
  1660  * Finds a vehicle approaching rail-road crossing
  1537 			VehicleFromPos(tile, &tile, TestTrainOnCrossing) == NULL && // empty?
  1661  * @param tile tile to test
  1538 			IsCrossingBarred(tile)) {
  1662  * @return pointer to vehicle approaching the crossing
  1539 		UnbarCrossing(tile);
  1663  * @pre tile is a rail-road crossing
       
  1664  */
       
  1665 static Vehicle *TrainApproachingCrossing(TileIndex tile)
       
  1666 {
       
  1667 	assert(IsLevelCrossingTile(tile));
       
  1668 
       
  1669 	DiagDirection dir = AxisToDiagDir(OtherAxis(GetCrossingRoadAxis(tile)));
       
  1670 	TileIndex tile_from = tile + TileOffsByDiagDir(dir);
       
  1671 
       
  1672 	Vehicle *v = (Vehicle *)VehicleFromPos(tile_from, &tile, &TrainApproachingCrossingEnum);
       
  1673 
       
  1674 	if (v != NULL) return v;
       
  1675 
       
  1676 	dir = ReverseDiagDir(dir);
       
  1677 	tile_from = tile + TileOffsByDiagDir(dir);
       
  1678 
       
  1679 	return (Vehicle *)VehicleFromPos(tile_from, &tile, &TrainApproachingCrossingEnum);
       
  1680 }
       
  1681 
       
  1682 
       
  1683 /**
       
  1684  * Sets correct crossing state
       
  1685  * @param tile tile to update
       
  1686  * @param sound should we play sound?
       
  1687  * @pre tile is a rail-road crossing
       
  1688  */
       
  1689 void UpdateLevelCrossing(TileIndex tile, bool sound)
       
  1690 {
       
  1691 	assert(IsLevelCrossingTile(tile));
       
  1692 
       
  1693 	/* train on crossing || train approaching crossing */
       
  1694 	bool new_state = VehicleFromPos(tile, NULL, &TrainOnTileEnum) || TrainApproachingCrossing(tile);
       
  1695 
       
  1696 	if (new_state != IsCrossingBarred(tile)) {
       
  1697 		if (new_state && sound) {
       
  1698 			SndPlayTileFx(SND_0E_LEVEL_CROSSING, tile);
       
  1699 		}
       
  1700 		SetCrossingBarred(tile, new_state);
  1540 		MarkTileDirtyByTile(tile);
  1701 		MarkTileDirtyByTile(tile);
  1541 	}
  1702 	}
  1542 }
  1703 }
       
  1704 
       
  1705 
       
  1706 /**
       
  1707  * Bars crossing and plays ding-ding sound if not barred already
       
  1708  * @param tile tile with crossing
       
  1709  * @pre tile is a rail-road crossing
       
  1710  */
       
  1711 static inline void MaybeBarCrossingWithSound(TileIndex tile)
       
  1712 {
       
  1713 	if (!IsCrossingBarred(tile)) {
       
  1714 		BarCrossing(tile);
       
  1715 		SndPlayTileFx(SND_0E_LEVEL_CROSSING, tile);
       
  1716 		MarkTileDirtyByTile(tile);
       
  1717 	}
       
  1718 }
       
  1719 
  1543 
  1720 
  1544 /**
  1721 /**
  1545  * Advances wagons for train reversing, needed for variable length wagons.
  1722  * Advances wagons for train reversing, needed for variable length wagons.
  1546  * Needs to be called once before the train is reversed, and once after it.
  1723  * Needs to be called once before the train is reversed, and once after it.
  1547  * @param v First vehicle in chain
  1724  * @param v First vehicle in chain
  1565 		if (differential > 0) {
  1742 		if (differential > 0) {
  1566 			/* disconnect last car to make sure only this subset moves */
  1743 			/* disconnect last car to make sure only this subset moves */
  1567 			Vehicle *tempnext = last->Next();
  1744 			Vehicle *tempnext = last->Next();
  1568 			last->SetNext(NULL);
  1745 			last->SetNext(NULL);
  1569 
  1746 
       
  1747 			/* do not update images now because the wagons are disconnected
       
  1748 			 * and that could cause problems with NewGRFs */
  1570 			for (int i = 0; i < differential; i++) TrainController(first, false);
  1749 			for (int i = 0; i < differential; i++) TrainController(first, false);
  1571 
  1750 
  1572 			last->SetNext(tempnext);
  1751 			last->SetNext(tempnext);
  1573 		}
  1752 		}
  1574 
  1753 
  1584 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL)) {
  1763 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL)) {
  1585 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  1764 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  1586 	}
  1765 	}
  1587 
  1766 
  1588 	/* Check if we were approaching a rail/road-crossing */
  1767 	/* Check if we were approaching a rail/road-crossing */
  1589 	{
  1768 	TileIndex crossing = TrainApproachingCrossingTile(v);
  1590 		TileIndex tile = v->tile;
       
  1591 		DiagDirection dir = DirToDiagDir(v->direction);
       
  1592 
       
  1593 		/* Determine the diagonal direction in which we will exit this tile */
       
  1594 		if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[dir]) {
       
  1595 			dir = ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT);
       
  1596 		}
       
  1597 		/* Calculate next tile */
       
  1598 		tile += TileOffsByDiagDir(dir);
       
  1599 
       
  1600 		/* Check if the train left a rail/road-crossing */
       
  1601 		DisableTrainCrossing(tile);
       
  1602 	}
       
  1603 
  1769 
  1604 	/* count number of vehicles */
  1770 	/* count number of vehicles */
  1605 	int r = -1;
  1771 	int r = 0;  ///< number of vehicles - 1
  1606 	const Vehicle *u = v;
  1772 	for (const Vehicle *u = v; (u = u->Next()) != NULL;) { r++; }
  1607 	do r++; while ((u = u->Next()) != NULL);
       
  1608 
  1773 
  1609 	AdvanceWagons(v, true);
  1774 	AdvanceWagons(v, true);
  1610 
  1775 
  1611 	/* swap start<>end, start+1<>end-1, ... */
  1776 	/* swap start<>end, start+1<>end-1, ... */
  1612 	int l = 0;
  1777 	int l = 0;
  1618 
  1783 
  1619 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL)) {
  1784 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL)) {
  1620 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  1785 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  1621 	}
  1786 	}
  1622 
  1787 
       
  1788 	/* update all images */
       
  1789 	for (Vehicle *u = v; u != NULL; u = u->Next()) { u->cur_image = u->GetImage(u->direction); }
       
  1790 
  1623 	ClrBit(v->u.rail.flags, VRF_REVERSING);
  1791 	ClrBit(v->u.rail.flags, VRF_REVERSING);
       
  1792 
       
  1793 	/* update crossing we were approaching */
       
  1794 	if (crossing != INVALID_TILE) UpdateLevelCrossing(crossing);
       
  1795 
       
  1796 	/* maybe we are approaching crossing now, after reversal */
       
  1797 	crossing = TrainApproachingCrossingTile(v);
       
  1798 	if (crossing != INVALID_TILE) MaybeBarCrossingWithSound(crossing);
  1624 }
  1799 }
  1625 
  1800 
  1626 /** Reverse train.
  1801 /** Reverse train.
  1627  * @param tile unused
  1802  * @param tile unused
  1628  * @param flags type of operation
  1803  * @param flags type of operation
  1711 
  1886 
  1712 	Vehicle *v = GetVehicle(p1);
  1887 	Vehicle *v = GetVehicle(p1);
  1713 
  1888 
  1714 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  1889 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  1715 	if (CheckTrainStoppedInDepot(v) < 0) return_cmd_error(STR_TRAIN_MUST_BE_STOPPED);
  1890 	if (CheckTrainStoppedInDepot(v) < 0) return_cmd_error(STR_TRAIN_MUST_BE_STOPPED);
       
  1891 	if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_CAN_T_REFIT_DESTROYED_VEHICLE);
  1716 
  1892 
  1717 	/* Check cargo */
  1893 	/* Check cargo */
  1718 	if (new_cid >= NUM_CARGO) return CMD_ERROR;
  1894 	if (new_cid >= NUM_CARGO) return CMD_ERROR;
  1719 
  1895 
  1720 	SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
  1896 	CommandCost cost(EXPENSES_TRAIN_RUN);
  1721 
       
  1722 	CommandCost cost;
       
  1723 	uint num = 0;
  1897 	uint num = 0;
  1724 
  1898 
  1725 	do {
  1899 	do {
  1726 		/* XXX: We also refit all the attached wagons en-masse if they
  1900 		/* XXX: We also refit all the attached wagons en-masse if they
  1727 		 * can be refitted. This is how TTDPatch does it.  TODO: Have
  1901 		 * can be refitted. This is how TTDPatch does it.  TODO: Have
  1856 			tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH;
  2030 			tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH;
  1857 			if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) tfdd.reverse = true;
  2031 			if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) tfdd.reverse = true;
  1858 		}
  2032 		}
  1859 	} else {
  2033 	} else {
  1860 		/* search in the forward direction first. */
  2034 		/* search in the forward direction first. */
  1861 		DiagDirection i = DirToDiagDir(v->direction);
  2035 		DiagDirection i = TrainExitDir(v->direction, v->u.rail.track);
  1862 		if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) {
       
  1863 			i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT);
       
  1864 		}
       
  1865 		NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
  2036 		NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
  1866 		if (tfdd.best_length == (uint)-1){
  2037 		if (tfdd.best_length == (uint)-1){
  1867 			tfdd.reverse = true;
  2038 			tfdd.reverse = true;
  1868 			/* search in backwards direction */
  2039 			/* search in backwards direction */
  1869 			i = ReverseDiagDir(DirToDiagDir(v->direction));
  2040 			i = TrainExitDir(ReverseDir(v->direction), v->u.rail.track);
  1870 			if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) {
       
  1871 				i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT);
       
  1872 			}
       
  1873 			NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
  2041 			NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
  1874 		}
  2042 		}
  1875 	}
  2043 	}
  1876 
  2044 
  1877 	return tfdd;
  2045 	return tfdd;
  1900 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  2068 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  1901 
  2069 
  1902 	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
  2070 	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
  1903 
  2071 
  1904 	if (v->current_order.type == OT_GOTO_DEPOT) {
  2072 	if (v->current_order.type == OT_GOTO_DEPOT) {
  1905 		if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
  2073 		if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) {
  1906 			/* We called with a different DEPOT_SERVICE setting.
  2074 			/* We called with a different DEPOT_SERVICE setting.
  1907 			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
  2075 			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
  1908 			 * Note: the if is (true for requesting service == true for ordered to stop in depot)          */
  2076 			 * Note: the if is (true for requesting service == true for ordered to stop in depot)          */
  1909 			if (flags & DC_EXEC) {
  2077 			if (flags & DC_EXEC) {
  1910 				ClrBit(v->current_order.flags, OFB_PART_OF_ORDERS);
  2078 				ClrBit(v->current_order.flags, OF_PART_OF_ORDERS);
  1911 				ToggleBit(v->current_order.flags, OFB_HALT_IN_DEPOT);
  2079 				ToggleBit(v->current_order.flags, OF_HALT_IN_DEPOT);
  1912 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  2080 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  1913 			}
  2081 			}
  1914 			return CommandCost();
  2082 			return CommandCost();
  1915 		}
  2083 		}
  1916 
  2084 
  1917 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
  2085 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
  1918 		if (flags & DC_EXEC) {
  2086 		if (flags & DC_EXEC) {
  1919 			if (HasBit(v->current_order.flags, OFB_PART_OF_ORDERS)) {
  2087 			if (HasBit(v->current_order.flags, OF_PART_OF_ORDERS)) {
  1920 				v->cur_order_index++;
  2088 				v->cur_order_index++;
  1921 			}
  2089 			}
  1922 
  2090 
  1923 			v->current_order.type = OT_DUMMY;
  2091 			v->current_order.type = OT_DUMMY;
  1924 			v->current_order.flags = 0;
  2092 			v->current_order.flags = 0;
  1925 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  2093 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  1926 		}
  2094 		}
  1927 		return CommandCost();
  2095 		return CommandCost();
  1928 	}
  2096 	}
  1929 
  2097 
  1930 	/* check if at a standstill (not stopped only) in a depot
  2098 	/* check if at a standstill (not stopped only) in a depot
  1937 	if (flags & DC_EXEC) {
  2105 	if (flags & DC_EXEC) {
  1938 		if (v->current_order.type == OT_LOADING) v->LeaveStation();
  2106 		if (v->current_order.type == OT_LOADING) v->LeaveStation();
  1939 
  2107 
  1940 		v->dest_tile = tfdd.tile;
  2108 		v->dest_tile = tfdd.tile;
  1941 		v->current_order.type = OT_GOTO_DEPOT;
  2109 		v->current_order.type = OT_GOTO_DEPOT;
  1942 		v->current_order.flags = OF_NON_STOP;
  2110 		v->current_order.flags = OFB_NON_STOP;
  1943 		if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OFB_HALT_IN_DEPOT);
  2111 		if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT);
  1944 		v->current_order.dest = GetDepotByTile(tfdd.tile)->index;
  2112 		v->current_order.dest = GetDepotByTile(tfdd.tile)->index;
  1945 		v->current_order.refit_cargo = CT_INVALID;
  2113 		v->current_order.refit_cargo = CT_INVALID;
  1946 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  2114 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  1947 		/* If there is no depot in front, reverse automatically */
  2115 		/* If there is no depot in front, reverse automatically */
  1948 		if (tfdd.reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
  2116 		if (tfdd.reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
  1949 	}
  2117 	}
  1950 
  2118 
  1951 	return CommandCost();
  2119 	return CommandCost();
  2075 			return true;
  2243 			return true;
  2076 		}
  2244 		}
  2077 
  2245 
  2078 		v->load_unload_time_rem = 0;
  2246 		v->load_unload_time_rem = 0;
  2079 
  2247 
  2080 		if (UpdateSignalsOnSegment(v->tile, DirToDiagDir(v->direction))) {
  2248 		if (UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner)) {
  2081 			InvalidateWindowClasses(WC_TRAINS_LIST);
  2249 			InvalidateWindowClasses(WC_TRAINS_LIST);
  2082 			return true;
  2250 			return true;
  2083 		}
  2251 		}
  2084 	}
  2252 	}
  2085 
  2253 
  2094 	v->cur_speed = 0;
  2262 	v->cur_speed = 0;
  2095 
  2263 
  2096 	v->UpdateDeltaXY(v->direction);
  2264 	v->UpdateDeltaXY(v->direction);
  2097 	v->cur_image = v->GetImage(v->direction);
  2265 	v->cur_image = v->GetImage(v->direction);
  2098 	VehiclePositionChanged(v);
  2266 	VehiclePositionChanged(v);
  2099 	UpdateSignalsOnSegment(v->tile, DirToDiagDir(v->direction));
  2267 	UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
  2100 	UpdateTrainAcceleration(v);
  2268 	UpdateTrainAcceleration(v);
  2101 	InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  2269 	InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  2102 
  2270 
  2103 	return false;
  2271 	return false;
  2104 }
  2272 }
  2388 
  2556 
  2389 static bool ProcessTrainOrder(Vehicle *v)
  2557 static bool ProcessTrainOrder(Vehicle *v)
  2390 {
  2558 {
  2391 	switch (v->current_order.type) {
  2559 	switch (v->current_order.type) {
  2392 		case OT_GOTO_DEPOT:
  2560 		case OT_GOTO_DEPOT:
  2393 			if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return false;
  2561 			if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return false;
  2394 			if ((v->current_order.flags & OF_SERVICE_IF_NEEDED) &&
  2562 			if ((v->current_order.flags & OFB_SERVICE_IF_NEEDED) &&
  2395 					!VehicleNeedsService(v)) {
  2563 					!VehicleNeedsService(v)) {
  2396 				UpdateVehicleTimetable(v, true);
  2564 				UpdateVehicleTimetable(v, true);
  2397 				v->cur_order_index++;
  2565 				v->cur_order_index++;
  2398 			}
  2566 			}
  2399 			break;
  2567 			break;
  2420 		v->cur_order_index++;
  2588 		v->cur_order_index++;
  2421 	}
  2589 	}
  2422 
  2590 
  2423 	/* check if we've reached a non-stop station while TTDPatch nonstop is enabled.. */
  2591 	/* check if we've reached a non-stop station while TTDPatch nonstop is enabled.. */
  2424 	if (_patches.new_nonstop &&
  2592 	if (_patches.new_nonstop &&
  2425 			v->current_order.flags & OF_NON_STOP &&
  2593 			v->current_order.flags & OFB_NON_STOP &&
  2426 			IsTileType(v->tile, MP_STATION) &&
  2594 			IsTileType(v->tile, MP_STATION) &&
  2427 			v->current_order.dest == GetStationIndex(v->tile)) {
  2595 			v->current_order.dest == GetStationIndex(v->tile)) {
  2428 		UpdateVehicleTimetable(v, true);
  2596 		UpdateVehicleTimetable(v, true);
  2429 		v->cur_order_index++;
  2597 		v->cur_order_index++;
  2430 	}
  2598 	}
  2479 void Train::MarkDirty()
  2647 void Train::MarkDirty()
  2480 {
  2648 {
  2481 	Vehicle *v = this;
  2649 	Vehicle *v = this;
  2482 	do {
  2650 	do {
  2483 		v->cur_image = v->GetImage(v->direction);
  2651 		v->cur_image = v->GetImage(v->direction);
  2484 		MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
  2652 		MarkSingleVehicleDirty(v);
  2485 	} while ((v = v->Next()) != NULL);
  2653 	} while ((v = v->Next()) != NULL);
  2486 
  2654 
  2487 	/* need to update acceleration and cached values since the goods on the train changed. */
  2655 	/* need to update acceleration and cached values since the goods on the train changed. */
  2488 	TrainCargoChanged(this);
  2656 	TrainCargoChanged(this);
  2489 	UpdateTrainAcceleration(this);
  2657 	UpdateTrainAcceleration(this);
  2592 							TileX(new_tile) - TileX(old_tile) + 1;
  2760 							TileX(new_tile) - TileX(old_tile) + 1;
  2593 	assert(offs < 11);
  2761 	assert(offs < 11);
  2594 	return _new_vehicle_direction_table[offs];
  2762 	return _new_vehicle_direction_table[offs];
  2595 }
  2763 }
  2596 
  2764 
  2597 static Direction GetNewVehicleDirection(const Vehicle *v, int x, int y)
       
  2598 {
       
  2599 	uint offs = (y - v->y_pos + 1) * 4 + (x - v->x_pos + 1);
       
  2600 	assert(offs < 11);
       
  2601 	return _new_vehicle_direction_table[offs];
       
  2602 }
       
  2603 
       
  2604 static int GetDirectionToVehicle(const Vehicle *v, int x, int y)
  2765 static int GetDirectionToVehicle(const Vehicle *v, int x, int y)
  2605 {
  2766 {
  2606 	byte offs;
  2767 	byte offs;
  2607 
  2768 
  2608 	x -= v->x_pos;
  2769 	x -= v->x_pos;
  2682 static void TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
  2843 static void TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
  2683 {
  2844 {
  2684 	if (IsTileType(tile, MP_RAILWAY) &&
  2845 	if (IsTileType(tile, MP_RAILWAY) &&
  2685 			GetRailTileType(tile) == RAIL_TILE_SIGNALS) {
  2846 			GetRailTileType(tile) == RAIL_TILE_SIGNALS) {
  2686 		uint i = FindFirstBit2x64(GetTrackBits(tile) * 0x101 & _reachable_tracks[dir]);
  2847 		uint i = FindFirstBit2x64(GetTrackBits(tile) * 0x101 & _reachable_tracks[dir]);
  2687 		UpdateSignalsOnSegment(tile, _otherside_signal_directions[i]);
  2848 		UpdateSignalsOnSegment(tile, _otherside_signal_directions[i], GetTileOwner(tile));
  2688 	}
  2849 	}
  2689 }
  2850 }
  2690 
  2851 
  2691 
  2852 
  2692 static void SetVehicleCrashed(Vehicle *v)
  2853 static void SetVehicleCrashed(Vehicle *v)
  2693 {
  2854 {
  2694 	if (v->u.rail.crash_anim_pos != 0) return;
  2855 	if (v->u.rail.crash_anim_pos != 0) return;
  2695 
  2856 
       
  2857 	/* we may need to update crossing we were approaching */
       
  2858 	TileIndex crossing = TrainApproachingCrossingTile(v);
       
  2859 
  2696 	v->u.rail.crash_anim_pos++;
  2860 	v->u.rail.crash_anim_pos++;
  2697 
  2861 
  2698 	Vehicle *u = v;
  2862 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
       
  2863 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
       
  2864 
       
  2865 	if (v->u.rail.track == TRACK_BIT_DEPOT) {
       
  2866 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
       
  2867 	}
       
  2868 
       
  2869 	RebuildVehicleLists();
       
  2870 
  2699 	BEGIN_ENUM_WAGONS(v)
  2871 	BEGIN_ENUM_WAGONS(v)
  2700 		v->vehstatus |= VS_CRASHED;
  2872 		v->vehstatus |= VS_CRASHED;
       
  2873 		MarkSingleVehicleDirty(v);
  2701 	END_ENUM_WAGONS(v)
  2874 	END_ENUM_WAGONS(v)
  2702 
  2875 
  2703 	InvalidateWindowWidget(WC_VEHICLE_VIEW, u->index, STATUS_BAR);
  2876 	/* must be updated after the train has been marked crashed */
       
  2877 	if (crossing != INVALID_TILE) UpdateLevelCrossing(crossing);
  2704 }
  2878 }
  2705 
  2879 
  2706 static uint CountPassengersInTrain(const Vehicle* v)
  2880 static uint CountPassengersInTrain(const Vehicle* v)
  2707 {
  2881 {
  2708 	uint num = 0;
  2882 	uint num = 0;
  2712 	return num;
  2886 	return num;
  2713 }
  2887 }
  2714 
  2888 
  2715 struct TrainCollideChecker {
  2889 struct TrainCollideChecker {
  2716 	Vehicle *v;
  2890 	Vehicle *v;
  2717 	const Vehicle *v_skip;
       
  2718 	uint num;
  2891 	uint num;
  2719 };
  2892 };
  2720 
  2893 
  2721 static void *FindTrainCollideEnum(Vehicle *v, void *data)
  2894 static void *FindTrainCollideEnum(Vehicle *v, void *data)
  2722 {
  2895 {
  2723 	TrainCollideChecker* tcc = (TrainCollideChecker*)data;
  2896 	TrainCollideChecker* tcc = (TrainCollideChecker*)data;
  2724 
  2897 
  2725 	if (v != tcc->v &&
  2898 	if (v->type != VEH_TRAIN) return NULL;
  2726 			v != tcc->v_skip &&
  2899 
  2727 			v->type == VEH_TRAIN &&
  2900 	/* get first vehicle now to make most usual checks faster */
  2728 			v->u.rail.track != TRACK_BIT_DEPOT &&
  2901 	Vehicle *coll = v->First();
  2729 			abs(v->z_pos - tcc->v->z_pos) < 6 &&
  2902 
  2730 			abs(v->x_pos - tcc->v->x_pos) < 6 &&
  2903 	/* can't collide with own wagons && can't crash in depot && the same height level */
  2731 			abs(v->y_pos - tcc->v->y_pos) < 6 ) {
  2904 	if (coll != tcc->v && v->u.rail.track != TRACK_BIT_DEPOT && abs(v->z_pos - tcc->v->z_pos) < 6) {
  2732 
  2905 		int x_diff = v->x_pos - tcc->v->x_pos;
  2733 		Vehicle *coll = v->First();
  2906 		int y_diff = v->y_pos - tcc->v->y_pos;
  2734 
  2907 
  2735 		/* it can't collide with its own wagons */
  2908 		/* needed to disable possible crash of competitor train in station by building diagonal track at its end */
  2736 		if (tcc->v == coll ||
  2909 		if (x_diff * x_diff + y_diff * y_diff > 25) return NULL;
  2737 			(tcc->v->u.rail.track == TRACK_BIT_WORMHOLE && (tcc->v->direction & 2) != (v->direction & 2)))
  2910 
  2738 			return NULL;
       
  2739 
       
  2740 		/* two drivers + passengers killed in train tcc->v (if it was not crashed already) */
       
  2741 		if (!(tcc->v->vehstatus & VS_CRASHED)) {
  2911 		if (!(tcc->v->vehstatus & VS_CRASHED)) {
       
  2912 			/* two drivers + passengers killed in train tcc->v (if it was not crashed already) */
  2742 			tcc->num += 2 + CountPassengersInTrain(tcc->v);
  2913 			tcc->num += 2 + CountPassengersInTrain(tcc->v);
  2743 			SetVehicleCrashed(tcc->v);
  2914 			SetVehicleCrashed(tcc->v);
  2744 		}
  2915 		}
  2745 
  2916 
  2746 		if (!(coll->vehstatus & VS_CRASHED)) {
  2917 		if (!(coll->vehstatus & VS_CRASHED)) {
  2766 
  2937 
  2767 	assert(v->u.rail.track == TRACK_BIT_WORMHOLE || TileVirtXY(v->x_pos, v->y_pos) == v->tile);
  2938 	assert(v->u.rail.track == TRACK_BIT_WORMHOLE || TileVirtXY(v->x_pos, v->y_pos) == v->tile);
  2768 
  2939 
  2769 	TrainCollideChecker tcc;
  2940 	TrainCollideChecker tcc;
  2770 	tcc.v = v;
  2941 	tcc.v = v;
  2771 	tcc.v_skip = v->Next();
       
  2772 	tcc.num = 0;
  2942 	tcc.num = 0;
  2773 
  2943 
  2774 	/* find colliding vehicles */
  2944 	/* find colliding vehicles */
  2775 	if (v->u.rail.track == TRACK_BIT_WORMHOLE) {
  2945 	if (v->u.rail.track == TRACK_BIT_WORMHOLE) {
  2776 		VehicleFromPos(v->tile, &tcc, FindTrainCollideEnum);
  2946 		VehicleFromPos(v->tile, &tcc, FindTrainCollideEnum);
  2777 		if (IsBridgeTile(v->tile)) {
  2947 		VehicleFromPos(GetOtherTunnelBridgeEnd(v->tile), &tcc, FindTrainCollideEnum);
  2778 			VehicleFromPos(GetOtherBridgeEnd(v->tile), &tcc, FindTrainCollideEnum);
       
  2779 		} else {
       
  2780 			VehicleFromPos(GetOtherTunnelEnd(v->tile), &tcc, FindTrainCollideEnum);
       
  2781 		}
       
  2782 	} else {
  2948 	} else {
  2783 		VehicleFromPosXY(v->x_pos, v->y_pos, &tcc, FindTrainCollideEnum);
  2949 		VehicleFromPosXY(v->x_pos, v->y_pos, &tcc, FindTrainCollideEnum);
  2784 	}
  2950 	}
  2785 
  2951 
  2786 	/* any dead -> no crash */
  2952 	/* any dead -> no crash */
  2795 
  2961 
  2796 	ModifyStationRatingAround(v->tile, v->owner, -160, 30);
  2962 	ModifyStationRatingAround(v->tile, v->owner, -160, 30);
  2797 	SndPlayVehicleFx(SND_13_BIG_CRASH, v);
  2963 	SndPlayVehicleFx(SND_13_BIG_CRASH, v);
  2798 }
  2964 }
  2799 
  2965 
  2800 struct VehicleAtSignalData {
       
  2801 	TileIndex tile;
       
  2802 	Direction direction;
       
  2803 };
       
  2804 
       
  2805 static void *CheckVehicleAtSignal(Vehicle *v, void *data)
  2966 static void *CheckVehicleAtSignal(Vehicle *v, void *data)
  2806 {
  2967 {
  2807 	const VehicleAtSignalData* vasd = (VehicleAtSignalData*)data;
  2968 	Direction dir = *(Direction*)data;
  2808 
  2969 
  2809 	if (v->type == VEH_TRAIN && IsFrontEngine(v) && v->tile == vasd->tile) {
  2970 	if (v->type == VEH_TRAIN && IsFrontEngine(v)) {
  2810 		DirDiff diff = ChangeDirDiff(DirDifference(v->direction, vasd->direction), DIRDIFF_90RIGHT);
  2971 		DirDiff diff = ChangeDirDiff(DirDifference(v->direction, dir), DIRDIFF_90RIGHT);
  2811 
  2972 
  2812 		if (diff == DIRDIFF_90RIGHT || (v->cur_speed <= 5 && diff <= DIRDIFF_REVERSE)) return v;
  2973 		if (diff == DIRDIFF_90RIGHT || (v->cur_speed <= 5 && diff <= DIRDIFF_REVERSE)) return v;
  2813 	}
  2974 	}
  2814 	return NULL;
  2975 	return NULL;
  2815 }
  2976 }
  2819 	Vehicle *prev;
  2980 	Vehicle *prev;
  2820 
  2981 
  2821 	/* For every vehicle after and including the given vehicle */
  2982 	/* For every vehicle after and including the given vehicle */
  2822 	for (prev = v->Previous(); v != NULL; prev = v, v = v->Next()) {
  2983 	for (prev = v->Previous(); v != NULL; prev = v, v = v->Next()) {
  2823 		DiagDirection enterdir = DIAGDIR_BEGIN;
  2984 		DiagDirection enterdir = DIAGDIR_BEGIN;
  2824 		bool update_signals = false;
  2985 		bool update_signals_crossing = false; // will we update signals or crossing state?
  2825 		BeginVehicleMove(v);
  2986 		BeginVehicleMove(v);
  2826 
  2987 
  2827 		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
  2988 		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
  2828 		if (v->u.rail.track != TRACK_BIT_WORMHOLE) {
  2989 		if (v->u.rail.track != TRACK_BIT_WORMHOLE) {
  2829 			/* Not inside tunnel */
  2990 			/* Not inside tunnel */
  2847 						return;
  3008 						return;
  2848 					}
  3009 					}
  2849 
  3010 
  2850 					if (v->current_order.type == OT_LEAVESTATION) {
  3011 					if (v->current_order.type == OT_LEAVESTATION) {
  2851 						v->current_order.Free();
  3012 						v->current_order.Free();
  2852 						InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  3013 						InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  2853 					}
  3014 					}
  2854 				}
  3015 				}
  2855 			} else {
  3016 			} else {
  2856 				/* A new tile is about to be entered. */
  3017 				/* A new tile is about to be entered. */
  2857 
  3018 
  2904 							v->cur_speed = 0;
  3065 							v->cur_speed = 0;
  2905 							v->subspeed = 0;
  3066 							v->subspeed = 0;
  2906 							v->progress = 255 - 10;
  3067 							v->progress = 255 - 10;
  2907 							if (++v->load_unload_time_rem < _patches.wait_twoway_signal * 73) {
  3068 							if (++v->load_unload_time_rem < _patches.wait_twoway_signal * 73) {
  2908 								TileIndex o_tile = gp.new_tile + TileOffsByDiagDir(enterdir);
  3069 								TileIndex o_tile = gp.new_tile + TileOffsByDiagDir(enterdir);
  2909 								VehicleAtSignalData vasd;
  3070 								Direction rdir = ReverseDir(dir);
  2910 								vasd.tile = o_tile;
       
  2911 								vasd.direction = ReverseDir(dir);
       
  2912 
  3071 
  2913 								/* check if a train is waiting on the other side */
  3072 								/* check if a train is waiting on the other side */
  2914 								if (VehicleFromPos(o_tile, &vasd, CheckVehicleAtSignal) == NULL) return;
  3073 								if (VehicleFromPos(o_tile, &rdir, &CheckVehicleAtSignal) == NULL) return;
  2915 							}
  3074 							}
  2916 						}
  3075 						}
  2917 						goto reverse_train_direction;
  3076 						goto reverse_train_direction;
  2918 					}
  3077 					}
  2919 				} else {
  3078 				} else {
  2944 				uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  3103 				uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2945 				if (HasBit(r, VETS_CANNOT_ENTER)) {
  3104 				if (HasBit(r, VETS_CANNOT_ENTER)) {
  2946 					goto invalid_rail;
  3105 					goto invalid_rail;
  2947 				}
  3106 				}
  2948 
  3107 
  2949 				if (IsLevelCrossingTile(v->tile) && v->Next() == NULL) {
       
  2950 					UnbarCrossing(v->tile);
       
  2951 					MarkTileDirtyByTile(v->tile);
       
  2952 				}
       
  2953 
       
  2954 				if (IsFrontEngine(v)) v->load_unload_time_rem = 0;
  3108 				if (IsFrontEngine(v)) v->load_unload_time_rem = 0;
  2955 
  3109 
  2956 				if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
  3110 				if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
  2957 					v->tile = gp.new_tile;
  3111 					v->tile = gp.new_tile;
  2958 
  3112 
  2964 					assert(v->u.rail.track);
  3118 					assert(v->u.rail.track);
  2965 				}
  3119 				}
  2966 
  3120 
  2967 				/* We need to update signal status, but after the vehicle position hash
  3121 				/* We need to update signal status, but after the vehicle position hash
  2968 				 * has been updated by AfterSetTrainPos() */
  3122 				 * has been updated by AfterSetTrainPos() */
  2969 				update_signals = true;
  3123 				update_signals_crossing = true;
  2970 
  3124 
  2971 				if (prev == NULL) AffectSpeedByDirChange(v, chosen_dir);
  3125 				if (prev == NULL) AffectSpeedByDirChange(v, chosen_dir);
  2972 
  3126 
  2973 				v->direction = chosen_dir;
  3127 				v->direction = chosen_dir;
  2974 			}
  3128 			}
  2975 		} else {
  3129 		} else {
  2976 			/* In tunnel or on a bridge */
  3130 			/* In a tunnel or on a bridge
       
  3131 			 * - for tunnels, only the part when the vehicle is not visible (part of enter/exit tile too)
       
  3132 			 * - for bridges, only the middle part - without the bridge heads */
  2977 			if (!(v->vehstatus & VS_HIDDEN)) {
  3133 			if (!(v->vehstatus & VS_HIDDEN)) {
  2978 				v->cur_speed =
  3134 				v->cur_speed =
  2979 					min(v->cur_speed, GetBridge(GetBridgeType(v->tile))->speed);
  3135 					min(v->cur_speed, GetBridge(GetBridgeType(v->tile))->speed);
  2980 			}
  3136 			}
  2981 
  3137 
  2987 				continue;
  3143 				continue;
  2988 			}
  3144 			}
  2989 		}
  3145 		}
  2990 
  3146 
  2991 		/* update image of train, as well as delta XY */
  3147 		/* update image of train, as well as delta XY */
  2992 		Direction newdir = GetNewVehicleDirection(v, gp.x, gp.y);
  3148 		v->UpdateDeltaXY(v->direction);
  2993 		v->UpdateDeltaXY(newdir);
  3149 		if (update_image) v->cur_image = v->GetImage(v->direction);
  2994 		if (update_image) v->cur_image = v->GetImage(newdir);
       
  2995 
  3150 
  2996 		v->x_pos = gp.x;
  3151 		v->x_pos = gp.x;
  2997 		v->y_pos = gp.y;
  3152 		v->y_pos = gp.y;
  2998 
  3153 
  2999 		/* update the Z position of the vehicle */
  3154 		/* update the Z position of the vehicle */
  3002 		if (prev == NULL) {
  3157 		if (prev == NULL) {
  3003 			/* This is the first vehicle in the train */
  3158 			/* This is the first vehicle in the train */
  3004 			AffectSpeedByZChange(v, old_z);
  3159 			AffectSpeedByZChange(v, old_z);
  3005 		}
  3160 		}
  3006 
  3161 
  3007 		if (update_signals) {
  3162 		if (update_signals_crossing) {
  3008 			if (IsFrontEngine(v)) TrainMovedChangeSignals(gp.new_tile, enterdir);
  3163 			if (IsFrontEngine(v)) TrainMovedChangeSignals(gp.new_tile, enterdir);
  3009 
  3164 
  3010 			/* Signals can only change when the first
  3165 			/* Signals can only change when the first
  3011 			 * (above) or the last vehicle moves. */
  3166 			 * (above) or the last vehicle moves. */
  3012 			if (v->Next() == NULL) TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir));
  3167 			if (v->Next() == NULL) {
       
  3168 				TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir));
       
  3169 				if (IsLevelCrossingTile(gp.old_tile)) UpdateLevelCrossing(gp.old_tile);
       
  3170 			}
  3013 		}
  3171 		}
  3014 	}
  3172 	}
  3015 	return;
  3173 	return;
  3016 
  3174 
  3017 invalid_rail:
  3175 invalid_rail:
  3023 	v->cur_speed = 0;
  3181 	v->cur_speed = 0;
  3024 	v->subspeed = 0;
  3182 	v->subspeed = 0;
  3025 	ReverseTrainDirection(v);
  3183 	ReverseTrainDirection(v);
  3026 }
  3184 }
  3027 
  3185 
  3028 extern TileIndex CheckTunnelBusy(TileIndex tile, uint *length);
       
  3029 
       
  3030 /**
  3186 /**
  3031  * Deletes/Clears the last wagon of a crashed train. It takes the engine of the
  3187  * Deletes/Clears the last wagon of a crashed train. It takes the engine of the
  3032  * train, then goes to the last wagon and deletes that. Each call to this function
  3188  * train, then goes to the last wagon and deletes that. Each call to this function
  3033  * will remove the last wagon of a crashed train. If this wagon was on a crossing,
  3189  * will remove the last wagon of a crashed train. If this wagon was on a crossing,
  3034  * or inside a tunnel, recalculate the signals as they might need updating
  3190  * or inside a tunnel/bridge, recalculate the signals as they might need updating
  3035  * @param v the Vehicle of which last wagon is to be removed
  3191  * @param v the Vehicle of which last wagon is to be removed
  3036  */
  3192  */
  3037 static void DeleteLastWagon(Vehicle *v)
  3193 static void DeleteLastWagon(Vehicle *v)
  3038 {
  3194 {
       
  3195 	Vehicle *first = v->First();
       
  3196 
  3039 	/* Go to the last wagon and delete the link pointing there
  3197 	/* Go to the last wagon and delete the link pointing there
  3040 	 * *u is then the one-before-last wagon, and *v the last
  3198 	 * *u is then the one-before-last wagon, and *v the last
  3041 	 * one which will physicially be removed */
  3199 	 * one which will physicially be removed */
  3042 	Vehicle *u = v;
  3200 	Vehicle *u = v;
  3043 	for (; v->Next() != NULL; v = v->Next()) u = v;
  3201 	for (; v->Next() != NULL; v = v->Next()) u = v;
  3044 	u->SetNext(NULL);
  3202 	u->SetNext(NULL);
  3045 
  3203 
  3046 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  3204 	if (first == v) {
  3047 	DeleteWindowById(WC_VEHICLE_VIEW, v->index);
  3205 		/* Removing front vehicle (the last to go) */
       
  3206 		DeleteWindowById(WC_VEHICLE_VIEW, v->index);
       
  3207 		InvalidateWindow(WC_COMPANY, v->owner);
       
  3208 	} else {
       
  3209 		/* Recalculate cached train properties */
       
  3210 		TrainConsistChanged(first);
       
  3211 		InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
       
  3212 		/* Update the depot window if the first vehicle is in depot -
       
  3213 		 * if v == first, then it is updated in PreDestructor() */
       
  3214 		if (first->u.rail.track == TRACK_BIT_DEPOT) {
       
  3215 			InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
       
  3216 		}
       
  3217 	}
       
  3218 
  3048 	RebuildVehicleLists();
  3219 	RebuildVehicleLists();
  3049 	InvalidateWindow(WC_COMPANY, v->owner);
  3220 
  3050 
  3221 	MarkSingleVehicleDirty(v);
  3051 	BeginVehicleMove(v);
  3222 
  3052 	EndVehicleMove(v);
  3223 	/* 'v' shouldn't be accessed after it has been deleted */
       
  3224 	TrackBits track = v->u.rail.track;
       
  3225 	TileIndex tile = v->tile;
       
  3226 	Owner owner = v->owner;
  3053 
  3227 
  3054 	delete v;
  3228 	delete v;
  3055 
  3229 	v = NULL; // make sure nobody will won't try to read 'v' anymore
  3056 	if (v->u.rail.track != TRACK_BIT_DEPOT && v->u.rail.track != TRACK_BIT_WORMHOLE)
  3230 
  3057 		SetSignalsOnBothDir(v->tile, FIND_FIRST_BIT(v->u.rail.track));
  3231 	/* check if the wagon was on a road/rail-crossing */
  3058 
  3232 	if (IsLevelCrossingTile(tile)) UpdateLevelCrossing(tile);
  3059 	/* Check if the wagon was on a road/rail-crossing and disable it if no
  3233 
  3060 	 * others are on it */
  3234 	/* Update signals */
  3061 	DisableTrainCrossing(v->tile);
  3235 	if (IsTileType(tile, MP_TUNNELBRIDGE) || IsTileDepotType(tile, TRANSPORT_RAIL)) {
  3062 
  3236 		UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, owner);
  3063 	if ((v->u.rail.track == TRACK_BIT_WORMHOLE && v->vehstatus & VS_HIDDEN)) { // inside a tunnel
  3237 	} else {
  3064 		TileIndex endtile = CheckTunnelBusy(v->tile, NULL);
  3238 		SetSignalsOnBothDir(tile, (Track)(FIND_FIRST_BIT(track)), owner);
  3065 
       
  3066 		if (endtile == INVALID_TILE) return; // tunnel is busy (error returned)
       
  3067 
       
  3068 		switch (v->direction) {
       
  3069 			case 1:
       
  3070 			case 5:
       
  3071 				SetSignalsOnBothDir(v->tile, 0);
       
  3072 				SetSignalsOnBothDir(endtile, 0);
       
  3073 				break;
       
  3074 
       
  3075 			case 3:
       
  3076 			case 7:
       
  3077 				SetSignalsOnBothDir(v->tile, 1);
       
  3078 				SetSignalsOnBothDir(endtile, 1);
       
  3079 				break;
       
  3080 
       
  3081 			default:
       
  3082 				break;
       
  3083 		}
       
  3084 	}
  3239 	}
  3085 }
  3240 }
  3086 
  3241 
  3087 static void ChangeTrainDirRandomly(Vehicle *v)
  3242 static void ChangeTrainDirRandomly(Vehicle *v)
  3088 {
  3243 {
  3169 			InvalidateWindow(WC_VEHICLE_VIEW, v->index);
  3324 			InvalidateWindow(WC_VEHICLE_VIEW, v->index);
  3170 		}
  3325 		}
  3171 	}
  3326 	}
  3172 }
  3327 }
  3173 
  3328 
  3174 static const byte _breakdown_speeds[16] = {
  3329 /** Maximum speeds for train that is broken down or approaching line end */
       
  3330 static const uint16 _breakdown_speeds[16] = {
  3175 	225, 210, 195, 180, 165, 150, 135, 120, 105, 90, 75, 60, 45, 30, 15, 15
  3331 	225, 210, 195, 180, 165, 150, 135, 120, 105, 90, 75, 60, 45, 30, 15, 15
  3176 };
  3332 };
  3177 
  3333 
       
  3334 
       
  3335 /**
       
  3336  * Train is approaching line end, slow down and possibly reverse
       
  3337  *
       
  3338  * @param v front train engine
       
  3339  * @param signal not line end, just a red signal
       
  3340  * @return true iff we did NOT have to reverse
       
  3341  */
       
  3342 static bool TrainApproachingLineEnd(Vehicle *v, bool signal)
       
  3343 {
       
  3344 	/* Calc position within the current tile */
       
  3345 	uint x = v->x_pos & 0xF;
       
  3346 	uint y = v->y_pos & 0xF;
       
  3347 
       
  3348 	/* for diagonal directions, 'x' will be 0..15 -
       
  3349 	 * for other directions, it will be 1, 3, 5, ..., 15 */
       
  3350 	switch (v->direction) {
       
  3351 		case DIR_N : x = ~x + ~y + 25; break;
       
  3352 		case DIR_NW: x = y;            /* FALLTHROUGH */
       
  3353 		case DIR_NE: x = ~x + 16;      break;
       
  3354 		case DIR_E : x = ~x + y + 9;   break;
       
  3355 		case DIR_SE: x = y;            break;
       
  3356 		case DIR_S : x = x + y - 7;    break;
       
  3357 		case DIR_W : x = ~y + x + 9;   break;
       
  3358 		default: break;
       
  3359 	}
       
  3360 
       
  3361 	/* do not reverse when approaching red signal */
       
  3362 	if (!signal && x + 4 >= TILE_SIZE) {
       
  3363 		/* we are too near the tile end, reverse now */
       
  3364 		v->cur_speed = 0;
       
  3365 		ReverseTrainDirection(v);
       
  3366 		return false;
       
  3367 	}
       
  3368 
       
  3369 	/* slow down */
       
  3370 	v->vehstatus |= VS_TRAIN_SLOWING;
       
  3371 	uint16 break_speed = _breakdown_speeds[x & 0xF];
       
  3372 	if (break_speed < v->cur_speed) v->cur_speed = break_speed;
       
  3373 
       
  3374 	return true;
       
  3375 }
       
  3376 
       
  3377 
       
  3378 /**
       
  3379  * Determines whether train would like to leave the tile
       
  3380  * @param v train to test
       
  3381  * @return true iff vehicle is NOT entering or inside a depot or tunnel/bridge
       
  3382  */
       
  3383 static bool TrainCanLeaveTile(const Vehicle *v)
       
  3384 {
       
  3385 	/* Exit if inside a tunnel/bridge or a depot */
       
  3386 	if (v->u.rail.track == TRACK_BIT_WORMHOLE || v->u.rail.track == TRACK_BIT_DEPOT) return false;
       
  3387 
       
  3388 	TileIndex tile = v->tile;
       
  3389 
       
  3390 	/* entering a tunnel/bridge? */
       
  3391 	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
       
  3392 		DiagDirection dir = GetTunnelBridgeDirection(tile);
       
  3393 		if (DiagDirToDir(dir) == v->direction) return false;
       
  3394 	}
       
  3395 
       
  3396 	/* entering a depot? */
       
  3397 	if (IsTileDepotType(tile, TRANSPORT_RAIL)) {
       
  3398 		DiagDirection dir = ReverseDiagDir(GetRailDepotDirection(tile));
       
  3399 		if (DiagDirToDir(dir) == v->direction) return false;
       
  3400 	}
       
  3401 
       
  3402 	return true;
       
  3403 }
       
  3404 
       
  3405 
       
  3406 /**
       
  3407  * Determines whether train is approaching a rail-road crossing
       
  3408  *   (thus making it barred)
       
  3409  * @param v front engine of train
       
  3410  * @return TileIndex of crossing the train is approaching, else INVALID_TILE
       
  3411  * @pre v in non-crashed front engine
       
  3412  */
       
  3413 static TileIndex TrainApproachingCrossingTile(const Vehicle *v)
       
  3414 {
       
  3415 	assert(IsFrontEngine(v));
       
  3416 	assert(!(v->vehstatus & VS_CRASHED));
       
  3417 
       
  3418 	if (!TrainCanLeaveTile(v)) return INVALID_TILE;
       
  3419 
       
  3420 	DiagDirection dir = TrainExitDir(v->direction, v->u.rail.track);
       
  3421 	TileIndex tile = v->tile + TileOffsByDiagDir(dir);
       
  3422 
       
  3423 	/* not a crossing || wrong axis || wrong railtype || wrong owner */
       
  3424 	if (!IsLevelCrossingTile(tile) || DiagDirToAxis(dir) == GetCrossingRoadAxis(tile) ||
       
  3425 			!CheckCompatibleRail(v, tile) || GetTileOwner(tile) != v->owner) {
       
  3426 		return INVALID_TILE;
       
  3427 	}
       
  3428 
       
  3429 	return tile;
       
  3430 }
       
  3431 
       
  3432 
       
  3433 /**
       
  3434  * Checks for line end. Also, bars crossing at next tile if needed
       
  3435  *
       
  3436  * @param v vehicle we are checking
       
  3437  * @return true iff we did NOT have to reverse
       
  3438  */
  3178 static bool TrainCheckIfLineEnds(Vehicle *v)
  3439 static bool TrainCheckIfLineEnds(Vehicle *v)
  3179 {
  3440 {
       
  3441 	/* First, handle broken down train */
       
  3442 
  3180 	int t = v->breakdown_ctr;
  3443 	int t = v->breakdown_ctr;
  3181 	if (t > 1) {
  3444 	if (t > 1) {
  3182 		v->vehstatus |= VS_TRAIN_SLOWING;
  3445 		v->vehstatus |= VS_TRAIN_SLOWING;
  3183 
  3446 
  3184 		uint16 break_speed = _breakdown_speeds[GB(~t, 4, 4)];
  3447 		uint16 break_speed = _breakdown_speeds[GB(~t, 4, 4)];
  3185 		if (break_speed < v->cur_speed) v->cur_speed = break_speed;
  3448 		if (break_speed < v->cur_speed) v->cur_speed = break_speed;
  3186 	} else {
  3449 	} else {
  3187 		v->vehstatus &= ~VS_TRAIN_SLOWING;
  3450 		v->vehstatus &= ~VS_TRAIN_SLOWING;
  3188 	}
  3451 	}
  3189 
  3452 
  3190 	if (v->u.rail.track == TRACK_BIT_WORMHOLE) return true; // exit if inside a tunnel
  3453 	if (!TrainCanLeaveTile(v)) return true;
  3191 	if (v->u.rail.track == TRACK_BIT_DEPOT) return true; // exit if inside a depot
       
  3192 
       
  3193 	TileIndex tile = v->tile;
       
  3194 
       
  3195 	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
       
  3196 		DiagDirection dir = IsTunnel(tile) ? GetTunnelDirection(tile) : GetBridgeRampDirection(tile);
       
  3197 		if (DiagDirToDir(dir) == v->direction) return true;
       
  3198 	}
       
  3199 
       
  3200 	// depot?
       
  3201 	/* XXX -- When enabled, this makes it possible to crash trains of others
       
  3202 	     (by building a depot right against a station) */
       
  3203 /*	if (IsTileType(tile, MP_RAILWAY) && GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT)
       
  3204 		return true;*/
       
  3205 
  3454 
  3206 	/* Determine the non-diagonal direction in which we will exit this tile */
  3455 	/* Determine the non-diagonal direction in which we will exit this tile */
  3207 	DiagDirection dir = DirToDiagDir(v->direction);
  3456 	DiagDirection dir = TrainExitDir(v->direction, v->u.rail.track);
  3208 	if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[dir]) {
       
  3209 		dir = ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT);
       
  3210 	}
       
  3211 	/* Calculate next tile */
  3457 	/* Calculate next tile */
  3212 	tile += TileOffsByDiagDir(dir);
  3458 	TileIndex tile = v->tile + TileOffsByDiagDir(dir);
  3213 	// determine the track status on the next tile.
  3459 
       
  3460 	/* Determine the track status on the next tile */
  3214 	uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & _reachable_tracks[dir];
  3461 	uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & _reachable_tracks[dir];
  3215 
  3462 
  3216 	/* Calc position within the current tile ?? */
  3463 	/* We are sure the train is not entering a depot, it is detected above */
  3217 	uint x = v->x_pos & 0xF;
  3464 
  3218 	uint y = v->y_pos & 0xF;
  3465 	/* no suitable trackbits at all || wrong railtype || not our track ||
  3219 
  3466 	 *   tunnel/bridge from opposite side || depot from opposite side */
  3220 	switch (v->direction) {
  3467 	if (GB(ts, 0, 16) == 0 || !CheckCompatibleRail(v, tile) || GetTileOwner(tile) != v->owner ||
  3221 		case DIR_N : x = ~x + ~y + 24; break;
  3468 			(IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(tile) != dir) ||
  3222 		case DIR_NW: x = y;            /* FALLTHROUGH */
  3469 			(IsTileDepotType(tile, TRANSPORT_RAIL) && GetRailDepotDirection(tile) == dir) ) {
  3223 		case DIR_NE: x = ~x + 16;      break;
  3470 		return TrainApproachingLineEnd(v, false);
  3224 		case DIR_E : x = ~x + y + 8;   break;
  3471 	}
  3225 		case DIR_SE: x = y;            break;
  3472 
  3226 		case DIR_S : x = x + y - 8;    break;
  3473 	/* approaching red signal */
  3227 		case DIR_W : x = ~y + x + 8;   break;
  3474 	if ((ts & (ts >> 16)) != 0) return TrainApproachingLineEnd(v, true);
  3228 		default: break;
  3475 
  3229 	}
  3476 	/* approaching a rail/road crossing? then make it red */
  3230 
  3477 	if (IsLevelCrossingTile(tile)) MaybeBarCrossingWithSound(tile);
  3231 	if (GB(ts, 0, 16) != 0) {
       
  3232 		/* If we approach a rail-piece which we can't enter, or the back of a depot, don't enter it! */
       
  3233 		if (x + 4 >= TILE_SIZE &&
       
  3234 				(!CheckCompatibleRail(v, tile) ||
       
  3235 				(IsTileDepotType(tile, TRANSPORT_RAIL) &&
       
  3236 				GetRailDepotDirection(tile) == dir))) {
       
  3237 			v->cur_speed = 0;
       
  3238 			ReverseTrainDirection(v);
       
  3239 			return false;
       
  3240 		}
       
  3241 		if ((ts &= (ts >> 16)) == 0) {
       
  3242 			/* make a rail/road crossing red */
       
  3243 			if (IsLevelCrossingTile(tile)) {
       
  3244 				if (!IsCrossingBarred(tile)) {
       
  3245 					BarCrossing(tile);
       
  3246 					SndPlayVehicleFx(SND_0E_LEVEL_CROSSING, v);
       
  3247 					MarkTileDirtyByTile(tile);
       
  3248 				}
       
  3249 			}
       
  3250 			return true;
       
  3251 		}
       
  3252 	} else if (x + 4 >= TILE_SIZE) {
       
  3253 		v->cur_speed = 0;
       
  3254 		ReverseTrainDirection(v);
       
  3255 		return false;
       
  3256 	}
       
  3257 
       
  3258 	/* slow down */
       
  3259 	v->vehstatus |= VS_TRAIN_SLOWING;
       
  3260 	uint16 break_speed = _breakdown_speeds[x & 0xF];
       
  3261 	if (!(v->direction & 1)) break_speed >>= 1;
       
  3262 	if (break_speed < v->cur_speed) v->cur_speed = break_speed;
       
  3263 
  3478 
  3264 	return true;
  3479 	return true;
  3265 }
  3480 }
       
  3481 
  3266 
  3482 
  3267 static void TrainLocoHandler(Vehicle *v, bool mode)
  3483 static void TrainLocoHandler(Vehicle *v, bool mode)
  3268 {
  3484 {
  3269 	/* train has crashed? */
  3485 	/* train has crashed? */
  3270 	if (v->vehstatus & VS_CRASHED) {
  3486 	if (v->vehstatus & VS_CRASHED) {
  3381 			/* If we were already heading for a depot but it has
  3597 			/* If we were already heading for a depot but it has
  3382 			 * suddenly moved farther away, we continue our normal
  3598 			 * suddenly moved farther away, we continue our normal
  3383 			 * schedule? */
  3599 			 * schedule? */
  3384 			v->current_order.type = OT_DUMMY;
  3600 			v->current_order.type = OT_DUMMY;
  3385 			v->current_order.flags = 0;
  3601 			v->current_order.flags = 0;
  3386 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  3602 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  3387 		}
  3603 		}
  3388 		return;
  3604 		return;
  3389 	}
  3605 	}
  3390 
  3606 
  3391 	const Depot* depot = GetDepotByTile(tfdd.tile);
  3607 	const Depot* depot = GetDepotByTile(tfdd.tile);
  3395 			!Chance16(3, 16)) {
  3611 			!Chance16(3, 16)) {
  3396 		return;
  3612 		return;
  3397 	}
  3613 	}
  3398 
  3614 
  3399 	v->current_order.type = OT_GOTO_DEPOT;
  3615 	v->current_order.type = OT_GOTO_DEPOT;
  3400 	v->current_order.flags = OF_NON_STOP;
  3616 	v->current_order.flags = OFB_NON_STOP;
  3401 	v->current_order.dest = depot->index;
  3617 	v->current_order.dest = depot->index;
  3402 	v->dest_tile = tfdd.tile;
  3618 	v->dest_tile = tfdd.tile;
  3403 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  3619 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  3404 }
  3620 }
  3405 
  3621 
  3406 void OnNewDay_Train(Vehicle *v)
  3622 void OnNewDay_Train(Vehicle *v)
  3407 {
  3623 {
  3408 	if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
  3624 	if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
  3421 			if (tile != 0) v->dest_tile = tile;
  3637 			if (tile != 0) v->dest_tile = tile;
  3422 		}
  3638 		}
  3423 
  3639 
  3424 		if ((v->vehstatus & VS_STOPPED) == 0) {
  3640 		if ((v->vehstatus & VS_STOPPED) == 0) {
  3425 			/* running costs */
  3641 			/* running costs */
  3426 			CommandCost cost(v->GetRunningCost() / 364);
  3642 			CommandCost cost(EXPENSES_TRAIN_RUN, v->GetRunningCost() / 364);
  3427 
  3643 
  3428 			v->profit_this_year -= cost.GetCost() >> 8;
  3644 			v->profit_this_year -= cost.GetCost() >> 8;
  3429 
  3645 
  3430 			SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
       
  3431 			SubtractMoneyFromPlayerFract(v->owner, cost);
  3646 			SubtractMoneyFromPlayerFract(v->owner, cost);
  3432 
  3647 
  3433 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  3648 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  3434 			InvalidateWindowClasses(WC_TRAINS_LIST);
  3649 			InvalidateWindowClasses(WC_TRAINS_LIST);
  3435 		}
  3650 		}