src/train_cmd.cpp
branchcustombridgeheads
changeset 5649 55c8267c933f
parent 5647 cbde85c8c878
child 5650 aefc131bf5ce
equal deleted inserted replaced
5648:1608018c5ff2 5649:55c8267c933f
       
     1 /* $Id$ */
       
     2 
       
     3 #include "stdafx.h"
       
     4 #include "openttd.h"
       
     5 #include "bridge_map.h"
       
     6 #include "debug.h"
       
     7 #include "functions.h"
       
     8 #include "gui.h"
       
     9 #include "station_map.h"
       
    10 #include "table/strings.h"
       
    11 #include "map.h"
       
    12 #include "tile.h"
       
    13 #include "tunnel_map.h"
       
    14 #include "vehicle.h"
       
    15 #include "command.h"
       
    16 #include "pathfind.h"
       
    17 #include "npf.h"
       
    18 #include "station.h"
       
    19 #include "table/train_cmd.h"
       
    20 #include "news.h"
       
    21 #include "engine.h"
       
    22 #include "player.h"
       
    23 #include "sound.h"
       
    24 #include "depot.h"
       
    25 #include "waypoint.h"
       
    26 #include "vehicle_gui.h"
       
    27 #include "train.h"
       
    28 #include "bridge.h"
       
    29 #include "newgrf_callbacks.h"
       
    30 #include "newgrf_engine.h"
       
    31 #include "newgrf_sound.h"
       
    32 #include "newgrf_text.h"
       
    33 #include "direction.h"
       
    34 #include "yapf/yapf.h"
       
    35 #include "date.h"
       
    36 
       
    37 static bool TrainCheckIfLineEnds(Vehicle *v);
       
    38 static void TrainController(Vehicle *v, bool update_image);
       
    39 
       
    40 static const byte _vehicle_initial_x_fract[4] = {10, 8, 4,  8};
       
    41 static const byte _vehicle_initial_y_fract[4] = { 8, 4, 8, 10};
       
    42 static const byte _state_dir_table[4] = { 0x20, 8, 0x10, 4 };
       
    43 
       
    44 
       
    45 /** Return the cargo weight multiplier to use for a rail vehicle
       
    46  * @param cargo Cargo type to get multiplier for
       
    47  * @return Cargo weight multiplier
       
    48  */
       
    49 byte FreightWagonMult(CargoID cargo)
       
    50 {
       
    51 	// XXX NewCargos introduces a specific "is freight" flag for this test.
       
    52 	if (cargo == CT_PASSENGERS || cargo == CT_MAIL) return 1;
       
    53 	return _patches.freight_trains;
       
    54 }
       
    55 
       
    56 
       
    57 /**
       
    58  * Recalculates the cached total power of a train. Should be called when the consist is changed
       
    59  * @param v First vehicle of the consist.
       
    60  */
       
    61 void TrainPowerChanged(Vehicle* v)
       
    62 {
       
    63 	Vehicle* u;
       
    64 	uint32 power = 0;
       
    65 	uint32 max_te = 0;
       
    66 
       
    67 	for (u = v; u != NULL; u = u->next) {
       
    68 		const RailVehicleInfo *rvi_u;
       
    69 		bool engine_has_power = true;
       
    70 		bool wagon_has_power = true;
       
    71 
       
    72 		/* Power is not added for articulated parts */
       
    73 		if (IsArticulatedPart(u)) continue;
       
    74 
       
    75 		if (IsLevelCrossingTile(u->tile)) {
       
    76 			if (!HasPowerOnRail(u->u.rail.railtype, GetRailTypeCrossing(u->tile))) engine_has_power = false;
       
    77 			if (!HasPowerOnRail(v->u.rail.railtype, GetRailTypeCrossing(u->tile))) wagon_has_power = false;
       
    78 		} else {
       
    79 			if (!HasPowerOnRail(u->u.rail.railtype, GetRailType(u->tile))) engine_has_power = false;
       
    80 			if (!HasPowerOnRail(v->u.rail.railtype, GetRailType(u->tile))) wagon_has_power = false;
       
    81 		}
       
    82 
       
    83 		rvi_u = RailVehInfo(u->engine_type);
       
    84 
       
    85 		if (engine_has_power && rvi_u->power != 0) {
       
    86 			power += rvi_u->power;
       
    87 			/* Tractive effort in (tonnes * 1000 * 10 =) N */
       
    88 			max_te += (u->u.rail.cached_veh_weight * 10000 * rvi_u->tractive_effort) / 256;
       
    89 		}
       
    90 
       
    91 		if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) {
       
    92 			power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power;
       
    93 		}
       
    94 	}
       
    95 
       
    96 	if (v->u.rail.cached_power != power || v->u.rail.cached_max_te != max_te) {
       
    97 		v->u.rail.cached_power = power;
       
    98 		v->u.rail.cached_max_te = max_te;
       
    99 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
       
   100 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
       
   101 	}
       
   102 }
       
   103 
       
   104 
       
   105 /**
       
   106  * Recalculates the cached weight of a train and its vehicles. Should be called each time the cargo on
       
   107  * the consist changes.
       
   108  * @param v First vehicle of the consist.
       
   109  */
       
   110 static void TrainCargoChanged(Vehicle* v)
       
   111 {
       
   112 	Vehicle *u;
       
   113 	uint32 weight = 0;
       
   114 
       
   115 	for (u = v; u != NULL; u = u->next) {
       
   116 		const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
       
   117 		uint32 vweight = (_cargoc.weights[u->cargo_type] * u->cargo_count * FreightWagonMult(u->cargo_type)) / 16;
       
   118 
       
   119 		// Vehicle weight is not added for articulated parts.
       
   120 		if (!IsArticulatedPart(u)) {
       
   121 			// vehicle weight is the sum of the weight of the vehicle and the weight of its cargo
       
   122 			vweight += rvi->weight;
       
   123 
       
   124 			// powered wagons have extra weight added
       
   125 			if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON))
       
   126 				vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight;
       
   127 		}
       
   128 
       
   129 		// consist weight is the sum of the weight of all vehicles in the consist
       
   130 		weight += vweight;
       
   131 
       
   132 		// store vehicle weight in cache
       
   133 		u->u.rail.cached_veh_weight = vweight;
       
   134 	};
       
   135 
       
   136 	// store consist weight in cache
       
   137 	v->u.rail.cached_weight = weight;
       
   138 
       
   139 	/* Now update train power (tractive effort is dependent on weight) */
       
   140 	TrainPowerChanged(v);
       
   141 }
       
   142 
       
   143 
       
   144 /**
       
   145  * Recalculates the cached stuff of a train. Should be called each time a vehicle is added
       
   146  * to/removed from the chain, and when the game is loaded.
       
   147  * Note: this needs to be called too for 'wagon chains' (in the depot, without an engine)
       
   148  * @param v First vehicle of the chain.
       
   149  */
       
   150 void TrainConsistChanged(Vehicle* v)
       
   151 {
       
   152 	const RailVehicleInfo *rvi_v;
       
   153 	Vehicle *u;
       
   154 	uint16 max_speed = 0xFFFF;
       
   155 	EngineID first_engine;
       
   156 
       
   157 	assert(v->type == VEH_Train);
       
   158 
       
   159 	assert(IsFrontEngine(v) || IsFreeWagon(v));
       
   160 
       
   161 	rvi_v = RailVehInfo(v->engine_type);
       
   162 	first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE;
       
   163 	v->u.rail.cached_total_length = 0;
       
   164 	v->u.rail.compatible_railtypes = 0;
       
   165 
       
   166 	for (u = v; u != NULL; u = u->next) {
       
   167 		const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
       
   168 		uint16 veh_len;
       
   169 
       
   170 		// Update the v->first cache. This is faster than having to brute force it later.
       
   171 		if (u->first == NULL) u->first = v;
       
   172 
       
   173 		// update the 'first engine'
       
   174 		u->u.rail.first_engine = (v == u) ? INVALID_ENGINE : first_engine;
       
   175 		u->u.rail.railtype = GetEngine(u->engine_type)->railtype;
       
   176 
       
   177 		if (IsTrainEngine(u)) first_engine = u->engine_type;
       
   178 
       
   179 		if (rvi_u->visual_effect != 0) {
       
   180 			u->u.rail.cached_vis_effect = rvi_u->visual_effect;
       
   181 		} else {
       
   182 			if (IsTrainWagon(u) || IsArticulatedPart(u)) {
       
   183 				// Wagons and articulated parts have no effect by default
       
   184 				u->u.rail.cached_vis_effect = 0x40;
       
   185 			} else if (rvi_u->engclass == 0) {
       
   186 				// Steam is offset by -4 units
       
   187 				u->u.rail.cached_vis_effect = 4;
       
   188 			} else {
       
   189 				// Diesel fumes and sparks come from the centre
       
   190 				u->u.rail.cached_vis_effect = 8;
       
   191 			}
       
   192 		}
       
   193 
       
   194 		if (!IsArticulatedPart(u)) {
       
   195 			// check if its a powered wagon
       
   196 			CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON);
       
   197 
       
   198 			/* Check powered wagon / visual effect callback */
       
   199 			if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_WAGON_POWER)) {
       
   200 				uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u);
       
   201 
       
   202 				if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback;
       
   203 			}
       
   204 
       
   205 			if ((rvi_v->pow_wag_power != 0) && (rvi_u->flags & RVI_WAGON) && UsesWagonOverride(u)) {
       
   206 				if (u->u.rail.cached_vis_effect < 0x40) {
       
   207 					/* wagon is powered */
       
   208 					SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status
       
   209 				}
       
   210 			}
       
   211 
       
   212 			/* Do not count powered wagons for the compatible railtypes, as wagons always
       
   213 			   have railtype normal */
       
   214 			if (rvi_u->power > 0) {
       
   215 				v->u.rail.compatible_railtypes |= GetRailTypeInfo(u->u.rail.railtype)->powered_railtypes;
       
   216 			}
       
   217 
       
   218 			/* Some electric engines can be allowed to run on normal rail. It happens to all
       
   219 			 * existing electric engines when elrails are disabled and then re-enabled */
       
   220 			if (HASBIT(u->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL)) {
       
   221 				u->u.rail.railtype = RAILTYPE_RAIL;
       
   222 				u->u.rail.compatible_railtypes |= (1 << RAILTYPE_RAIL);
       
   223 			}
       
   224 
       
   225 			// max speed is the minimum of the speed limits of all vehicles in the consist
       
   226 			if (!(rvi_u->flags & RVI_WAGON) || _patches.wagon_speed_limits)
       
   227 				if (rvi_u->max_speed != 0 && !UsesWagonOverride(u))
       
   228 					max_speed = min(rvi_u->max_speed, max_speed);
       
   229 		}
       
   230 
       
   231 		// check the vehicle length (callback)
       
   232 		veh_len = CALLBACK_FAILED;
       
   233 		if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) {
       
   234 			veh_len = GetVehicleCallback(CBID_TRAIN_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
       
   235 		}
       
   236 		if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor;
       
   237 		veh_len = clamp(veh_len, 0, u->next == NULL ? 7 : 5); // the clamp on vehicles not the last in chain is stricter, as too short wagons can break the 'follow next vehicle' code
       
   238 		u->u.rail.cached_veh_length = 8 - veh_len;
       
   239 		v->u.rail.cached_total_length += u->u.rail.cached_veh_length;
       
   240 
       
   241 	};
       
   242 
       
   243 	// store consist weight/max speed in cache
       
   244 	v->u.rail.cached_max_speed = max_speed;
       
   245 
       
   246 	// 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)
       
   247 	TrainCargoChanged(v);
       
   248 }
       
   249 
       
   250 /* These two arrays are used for realistic acceleration. XXX: How should they
       
   251  * be interpreted? */
       
   252 static const byte _curve_neighbours45[8][2] = {
       
   253 	{7, 1},
       
   254 	{0, 2},
       
   255 	{1, 3},
       
   256 	{2, 4},
       
   257 	{3, 5},
       
   258 	{4, 6},
       
   259 	{5, 7},
       
   260 	{6, 0},
       
   261 };
       
   262 
       
   263 static const byte _curve_neighbours90[8][2] = {
       
   264 	{6, 2},
       
   265 	{7, 3},
       
   266 	{0, 4},
       
   267 	{1, 5},
       
   268 	{2, 6},
       
   269 	{3, 7},
       
   270 	{4, 0},
       
   271 	{5, 1},
       
   272 };
       
   273 
       
   274 enum AccelType {
       
   275 	AM_ACCEL,
       
   276 	AM_BRAKE
       
   277 };
       
   278 
       
   279 static bool TrainShouldStop(const Vehicle* v, TileIndex tile)
       
   280 {
       
   281 	const Order* o = &v->current_order;
       
   282 	StationID sid = GetStationIndex(tile);
       
   283 
       
   284 	assert(v->type == VEH_Train);
       
   285 	//When does a train drive through a station
       
   286 	//first we deal with the "new nonstop handling"
       
   287 	if (_patches.new_nonstop && o->flags & OF_NON_STOP && sid == o->dest) {
       
   288 		return false;
       
   289 	}
       
   290 
       
   291 	if (v->last_station_visited == sid) return false;
       
   292 
       
   293 	if (sid != o->dest && (o->flags & OF_NON_STOP || _patches.new_nonstop)) {
       
   294 		return false;
       
   295 	}
       
   296 
       
   297 	return true;
       
   298 }
       
   299 
       
   300 //new acceleration
       
   301 static int GetTrainAcceleration(Vehicle *v, bool mode)
       
   302 {
       
   303 	const Vehicle *u;
       
   304 	int num = 0; //number of vehicles, change this into the number of axles later
       
   305 	int power = 0;
       
   306 	int mass = 0;
       
   307 	int max_speed = 2000;
       
   308 	int area = 120;
       
   309 	int friction = 35; //[1e-3]
       
   310 	int drag_coeff = 20; //[1e-4]
       
   311 	int incl = 0;
       
   312 	int resistance;
       
   313 	int speed = v->cur_speed; //[mph]
       
   314 	int force = 0x3FFFFFFF;
       
   315 	int pos = 0;
       
   316 	int lastpos = -1;
       
   317 	int curvecount[2] = {0, 0};
       
   318 	int sum = 0;
       
   319 	int numcurve = 0;
       
   320 	int max_te = v->u.rail.cached_max_te; // [N]
       
   321 
       
   322 	speed *= 10;
       
   323 	speed /= 16;
       
   324 
       
   325 	//first find the curve speed limit
       
   326 	for (u = v; u->next != NULL; u = u->next, pos++) {
       
   327 		Direction dir = u->direction;
       
   328 		Direction ndir = u->next->direction;
       
   329 		int i;
       
   330 
       
   331 		for (i = 0; i < 2; i++) {
       
   332 			if ( _curve_neighbours45[dir][i] == ndir) {
       
   333 				curvecount[i]++;
       
   334 				if (lastpos != -1) {
       
   335 					numcurve++;
       
   336 					sum += pos - lastpos;
       
   337 					if (pos - lastpos == 1) {
       
   338 						max_speed = 88;
       
   339 					}
       
   340 				}
       
   341 				lastpos = pos;
       
   342 			}
       
   343 		}
       
   344 
       
   345 		//if we have a 90 degree turn, fix the speed limit to 60
       
   346 		if (_curve_neighbours90[dir][0] == ndir ||
       
   347 				_curve_neighbours90[dir][1] == ndir) {
       
   348 			max_speed = 61;
       
   349 		}
       
   350 	}
       
   351 
       
   352 	if (numcurve > 0) sum /= numcurve;
       
   353 
       
   354 	if ((curvecount[0] != 0 || curvecount[1] != 0) && max_speed > 88) {
       
   355 		int total = curvecount[0] + curvecount[1];
       
   356 
       
   357 		if (curvecount[0] == 1 && curvecount[1] == 1) {
       
   358 			max_speed = 0xFFFF;
       
   359 		} else if (total > 1) {
       
   360 			max_speed = 232 - (13 - clamp(sum, 1, 12)) * (13 - clamp(sum, 1, 12));
       
   361 		}
       
   362 	}
       
   363 
       
   364 	max_speed += (max_speed / 2) * v->u.rail.railtype;
       
   365 
       
   366 	if (IsTileType(v->tile, MP_STATION) && IsFrontEngine(v)) {
       
   367 		if (TrainShouldStop(v, v->tile)) {
       
   368 			uint station_length = GetPlatformLength(v->tile, DirToDiagDir(v->direction));
       
   369 			int delta_v;
       
   370 
       
   371 			max_speed = 120;
       
   372 
       
   373 			delta_v = v->cur_speed / (station_length + 1);
       
   374 			if (v->max_speed > (v->cur_speed - delta_v))
       
   375 				max_speed = v->cur_speed - (delta_v / 10);
       
   376 
       
   377 			max_speed = max(max_speed, 25 * station_length);
       
   378 		}
       
   379 	}
       
   380 
       
   381 	mass = v->u.rail.cached_weight;
       
   382 	power = v->u.rail.cached_power * 746;
       
   383 	max_speed = min(max_speed, v->u.rail.cached_max_speed);
       
   384 
       
   385 	for (u = v; u != NULL; u = u->next) {
       
   386 		num++;
       
   387 		drag_coeff += 3;
       
   388 
       
   389 		if (u->u.rail.track == 0x80) max_speed = min(max_speed, 61);
       
   390 
       
   391 		if (HASBIT(u->u.rail.flags, VRF_GOINGUP)) {
       
   392 			incl += u->u.rail.cached_veh_weight * 60; //3% slope, quite a bit actually
       
   393 		} else if (HASBIT(u->u.rail.flags, VRF_GOINGDOWN)) {
       
   394 			incl -= u->u.rail.cached_veh_weight * 60;
       
   395 		}
       
   396 	}
       
   397 
       
   398 	v->max_speed = max_speed;
       
   399 
       
   400 	if (v->u.rail.railtype != RAILTYPE_MAGLEV) {
       
   401 		resistance = 13 * mass / 10;
       
   402 		resistance += 60 * num;
       
   403 		resistance += friction * mass * speed / 1000;
       
   404 		resistance += (area * drag_coeff * speed * speed) / 10000;
       
   405 	} else {
       
   406 		resistance = (area * (drag_coeff / 2) * speed * speed) / 10000;
       
   407 	}
       
   408 	resistance += incl;
       
   409 	resistance *= 4; //[N]
       
   410 
       
   411 	/* Due to the mph to m/s conversion below, at speeds below 3 mph the force is
       
   412 	 * actually double the train's power */
       
   413 	if (speed > 2) {
       
   414 		switch (v->u.rail.railtype) {
       
   415 			case RAILTYPE_RAIL:
       
   416 			case RAILTYPE_ELECTRIC:
       
   417 			case RAILTYPE_MONO:
       
   418 				force = power / speed; //[N]
       
   419 				force *= 22;
       
   420 				force /= 10;
       
   421 				if (mode == AM_ACCEL && force > max_te) force = max_te;
       
   422 				break;
       
   423 
       
   424 			case RAILTYPE_MAGLEV:
       
   425 				force = power / 25;
       
   426 				break;
       
   427 		}
       
   428 	} else {
       
   429 		//"kickoff" acceleration
       
   430 		force = (mode == AM_ACCEL && v->u.rail.railtype != RAILTYPE_MAGLEV) ? min(max_te, power) : power;
       
   431 		force = max(force, (mass * 8) + resistance);
       
   432 	}
       
   433 
       
   434 	if (force <= 0) force = 10000;
       
   435 
       
   436 	if (v->u.rail.railtype != RAILTYPE_MAGLEV) force = min(force, mass * 10 * 200);
       
   437 
       
   438 	if (mode == AM_ACCEL) {
       
   439 		return (force - resistance) / (mass * 4);
       
   440 	} else {
       
   441 		return min((-force - resistance) / (mass * 4), -10000 / (mass * 4));
       
   442 	}
       
   443 }
       
   444 
       
   445 static void UpdateTrainAcceleration(Vehicle* v)
       
   446 {
       
   447 	uint power = 0;
       
   448 	uint weight = 0;
       
   449 
       
   450 	assert(IsFrontEngine(v));
       
   451 
       
   452 	weight = v->u.rail.cached_weight;
       
   453 	power = v->u.rail.cached_power;
       
   454 	v->max_speed = v->u.rail.cached_max_speed;
       
   455 
       
   456 	assert(weight != 0);
       
   457 
       
   458 	v->acceleration = clamp(power / weight * 4, 1, 255);
       
   459 }
       
   460 
       
   461 int GetTrainImage(const Vehicle* v, Direction direction)
       
   462 {
       
   463 	int img = v->spritenum;
       
   464 	int base;
       
   465 
       
   466 	if (HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction);
       
   467 
       
   468 	if (is_custom_sprite(img)) {
       
   469 		base = GetCustomVehicleSprite(v, direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img));
       
   470 		if (base != 0) return base;
       
   471 		img = orig_rail_vehicle_info[v->engine_type].image_index;
       
   472 	}
       
   473 
       
   474 	base = _engine_sprite_base[img] + ((direction + _engine_sprite_add[img]) & _engine_sprite_and[img]);
       
   475 
       
   476 	if (v->cargo_count >= v->cargo_cap / 2) base += _wagon_full_adder[img];
       
   477 	return base;
       
   478 }
       
   479 
       
   480 void DrawTrainEngine(int x, int y, EngineID engine, uint32 image_ormod)
       
   481 {
       
   482 	const RailVehicleInfo *rvi = RailVehInfo(engine);
       
   483 
       
   484 	int img = rvi->image_index;
       
   485 	uint32 image = 0;
       
   486 
       
   487 	if (is_custom_sprite(img)) {
       
   488 		image = GetCustomVehicleIcon(engine, DIR_W);
       
   489 		if (image == 0) {
       
   490 			img = orig_rail_vehicle_info[engine].image_index;
       
   491 		} else {
       
   492 			y += _traininfo_vehicle_pitch;
       
   493 		}
       
   494 	}
       
   495 	if (image == 0) {
       
   496 		image = (6 & _engine_sprite_and[img]) + _engine_sprite_base[img];
       
   497 	}
       
   498 
       
   499 	if (rvi->flags & RVI_MULTIHEAD) {
       
   500 		DrawSprite(image | image_ormod, x - 14, y);
       
   501 		x += 15;
       
   502 		image = 0;
       
   503 		if (is_custom_sprite(img)) {
       
   504 			image = GetCustomVehicleIcon(engine, 2);
       
   505 			if (image == 0) img = orig_rail_vehicle_info[engine].image_index;
       
   506 		}
       
   507 		if (image == 0) {
       
   508 			image =
       
   509 				((6 + _engine_sprite_add[img + 1]) & _engine_sprite_and[img + 1]) +
       
   510 				_engine_sprite_base[img + 1];
       
   511 		}
       
   512 	}
       
   513 	DrawSprite(image | image_ormod, x, y);
       
   514 }
       
   515 
       
   516 uint CountArticulatedParts(EngineID engine_type)
       
   517 {
       
   518 	uint16 callback;
       
   519 	uint i;
       
   520 
       
   521 	if (!HASBIT(EngInfo(engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return 0;
       
   522 
       
   523 	for (i = 1; i < 10; i++) {
       
   524 		callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, engine_type, NULL);
       
   525 		if (callback == CALLBACK_FAILED || callback == 0xFF) break;
       
   526 	}
       
   527 
       
   528 	return i - 1;
       
   529 }
       
   530 
       
   531 static void AddArticulatedParts(Vehicle **vl)
       
   532 {
       
   533 	const RailVehicleInfo *rvi_artic;
       
   534 	EngineID engine_type;
       
   535 	Vehicle *v = vl[0];
       
   536 	Vehicle *u = v;
       
   537 	uint16 callback;
       
   538 	bool flip_image;
       
   539 	uint i;
       
   540 
       
   541 	if (!HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return;
       
   542 
       
   543 	for (i = 1; i < 10; i++) {
       
   544 		callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, v->engine_type, v);
       
   545 		if (callback == CALLBACK_FAILED || callback == 0xFF) return;
       
   546 
       
   547 		/* Attempt to use pre-allocated vehicles until they run out. This can happen
       
   548 		 * if the callback returns different values depending on the cargo type. */
       
   549 		u->next = vl[i];
       
   550 		if (u->next == NULL) u->next = AllocateVehicle();
       
   551 		if (u->next == NULL) return;
       
   552 
       
   553 		u = u->next;
       
   554 
       
   555 		engine_type = GB(callback, 0, 7);
       
   556 		flip_image = HASBIT(callback, 7);
       
   557 		rvi_artic = RailVehInfo(engine_type);
       
   558 
       
   559 		// get common values from first engine
       
   560 		u->direction = v->direction;
       
   561 		u->owner = v->owner;
       
   562 		u->tile = v->tile;
       
   563 		u->x_pos = v->x_pos;
       
   564 		u->y_pos = v->y_pos;
       
   565 		u->z_pos = v->z_pos;
       
   566 		u->z_height = v->z_height;
       
   567 		u->u.rail.track = v->u.rail.track;
       
   568 		u->u.rail.railtype = v->u.rail.railtype;
       
   569 		u->build_year = v->build_year;
       
   570 		u->vehstatus = v->vehstatus & ~VS_STOPPED;
       
   571 		u->u.rail.first_engine = v->engine_type;
       
   572 
       
   573 		// get more settings from rail vehicle info
       
   574 		u->spritenum = rvi_artic->image_index;
       
   575 		if (flip_image) u->spritenum++;
       
   576 		u->cargo_type = rvi_artic->cargo_type;
       
   577 		u->cargo_subtype = 0;
       
   578 		u->cargo_cap = rvi_artic->capacity;
       
   579 		u->max_speed = 0;
       
   580 		u->max_age = 0;
       
   581 		u->engine_type = engine_type;
       
   582 		u->value = 0;
       
   583 		u->type = VEH_Train;
       
   584 		u->subtype = 0;
       
   585 		SetArticulatedPart(u);
       
   586 		u->cur_image = 0xAC2;
       
   587 		u->random_bits = VehicleRandomBits();
       
   588 
       
   589 		VehiclePositionChanged(u);
       
   590 	}
       
   591 }
       
   592 
       
   593 static int32 CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags)
       
   594 {
       
   595 	int32 value;
       
   596 	const RailVehicleInfo *rvi;
       
   597 	uint num_vehicles;
       
   598 
       
   599 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
   600 
       
   601 	rvi = RailVehInfo(engine);
       
   602 	value = (rvi->base_cost * _price.build_railwagon) >> 8;
       
   603 
       
   604 	num_vehicles = 1 + CountArticulatedParts(engine);
       
   605 
       
   606 	if (!(flags & DC_QUERY_COST)) {
       
   607 		Vehicle *vl[11]; // Allow for wagon and upto 10 artic parts.
       
   608 		Vehicle* v;
       
   609 		int x;
       
   610 		int y;
       
   611 
       
   612 		memset(&vl, 0, sizeof(vl));
       
   613 
       
   614 		if (!AllocateVehicles(vl, num_vehicles))
       
   615 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
       
   616 
       
   617 		if (flags & DC_EXEC) {
       
   618 			Vehicle *u, *w;
       
   619 			DiagDirection dir;
       
   620 
       
   621 			v = vl[0];
       
   622 			v->spritenum = rvi->image_index;
       
   623 
       
   624 			u = NULL;
       
   625 
       
   626 			FOR_ALL_VEHICLES(w) {
       
   627 				if (w->type == VEH_Train && w->tile == tile &&
       
   628 				    IsFreeWagon(w) && w->engine_type == engine) {
       
   629 					u = GetLastVehicleInChain(w);
       
   630 					break;
       
   631 				}
       
   632 			}
       
   633 
       
   634 			v->engine_type = engine;
       
   635 
       
   636 			dir = GetRailDepotDirection(tile);
       
   637 
       
   638 			v->direction = DiagDirToDir(dir);
       
   639 			v->tile = tile;
       
   640 
       
   641 			x = TileX(tile) * TILE_SIZE | _vehicle_initial_x_fract[dir];
       
   642 			y = TileY(tile) * TILE_SIZE | _vehicle_initial_y_fract[dir];
       
   643 
       
   644 			v->x_pos = x;
       
   645 			v->y_pos = y;
       
   646 			v->z_pos = GetSlopeZ(x,y);
       
   647 			v->owner = _current_player;
       
   648 			v->z_height = 6;
       
   649 			v->u.rail.track = 0x80;
       
   650 			v->vehstatus = VS_HIDDEN | VS_DEFPAL;
       
   651 
       
   652 			v->subtype = 0;
       
   653 			SetTrainWagon(v);
       
   654 			if (u != NULL) {
       
   655 				u->next = v;
       
   656 			} else {
       
   657 				SetFreeWagon(v);
       
   658 				InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
       
   659 			}
       
   660 
       
   661 			v->cargo_type = rvi->cargo_type;
       
   662 			v->cargo_subtype = 0;
       
   663 			v->cargo_cap = rvi->capacity;
       
   664 			v->value = value;
       
   665 //			v->day_counter = 0;
       
   666 
       
   667 			v->u.rail.railtype = GetEngine(engine)->railtype;
       
   668 
       
   669 			v->build_year = _cur_year;
       
   670 			v->type = VEH_Train;
       
   671 			v->cur_image = 0xAC2;
       
   672 			v->random_bits = VehicleRandomBits();
       
   673 
       
   674 			AddArticulatedParts(vl);
       
   675 
       
   676 			_new_vehicle_id = v->index;
       
   677 
       
   678 			VehiclePositionChanged(v);
       
   679 			TrainConsistChanged(GetFirstVehicleInChain(v));
       
   680 			GetPlayer(_current_player)->num_engines[engine]++;
       
   681 
       
   682 			InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
       
   683 			if (IsLocalPlayer()) {
       
   684 				InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train); // updates the replace Train window
       
   685 			}
       
   686 		}
       
   687 	}
       
   688 
       
   689 	return value;
       
   690 }
       
   691 
       
   692 // Move all free vehicles in the depot to the train
       
   693 static void NormalizeTrainVehInDepot(const Vehicle* u)
       
   694 {
       
   695 	const Vehicle* v;
       
   696 
       
   697 	FOR_ALL_VEHICLES(v) {
       
   698 		if (v->type == VEH_Train && IsFreeWagon(v) &&
       
   699 				v->tile == u->tile &&
       
   700 				v->u.rail.track == 0x80) {
       
   701 			if (CmdFailed(DoCommand(0, v->index | (u->index << 16), 1, DC_EXEC,
       
   702 					CMD_MOVE_RAIL_VEHICLE)))
       
   703 				break;
       
   704 		}
       
   705 	}
       
   706 }
       
   707 
       
   708 static int32 EstimateTrainCost(const RailVehicleInfo* rvi)
       
   709 {
       
   710 	return rvi->base_cost * (_price.build_railvehicle >> 3) >> 5;
       
   711 }
       
   712 
       
   713 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
       
   714 {
       
   715 	u->direction = v->direction;
       
   716 	u->owner = v->owner;
       
   717 	u->tile = v->tile;
       
   718 	u->x_pos = v->x_pos;
       
   719 	u->y_pos = v->y_pos;
       
   720 	u->z_pos = v->z_pos;
       
   721 	u->z_height = 6;
       
   722 	u->u.rail.track = 0x80;
       
   723 	u->vehstatus = v->vehstatus & ~VS_STOPPED;
       
   724 	u->subtype = 0;
       
   725 	SetMultiheaded(u);
       
   726 	u->spritenum = v->spritenum + 1;
       
   727 	u->cargo_type = v->cargo_type;
       
   728 	u->cargo_subtype = v->cargo_subtype;
       
   729 	u->cargo_cap = v->cargo_cap;
       
   730 	u->u.rail.railtype = v->u.rail.railtype;
       
   731 	if (building) v->next = u;
       
   732 	u->engine_type = v->engine_type;
       
   733 	u->build_year = v->build_year;
       
   734 	if (building) v->value >>= 1;
       
   735 	u->value = v->value;
       
   736 	u->type = VEH_Train;
       
   737 	u->cur_image = 0xAC2;
       
   738 	u->random_bits = VehicleRandomBits();
       
   739 	VehiclePositionChanged(u);
       
   740 }
       
   741 
       
   742 /** Build a railroad vehicle.
       
   743  * @param tile tile of the depot where rail-vehicle is built
       
   744  * @param p1 engine type id
       
   745  * @param p2 bit 0 when set, the train will get number 0, otherwise it will get a free number
       
   746  *           bit 1 prevents any free cars from being added to the train
       
   747  */
       
   748 int32 CmdBuildRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
   749 {
       
   750 	const RailVehicleInfo *rvi;
       
   751 	int value;
       
   752 	Vehicle *v;
       
   753 	UnitID unit_num;
       
   754 	Engine *e;
       
   755 	uint num_vehicles;
       
   756 
       
   757 	/* Check if the engine-type is valid (for the player) */
       
   758 	if (!IsEngineBuildable(p1, VEH_Train, _current_player)) return_cmd_error(STR_ENGINE_NOT_BUILDABLE);
       
   759 
       
   760 	/* Check if the train is actually being built in a depot belonging
       
   761 	 * to the player. Doesn't matter if only the cost is queried */
       
   762 	if (!(flags & DC_QUERY_COST)) {
       
   763 		if (!IsTileDepotType(tile, TRANSPORT_RAIL)) return CMD_ERROR;
       
   764 		if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
       
   765 	}
       
   766 
       
   767 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
   768 
       
   769 	rvi = RailVehInfo(p1);
       
   770 	e = GetEngine(p1);
       
   771 
       
   772 	/* Check if depot and new engine uses the same kind of tracks */
       
   773 	/* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
       
   774 	if (!HasPowerOnRail(e->railtype, GetRailType(tile))) return CMD_ERROR;
       
   775 
       
   776 	if (rvi->flags & RVI_WAGON) return CmdBuildRailWagon(p1, tile, flags);
       
   777 
       
   778 	value = EstimateTrainCost(rvi);
       
   779 
       
   780 	num_vehicles = (rvi->flags & RVI_MULTIHEAD) ? 2 : 1;
       
   781 	num_vehicles += CountArticulatedParts(p1);
       
   782 
       
   783 	if (!(flags & DC_QUERY_COST)) {
       
   784 		Vehicle *vl[12]; // Allow for upto 10 artic parts and dual-heads
       
   785 
       
   786 		memset(&vl, 0, sizeof(vl));
       
   787 
       
   788 		if (!AllocateVehicles(vl, num_vehicles) || IsOrderPoolFull())
       
   789 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
       
   790 
       
   791 		v = vl[0];
       
   792 
       
   793 		unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_Train);
       
   794 		if (unit_num > _patches.max_trains)
       
   795 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
       
   796 
       
   797 		if (flags & DC_EXEC) {
       
   798 			DiagDirection dir = GetRailDepotDirection(tile);
       
   799 			int x = TileX(tile) * TILE_SIZE + _vehicle_initial_x_fract[dir];
       
   800 			int y = TileY(tile) * TILE_SIZE + _vehicle_initial_y_fract[dir];
       
   801 
       
   802 			v->unitnumber = unit_num;
       
   803 			v->direction = DiagDirToDir(dir);
       
   804 			v->tile = tile;
       
   805 			v->owner = _current_player;
       
   806 			v->x_pos = x;
       
   807 			v->y_pos = y;
       
   808 			v->z_pos = GetSlopeZ(x,y);
       
   809 			v->z_height = 6;
       
   810 			v->u.rail.track = 0x80;
       
   811 			v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
       
   812 			v->spritenum = rvi->image_index;
       
   813 			v->cargo_type = rvi->cargo_type;
       
   814 			v->cargo_subtype = 0;
       
   815 			v->cargo_cap = rvi->capacity;
       
   816 			v->max_speed = rvi->max_speed;
       
   817 			v->value = value;
       
   818 			v->last_station_visited = INVALID_STATION;
       
   819 			v->dest_tile = 0;
       
   820 
       
   821 			v->engine_type = p1;
       
   822 
       
   823 			v->reliability = e->reliability;
       
   824 			v->reliability_spd_dec = e->reliability_spd_dec;
       
   825 			v->max_age = e->lifelength * 366;
       
   826 
       
   827 			v->string_id = STR_SV_TRAIN_NAME;
       
   828 			v->u.rail.railtype = e->railtype;
       
   829 			_new_vehicle_id = v->index;
       
   830 
       
   831 			v->service_interval = _patches.servint_trains;
       
   832 			v->date_of_last_service = _date;
       
   833 			v->build_year = _cur_year;
       
   834 			v->type = VEH_Train;
       
   835 			v->cur_image = 0xAC2;
       
   836 			v->random_bits = VehicleRandomBits();
       
   837 
       
   838 			v->subtype = 0;
       
   839 			SetFrontEngine(v);
       
   840 			SetTrainEngine(v);
       
   841 
       
   842 			VehiclePositionChanged(v);
       
   843 
       
   844 			if (rvi->flags & RVI_MULTIHEAD) {
       
   845 				SetMultiheaded(v);
       
   846 				AddRearEngineToMultiheadedTrain(vl[0], vl[1], true);
       
   847 				/* Now we need to link the front and rear engines together
       
   848 				 * other_multiheaded_part is the pointer that links to the other half of the engine
       
   849 				 * vl[0] is the front and vl[1] is the rear
       
   850 				 */
       
   851 				vl[0]->u.rail.other_multiheaded_part = vl[1];
       
   852 				vl[1]->u.rail.other_multiheaded_part = vl[0];
       
   853 			} else {
       
   854 				AddArticulatedParts(vl);
       
   855 			}
       
   856 
       
   857 			TrainConsistChanged(v);
       
   858 			UpdateTrainAcceleration(v);
       
   859 
       
   860 			if (!HASBIT(p2, 1)) { // check if the cars should be added to the new vehicle
       
   861 				NormalizeTrainVehInDepot(v);
       
   862 			}
       
   863 
       
   864 			GetPlayer(_current_player)->num_engines[p1]++;
       
   865 			InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
       
   866 			RebuildVehicleLists();
       
   867 			InvalidateWindow(WC_COMPANY, v->owner);
       
   868 			if (IsLocalPlayer()) {
       
   869 				InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train); // updates the replace Train window
       
   870 			}
       
   871 		}
       
   872 	}
       
   873 
       
   874 	return value;
       
   875 }
       
   876 
       
   877 
       
   878 /* Check if all the wagons of the given train are in a depot, returns the
       
   879  * number of cars (including loco) then. If not it returns -1 */
       
   880 int CheckTrainInDepot(const Vehicle *v, bool needs_to_be_stopped)
       
   881 {
       
   882 	int count;
       
   883 	TileIndex tile = v->tile;
       
   884 
       
   885 	/* check if stopped in a depot */
       
   886 	if (!IsTileDepotType(tile, TRANSPORT_RAIL) || v->cur_speed != 0) return -1;
       
   887 
       
   888 	count = 0;
       
   889 	for (; v != NULL; v = v->next) {
       
   890 		/* This count is used by the depot code to determine the number of engines
       
   891 		 * in the consist. Exclude articulated parts so that autoreplacing to
       
   892 		 * engines with more articulated parts than before works correctly.
       
   893 		 *
       
   894 		 * Also skip counting rear ends of multiheaded engines */
       
   895 		if (!IsArticulatedPart(v) && !(!IsTrainEngine(v) && IsMultiheaded(v))) count++;
       
   896 		if (v->u.rail.track != 0x80 || v->tile != tile ||
       
   897 				(IsFrontEngine(v) && needs_to_be_stopped && !(v->vehstatus & VS_STOPPED))) {
       
   898 			return -1;
       
   899 		}
       
   900 	}
       
   901 
       
   902 	return count;
       
   903 }
       
   904 
       
   905 /* Used to check if the train is inside the depot and verifying that the VS_STOPPED flag is set */
       
   906 inline int CheckTrainStoppedInDepot(const Vehicle *v)
       
   907 {
       
   908 	return CheckTrainInDepot(v, true);
       
   909 }
       
   910 
       
   911 /* Used to check if the train is inside the depot, but not checking the VS_STOPPED flag */
       
   912 inline bool CheckTrainIsInsideDepot(const Vehicle *v)
       
   913 {
       
   914 	return (CheckTrainInDepot(v, false) > 0);
       
   915 }
       
   916 
       
   917 /**
       
   918  * Unlink a rail wagon from the consist.
       
   919  * @param v Vehicle to remove.
       
   920  * @param first The first vehicle of the consist.
       
   921  * @return The first vehicle of the consist.
       
   922  */
       
   923 static Vehicle *UnlinkWagon(Vehicle *v, Vehicle *first)
       
   924 {
       
   925 	Vehicle *u;
       
   926 
       
   927 	// unlinking the first vehicle of the chain?
       
   928 	if (v == first) {
       
   929 		v = GetNextVehicle(v);
       
   930 		if (v == NULL) return NULL;
       
   931 
       
   932 		if (IsTrainWagon(v)) SetFreeWagon(v);
       
   933 
       
   934 		return v;
       
   935 	}
       
   936 
       
   937 	for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
       
   938 	GetLastEnginePart(u)->next = GetNextVehicle(v);
       
   939 	return first;
       
   940 }
       
   941 
       
   942 static Vehicle *FindGoodVehiclePos(const Vehicle *src)
       
   943 {
       
   944 	Vehicle *dst;
       
   945 	EngineID eng = src->engine_type;
       
   946 	TileIndex tile = src->tile;
       
   947 
       
   948 	FOR_ALL_VEHICLES(dst) {
       
   949 		if (dst->type == VEH_Train && IsFreeWagon(dst) && dst->tile == tile) {
       
   950 			// check so all vehicles in the line have the same engine.
       
   951 			Vehicle *v = dst;
       
   952 
       
   953 			while (v->engine_type == eng) {
       
   954 				v = v->next;
       
   955 				if (v == NULL) return dst;
       
   956 			}
       
   957 		}
       
   958 	}
       
   959 
       
   960 	return NULL;
       
   961 }
       
   962 
       
   963 /*
       
   964  * add a vehicle v behind vehicle dest
       
   965  * use this function since it sets flags as needed
       
   966  */
       
   967 static void AddWagonToConsist(Vehicle *v, Vehicle *dest)
       
   968 {
       
   969 	UnlinkWagon(v, GetFirstVehicleInChain(v));
       
   970 	if (dest == NULL) return;
       
   971 
       
   972 	v->next = dest->next;
       
   973 	dest->next = v;
       
   974 	ClearFreeWagon(v);
       
   975 	ClearFrontEngine(v);
       
   976 }
       
   977 
       
   978 /*
       
   979  * move around on the train so rear engines are placed correctly according to the other engines
       
   980  * always call with the front engine
       
   981  */
       
   982 static void NormaliseTrainConsist(Vehicle *v)
       
   983 {
       
   984 	Vehicle *u;
       
   985 
       
   986 	if (IsFreeWagon(v)) return;
       
   987 
       
   988 	assert(IsFrontEngine(v));
       
   989 
       
   990 	for (; v != NULL; v = GetNextVehicle(v)) {
       
   991 		if (!IsMultiheaded(v) || !IsTrainEngine(v)) continue;
       
   992 
       
   993 		/* make sure that there are no free cars before next engine */
       
   994 		for (u = v; u->next != NULL && !IsTrainEngine(u->next); u = u->next);
       
   995 
       
   996 		if (u == v->u.rail.other_multiheaded_part) continue;
       
   997 		AddWagonToConsist(v->u.rail.other_multiheaded_part, u);
       
   998 	}
       
   999 }
       
  1000 
       
  1001 /** Move a rail vehicle around inside the depot.
       
  1002  * @param tile unused
       
  1003  * @param p1 various bitstuffed elements
       
  1004  * - p1 (bit  0 - 15) source vehicle index
       
  1005  * - p1 (bit 16 - 31) what wagon to put the source wagon AFTER, XXX - INVALID_VEHICLE to make a new line
       
  1006  * @param p2 (bit 0) move all vehicles following the source vehicle
       
  1007  */
       
  1008 int32 CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  1009 {
       
  1010 	VehicleID s = GB(p1, 0, 16);
       
  1011 	VehicleID d = GB(p1, 16, 16);
       
  1012 	Vehicle *src, *dst, *src_head, *dst_head;
       
  1013 
       
  1014 	if (!IsValidVehicleID(s)) return CMD_ERROR;
       
  1015 
       
  1016 	src = GetVehicle(s);
       
  1017 
       
  1018 	if (src->type != VEH_Train) return CMD_ERROR;
       
  1019 
       
  1020 	// if nothing is selected as destination, try and find a matching vehicle to drag to.
       
  1021 	if (d == INVALID_VEHICLE) {
       
  1022 		dst = IsTrainEngine(src) ? NULL : FindGoodVehiclePos(src);
       
  1023 	} else {
       
  1024 		dst = GetVehicle(d);
       
  1025 	}
       
  1026 
       
  1027 	// if an articulated part is being handled, deal with its parent vehicle
       
  1028 	while (IsArticulatedPart(src)) src = GetPrevVehicleInChain(src);
       
  1029 	if (dst != NULL) {
       
  1030 		while (IsArticulatedPart(dst)) dst = GetPrevVehicleInChain(dst);
       
  1031 	}
       
  1032 
       
  1033 	// don't move the same vehicle..
       
  1034 	if (src == dst) return 0;
       
  1035 
       
  1036 	/* the player must be the owner */
       
  1037 	if (!CheckOwnership(src->owner) || (dst != NULL && !CheckOwnership(dst->owner)))
       
  1038 		return CMD_ERROR;
       
  1039 
       
  1040 	/* locate the head of the two chains */
       
  1041 	src_head = GetFirstVehicleInChain(src);
       
  1042 	dst_head = NULL;
       
  1043 	if (dst != NULL) {
       
  1044 		dst_head = GetFirstVehicleInChain(dst);
       
  1045 		// Now deal with articulated part of destination wagon
       
  1046 		dst = GetLastEnginePart(dst);
       
  1047 	}
       
  1048 
       
  1049 	if (dst != NULL && IsMultiheaded(dst) && !IsTrainEngine(dst) && IsTrainWagon(src)) {
       
  1050 		/* We are moving a wagon to the rear part of a multiheaded engine */
       
  1051 		if (dst->next == NULL) {
       
  1052 			/* It's the last one, so we will add the wagon just before the rear engine */
       
  1053 			dst = GetPrevVehicleInChain(dst);
       
  1054 			/* Now if the vehicle we want to link to is the vehicle itself, drop out */
       
  1055 			if (dst == src) return CMD_ERROR;
       
  1056 			// if dst is NULL, it means that dst got a rear multiheaded engine as first engine. We can't use that
       
  1057 			if (dst == NULL) return CMD_ERROR;
       
  1058 		} else {
       
  1059 			/* there are more units on this train, so we will add the wagon after the next one*/
       
  1060 			dst = dst->next;
       
  1061 		}
       
  1062 	}
       
  1063 
       
  1064 	if (IsTrainEngine(src) && dst_head != NULL) {
       
  1065 		/* we need to make sure that we didn't place it between a pair of multiheaded engines */
       
  1066 		Vehicle *u, *engine = NULL;
       
  1067 
       
  1068 		for (u = dst_head; u != NULL; u = u->next) {
       
  1069 			if (IsTrainEngine(u) && IsMultiheaded(u) && u->u.rail.other_multiheaded_part != NULL) {
       
  1070 				engine = u;
       
  1071 			}
       
  1072 			if (engine != NULL && engine->u.rail.other_multiheaded_part == u) {
       
  1073 				engine = NULL;
       
  1074 			}
       
  1075 			if (u == dst) {
       
  1076 				if (engine != NULL) dst = engine->u.rail.other_multiheaded_part;
       
  1077 				break;
       
  1078 			}
       
  1079 		}
       
  1080 	}
       
  1081 
       
  1082 	if (IsMultiheaded(src) && !IsTrainEngine(src)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR);
       
  1083 
       
  1084 	// when moving all wagons, we can't have the same src_head and dst_head
       
  1085 	if (HASBIT(p2, 0) && src_head == dst_head) return 0;
       
  1086 
       
  1087 	{
       
  1088 		int src_len = 0;
       
  1089 		int max_len = _patches.mammoth_trains ? 100 : 9;
       
  1090 
       
  1091 		// check if all vehicles in the source train are stopped inside a depot.
       
  1092 		src_len = CheckTrainStoppedInDepot(src_head);
       
  1093 		if (src_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
       
  1094 
       
  1095 		// check the destination row if the source and destination aren't the same.
       
  1096 		if (src_head != dst_head) {
       
  1097 			int dst_len = 0;
       
  1098 
       
  1099 			if (dst_head != NULL) {
       
  1100 				// check if all vehicles in the dest train are stopped.
       
  1101 				dst_len = CheckTrainStoppedInDepot(dst_head);
       
  1102 				if (dst_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
       
  1103 
       
  1104 				assert(dst_head->tile == src_head->tile);
       
  1105 			}
       
  1106 
       
  1107 			// We are moving between rows, so only count the wagons from the source
       
  1108 			// row that are being moved.
       
  1109 			if (HASBIT(p2, 0)) {
       
  1110 				const Vehicle *u;
       
  1111 				for (u = src_head; u != src && u != NULL; u = GetNextVehicle(u))
       
  1112 					src_len--;
       
  1113 			} else {
       
  1114 				// If moving only one vehicle, just count that.
       
  1115 				src_len = 1;
       
  1116 			}
       
  1117 
       
  1118 			if (src_len + dst_len > max_len) {
       
  1119 				// Abort if we're adding too many wagons to a train.
       
  1120 				if (dst_head != NULL && IsFrontEngine(dst_head)) return_cmd_error(STR_8819_TRAIN_TOO_LONG);
       
  1121 				// Abort if we're making a train on a new row.
       
  1122 				if (dst_head == NULL && IsTrainEngine(src)) return_cmd_error(STR_8819_TRAIN_TOO_LONG);
       
  1123 			}
       
  1124 		} else {
       
  1125 			// Abort if we're creating a new train on an existing row.
       
  1126 			if (src_len > max_len && src == src_head && IsTrainEngine(GetNextVehicle(src_head)))
       
  1127 				return_cmd_error(STR_8819_TRAIN_TOO_LONG);
       
  1128 		}
       
  1129 	}
       
  1130 
       
  1131 	// moving a loco to a new line?, then we need to assign a unitnumber.
       
  1132 	if (dst == NULL && !IsFrontEngine(src) && IsTrainEngine(src)) {
       
  1133 		UnitID unit_num = GetFreeUnitNumber(VEH_Train);
       
  1134 		if (unit_num > _patches.max_trains)
       
  1135 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
       
  1136 
       
  1137 		if (flags & DC_EXEC) src->unitnumber = unit_num;
       
  1138 	}
       
  1139 
       
  1140 	if (dst_head != NULL) {
       
  1141 		/* Check NewGRF Callback 0x1D */
       
  1142 		uint16 callback = GetVehicleCallbackParent(CBID_TRAIN_ALLOW_WAGON_ATTACH, 0, 0, dst_head->engine_type, src, dst_head);
       
  1143 		if (callback != CALLBACK_FAILED) {
       
  1144 			if (callback == 0xFD) return_cmd_error(STR_INCOMPATIBLE_RAIL_TYPES);
       
  1145 			if (callback < 0xFD) {
       
  1146 				StringID error = GetGRFStringID(GetEngineGRFID(dst_head->engine_type), 0xD000 + callback);
       
  1147 				return_cmd_error(error);
       
  1148 			}
       
  1149 		}
       
  1150 	}
       
  1151 
       
  1152 	/* do it? */
       
  1153 	if (flags & DC_EXEC) {
       
  1154 		/* clear the ->first cache */
       
  1155 		{
       
  1156 			Vehicle *u;
       
  1157 
       
  1158 			for (u = src_head; u != NULL; u = u->next) u->first = NULL;
       
  1159 			for (u = dst_head; u != NULL; u = u->next) u->first = NULL;
       
  1160 		}
       
  1161 
       
  1162 		if (HASBIT(p2, 0)) {
       
  1163 			// unlink ALL wagons
       
  1164 			if (src != src_head) {
       
  1165 				Vehicle *v = src_head;
       
  1166 				while (GetNextVehicle(v) != src) v = GetNextVehicle(v);
       
  1167 				GetLastEnginePart(v)->next = NULL;
       
  1168 			} else {
       
  1169 				InvalidateWindowData(WC_VEHICLE_DEPOT, src_head->tile); // We removed a line
       
  1170 				src_head = NULL;
       
  1171 			}
       
  1172 		} else {
       
  1173 			// if moving within the same chain, dont use dst_head as it may get invalidated
       
  1174 			if (src_head == dst_head) dst_head = NULL;
       
  1175 			// unlink single wagon from linked list
       
  1176 			src_head = UnlinkWagon(src, src_head);
       
  1177 			GetLastEnginePart(src)->next = NULL;
       
  1178 		}
       
  1179 
       
  1180 		if (dst == NULL) {
       
  1181 			/* We make a new line in the depot, so we know already that we invalidate the window data */
       
  1182 			InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile);
       
  1183 
       
  1184 			// move the train to an empty line. for locomotives, we set the type to TS_Front. for wagons, 4.
       
  1185 			if (IsTrainEngine(src)) {
       
  1186 				if (!IsFrontEngine(src)) {
       
  1187 					// setting the type to 0 also involves setting up the orders field.
       
  1188 					SetFrontEngine(src);
       
  1189 					assert(src->orders == NULL);
       
  1190 					src->num_orders = 0;
       
  1191 				}
       
  1192 			} else {
       
  1193 				SetFreeWagon(src);
       
  1194 			}
       
  1195 			dst_head = src;
       
  1196 		} else {
       
  1197 			if (IsFrontEngine(src)) {
       
  1198 				// the vehicle was previously a loco. need to free the order list and delete vehicle windows etc.
       
  1199 				DeleteWindowById(WC_VEHICLE_VIEW, src->index);
       
  1200 				DeleteVehicleOrders(src);
       
  1201 			}
       
  1202 
       
  1203 			if (IsFrontEngine(src) || IsFreeWagon(src)) {
       
  1204 				InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile);
       
  1205 				ClearFrontEngine(src);
       
  1206 				ClearFreeWagon(src);
       
  1207 				src->unitnumber = 0; // doesn't occupy a unitnumber anymore.
       
  1208 			}
       
  1209 
       
  1210 			// link in the wagon(s) in the chain.
       
  1211 			{
       
  1212 				Vehicle *v;
       
  1213 
       
  1214 				for (v = src; GetNextVehicle(v) != NULL; v = GetNextVehicle(v));
       
  1215 				GetLastEnginePart(v)->next = dst->next;
       
  1216 			}
       
  1217 			dst->next = src;
       
  1218 		}
       
  1219 		if (src->u.rail.other_multiheaded_part != NULL) {
       
  1220 			if (src->u.rail.other_multiheaded_part == src_head) {
       
  1221 				src_head = src_head->next;
       
  1222 			}
       
  1223 			AddWagonToConsist(src->u.rail.other_multiheaded_part, src);
       
  1224 			// previous line set the front engine to the old front. We need to clear that
       
  1225 			src->u.rail.other_multiheaded_part->first = NULL;
       
  1226 		}
       
  1227 
       
  1228 		if (HASBIT(p2, 0) && src_head != NULL && src_head != src) {
       
  1229 			/* if we stole a rear multiheaded engine, we better give it back to the front end */
       
  1230 			Vehicle *engine = NULL, *u;
       
  1231 			for (u = src_head; u != NULL; u = u->next) {
       
  1232 				if (IsMultiheaded(u)) {
       
  1233 					if (IsTrainEngine(u)) {
       
  1234 						engine = u;
       
  1235 						continue;
       
  1236 					}
       
  1237 					/* we got the rear engine to match with the front one */
       
  1238 					engine = NULL;
       
  1239 				}
       
  1240 			}
       
  1241 			if (engine != NULL && engine->u.rail.other_multiheaded_part != NULL) {
       
  1242 				AddWagonToConsist(engine->u.rail.other_multiheaded_part, engine);
       
  1243 				// previous line set the front engine to the old front. We need to clear that
       
  1244 				engine->u.rail.other_multiheaded_part->first = NULL;
       
  1245 			}
       
  1246 		}
       
  1247 
       
  1248 		/* If there is an engine behind first_engine we moved away, it should become new first_engine
       
  1249 		 * To do this, CmdMoveRailVehicle must be called once more
       
  1250 		 * we can't loop forever here because next time we reach this line we will have a front engine */
       
  1251 		if (src_head != NULL && !IsFrontEngine(src_head) && IsTrainEngine(src_head)) {
       
  1252 			CmdMoveRailVehicle(0, flags, src_head->index | (INVALID_VEHICLE << 16), 1);
       
  1253 			src_head = NULL; // don't do anything more to this train since the new call will do it
       
  1254 		}
       
  1255 
       
  1256 		if (src_head != NULL) {
       
  1257 			NormaliseTrainConsist(src_head);
       
  1258 			TrainConsistChanged(src_head);
       
  1259 			if (IsFrontEngine(src_head)) {
       
  1260 				UpdateTrainAcceleration(src_head);
       
  1261 				InvalidateWindow(WC_VEHICLE_DETAILS, src_head->index);
       
  1262 				/* Update the refit button and window */
       
  1263 				InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
       
  1264 				InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, 12);
       
  1265 			}
       
  1266 			/* Update the depot window */
       
  1267 			InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
       
  1268 		};
       
  1269 
       
  1270 		if (dst_head != NULL) {
       
  1271 			NormaliseTrainConsist(dst_head);
       
  1272 			TrainConsistChanged(dst_head);
       
  1273 			if (IsFrontEngine(dst_head)) {
       
  1274 				UpdateTrainAcceleration(dst_head);
       
  1275 				InvalidateWindow(WC_VEHICLE_DETAILS, dst_head->index);
       
  1276 				/* Update the refit button and window */
       
  1277 				InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, 12);
       
  1278 				InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
       
  1279 			}
       
  1280 			/* Update the depot window */
       
  1281 			InvalidateWindow(WC_VEHICLE_DEPOT, dst_head->tile);
       
  1282 		}
       
  1283 
       
  1284 		RebuildVehicleLists();
       
  1285 	}
       
  1286 
       
  1287 	return 0;
       
  1288 }
       
  1289 
       
  1290 /** Start/Stop a train.
       
  1291  * @param tile unused
       
  1292  * @param p1 train to start/stop
       
  1293  * @param p2 unused
       
  1294  */
       
  1295 int32 CmdStartStopTrain(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  1296 {
       
  1297 	Vehicle *v;
       
  1298 	uint16 callback;
       
  1299 
       
  1300 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
       
  1301 
       
  1302 	v = GetVehicle(p1);
       
  1303 
       
  1304 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
       
  1305 
       
  1306 	/* Check if this train can be started/stopped. The callback will fail or
       
  1307 	 * return 0xFF if it can. */
       
  1308 	callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
       
  1309 	if (callback != CALLBACK_FAILED && callback != 0xFF) {
       
  1310 		StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
       
  1311 		return_cmd_error(error);
       
  1312 	}
       
  1313 
       
  1314 	if (v->vehstatus & VS_STOPPED && v->u.rail.cached_power == 0) return_cmd_error(STR_TRAIN_START_NO_CATENARY);
       
  1315 
       
  1316 	if (flags & DC_EXEC) {
       
  1317 		if (v->vehstatus & VS_STOPPED && v->u.rail.track == 0x80) {
       
  1318 			DeleteVehicleNews(p1, STR_8814_TRAIN_IS_WAITING_IN_DEPOT);
       
  1319 		}
       
  1320 
       
  1321 		v->u.rail.days_since_order_progr = 0;
       
  1322 		v->vehstatus ^= VS_STOPPED;
       
  1323 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
       
  1324 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
       
  1325 	}
       
  1326 	return 0;
       
  1327 }
       
  1328 
       
  1329 /** Sell a (single) train wagon/engine.
       
  1330  * @param tile unused
       
  1331  * @param p1 the wagon/engine index
       
  1332  * @param p2 the selling mode
       
  1333  * - p2 = 0: only sell the single dragged wagon/engine (and any belonging rear-engines)
       
  1334  * - p2 = 1: sell the vehicle and all vehicles following it in the chain
       
  1335              if the wagon is dragged, don't delete the possibly belonging rear-engine to some front
       
  1336  * - p2 = 2: when selling attached locos, rearrange all vehicles after it to separate lines;
       
  1337  *           all wagons of the same type will go on the same line. Used by the AI currently
       
  1338  */
       
  1339 int32 CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  1340 {
       
  1341 	Vehicle *v, *tmp, *first;
       
  1342 	Vehicle *new_f = NULL;
       
  1343 	int32 cost = 0;
       
  1344 
       
  1345 	if (!IsValidVehicleID(p1) || p2 > 2) return CMD_ERROR;
       
  1346 
       
  1347 	v = GetVehicle(p1);
       
  1348 
       
  1349 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
       
  1350 
       
  1351 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
  1352 
       
  1353 	while (IsArticulatedPart(v)) v = GetPrevVehicleInChain(v);
       
  1354 	first = GetFirstVehicleInChain(v);
       
  1355 
       
  1356 	// make sure the vehicle is stopped in the depot
       
  1357 	if (CheckTrainStoppedInDepot(first) < 0) {
       
  1358 		return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
       
  1359 	}
       
  1360 
       
  1361 	if (IsMultiheaded(v) && !IsTrainEngine(v)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR);
       
  1362 
       
  1363 	if (flags & DC_EXEC) {
       
  1364 		if (v == first && IsFrontEngine(first)) {
       
  1365 			DeleteWindowById(WC_VEHICLE_VIEW, first->index);
       
  1366 		}
       
  1367 		if (IsLocalPlayer() && (p1 == 1 || !(RailVehInfo(v->engine_type)->flags & RVI_WAGON))) {
       
  1368 			InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train);
       
  1369 		}
       
  1370 		InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
       
  1371 		RebuildVehicleLists();
       
  1372 	}
       
  1373 
       
  1374 	switch (p2) {
       
  1375 		case 0: case 2: { /* Delete given wagon */
       
  1376 			bool switch_engine = false;    // update second wagon to engine?
       
  1377 			byte ori_subtype = v->subtype; // backup subtype of deleted wagon in case DeleteVehicle() changes
       
  1378 
       
  1379 			/* 1. Delete the engine, if it is dualheaded also delete the matching
       
  1380 			 * rear engine of the loco (from the point of deletion onwards) */
       
  1381 			Vehicle *rear = (IsMultiheaded(v) &&
       
  1382 				IsTrainEngine(v)) ? v->u.rail.other_multiheaded_part : NULL;
       
  1383 
       
  1384 			if (rear != NULL) {
       
  1385 				cost -= rear->value;
       
  1386 				if (flags & DC_EXEC) {
       
  1387 					UnlinkWagon(rear, first);
       
  1388 					DeleteDepotHighlightOfVehicle(rear);
       
  1389 					DeleteVehicle(rear);
       
  1390 				}
       
  1391 			}
       
  1392 
       
  1393 			/* 2. We are selling the first engine, some special action might be required
       
  1394 			 * here, so take attention */
       
  1395 			if ((flags & DC_EXEC) && v == first) {
       
  1396 				new_f = GetNextVehicle(first);
       
  1397 
       
  1398 				/* 2.1 If the first wagon is sold, update the first-> pointers to NULL */
       
  1399 				for (tmp = first; tmp != NULL; tmp = tmp->next) tmp->first = NULL;
       
  1400 
       
  1401 				/* 2.2 If there are wagons present after the deleted front engine, check
       
  1402          * if the second wagon (which will be first) is an engine. If it is one,
       
  1403          * promote it as a new train, retaining the unitnumber, orders */
       
  1404 				if (new_f != NULL) {
       
  1405 					if (IsTrainEngine(new_f)) {
       
  1406 						switch_engine = true;
       
  1407 						/* Copy important data from the front engine */
       
  1408 						new_f->unitnumber = first->unitnumber;
       
  1409 						new_f->current_order = first->current_order;
       
  1410 						new_f->cur_order_index = first->cur_order_index;
       
  1411 						new_f->orders = first->orders;
       
  1412 						if (first->prev_shared != NULL) {
       
  1413 							first->prev_shared->next_shared = new_f;
       
  1414 							new_f->prev_shared = first->prev_shared;
       
  1415 						}
       
  1416 
       
  1417 						if (first->next_shared != NULL) {
       
  1418 							first->next_shared->prev_shared = new_f;
       
  1419 							new_f->next_shared = first->next_shared;
       
  1420 						}
       
  1421 
       
  1422 						new_f->num_orders = first->num_orders;
       
  1423 						first->orders = NULL; // XXX - to not to delete the orders */
       
  1424 						if (IsLocalPlayer()) ShowTrainViewWindow(new_f);
       
  1425 					}
       
  1426 				}
       
  1427 			}
       
  1428 
       
  1429 			/* 3. Delete the requested wagon */
       
  1430 			cost -= v->value;
       
  1431 			if (flags & DC_EXEC) {
       
  1432 				first = UnlinkWagon(v, first);
       
  1433 				DeleteDepotHighlightOfVehicle(v);
       
  1434 				DeleteVehicle(v);
       
  1435 
       
  1436 				/* 4 If the second wagon was an engine, update it to front_engine
       
  1437 					* which UnlinkWagon() has changed to TS_Free_Car */
       
  1438 				if (switch_engine) SetFrontEngine(first);
       
  1439 
       
  1440 				/* 5. If the train still exists, update its acceleration, window, etc. */
       
  1441 				if (first != NULL) {
       
  1442 					NormaliseTrainConsist(first);
       
  1443 					TrainConsistChanged(first);
       
  1444 					if (IsFrontEngine(first)) {
       
  1445 						InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
       
  1446 						InvalidateWindow(WC_VEHICLE_REFIT, first->index);
       
  1447 						UpdateTrainAcceleration(first);
       
  1448 					}
       
  1449 				}
       
  1450 
       
  1451 
       
  1452 				/* (6.) Borked AI. If it sells an engine it expects all wagons lined
       
  1453 				 * up on a new line to be added to the newly built loco. Replace it is.
       
  1454 				 * Totally braindead cause building a new engine adds all loco-less
       
  1455 				 * engines to its train anyways */
       
  1456 				if (p2 == 2 && HASBIT(ori_subtype, Train_Front)) {
       
  1457 					for (v = first; v != NULL; v = tmp) {
       
  1458 						tmp = GetNextVehicle(v);
       
  1459 						DoCommand(v->tile, v->index | INVALID_VEHICLE << 16, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
       
  1460 					}
       
  1461 				}
       
  1462 			}
       
  1463 		} break;
       
  1464 		case 1: { /* Delete wagon and all wagons after it given certain criteria */
       
  1465 			/* Start deleting every vehicle after the selected one
       
  1466 			 * If we encounter a matching rear-engine to a front-engine
       
  1467 			 * earlier in the chain (before deletion), leave it alone */
       
  1468 			for (; v != NULL; v = tmp) {
       
  1469 				tmp = GetNextVehicle(v);
       
  1470 
       
  1471 				if (IsMultiheaded(v)) {
       
  1472 					if (IsTrainEngine(v)) {
       
  1473 						/* We got a front engine of a multiheaded set. Now we will sell the rear end too */
       
  1474 						Vehicle *rear = v->u.rail.other_multiheaded_part;
       
  1475 
       
  1476 						if (rear != NULL) {
       
  1477 							cost -= rear->value;
       
  1478 							if (flags & DC_EXEC) {
       
  1479 								first = UnlinkWagon(rear, first);
       
  1480 								DeleteDepotHighlightOfVehicle(rear);
       
  1481 								DeleteVehicle(rear);
       
  1482 							}
       
  1483 						}
       
  1484 					} else if (v->u.rail.other_multiheaded_part != NULL) {
       
  1485 						/* The front to this engine is earlier in this train. Do nothing */
       
  1486 						continue;
       
  1487 					}
       
  1488 				}
       
  1489 
       
  1490 				cost -= v->value;
       
  1491 				if (flags & DC_EXEC) {
       
  1492 					first = UnlinkWagon(v, first);
       
  1493 					DeleteDepotHighlightOfVehicle(v);
       
  1494 					DeleteVehicle(v);
       
  1495 				}
       
  1496 			}
       
  1497 
       
  1498 			/* 3. If it is still a valid train after selling, update its acceleration and cached values */
       
  1499 			if (flags & DC_EXEC && first != NULL) {
       
  1500 				NormaliseTrainConsist(first);
       
  1501 				TrainConsistChanged(first);
       
  1502 				if (IsFrontEngine(first)) UpdateTrainAcceleration(first);
       
  1503 				InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
       
  1504 				InvalidateWindow(WC_VEHICLE_REFIT, first->index);
       
  1505 			}
       
  1506 		} break;
       
  1507 	}
       
  1508 	return cost;
       
  1509 }
       
  1510 
       
  1511 static void UpdateTrainDeltaXY(Vehicle *v, Direction direction)
       
  1512 {
       
  1513 #define MKIT(a,b,c,d) ((a&0xFF)<<24) | ((b&0xFF)<<16) | ((c&0xFF)<<8) | ((d&0xFF)<<0)
       
  1514 	static const uint32 _delta_xy_table[8] = {
       
  1515 		MKIT(3, 3, -1, -1),
       
  1516 		MKIT(3, 7, -1, -3),
       
  1517 		MKIT(3, 3, -1, -1),
       
  1518 		MKIT(7, 3, -3, -1),
       
  1519 		MKIT(3, 3, -1, -1),
       
  1520 		MKIT(3, 7, -1, -3),
       
  1521 		MKIT(3, 3, -1, -1),
       
  1522 		MKIT(7, 3, -3, -1),
       
  1523 	};
       
  1524 #undef MKIT
       
  1525 
       
  1526 	uint32 x = _delta_xy_table[direction];
       
  1527 
       
  1528 	v->x_offs        = GB(x,  0, 8);
       
  1529 	v->y_offs        = GB(x,  8, 8);
       
  1530 	v->sprite_width  = GB(x, 16, 8);
       
  1531 	v->sprite_height = GB(x, 24, 8);
       
  1532 }
       
  1533 
       
  1534 static void UpdateVarsAfterSwap(Vehicle *v)
       
  1535 {
       
  1536 	UpdateTrainDeltaXY(v, v->direction);
       
  1537 	v->cur_image = GetTrainImage(v, v->direction);
       
  1538 	BeginVehicleMove(v);
       
  1539 	VehiclePositionChanged(v);
       
  1540 	EndVehicleMove(v);
       
  1541 }
       
  1542 
       
  1543 static void SetLastSpeed(Vehicle* v, int spd)
       
  1544 {
       
  1545 	int old = v->u.rail.last_speed;
       
  1546 	if (spd != old) {
       
  1547 		v->u.rail.last_speed = spd;
       
  1548 		if (_patches.vehicle_speed || (old == 0) != (spd == 0))
       
  1549 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
       
  1550 	}
       
  1551 }
       
  1552 
       
  1553 static void SwapTrainFlags(byte *swap_flag1, byte *swap_flag2)
       
  1554 {
       
  1555 	byte flag1, flag2;
       
  1556 
       
  1557 	flag1 = *swap_flag1;
       
  1558 	flag2 = *swap_flag2;
       
  1559 
       
  1560 	/* Clear the flags */
       
  1561 	CLRBIT(*swap_flag1, VRF_GOINGUP);
       
  1562 	CLRBIT(*swap_flag1, VRF_GOINGDOWN);
       
  1563 	CLRBIT(*swap_flag2, VRF_GOINGUP);
       
  1564 	CLRBIT(*swap_flag2, VRF_GOINGDOWN);
       
  1565 
       
  1566 	/* Reverse the rail-flags (if needed) */
       
  1567 	if (HASBIT(flag1, VRF_GOINGUP)) {
       
  1568 		SETBIT(*swap_flag2, VRF_GOINGDOWN);
       
  1569 	} else if (HASBIT(flag1, VRF_GOINGDOWN)) {
       
  1570 		SETBIT(*swap_flag2, VRF_GOINGUP);
       
  1571 	}
       
  1572 	if (HASBIT(flag2, VRF_GOINGUP)) {
       
  1573 		SETBIT(*swap_flag1, VRF_GOINGDOWN);
       
  1574 	} else if (HASBIT(flag2, VRF_GOINGDOWN)) {
       
  1575 		SETBIT(*swap_flag1, VRF_GOINGUP);
       
  1576 	}
       
  1577 }
       
  1578 
       
  1579 static void ReverseTrainSwapVeh(Vehicle *v, int l, int r)
       
  1580 {
       
  1581 	Vehicle *a, *b;
       
  1582 
       
  1583 	/* locate vehicles to swap */
       
  1584 	for (a = v; l != 0; l--) a = a->next;
       
  1585 	for (b = v; r != 0; r--) b = b->next;
       
  1586 
       
  1587 	if (a != b) {
       
  1588 		/* swap the hidden bits */
       
  1589 		{
       
  1590 			uint16 tmp = (a->vehstatus & ~VS_HIDDEN) | (b->vehstatus&VS_HIDDEN);
       
  1591 			b->vehstatus = (b->vehstatus & ~VS_HIDDEN) | (a->vehstatus&VS_HIDDEN);
       
  1592 			a->vehstatus = tmp;
       
  1593 		}
       
  1594 
       
  1595 		/* swap variables */
       
  1596 		swap_byte(&a->u.rail.track, &b->u.rail.track);
       
  1597 		swap_byte(&a->direction, &b->direction);
       
  1598 
       
  1599 		/* toggle direction */
       
  1600 		if (!(a->u.rail.track & 0x80)) a->direction = ReverseDir(a->direction);
       
  1601 		if (!(b->u.rail.track & 0x80)) b->direction = ReverseDir(b->direction);
       
  1602 
       
  1603 		/* swap more variables */
       
  1604 		swap_int32(&a->x_pos, &b->x_pos);
       
  1605 		swap_int32(&a->y_pos, &b->y_pos);
       
  1606 		swap_tile(&a->tile, &b->tile);
       
  1607 		swap_byte(&a->z_pos, &b->z_pos);
       
  1608 
       
  1609 		SwapTrainFlags(&a->u.rail.flags, &b->u.rail.flags);
       
  1610 
       
  1611 		/* update other vars */
       
  1612 		UpdateVarsAfterSwap(a);
       
  1613 		UpdateVarsAfterSwap(b);
       
  1614 
       
  1615 		/* call the proper EnterTile function unless we are in a wormhole */
       
  1616 		if (!(a->u.rail.track & 0x40)) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
       
  1617 		if (!(b->u.rail.track & 0x40)) VehicleEnterTile(b, b->tile, b->x_pos, b->y_pos);
       
  1618 	} else {
       
  1619 		if (!(a->u.rail.track & 0x80)) a->direction = ReverseDir(a->direction);
       
  1620 		UpdateVarsAfterSwap(a);
       
  1621 
       
  1622 		if (!(a->u.rail.track & 0x40)) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
       
  1623 	}
       
  1624 
       
  1625 	/* Update train's power incase tiles were different rail type */
       
  1626 	TrainPowerChanged(v);
       
  1627 }
       
  1628 
       
  1629 /* Check if the vehicle is a train and is on the tile we are testing */
       
  1630 static void *TestTrainOnCrossing(Vehicle *v, void *data)
       
  1631 {
       
  1632 	if (v->tile != *(const TileIndex*)data || v->type != VEH_Train) return NULL;
       
  1633 	return v;
       
  1634 }
       
  1635 
       
  1636 static void DisableTrainCrossing(TileIndex tile)
       
  1637 {
       
  1638 	if (IsLevelCrossingTile(tile) &&
       
  1639 			VehicleFromPos(tile, &tile, TestTrainOnCrossing) == NULL && // empty?
       
  1640 			IsCrossingBarred(tile)) {
       
  1641 		UnbarCrossing(tile);
       
  1642 		MarkTileDirtyByTile(tile);
       
  1643 	}
       
  1644 }
       
  1645 
       
  1646 /**
       
  1647  * Advances wagons for train reversing, needed for variable length wagons.
       
  1648  * Needs to be called once before the train is reversed, and once after it.
       
  1649  * @param v First vehicle in chain
       
  1650  * @param before Set to true for the call before reversing, false otherwise
       
  1651  */
       
  1652 static void AdvanceWagons(Vehicle *v, bool before)
       
  1653 {
       
  1654 	Vehicle* base;
       
  1655 	Vehicle* first;
       
  1656 	int length;
       
  1657 
       
  1658 	base = v;
       
  1659 	first = base->next;
       
  1660 	length = CountVehiclesInChain(v);
       
  1661 
       
  1662 	while (length > 2) {
       
  1663 		Vehicle* last;
       
  1664 		int differential;
       
  1665 		int i;
       
  1666 
       
  1667 		// find pairwise matching wagon
       
  1668 		// start<>end, start+1<>end-1, ...
       
  1669 		last = first;
       
  1670 		for (i = length - 3; i > 0; i--) last = last->next;
       
  1671 
       
  1672 		differential = last->u.rail.cached_veh_length - base->u.rail.cached_veh_length;
       
  1673 		if (before) differential *= -1;
       
  1674 
       
  1675 		if (differential > 0) {
       
  1676 			Vehicle* tempnext;
       
  1677 
       
  1678 			// disconnect last car to make sure only this subset moves
       
  1679 			tempnext = last->next;
       
  1680 			last->next = NULL;
       
  1681 
       
  1682 			for (i = 0; i < differential; i++) TrainController(first, false);
       
  1683 
       
  1684 			last->next = tempnext;
       
  1685 		}
       
  1686 
       
  1687 		base = first;
       
  1688 		first = first->next;
       
  1689 		length -= 2;
       
  1690 	}
       
  1691 }
       
  1692 
       
  1693 
       
  1694 static void ReverseTrainDirection(Vehicle *v)
       
  1695 {
       
  1696 	int l = 0, r = -1;
       
  1697 	Vehicle *u;
       
  1698 
       
  1699 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL)) {
       
  1700 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
       
  1701 	}
       
  1702 
       
  1703 	/* Check if we were approaching a rail/road-crossing */
       
  1704 	{
       
  1705 		TileIndex tile = v->tile;
       
  1706 		DiagDirection dir = DirToDiagDir(v->direction);
       
  1707 
       
  1708 		/* Determine the diagonal direction in which we will exit this tile */
       
  1709 		if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[dir]) {
       
  1710 			dir = ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT);
       
  1711 		}
       
  1712 		/* Calculate next tile */
       
  1713 		tile += TileOffsByDiagDir(dir);
       
  1714 
       
  1715 		/* Check if the train left a rail/road-crossing */
       
  1716 		DisableTrainCrossing(tile);
       
  1717 	}
       
  1718 
       
  1719 	// count number of vehicles
       
  1720 	u = v;
       
  1721 	do r++; while ( (u = u->next) != NULL );
       
  1722 
       
  1723 	AdvanceWagons(v, true);
       
  1724 
       
  1725 	/* swap start<>end, start+1<>end-1, ... */
       
  1726 	do {
       
  1727 		ReverseTrainSwapVeh(v, l++, r--);
       
  1728 	} while (l <= r);
       
  1729 
       
  1730 	AdvanceWagons(v, false);
       
  1731 
       
  1732 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL)) {
       
  1733 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
       
  1734 	}
       
  1735 
       
  1736 	CLRBIT(v->u.rail.flags, VRF_REVERSING);
       
  1737 }
       
  1738 
       
  1739 /** Reverse train.
       
  1740  * @param tile unused
       
  1741  * @param p1 train to reverse
       
  1742  * @param p2 if true, reverse a unit in a train (needs to be in a depot)
       
  1743  */
       
  1744 int32 CmdReverseTrainDirection(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  1745 {
       
  1746 	Vehicle *v;
       
  1747 
       
  1748 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
       
  1749 
       
  1750 	v = GetVehicle(p1);
       
  1751 
       
  1752 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
       
  1753 
       
  1754 	if (p2) {
       
  1755 		// turn a single unit around
       
  1756 		Vehicle *front;
       
  1757 
       
  1758 		if (IsMultiheaded(v) || HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) {
       
  1759 			return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
       
  1760 		}
       
  1761 
       
  1762 		front = GetFirstVehicleInChain(v);
       
  1763 		// make sure the vehicle is stopped in the depot
       
  1764 		if (CheckTrainStoppedInDepot(front) < 0) {
       
  1765 			return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
       
  1766 		}
       
  1767 
       
  1768 		if (flags & DC_EXEC) {
       
  1769 			TOGGLEBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION);
       
  1770 			InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
       
  1771 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
       
  1772 		}
       
  1773 	} else {
       
  1774 		//turn the whole train around
       
  1775 		if (v->u.rail.crash_anim_pos != 0 || v->breakdown_ctr != 0) return CMD_ERROR;
       
  1776 
       
  1777 		if (flags & DC_EXEC) {
       
  1778 			if (_patches.realistic_acceleration && v->cur_speed != 0) {
       
  1779 				TOGGLEBIT(v->u.rail.flags, VRF_REVERSING);
       
  1780 			} else {
       
  1781 				v->cur_speed = 0;
       
  1782 				SetLastSpeed(v, 0);
       
  1783 				ReverseTrainDirection(v);
       
  1784 			}
       
  1785 		}
       
  1786 	}
       
  1787 	return 0;
       
  1788 }
       
  1789 
       
  1790 /** Force a train through a red signal
       
  1791  * @param tile unused
       
  1792  * @param p1 train to ignore the red signal
       
  1793  * @param p2 unused
       
  1794  */
       
  1795 int32 CmdForceTrainProceed(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  1796 {
       
  1797 	Vehicle *v;
       
  1798 
       
  1799 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
       
  1800 
       
  1801 	v = GetVehicle(p1);
       
  1802 
       
  1803 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
       
  1804 
       
  1805 	if (flags & DC_EXEC) v->u.rail.force_proceed = 0x50;
       
  1806 
       
  1807 	return 0;
       
  1808 }
       
  1809 
       
  1810 /** Refits a train to the specified cargo type.
       
  1811  * @param tile unused
       
  1812  * @param p1 vehicle ID of the train to refit
       
  1813  * param p2 various bitstuffed elements
       
  1814  * - p2 = (bit 0-7) - the new cargo type to refit to
       
  1815  * - p2 = (bit 8-15) - the new cargo subtype to refit to
       
  1816  */
       
  1817 int32 CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  1818 {
       
  1819 	CargoID new_cid = GB(p2, 0, 8);
       
  1820 	byte new_subtype = GB(p2, 8, 8);
       
  1821 	Vehicle *v;
       
  1822 	int32 cost;
       
  1823 	uint num;
       
  1824 
       
  1825 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
       
  1826 
       
  1827 	v = GetVehicle(p1);
       
  1828 
       
  1829 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
       
  1830 	if (CheckTrainStoppedInDepot(v) < 0) return_cmd_error(STR_TRAIN_MUST_BE_STOPPED);
       
  1831 
       
  1832 	/* Check cargo */
       
  1833 	if (new_cid > NUM_CARGO) return CMD_ERROR;
       
  1834 
       
  1835 	SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
       
  1836 
       
  1837 	cost = 0;
       
  1838 	num = 0;
       
  1839 
       
  1840 	do {
       
  1841 		/* XXX: We also refit all the attached wagons en-masse if they
       
  1842 		 * can be refitted. This is how TTDPatch does it.  TODO: Have
       
  1843 		 * some nice [Refit] button near each wagon. --pasky */
       
  1844 		if (!CanRefitTo(v->engine_type, new_cid)) continue;
       
  1845 
       
  1846 		if (v->cargo_cap != 0) {
       
  1847 			const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
       
  1848 			uint16 amount = CALLBACK_FAILED;
       
  1849 
       
  1850 			if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
       
  1851 				/* Back up the vehicle's cargo type */
       
  1852 				CargoID temp_cid = v->cargo_type;
       
  1853 				byte temp_subtype = v->cargo_subtype;
       
  1854 				v->cargo_type = new_cid;
       
  1855 				v->cargo_subtype = new_subtype;
       
  1856 				/* Check the refit capacity callback */
       
  1857 				amount = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, v->engine_type, v);
       
  1858 				/* Restore the original cargo type */
       
  1859 				v->cargo_type = temp_cid;
       
  1860 				v->cargo_subtype = temp_subtype;
       
  1861 			}
       
  1862 
       
  1863 			if (amount == CALLBACK_FAILED) { // callback failed or not used, use default
       
  1864 				CargoID old_cid = rvi->cargo_type;
       
  1865 				/* normally, the capacity depends on the cargo type, a rail vehicle can
       
  1866 				 * carry twice as much mail/goods as normal cargo, and four times as
       
  1867 				 * many passengers
       
  1868 				 */
       
  1869 				amount = rvi->capacity;
       
  1870 				switch (old_cid) {
       
  1871 					case CT_PASSENGERS: break;
       
  1872 					case CT_MAIL:
       
  1873 					case CT_GOODS: amount *= 2; break;
       
  1874 					default:       amount *= 4; break;
       
  1875 				}
       
  1876 				switch (new_cid) {
       
  1877 					case CT_PASSENGERS: break;
       
  1878 					case CT_MAIL:
       
  1879 					case CT_GOODS: amount /= 2; break;
       
  1880 					default:       amount /= 4; break;
       
  1881 				}
       
  1882 			};
       
  1883 
       
  1884 			if (amount != 0) {
       
  1885 				if (new_cid != v->cargo_type) {
       
  1886 					cost += GetRefitCost(v->engine_type);
       
  1887 				}
       
  1888 
       
  1889 				num += amount;
       
  1890 				if (flags & DC_EXEC) {
       
  1891 					v->cargo_count = (v->cargo_type == new_cid) ? min(amount, v->cargo_count) : 0;
       
  1892 					v->cargo_type = new_cid;
       
  1893 					v->cargo_cap = amount;
       
  1894 					v->cargo_subtype = new_subtype;
       
  1895 					InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
       
  1896 					InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
       
  1897 					RebuildVehicleLists();
       
  1898 				}
       
  1899 			}
       
  1900 		}
       
  1901 	} while ((v = v->next) != NULL);
       
  1902 
       
  1903 	_returned_refit_capacity = num;
       
  1904 
       
  1905 	/* Update the train's cached variables */
       
  1906 	if (flags & DC_EXEC) TrainConsistChanged(GetFirstVehicleInChain(GetVehicle(p1)));
       
  1907 
       
  1908 	return cost;
       
  1909 }
       
  1910 
       
  1911 typedef struct TrainFindDepotData {
       
  1912 	uint best_length;
       
  1913 	TileIndex tile;
       
  1914 	PlayerID owner;
       
  1915 	/**
       
  1916 	 * true if reversing is necessary for the train to get to this depot
       
  1917 	 * This value is unused when new depot finding and NPF are both disabled
       
  1918 	 */
       
  1919 	bool reverse;
       
  1920 } TrainFindDepotData;
       
  1921 
       
  1922 static bool NtpCallbFindDepot(TileIndex tile, TrainFindDepotData *tfdd, int track, uint length)
       
  1923 {
       
  1924 	if (IsTileType(tile, MP_RAILWAY) &&
       
  1925 			IsTileOwner(tile, tfdd->owner) &&
       
  1926 			IsRailDepot(tile)) {
       
  1927 		/* approximate number of tiles by dividing by DIAG_FACTOR */
       
  1928 		tfdd->best_length = length / DIAG_FACTOR;
       
  1929 		tfdd->tile = tile;
       
  1930 		return true;
       
  1931 	}
       
  1932 
       
  1933 	return false;
       
  1934 }
       
  1935 
       
  1936 // returns the tile of a depot to goto to. The given vehicle must not be
       
  1937 // crashed!
       
  1938 static TrainFindDepotData FindClosestTrainDepot(Vehicle *v, int max_distance)
       
  1939 {
       
  1940 	TrainFindDepotData tfdd;
       
  1941 	TileIndex tile = v->tile;
       
  1942 
       
  1943 	assert(!(v->vehstatus & VS_CRASHED));
       
  1944 
       
  1945 	tfdd.owner = v->owner;
       
  1946 	tfdd.best_length = (uint)-1;
       
  1947 	tfdd.reverse = false;
       
  1948 
       
  1949 	if (IsTileDepotType(tile, TRANSPORT_RAIL)){
       
  1950 		tfdd.tile = tile;
       
  1951 		tfdd.best_length = 0;
       
  1952 		return tfdd;
       
  1953 	}
       
  1954 
       
  1955 	if (_patches.yapf.rail_use_yapf) {
       
  1956 		bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse);
       
  1957 		tfdd.best_length = found ? max_distance / 2 : -1; // some fake distance or NOT_FOUND
       
  1958 	} else if (_patches.new_pathfinding_all) {
       
  1959 		NPFFoundTargetData ftd;
       
  1960 		Vehicle* last = GetLastVehicleInChain(v);
       
  1961 		Trackdir trackdir = GetVehicleTrackdir(v);
       
  1962 		Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
       
  1963 
       
  1964 		assert (trackdir != INVALID_TRACKDIR);
       
  1965 		ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY);
       
  1966 		if (ftd.best_bird_dist == 0) {
       
  1967 			/* Found target */
       
  1968 			tfdd.tile = ftd.node.tile;
       
  1969 			/* Our caller expects a number of tiles, so we just approximate that
       
  1970 			 * number by this. It might not be completely what we want, but it will
       
  1971 			 * work for now :-) We can possibly change this when the old pathfinder
       
  1972 			 * is removed. */
       
  1973 			tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH;
       
  1974 			if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) tfdd.reverse = true;
       
  1975 		}
       
  1976 	} else {
       
  1977 		// search in the forward direction first.
       
  1978 		DiagDirection i;
       
  1979 
       
  1980 		i = DirToDiagDir(v->direction);
       
  1981 		if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) {
       
  1982 			i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT);
       
  1983 		}
       
  1984 		NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
       
  1985 		if (tfdd.best_length == (uint)-1){
       
  1986 			tfdd.reverse = true;
       
  1987 			// search in backwards direction
       
  1988 			i = ReverseDiagDir(DirToDiagDir(v->direction));
       
  1989 			if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) {
       
  1990 				i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT);
       
  1991 			}
       
  1992 			NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
       
  1993 		}
       
  1994 	}
       
  1995 
       
  1996 	return tfdd;
       
  1997 }
       
  1998 
       
  1999 /** Send a train to a depot
       
  2000  * @param tile unused
       
  2001  * @param p1 train to send to the depot
       
  2002  * @param p2 various bitmasked elements
       
  2003  * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
       
  2004  * - p2 bit 8-10 - VLW flag (for mass goto depot)
       
  2005  */
       
  2006 int32 CmdSendTrainToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
       
  2007 {
       
  2008 	Vehicle *v;
       
  2009 	TrainFindDepotData tfdd;
       
  2010 
       
  2011 	if (p2 & DEPOT_MASS_SEND) {
       
  2012 		/* Mass goto depot requested */
       
  2013 		if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR;
       
  2014 		return SendAllVehiclesToDepot(VEH_Train, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1);
       
  2015 	}
       
  2016 
       
  2017 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
       
  2018 
       
  2019 	v = GetVehicle(p1);
       
  2020 
       
  2021 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
       
  2022 
       
  2023 	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
       
  2024 
       
  2025 	if (v->current_order.type == OT_GOTO_DEPOT) {
       
  2026 		if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
       
  2027 			/* We called with a different DEPOT_SERVICE setting.
       
  2028 			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
       
  2029 			 * Note: the if is (true for requesting service == true for ordered to stop in depot)          */
       
  2030 			if (flags & DC_EXEC) {
       
  2031 				TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
       
  2032 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
       
  2033 			}
       
  2034 			return 0;
       
  2035 		}
       
  2036 
       
  2037 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
       
  2038 		if (flags & DC_EXEC) {
       
  2039 			if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
       
  2040 				v->u.rail.days_since_order_progr = 0;
       
  2041 				v->cur_order_index++;
       
  2042 			}
       
  2043 
       
  2044 			v->current_order.type = OT_DUMMY;
       
  2045 			v->current_order.flags = 0;
       
  2046 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
       
  2047 		}
       
  2048 		return 0;
       
  2049 	}
       
  2050 
       
  2051 	/* check if at a standstill (not stopped only) in a depot
       
  2052 	 * the check is down here to make it possible to alter stop/service for trains entering the depot */
       
  2053 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL) && v->cur_speed == 0) return CMD_ERROR;
       
  2054 
       
  2055 	tfdd = FindClosestTrainDepot(v, 0);
       
  2056 	if (tfdd.best_length == (uint)-1) return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO);
       
  2057 
       
  2058 	if (flags & DC_EXEC) {
       
  2059 		v->dest_tile = tfdd.tile;
       
  2060 		v->current_order.type = OT_GOTO_DEPOT;
       
  2061 		v->current_order.flags = OF_NON_STOP;
       
  2062 		if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
       
  2063 		v->current_order.dest = GetDepotByTile(tfdd.tile)->index;
       
  2064 		v->current_order.refit_cargo = CT_INVALID;
       
  2065 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
       
  2066 		/* If there is no depot in front, reverse automatically */
       
  2067 		if (tfdd.reverse)
       
  2068 			DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
       
  2069 	}
       
  2070 
       
  2071 	return 0;
       
  2072 }
       
  2073 
       
  2074 
       
  2075 void OnTick_Train(void)
       
  2076 {
       
  2077 	_age_cargo_skip_counter = (_age_cargo_skip_counter == 0) ? 184 : (_age_cargo_skip_counter - 1);
       
  2078 }
       
  2079 
       
  2080 static const int8 _vehicle_smoke_pos[8] = {
       
  2081 	1, 1, 1, 0, -1, -1, -1, 0
       
  2082 };
       
  2083 
       
  2084 static void HandleLocomotiveSmokeCloud(const Vehicle* v)
       
  2085 {
       
  2086 	const Vehicle* u;
       
  2087 	bool sound = false;
       
  2088 
       
  2089 	if (v->vehstatus & VS_TRAIN_SLOWING || v->load_unload_time_rem != 0 || v->cur_speed < 2)
       
  2090 		return;
       
  2091 
       
  2092 	u = v;
       
  2093 
       
  2094 	do {
       
  2095 		EngineID engtype = v->engine_type;
       
  2096 		int effect_offset = GB(v->u.rail.cached_vis_effect, 0, 4) - 8;
       
  2097 		byte effect_type = GB(v->u.rail.cached_vis_effect, 4, 2);
       
  2098 		bool disable_effect = HASBIT(v->u.rail.cached_vis_effect, 6);
       
  2099 		int x, y;
       
  2100 
       
  2101 		// no smoke?
       
  2102 		if ((RailVehInfo(engtype)->flags & RVI_WAGON && effect_type == 0) ||
       
  2103 				disable_effect ||
       
  2104 				GetEngine(engtype)->railtype > RAILTYPE_ELECTRIC ||
       
  2105 				v->vehstatus & VS_HIDDEN) {
       
  2106 			continue;
       
  2107 		}
       
  2108 
       
  2109 		// No smoke in depots or tunnels
       
  2110 		if (IsTileDepotType(v->tile, TRANSPORT_RAIL) || IsTunnelTile(v->tile)) continue;
       
  2111 
       
  2112 		// No sparks for electric vehicles on nonelectrified tracks
       
  2113 		if (!HasPowerOnRail(v->u.rail.railtype, GetTileRailType(v->tile, GetVehicleTrackdir(v)))) continue;
       
  2114 
       
  2115 		if (effect_type == 0) {
       
  2116 			// Use default effect type for engine class.
       
  2117 			effect_type = RailVehInfo(engtype)->engclass;
       
  2118 		} else {
       
  2119 			effect_type--;
       
  2120 		}
       
  2121 
       
  2122 		x = _vehicle_smoke_pos[v->direction] * effect_offset;
       
  2123 		y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
       
  2124 
       
  2125 		if (HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
       
  2126 			x = -x;
       
  2127 			y = -y;
       
  2128 		}
       
  2129 
       
  2130 		switch (effect_type) {
       
  2131 		case 0:
       
  2132 			// steam smoke.
       
  2133 			if (GB(v->tick_counter, 0, 4) == 0) {
       
  2134 				CreateEffectVehicleRel(v, x, y, 10, EV_STEAM_SMOKE);
       
  2135 				sound = true;
       
  2136 			}
       
  2137 			break;
       
  2138 
       
  2139 		case 1:
       
  2140 			// diesel smoke
       
  2141 			if (u->cur_speed <= 40 && CHANCE16(15, 128)) {
       
  2142 				CreateEffectVehicleRel(v, 0, 0, 10, EV_DIESEL_SMOKE);
       
  2143 				sound = true;
       
  2144 			}
       
  2145 			break;
       
  2146 
       
  2147 		case 2:
       
  2148 			// blue spark
       
  2149 			if (GB(v->tick_counter, 0, 2) == 0 && CHANCE16(1, 45)) {
       
  2150 				CreateEffectVehicleRel(v, 0, 0, 10, EV_ELECTRIC_SPARK);
       
  2151 				sound = true;
       
  2152 			}
       
  2153 			break;
       
  2154 		}
       
  2155 	} while ((v = v->next) != NULL);
       
  2156 
       
  2157 	if (sound) PlayVehicleSound(u, VSE_TRAIN_EFFECT);
       
  2158 }
       
  2159 
       
  2160 static void TrainPlayLeaveStationSound(const Vehicle* v)
       
  2161 {
       
  2162 	static const SoundFx sfx[] = {
       
  2163 		SND_04_TRAIN,
       
  2164 		SND_0A_TRAIN_HORN,
       
  2165 		SND_0A_TRAIN_HORN
       
  2166 	};
       
  2167 
       
  2168 	EngineID engtype = v->engine_type;
       
  2169 
       
  2170 	if (PlayVehicleSound(v, VSE_START)) return;
       
  2171 
       
  2172 	switch (GetEngine(engtype)->railtype) {
       
  2173 		case RAILTYPE_RAIL:
       
  2174 		case RAILTYPE_ELECTRIC:
       
  2175 			SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], v);
       
  2176 			break;
       
  2177 
       
  2178 		case RAILTYPE_MONO: SndPlayVehicleFx(SND_47_MAGLEV_2, v); break;
       
  2179 		case RAILTYPE_MAGLEV: SndPlayVehicleFx(SND_41_MAGLEV, v); break;
       
  2180 	}
       
  2181 }
       
  2182 
       
  2183 static bool CheckTrainStayInDepot(Vehicle *v)
       
  2184 {
       
  2185 	Vehicle *u;
       
  2186 
       
  2187 	// bail out if not all wagons are in the same depot or not in a depot at all
       
  2188 	for (u = v; u != NULL; u = u->next) {
       
  2189 		if (u->u.rail.track != 0x80 || u->tile != v->tile) return false;
       
  2190 	}
       
  2191 
       
  2192 	// if the train got no power, then keep it in the depot
       
  2193 	if (v->u.rail.cached_power == 0) {
       
  2194 		v->vehstatus |= VS_STOPPED;
       
  2195 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
       
  2196 		return true;
       
  2197 	}
       
  2198 
       
  2199 	if (v->u.rail.force_proceed == 0) {
       
  2200 		if (++v->load_unload_time_rem < 37) {
       
  2201 			InvalidateWindowClasses(WC_TRAINS_LIST);
       
  2202 			return true;
       
  2203 		}
       
  2204 
       
  2205 		v->load_unload_time_rem = 0;
       
  2206 
       
  2207 		if (UpdateSignalsOnSegment(v->tile, DirToDiagDir(v->direction))) {
       
  2208 			InvalidateWindowClasses(WC_TRAINS_LIST);
       
  2209 			return true;
       
  2210 		}
       
  2211 	}
       
  2212 
       
  2213 	VehicleServiceInDepot(v);
       
  2214 	InvalidateWindowClasses(WC_TRAINS_LIST);
       
  2215 	TrainPlayLeaveStationSound(v);
       
  2216 
       
  2217 	v->u.rail.track = 1;
       
  2218 	if (v->direction & 2) v->u.rail.track = 2;
       
  2219 
       
  2220 	v->vehstatus &= ~VS_HIDDEN;
       
  2221 	v->cur_speed = 0;
       
  2222 
       
  2223 	UpdateTrainDeltaXY(v, v->direction);
       
  2224 	v->cur_image = GetTrainImage(v, v->direction);
       
  2225 	VehiclePositionChanged(v);
       
  2226 	UpdateSignalsOnSegment(v->tile, DirToDiagDir(v->direction));
       
  2227 	UpdateTrainAcceleration(v);
       
  2228 	InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
       
  2229 
       
  2230 	return false;
       
  2231 }
       
  2232 
       
  2233 /* Check for station tiles */
       
  2234 typedef struct TrainTrackFollowerData {
       
  2235 	TileIndex dest_coords;
       
  2236 	StationID station_index; // station index we're heading for
       
  2237 	uint best_bird_dist;
       
  2238 	uint best_track_dist;
       
  2239 	byte best_track;
       
  2240 } TrainTrackFollowerData;
       
  2241 
       
  2242 static bool NtpCallbFindStation(TileIndex tile, TrainTrackFollowerData *ttfd, int track, uint length)
       
  2243 {
       
  2244 	// heading for nowhere?
       
  2245 	if (ttfd->dest_coords == 0) return false;
       
  2246 
       
  2247 	// did we reach the final station?
       
  2248 	if ((ttfd->station_index == INVALID_STATION && tile == ttfd->dest_coords) || (
       
  2249 				IsTileType(tile, MP_STATION) &&
       
  2250 				IsRailwayStation(tile) &&
       
  2251 				GetStationIndex(tile) == ttfd->station_index
       
  2252 			)) {
       
  2253 		/* We do not check for dest_coords if we have a station_index,
       
  2254 		 * because in that case the dest_coords are just an
       
  2255 		 * approximation of where the station is */
       
  2256 		// found station
       
  2257 		ttfd->best_bird_dist = 0; // we found destination
       
  2258 		ttfd->best_track = track;
       
  2259 		return true;
       
  2260 	} else {
       
  2261 		uint dist;
       
  2262 
       
  2263 		// didn't find station, keep track of the best path so far.
       
  2264 		dist = DistanceManhattan(tile, ttfd->dest_coords);
       
  2265 		if (dist < ttfd->best_bird_dist) {
       
  2266 			ttfd->best_bird_dist = dist;
       
  2267 			ttfd->best_track = track;
       
  2268 		}
       
  2269 		return false;
       
  2270 	}
       
  2271 }
       
  2272 
       
  2273 static void FillWithStationData(TrainTrackFollowerData* fd, const Vehicle* v)
       
  2274 {
       
  2275 	fd->dest_coords = v->dest_tile;
       
  2276 	if (v->current_order.type == OT_GOTO_STATION) {
       
  2277 		fd->station_index = v->current_order.dest;
       
  2278 	} else {
       
  2279 		fd->station_index = INVALID_STATION;
       
  2280 	}
       
  2281 }
       
  2282 
       
  2283 static const byte _initial_tile_subcoord[6][4][3] = {
       
  2284 {{ 15, 8, 1 }, { 0, 0, 0 }, { 0, 8, 5 }, { 0,  0, 0 }},
       
  2285 {{  0, 0, 0 }, { 8, 0, 3 }, { 0, 0, 0 }, { 8, 15, 7 }},
       
  2286 {{  0, 0, 0 }, { 7, 0, 2 }, { 0, 7, 6 }, { 0,  0, 0 }},
       
  2287 {{ 15, 8, 2 }, { 0, 0, 0 }, { 0, 0, 0 }, { 8, 15, 6 }},
       
  2288 {{ 15, 7, 0 }, { 8, 0, 4 }, { 0, 0, 0 }, { 0,  0, 0 }},
       
  2289 {{  0, 0, 0 }, { 0, 0, 0 }, { 0, 8, 4 }, { 7, 15, 0 }},
       
  2290 };
       
  2291 
       
  2292 static const uint32 _reachable_tracks[4] = {
       
  2293 	0x10091009,
       
  2294 	0x00160016,
       
  2295 	0x05200520,
       
  2296 	0x2A002A00,
       
  2297 };
       
  2298 
       
  2299 static const byte _search_directions[6][4] = {
       
  2300 	{ 0, 9, 2, 9 }, // track 1
       
  2301 	{ 9, 1, 9, 3 }, // track 2
       
  2302 	{ 9, 0, 3, 9 }, // track upper
       
  2303 	{ 1, 9, 9, 2 }, // track lower
       
  2304 	{ 3, 2, 9, 9 }, // track left
       
  2305 	{ 9, 9, 1, 0 }, // track right
       
  2306 };
       
  2307 
       
  2308 static const byte _pick_track_table[6] = {1, 3, 2, 2, 0, 0};
       
  2309 
       
  2310 /* choose a track */
       
  2311 static byte ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirbits)
       
  2312 {
       
  2313 	TrainTrackFollowerData fd;
       
  2314 	uint best_track;
       
  2315 	// pathfinders are able to tell that route was only 'guessed'
       
  2316 	bool path_not_found = false;
       
  2317 
       
  2318 #ifdef PF_BENCHMARK
       
  2319 	TIC()
       
  2320 #endif
       
  2321 
       
  2322 	assert((trackdirbits & ~0x3F) == 0);
       
  2323 
       
  2324 	/* quick return in case only one possible track is available */
       
  2325 	if (KILL_FIRST_BIT(trackdirbits) == 0) return FIND_FIRST_BIT(trackdirbits);
       
  2326 
       
  2327 	if (_patches.yapf.rail_use_yapf) {
       
  2328 		Trackdir trackdir = YapfChooseRailTrack(v, tile, enterdir, trackdirbits, &path_not_found);
       
  2329 		if (trackdir != INVALID_TRACKDIR) {
       
  2330 			best_track = TrackdirToTrack(trackdir);
       
  2331 		} else {
       
  2332 			best_track = FIND_FIRST_BIT(TrackdirBitsToTrackBits(trackdirbits));
       
  2333 		}
       
  2334 	} else if (_patches.new_pathfinding_all) { /* Use a new pathfinding for everything */
       
  2335 		void* perf = NpfBeginInterval();
       
  2336 		int time = 0;
       
  2337 
       
  2338 		NPFFindStationOrTileData fstd;
       
  2339 		NPFFoundTargetData ftd;
       
  2340 		Trackdir trackdir;
       
  2341 
       
  2342 		NPFFillWithOrderData(&fstd, v);
       
  2343 		/* The enterdir for the new tile, is the exitdir for the old tile */
       
  2344 		trackdir = GetVehicleTrackdir(v);
       
  2345 		assert(trackdir != 0xff);
       
  2346 
       
  2347 		ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes);
       
  2348 
       
  2349 		if (ftd.best_trackdir == 0xff) {
       
  2350 			/* We are already at our target. Just do something */
       
  2351 			//TODO: maybe display error?
       
  2352 			//TODO: go straight ahead if possible?
       
  2353 			best_track = FIND_FIRST_BIT(trackdirbits);
       
  2354 		} else {
       
  2355 			/* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
       
  2356 			the direction we need to take to get there, if ftd.best_bird_dist is not 0,
       
  2357 			we did not find our target, but ftd.best_trackdir contains the direction leading
       
  2358 			to the tile closest to our target. */
       
  2359 			if (ftd.best_bird_dist != 0) path_not_found = true;
       
  2360 			/* Discard enterdir information, making it a normal track */
       
  2361 			best_track = TrackdirToTrack(ftd.best_trackdir);
       
  2362 		}
       
  2363 
       
  2364 		time = NpfEndInterval(perf);
       
  2365 		DEBUG(yapf, 4, "[NPFT] %d us - %d rounds - %d open - %d closed -- ", time, 0, _aystar_stats_open_size, _aystar_stats_closed_size);
       
  2366 	} else {
       
  2367 		void* perf = NpfBeginInterval();
       
  2368 		int time = 0;
       
  2369 
       
  2370 		FillWithStationData(&fd, v);
       
  2371 
       
  2372 		/* New train pathfinding */
       
  2373 		fd.best_bird_dist = (uint)-1;
       
  2374 		fd.best_track_dist = (uint)-1;
       
  2375 		fd.best_track = 0xFF;
       
  2376 
       
  2377 		NewTrainPathfind(tile - TileOffsByDiagDir(enterdir), v->dest_tile,
       
  2378 			v->u.rail.compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd);
       
  2379 
       
  2380 		// check whether the path was found or only 'guessed'
       
  2381 		if (fd.best_bird_dist != 0) path_not_found = true;
       
  2382 
       
  2383 		if (fd.best_track == 0xff) {
       
  2384 			// blaha
       
  2385 			best_track = FIND_FIRST_BIT(trackdirbits);
       
  2386 		} else {
       
  2387 			best_track = fd.best_track & 7;
       
  2388 		}
       
  2389 
       
  2390 		time = NpfEndInterval(perf);
       
  2391 		DEBUG(yapf, 4, "[NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0);
       
  2392 	}
       
  2393 	// handle "path not found" state
       
  2394 	if (path_not_found) {
       
  2395 		// PF didn't find the route
       
  2396 		if (!HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
       
  2397 			// it is first time the problem occurred, set the "path not found" flag
       
  2398 			SETBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
       
  2399 			// and notify user about the event
       
  2400 			if (_patches.lost_train_warn && v->owner == _local_player) {
       
  2401 				SetDParam(0, v->unitnumber);
       
  2402 				AddNewsItem(
       
  2403 					STR_TRAIN_IS_LOST,
       
  2404 					NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0),
       
  2405 					v->index,
       
  2406 					0);
       
  2407 			}
       
  2408 		}
       
  2409 	} else {
       
  2410 		// route found, is the train marked with "path not found" flag?
       
  2411 		if (HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
       
  2412 			// clear the flag as the PF's problem was solved
       
  2413 			CLRBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
       
  2414 			// can we also delete the "News" item somehow?
       
  2415 		}
       
  2416 	}
       
  2417 
       
  2418 #ifdef PF_BENCHMARK
       
  2419 	TOC("PF time = ", 1)
       
  2420 #endif
       
  2421 
       
  2422 	return best_track;
       
  2423 }
       
  2424 
       
  2425 
       
  2426 static bool CheckReverseTrain(Vehicle *v)
       
  2427 {
       
  2428 	TrainTrackFollowerData fd;
       
  2429 	int i, r;
       
  2430 	int best_track;
       
  2431 	uint best_bird_dist  = 0;
       
  2432 	uint best_track_dist = 0;
       
  2433 	uint reverse, reverse_best;
       
  2434 
       
  2435 	if (_opt.diff.line_reverse_mode != 0 ||
       
  2436 			v->u.rail.track & 0xC0 ||
       
  2437 			!(v->direction & 1))
       
  2438 		return false;
       
  2439 
       
  2440 	FillWithStationData(&fd, v);
       
  2441 
       
  2442 	best_track = -1;
       
  2443 	reverse_best = reverse = 0;
       
  2444 
       
  2445 	assert(v->u.rail.track);
       
  2446 
       
  2447 	i = _search_directions[FIND_FIRST_BIT(v->u.rail.track)][DirToDiagDir(v->direction)];
       
  2448 
       
  2449 	if (_patches.yapf.rail_use_yapf) {
       
  2450 		reverse_best = YapfCheckReverseTrain(v);
       
  2451 	} else if (_patches.new_pathfinding_all) { /* Use a new pathfinding for everything */
       
  2452 		NPFFindStationOrTileData fstd;
       
  2453 		NPFFoundTargetData ftd;
       
  2454 		byte trackdir, trackdir_rev;
       
  2455 		Vehicle* last = GetLastVehicleInChain(v);
       
  2456 
       
  2457 		NPFFillWithOrderData(&fstd, v);
       
  2458 
       
  2459 		trackdir = GetVehicleTrackdir(v);
       
  2460 		trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
       
  2461 		assert(trackdir != 0xff);
       
  2462 		assert(trackdir_rev != 0xff);
       
  2463 
       
  2464 		ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes);
       
  2465 		if (ftd.best_bird_dist != 0) {
       
  2466 			/* We didn't find anything, just keep on going straight ahead */
       
  2467 			reverse_best = false;
       
  2468 		} else {
       
  2469 			if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) {
       
  2470 				reverse_best = true;
       
  2471 			} else {
       
  2472 				reverse_best = false;
       
  2473 			}
       
  2474 		}
       
  2475 	} else {
       
  2476 		for (;;) {
       
  2477 			fd.best_bird_dist = (uint)-1;
       
  2478 			fd.best_track_dist = (uint)-1;
       
  2479 
       
  2480 			NewTrainPathfind(v->tile, v->dest_tile, v->u.rail.compatible_railtypes, reverse ^ i, (NTPEnumProc*)NtpCallbFindStation, &fd);
       
  2481 
       
  2482 			if (best_track != -1) {
       
  2483 				if (best_bird_dist != 0) {
       
  2484 					if (fd.best_bird_dist != 0) {
       
  2485 						/* neither reached the destination, pick the one with the smallest bird dist */
       
  2486 						if (fd.best_bird_dist > best_bird_dist) goto bad;
       
  2487 						if (fd.best_bird_dist < best_bird_dist) goto good;
       
  2488 					} else {
       
  2489 						/* we found the destination for the first time */
       
  2490 						goto good;
       
  2491 					}
       
  2492 				} else {
       
  2493 					if (fd.best_bird_dist != 0) {
       
  2494 						/* didn't find destination, but we've found the destination previously */
       
  2495 						goto bad;
       
  2496 					} else {
       
  2497 						/* both old & new reached the destination, compare track length */
       
  2498 						if (fd.best_track_dist > best_track_dist) goto bad;
       
  2499 						if (fd.best_track_dist < best_track_dist) goto good;
       
  2500 					}
       
  2501 				}
       
  2502 
       
  2503 				/* if we reach this position, there's two paths of equal value so far.
       
  2504 				 * pick one randomly. */
       
  2505 				r = GB(Random(), 0, 8);
       
  2506 				if (_pick_track_table[i] == (v->direction & 3)) r += 80;
       
  2507 				if (_pick_track_table[best_track] == (v->direction & 3)) r -= 80;
       
  2508 				if (r <= 127) goto bad;
       
  2509 			}
       
  2510 good:;
       
  2511 			best_track = i;
       
  2512 			best_bird_dist = fd.best_bird_dist;
       
  2513 			best_track_dist = fd.best_track_dist;
       
  2514 			reverse_best = reverse;
       
  2515 bad:;
       
  2516 			if (reverse != 0) break;
       
  2517 			reverse = 2;
       
  2518 		}
       
  2519 	}
       
  2520 
       
  2521 	return reverse_best != 0;
       
  2522 }
       
  2523 
       
  2524 static bool ProcessTrainOrder(Vehicle *v)
       
  2525 {
       
  2526 	const Order *order;
       
  2527 	bool at_waypoint = false;
       
  2528 
       
  2529 	switch (v->current_order.type) {
       
  2530 		case OT_GOTO_DEPOT:
       
  2531 			if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return false;
       
  2532 			if ((v->current_order.flags & OF_SERVICE_IF_NEEDED) &&
       
  2533 					!VehicleNeedsService(v)) {
       
  2534 				v->cur_order_index++;
       
  2535 			}
       
  2536 			break;
       
  2537 
       
  2538 		case OT_LOADING:
       
  2539 		case OT_LEAVESTATION:
       
  2540 			return false;
       
  2541 
       
  2542 		default: break;
       
  2543 	}
       
  2544 
       
  2545 	// check if we've reached the waypoint?
       
  2546 	if (v->current_order.type == OT_GOTO_WAYPOINT && v->tile == v->dest_tile) {
       
  2547 		v->cur_order_index++;
       
  2548 		at_waypoint = true;
       
  2549 	}
       
  2550 
       
  2551 	// check if we've reached a non-stop station while TTDPatch nonstop is enabled..
       
  2552 	if (_patches.new_nonstop &&
       
  2553 			v->current_order.flags & OF_NON_STOP &&
       
  2554 			IsTileType(v->tile, MP_STATION) &&
       
  2555 			v->current_order.dest == GetStationIndex(v->tile)) {
       
  2556 		v->cur_order_index++;
       
  2557 	}
       
  2558 
       
  2559 	// Get the current order
       
  2560 	if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
       
  2561 
       
  2562 	order = GetVehicleOrder(v, v->cur_order_index);
       
  2563 
       
  2564 	// If no order, do nothing.
       
  2565 	if (order == NULL) {
       
  2566 		v->current_order.type = OT_NOTHING;
       
  2567 		v->current_order.flags = 0;
       
  2568 		v->dest_tile = 0;
       
  2569 		return false;
       
  2570 	}
       
  2571 
       
  2572 	// If it is unchanged, keep it.
       
  2573 	if (order->type  == v->current_order.type &&
       
  2574 			order->flags == v->current_order.flags &&
       
  2575 			order->dest  == v->current_order.dest)
       
  2576 		return false;
       
  2577 
       
  2578 	// Otherwise set it, and determine the destination tile.
       
  2579 	v->current_order = *order;
       
  2580 
       
  2581 	v->dest_tile = 0;
       
  2582 
       
  2583 	InvalidateVehicleOrder(v);
       
  2584 
       
  2585 	switch (order->type) {
       
  2586 		case OT_GOTO_STATION:
       
  2587 			if (order->dest == v->last_station_visited)
       
  2588 				v->last_station_visited = INVALID_STATION;
       
  2589 			v->dest_tile = GetStation(order->dest)->xy;
       
  2590 			break;
       
  2591 
       
  2592 		case OT_GOTO_DEPOT:
       
  2593 			v->dest_tile = GetDepot(order->dest)->xy;
       
  2594 			break;
       
  2595 
       
  2596 		case OT_GOTO_WAYPOINT:
       
  2597 			v->dest_tile = GetWaypoint(order->dest)->xy;
       
  2598 			break;
       
  2599 
       
  2600 		default:
       
  2601 			return false;
       
  2602 	}
       
  2603 
       
  2604 	return !at_waypoint && CheckReverseTrain(v);
       
  2605 }
       
  2606 
       
  2607 static void MarkTrainDirty(Vehicle *v)
       
  2608 {
       
  2609 	do {
       
  2610 		v->cur_image = GetTrainImage(v, v->direction);
       
  2611 		MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
       
  2612 	} while ((v = v->next) != NULL);
       
  2613 }
       
  2614 
       
  2615 static void HandleTrainLoading(Vehicle *v, bool mode)
       
  2616 {
       
  2617 	if (v->current_order.type == OT_NOTHING) return;
       
  2618 
       
  2619 	if (v->current_order.type != OT_DUMMY) {
       
  2620 		if (v->current_order.type != OT_LOADING) return;
       
  2621 		if (mode) return;
       
  2622 
       
  2623 		// don't mark the train as lost if we're loading on the final station.
       
  2624 		if (v->current_order.flags & OF_NON_STOP)
       
  2625 			v->u.rail.days_since_order_progr = 0;
       
  2626 
       
  2627 		if (--v->load_unload_time_rem) return;
       
  2628 
       
  2629 		if (CanFillVehicle(v) && (v->current_order.flags & OF_FULL_LOAD ||
       
  2630 				(_patches.gradual_loading && !HASBIT(v->load_status, LS_LOADING_FINISHED)))) {
       
  2631 			v->u.rail.days_since_order_progr = 0; /* Prevent a train lost message for full loading trains */
       
  2632 			SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC);
       
  2633 			if (LoadUnloadVehicle(v, false)) {
       
  2634 				InvalidateWindow(WC_TRAINS_LIST, v->owner);
       
  2635 				MarkTrainDirty(v);
       
  2636 
       
  2637 				// need to update acceleration and cached values since the goods on the train changed.
       
  2638 				TrainCargoChanged(v);
       
  2639 				UpdateTrainAcceleration(v);
       
  2640 			}
       
  2641 			return;
       
  2642 		}
       
  2643 
       
  2644 		TrainPlayLeaveStationSound(v);
       
  2645 
       
  2646 		{
       
  2647 			Order b = v->current_order;
       
  2648 			v->current_order.type = OT_LEAVESTATION;
       
  2649 			v->current_order.flags = 0;
       
  2650 
       
  2651 			// If this was not the final order, don't remove it from the list.
       
  2652 			if (!(b.flags & OF_NON_STOP)) return;
       
  2653 		}
       
  2654 	}
       
  2655 
       
  2656 	v->u.rail.days_since_order_progr = 0;
       
  2657 	v->cur_order_index++;
       
  2658 	InvalidateVehicleOrder(v);
       
  2659 }
       
  2660 
       
  2661 static int UpdateTrainSpeed(Vehicle *v)
       
  2662 {
       
  2663 	uint spd;
       
  2664 	uint accel;
       
  2665 
       
  2666 	if (v->vehstatus & VS_STOPPED || HASBIT(v->u.rail.flags, VRF_REVERSING)) {
       
  2667 		if (_patches.realistic_acceleration) {
       
  2668 			accel = GetTrainAcceleration(v, AM_BRAKE) * 2;
       
  2669 		} else {
       
  2670 			accel = v->acceleration * -2;
       
  2671 		}
       
  2672 	} else {
       
  2673 		if (_patches.realistic_acceleration) {
       
  2674 			accel = GetTrainAcceleration(v, AM_ACCEL);
       
  2675 		} else {
       
  2676 			accel = v->acceleration;
       
  2677 		}
       
  2678 	}
       
  2679 
       
  2680 	spd = v->subspeed + accel * 2;
       
  2681 	v->subspeed = (byte)spd;
       
  2682 	{
       
  2683 		int tempmax = v->max_speed;
       
  2684 		if (v->cur_speed > v->max_speed)
       
  2685 			tempmax = v->cur_speed - (v->cur_speed / 10) - 1;
       
  2686 		v->cur_speed = spd = clamp(v->cur_speed + ((int)spd >> 8), 0, tempmax);
       
  2687 	}
       
  2688 
       
  2689 	if (!(v->direction & 1)) spd = spd * 3 >> 2;
       
  2690 
       
  2691 	spd += v->progress;
       
  2692 	v->progress = (byte)spd;
       
  2693 	return (spd >> 8);
       
  2694 }
       
  2695 
       
  2696 static void TrainEnterStation(Vehicle *v, StationID station)
       
  2697 {
       
  2698 	Station *st;
       
  2699 	uint32 flags;
       
  2700 
       
  2701 	v->last_station_visited = station;
       
  2702 
       
  2703 	/* check if a train ever visited this station before */
       
  2704 	st = GetStation(station);
       
  2705 	if (!(st->had_vehicle_of_type & HVOT_TRAIN)) {
       
  2706 		st->had_vehicle_of_type |= HVOT_TRAIN;
       
  2707 		SetDParam(0, st->index);
       
  2708 		flags = (v->owner == _local_player) ? NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) : NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_OTHER, 0);
       
  2709 		AddNewsItem(
       
  2710 			STR_8801_CITIZENS_CELEBRATE_FIRST,
       
  2711 			flags,
       
  2712 			v->index,
       
  2713 			0
       
  2714 		);
       
  2715 	}
       
  2716 
       
  2717 	// Did we reach the final destination?
       
  2718 	if (v->current_order.type == OT_GOTO_STATION &&
       
  2719 			v->current_order.dest == station) {
       
  2720 		// Yeah, keep the load/unload flags
       
  2721 		// Non Stop now means if the order should be increased.
       
  2722 		v->current_order.type = OT_LOADING;
       
  2723 		v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER;
       
  2724 		v->current_order.flags |= OF_NON_STOP;
       
  2725 	} else {
       
  2726 		// No, just do a simple load
       
  2727 		v->current_order.type = OT_LOADING;
       
  2728 		v->current_order.flags = 0;
       
  2729 	}
       
  2730 	v->current_order.dest = 0;
       
  2731 
       
  2732 	SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC);
       
  2733 	if (LoadUnloadVehicle(v, true) != 0) {
       
  2734 		InvalidateWindow(WC_TRAINS_LIST, v->owner);
       
  2735 		TrainCargoChanged(v);
       
  2736 		UpdateTrainAcceleration(v);
       
  2737 	}
       
  2738 	MarkTrainDirty(v);
       
  2739 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
       
  2740 }
       
  2741 
       
  2742 static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
       
  2743 {
       
  2744 	byte new_z, old_z;
       
  2745 
       
  2746 	// need this hint so it returns the right z coordinate on bridges.
       
  2747 	new_z = GetSlopeZ(v->x_pos, v->y_pos);
       
  2748 
       
  2749 	old_z = v->z_pos;
       
  2750 	v->z_pos = new_z;
       
  2751 
       
  2752 	if (new_tile) {
       
  2753 		CLRBIT(v->u.rail.flags, VRF_GOINGUP);
       
  2754 		CLRBIT(v->u.rail.flags, VRF_GOINGDOWN);
       
  2755 
       
  2756 		if (new_z != old_z) {
       
  2757 			TileIndex tile = TileVirtXY(v->x_pos, v->y_pos);
       
  2758 
       
  2759 			// XXX workaround, whole UP/DOWN detection needs overhaul
       
  2760 			if (!IsTunnelTile(tile)) {
       
  2761 				SETBIT(v->u.rail.flags, (new_z > old_z) ? VRF_GOINGUP : VRF_GOINGDOWN);
       
  2762 			}
       
  2763 		}
       
  2764 	}
       
  2765 
       
  2766 	VehiclePositionChanged(v);
       
  2767 	EndVehicleMove(v);
       
  2768 	return old_z;
       
  2769 }
       
  2770 
       
  2771 static const Direction _new_vehicle_direction_table[11] = {
       
  2772 	DIR_N , DIR_NW, DIR_W , 0,
       
  2773 	DIR_NE, DIR_N , DIR_SW, 0,
       
  2774 	DIR_E , DIR_SE, DIR_S
       
  2775 };
       
  2776 
       
  2777 static Direction GetNewVehicleDirectionByTile(TileIndex new_tile, TileIndex old_tile)
       
  2778 {
       
  2779 	uint offs = (TileY(new_tile) - TileY(old_tile) + 1) * 4 +
       
  2780 							TileX(new_tile) - TileX(old_tile) + 1;
       
  2781 	assert(offs < 11);
       
  2782 	return _new_vehicle_direction_table[offs];
       
  2783 }
       
  2784 
       
  2785 static Direction GetNewVehicleDirection(const Vehicle *v, int x, int y)
       
  2786 {
       
  2787 	uint offs = (y - v->y_pos + 1) * 4 + (x - v->x_pos + 1);
       
  2788 	assert(offs < 11);
       
  2789 	return _new_vehicle_direction_table[offs];
       
  2790 }
       
  2791 
       
  2792 static int GetDirectionToVehicle(const Vehicle *v, int x, int y)
       
  2793 {
       
  2794 	byte offs;
       
  2795 
       
  2796 	x -= v->x_pos;
       
  2797 	if (x >= 0) {
       
  2798 		offs = (x > 2) ? 0 : 1;
       
  2799 	} else {
       
  2800 		offs = (x < -2) ? 2 : 1;
       
  2801 	}
       
  2802 
       
  2803 	y -= v->y_pos;
       
  2804 	if (y >= 0) {
       
  2805 		offs += ((y > 2) ? 0 : 1) * 4;
       
  2806 	} else {
       
  2807 		offs += ((y < -2) ? 2 : 1) * 4;
       
  2808 	}
       
  2809 
       
  2810 	assert(offs < 11);
       
  2811 	return _new_vehicle_direction_table[offs];
       
  2812 }
       
  2813 
       
  2814 /* Check if the vehicle is compatible with the specified tile */
       
  2815 static bool CheckCompatibleRail(const Vehicle *v, TileIndex tile)
       
  2816 {
       
  2817 	switch (GetTileType(tile)) {
       
  2818 		case MP_RAILWAY_BRIDGE:
       
  2819 		case MP_RAILWAY:
       
  2820 		case MP_STATION:
       
  2821 			// normal tracks, jump to owner check
       
  2822 			break;
       
  2823 
       
  2824 		case MP_STREET:
       
  2825 			// tracks over roads, do owner check of tracks
       
  2826 			return
       
  2827 				IsTileOwner(tile, v->owner) && (
       
  2828 					!IsFrontEngine(v) ||
       
  2829 					IsCompatibleRail(v->u.rail.railtype, GetRailTypeCrossing(tile))
       
  2830 				);
       
  2831 
       
  2832 		default:
       
  2833 			return true;
       
  2834 	}
       
  2835 
       
  2836 	return
       
  2837 		IsTileOwner(tile, v->owner) && (
       
  2838 			!IsFrontEngine(v) ||
       
  2839 			HASBIT(v->u.rail.compatible_railtypes, GetRailType(tile))
       
  2840 		);
       
  2841 }
       
  2842 
       
  2843 typedef struct {
       
  2844 	byte small_turn, large_turn;
       
  2845 	byte z_up; // fraction to remove when moving up
       
  2846 	byte z_down; // fraction to remove when moving down
       
  2847 } RailtypeSlowdownParams;
       
  2848 
       
  2849 static const RailtypeSlowdownParams _railtype_slowdown[] = {
       
  2850 	// normal accel
       
  2851 	{256 / 4, 256 / 2, 256 / 4, 2}, // normal
       
  2852 	{256 / 4, 256 / 2, 256 / 4, 2}, // electrified
       
  2853 	{256 / 4, 256 / 2, 256 / 4, 2}, // monorail
       
  2854 	{0,       256 / 2, 256 / 4, 2}, // maglev
       
  2855 };
       
  2856 
       
  2857 /* Modify the speed of the vehicle due to a turn */
       
  2858 static void AffectSpeedByDirChange(Vehicle* v, Direction new_dir)
       
  2859 {
       
  2860 	DirDiff diff;
       
  2861 	const RailtypeSlowdownParams *rsp;
       
  2862 
       
  2863 	if (_patches.realistic_acceleration) return;
       
  2864 
       
  2865 	diff = DirDifference(v->direction, new_dir);
       
  2866 	if (diff == DIRDIFF_SAME) return;
       
  2867 
       
  2868 	rsp = &_railtype_slowdown[v->u.rail.railtype];
       
  2869 	v->cur_speed -= (diff == DIRDIFF_45RIGHT || diff == DIRDIFF_45LEFT ? rsp->small_turn : rsp->large_turn) * v->cur_speed >> 8;
       
  2870 }
       
  2871 
       
  2872 /* Modify the speed of the vehicle due to a change in altitude */
       
  2873 static void AffectSpeedByZChange(Vehicle *v, byte old_z)
       
  2874 {
       
  2875 	const RailtypeSlowdownParams *rsp;
       
  2876 	if (old_z == v->z_pos || _patches.realistic_acceleration) return;
       
  2877 
       
  2878 	rsp = &_railtype_slowdown[v->u.rail.railtype];
       
  2879 
       
  2880 	if (old_z < v->z_pos) {
       
  2881 		v->cur_speed -= (v->cur_speed * rsp->z_up >> 8);
       
  2882 	} else {
       
  2883 		uint16 spd = v->cur_speed + rsp->z_down;
       
  2884 		if (spd <= v->max_speed) v->cur_speed = spd;
       
  2885 	}
       
  2886 }
       
  2887 
       
  2888 static const DiagDirection _otherside_signal_directions[] = {
       
  2889 	DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, 0, 0,
       
  2890 	DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
       
  2891 };
       
  2892 
       
  2893 static void TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
       
  2894 {
       
  2895 	if ( (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_RAILWAY_BRIDGE)) &&
       
  2896 			GetRailTileType(tile) == RAIL_TILE_SIGNALS) {
       
  2897 		uint i = FindFirstBit2x64(GetTrackBits(tile) * 0x101 & _reachable_tracks[dir]);
       
  2898 		UpdateSignalsOnSegment(tile, _otherside_signal_directions[i]);
       
  2899 	}
       
  2900 }
       
  2901 
       
  2902 
       
  2903 typedef struct TrainCollideChecker {
       
  2904 	const Vehicle *v;
       
  2905 	const Vehicle *v_skip;
       
  2906 } TrainCollideChecker;
       
  2907 
       
  2908 static void *FindTrainCollideEnum(Vehicle *v, void *data)
       
  2909 {
       
  2910 	const TrainCollideChecker* tcc = data;
       
  2911 
       
  2912 	if (v != tcc->v &&
       
  2913 			v != tcc->v_skip &&
       
  2914 			v->type == VEH_Train &&
       
  2915 			v->u.rail.track != 0x80 &&
       
  2916 			myabs(v->z_pos - tcc->v->z_pos) <= 6 &&
       
  2917 			myabs(v->x_pos - tcc->v->x_pos) < 6 &&
       
  2918 			myabs(v->y_pos - tcc->v->y_pos) < 6) {
       
  2919 		return v;
       
  2920 	} else {
       
  2921 		return NULL;
       
  2922 	}
       
  2923 }
       
  2924 
       
  2925 static void SetVehicleCrashed(Vehicle *v)
       
  2926 {
       
  2927 	Vehicle *u;
       
  2928 
       
  2929 	if (v->u.rail.crash_anim_pos != 0) return;
       
  2930 
       
  2931 	v->u.rail.crash_anim_pos++;
       
  2932 
       
  2933 	u = v;
       
  2934 	BEGIN_ENUM_WAGONS(v)
       
  2935 		v->vehstatus |= VS_CRASHED;
       
  2936 	END_ENUM_WAGONS(v)
       
  2937 
       
  2938 	InvalidateWindowWidget(WC_VEHICLE_VIEW, u->index, STATUS_BAR);
       
  2939 }
       
  2940 
       
  2941 static uint CountPassengersInTrain(const Vehicle* v)
       
  2942 {
       
  2943 	uint num = 0;
       
  2944 	BEGIN_ENUM_WAGONS(v)
       
  2945 		if (v->cargo_type == CT_PASSENGERS) num += v->cargo_count;
       
  2946 	END_ENUM_WAGONS(v)
       
  2947 	return num;
       
  2948 }
       
  2949 
       
  2950 /*
       
  2951  * Checks whether the specified train has a collision with another vehicle. If
       
  2952  * so, destroys this vehicle, and the other vehicle if its subtype has TS_Front.
       
  2953  * Reports the incident in a flashy news item, modifies station ratings and
       
  2954  * plays a sound.
       
  2955  */
       
  2956 static void CheckTrainCollision(Vehicle *v)
       
  2957 {
       
  2958 	TrainCollideChecker tcc;
       
  2959 	Vehicle *coll;
       
  2960 	Vehicle *realcoll;
       
  2961 	uint num;
       
  2962 
       
  2963 	/* can't collide in depot */
       
  2964 	if (v->u.rail.track == 0x80) return;
       
  2965 
       
  2966 	assert(v->u.rail.track == 0x40 || TileVirtXY(v->x_pos, v->y_pos) == v->tile);
       
  2967 
       
  2968 	tcc.v = v;
       
  2969 	tcc.v_skip = v->next;
       
  2970 
       
  2971 	/* find colliding vehicle */
       
  2972 	realcoll = VehicleFromPos(TileVirtXY(v->x_pos, v->y_pos), &tcc, FindTrainCollideEnum);
       
  2973 	if (realcoll == NULL) return;
       
  2974 
       
  2975 	coll = GetFirstVehicleInChain(realcoll);
       
  2976 
       
  2977 	/* it can't collide with its own wagons */
       
  2978 	if (v == coll ||
       
  2979 			(v->u.rail.track & 0x40 && (v->direction & 2) != (realcoll->direction & 2)))
       
  2980 		return;
       
  2981 
       
  2982 	//two drivers + passangers killed in train v
       
  2983 	num = 2 + CountPassengersInTrain(v);
       
  2984 	if (!(coll->vehstatus & VS_CRASHED))
       
  2985 		//two drivers + passangers killed in train coll (if it was not crashed already)
       
  2986 		num += 2 + CountPassengersInTrain(coll);
       
  2987 
       
  2988 	SetVehicleCrashed(v);
       
  2989 	if (IsFrontEngine(coll)) SetVehicleCrashed(coll);
       
  2990 
       
  2991 	SetDParam(0, num);
       
  2992 	AddNewsItem(STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL,
       
  2993 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ACCIDENT, 0),
       
  2994 		v->index,
       
  2995 		0
       
  2996 	);
       
  2997 
       
  2998 	ModifyStationRatingAround(v->tile, v->owner, -160, 30);
       
  2999 	SndPlayVehicleFx(SND_13_BIG_CRASH, v);
       
  3000 }
       
  3001 
       
  3002 typedef struct VehicleAtSignalData {
       
  3003 	TileIndex tile;
       
  3004 	Direction direction;
       
  3005 } VehicleAtSignalData;
       
  3006 
       
  3007 static void *CheckVehicleAtSignal(Vehicle *v, void *data)
       
  3008 {
       
  3009 	const VehicleAtSignalData* vasd = data;
       
  3010 
       
  3011 	if (v->type == VEH_Train && IsFrontEngine(v) && v->tile == vasd->tile) {
       
  3012 		DirDiff diff = ChangeDirDiff(DirDifference(v->direction, vasd->direction), DIRDIFF_90RIGHT);
       
  3013 
       
  3014 		if (diff == DIRDIFF_90RIGHT || (v->cur_speed <= 5 && diff <= DIRDIFF_REVERSE)) return v;
       
  3015 	}
       
  3016 	return NULL;
       
  3017 }
       
  3018 
       
  3019 static void TrainController(Vehicle *v, bool update_image)
       
  3020 {
       
  3021 	Vehicle *prev;
       
  3022 	GetNewVehiclePosResult gp;
       
  3023 	uint32 r, tracks,ts;
       
  3024 	int i;
       
  3025 	DiagDirection enterdir;
       
  3026 	Direction dir;
       
  3027 	Direction newdir;
       
  3028 	Direction chosen_dir;
       
  3029 	byte chosen_track;
       
  3030 	byte old_z;
       
  3031 
       
  3032 	/* For every vehicle after and including the given vehicle */
       
  3033 	for (prev = GetPrevVehicleInChain(v); v != NULL; prev = v, v = v->next) {
       
  3034 
       
  3035 		bool in_tunnel_or_bridge = (v->u.rail.track == 0x40);
       
  3036 		bool entering_new_tile;
       
  3037 
       
  3038 		BeginVehicleMove(v);
       
  3039 
       
  3040 		entering_new_tile = !GetNewVehiclePos(v, &gp);
       
  3041 
       
  3042 		if (in_tunnel_or_bridge) {
       
  3043 			uint32 res;
       
  3044 			/* in tunnel or on a bridge */
       
  3045 
       
  3046 			SetSpeedLimitOnBridge(v);
       
  3047 
       
  3048 			if (!(IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) || !((res = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y)) & 0x4)) {
       
  3049 				/* stay in tunnel/bridge wormhole */
       
  3050 				v->x_pos = gp.x;
       
  3051 				v->y_pos = gp.y;
       
  3052 				VehiclePositionChanged(v);
       
  3053 				if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
       
  3054 				continue;
       
  3055 			}
       
  3056 			/* left tunnel/bridge wormhole */
       
  3057 			dir = v->direction;
       
  3058 			enterdir = INVALID_DIAGDIR;
       
  3059 			if (IsBridgeTile(gp.new_tile) && res & 0x4) {
       
  3060 				/* ok we have just left the bridge (because the status was "onbridge" before and we got
       
  3061 				a return value of 4 from VehicleEnterTile. we know the enterdir from the bridge ramp
       
  3062 				direction, and act as if we entered the tile normally (hence the goto) */
       
  3063 				dir = v->direction;
       
  3064 				enterdir = ReverseDiagDir(GetBridgeRampDirection(gp.new_tile));
       
  3065 				in_tunnel_or_bridge = false;
       
  3066 			}
       
  3067 		} else {
       
  3068 			/* Not inside tunnel */
       
  3069 			if (!entering_new_tile) {
       
  3070 				/* Staying in the old tile */
       
  3071 				if (v->u.rail.track == 0x80) {
       
  3072 					/* inside depot */
       
  3073 					gp.x = v->x_pos;
       
  3074 					gp.y = v->y_pos;
       
  3075 				} else {
       
  3076 					/* is not inside depot */
       
  3077 
       
  3078 					if (!TrainCheckIfLineEnds(v)) return;
       
  3079 
       
  3080 					r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
       
  3081 					if (r & 0x8) {
       
  3082 						DEBUG(misc, 2, "%x & 0x8 (in tile)", r);
       
  3083 						goto invalid_rail;
       
  3084 					}
       
  3085 					if (r & 0x2) {
       
  3086 						TrainEnterStation(v, r >> 8);
       
  3087 						return;
       
  3088 					}
       
  3089 
       
  3090 					if (v->current_order.type == OT_LEAVESTATION) {
       
  3091 						v->current_order.type = OT_NOTHING;
       
  3092 						v->current_order.flags = 0;
       
  3093 						InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
       
  3094 					}
       
  3095 				}
       
  3096 			} else {
       
  3097 				/* A new tile is about to be entered normally (not from bridge wormhole to ramp) */
       
  3098 				/* Determine what direction we're entering the new tile from */
       
  3099 				dir = GetNewVehicleDirectionByTile(gp.new_tile, gp.old_tile);
       
  3100 				enterdir = DirToDiagDir(dir);
       
  3101 				assert(enterdir==0 || enterdir==1 || enterdir==2 || enterdir==3);
       
  3102 			}
       
  3103 		}
       
  3104 		if (entering_new_tile && !in_tunnel_or_bridge) {
       
  3105 			/* A new tile is about to be entered. */
       
  3106 			byte bits;
       
  3107 
       
  3108 			/* Get the status of the tracks in the new tile and mask
       
  3109 			 * away the bits that aren't reachable. */
       
  3110 			ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL) & _reachable_tracks[enterdir];
       
  3111 
       
  3112 			/* Combine the from & to directions.
       
  3113 			 * Now, the lower byte contains the track status, and the byte at bit 16 contains
       
  3114 			 * the signal status. */
       
  3115 			tracks = ts | (ts >> 8);
       
  3116 			bits = tracks & 0xFF;
       
  3117 			if ((_patches.new_pathfinding_all || _patches.yapf.rail_use_yapf) && _patches.forbid_90_deg && prev == NULL) {
       
  3118 				/* We allow wagons to make 90 deg turns, because forbid_90_deg
       
  3119 				 * can be switched on halfway a turn */
       
  3120 				bits &= ~TrackCrossesTracks(FIND_FIRST_BIT(v->u.rail.track));
       
  3121 			}
       
  3122 
       
  3123 			if (bits == 0) {
       
  3124 				DEBUG(misc, 2, "%x == 0", bits);
       
  3125 				goto invalid_rail;
       
  3126 			}
       
  3127 
       
  3128 			/* Check if the new tile contrains tracks that are compatible
       
  3129 			 * with the current train, if not, bail out. */
       
  3130 			if (!CheckCompatibleRail(v, gp.new_tile)) {
       
  3131 				DEBUG(misc, 2, "!CheckCompatibleRail(%p, %x)", v, gp.new_tile);
       
  3132 				goto invalid_rail;
       
  3133 			}
       
  3134 
       
  3135 			if (prev == NULL) {
       
  3136 				/* Currently the locomotive is active. Determine which one of the
       
  3137 				 * available tracks to choose */
       
  3138 				chosen_track = 1 << ChooseTrainTrack(v, gp.new_tile, enterdir, bits);
       
  3139 				assert(chosen_track & tracks);
       
  3140 
       
  3141 				/* Check if it's a red signal and that force proceed is not clicked. */
       
  3142 				if ( (tracks>>16)&chosen_track && v->u.rail.force_proceed == 0) goto red_light;
       
  3143 			} else {
       
  3144 				static byte _matching_tracks[8] = {0x30, 1, 0xC, 2, 0x30, 1, 0xC, 2};
       
  3145 
       
  3146 				/* The wagon is active, simply follow the prev vehicle. */
       
  3147 				chosen_track = (byte)(_matching_tracks[GetDirectionToVehicle(prev, gp.x, gp.y)] & bits);
       
  3148 			}
       
  3149 
       
  3150 			/* make sure chosen track is a valid track */
       
  3151 			assert(chosen_track==1 || chosen_track==2 || chosen_track==4 || chosen_track==8 || chosen_track==16 || chosen_track==32);
       
  3152 
       
  3153 			/* Update XY to reflect the entrance to the new tile, and select the direction to use */
       
  3154 			{
       
  3155 				const byte *b = _initial_tile_subcoord[FIND_FIRST_BIT(chosen_track)][enterdir];
       
  3156 				gp.x = (gp.x & ~0xF) | b[0];
       
  3157 				gp.y = (gp.y & ~0xF) | b[1];
       
  3158 				chosen_dir = b[2];
       
  3159 			}
       
  3160 
       
  3161 			/* Call the landscape function and tell it that the vehicle entered the tile */
       
  3162 			r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
       
  3163 			if (r & 0x8) {
       
  3164 				DEBUG(misc, 2, "%x & 0x8 (new tile)", r);
       
  3165 				goto invalid_rail;
       
  3166 			}
       
  3167 
       
  3168 			if (IsLevelCrossingTile(v->tile) && v->next == NULL) {
       
  3169 				UnbarCrossing(v->tile);
       
  3170 				MarkTileDirtyByTile(v->tile);
       
  3171 			}
       
  3172 
       
  3173 			if (IsFrontEngine(v)) v->load_unload_time_rem = 0;
       
  3174 
       
  3175 			if (!(r&0x4)) {
       
  3176 				v->tile = gp.new_tile;
       
  3177 
       
  3178 				if (GetTileRailType(gp.new_tile, chosen_track) != GetTileRailType(gp.old_tile, v->u.rail.track)) {
       
  3179 					TrainPowerChanged(GetFirstVehicleInChain(v));
       
  3180 				}
       
  3181 
       
  3182 				v->u.rail.track = chosen_track;
       
  3183 				assert(v->u.rail.track);
       
  3184 			}
       
  3185 
       
  3186 			if (IsFrontEngine(v)) TrainMovedChangeSignals(gp.new_tile, enterdir);
       
  3187 
       
  3188 			/* Signals can only change when the first
       
  3189 			 * (above) or the last vehicle moves. */
       
  3190 			if (v->next == NULL)
       
  3191 				TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir));
       
  3192 
       
  3193 			if (prev == NULL) AffectSpeedByDirChange(v, chosen_dir);
       
  3194 
       
  3195 			v->direction = chosen_dir;
       
  3196 		}
       
  3197 
       
  3198 		/* update image of train, as well as delta XY */
       
  3199 		newdir = GetNewVehicleDirection(v, gp.x, gp.y);
       
  3200 		UpdateTrainDeltaXY(v, newdir);
       
  3201 		if (update_image) v->cur_image = GetTrainImage(v, newdir);
       
  3202 
       
  3203 		v->x_pos = gp.x;
       
  3204 		v->y_pos = gp.y;
       
  3205 
       
  3206 		/* update the Z position of the vehicle */
       
  3207 		old_z = AfterSetTrainPos(v, (gp.new_tile != gp.old_tile));
       
  3208 
       
  3209 		if (prev == NULL) {
       
  3210 			/* This is the first vehicle in the train */
       
  3211 			AffectSpeedByZChange(v, old_z);
       
  3212 		}
       
  3213 	}
       
  3214 	return;
       
  3215 
       
  3216 invalid_rail:
       
  3217 	/* We've reached end of line?? */
       
  3218 	if (prev != NULL) error("!Disconnecting train");
       
  3219 	goto reverse_train_direction;
       
  3220 
       
  3221 red_light: {
       
  3222 	/* We're in front of a red signal ?? */
       
  3223 		/* find the first set bit in ts. need to do it in 2 steps, since
       
  3224 		 * FIND_FIRST_BIT only handles 6 bits at a time. */
       
  3225 		i = FindFirstBit2x64(ts);
       
  3226 
       
  3227 		if (!HasSignalOnTrackdir(gp.new_tile, ReverseTrackdir(i))) {
       
  3228 			v->cur_speed = 0;
       
  3229 			v->subspeed = 0;
       
  3230 			v->progress = 255 - 100;
       
  3231 			if (++v->load_unload_time_rem < _patches.wait_oneway_signal * 20) return;
       
  3232 		} else if (HasSignalOnTrackdir(gp.new_tile, i)){
       
  3233 			v->cur_speed = 0;
       
  3234 			v->subspeed = 0;
       
  3235 			v->progress = 255-10;
       
  3236 			if (++v->load_unload_time_rem < _patches.wait_twoway_signal * 73) {
       
  3237 				TileIndex o_tile = gp.new_tile + TileOffsByDiagDir(enterdir);
       
  3238 				VehicleAtSignalData vasd;
       
  3239 				vasd.tile = o_tile;
       
  3240 				vasd.direction = ReverseDir(dir);
       
  3241 
       
  3242 				/* check if a train is waiting on the other side */
       
  3243 				if (VehicleFromPos(o_tile, &vasd, CheckVehicleAtSignal) == NULL) return;
       
  3244 			}
       
  3245 		}
       
  3246 	}
       
  3247 
       
  3248 reverse_train_direction:
       
  3249 	v->load_unload_time_rem = 0;
       
  3250 	v->cur_speed = 0;
       
  3251 	v->subspeed = 0;
       
  3252 	ReverseTrainDirection(v);
       
  3253 }
       
  3254 
       
  3255 extern TileIndex CheckTunnelBusy(TileIndex tile, uint *length);
       
  3256 
       
  3257 /**
       
  3258  * Deletes/Clears the last wagon of a crashed train. It takes the engine of the
       
  3259  * train, then goes to the last wagon and deletes that. Each call to this function
       
  3260  * will remove the last wagon of a crashed train. If this wagon was on a crossing,
       
  3261  * or inside a tunnel, recalculate the signals as they might need updating
       
  3262  * @param v the @Vehicle of which last wagon is to be removed
       
  3263  */
       
  3264 static void DeleteLastWagon(Vehicle *v)
       
  3265 {
       
  3266 	Vehicle *u = v;
       
  3267 
       
  3268 	/* Go to the last wagon and delete the link pointing there
       
  3269 	 * *u is then the one-before-last wagon, and *v the last
       
  3270 	 * one which will physicially be removed */
       
  3271 	for (; v->next != NULL; v = v->next) u = v;
       
  3272 	u->next = NULL;
       
  3273 
       
  3274 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
       
  3275 	DeleteWindowById(WC_VEHICLE_VIEW, v->index);
       
  3276 	RebuildVehicleLists();
       
  3277 	InvalidateWindow(WC_COMPANY, v->owner);
       
  3278 
       
  3279 	BeginVehicleMove(v);
       
  3280 	EndVehicleMove(v);
       
  3281 	DeleteVehicle(v);
       
  3282 
       
  3283 	if (!(v->u.rail.track & 0xC0))
       
  3284 		SetSignalsOnBothDir(v->tile, FIND_FIRST_BIT(v->u.rail.track));
       
  3285 
       
  3286 	/* Check if the wagon was on a road/rail-crossing and disable it if no
       
  3287 	 * others are on it */
       
  3288 	DisableTrainCrossing(v->tile);
       
  3289 
       
  3290 	if ( (v->u.rail.track == 0x40 && v->vehstatus & VS_HIDDEN) ) { // inside a tunnel
       
  3291 		TileIndex endtile = CheckTunnelBusy(v->tile, NULL);
       
  3292 
       
  3293 		if (endtile == INVALID_TILE) return; // tunnel is busy (error returned)
       
  3294 
       
  3295 		switch (v->direction) {
       
  3296 			case 1:
       
  3297 			case 5:
       
  3298 				SetSignalsOnBothDir(v->tile, 0);
       
  3299 				SetSignalsOnBothDir(endtile, 0);
       
  3300 				break;
       
  3301 
       
  3302 			case 3:
       
  3303 			case 7:
       
  3304 				SetSignalsOnBothDir(v->tile, 1);
       
  3305 				SetSignalsOnBothDir(endtile, 1);
       
  3306 				break;
       
  3307 
       
  3308 			default:
       
  3309 				break;
       
  3310 		}
       
  3311 	}
       
  3312 }
       
  3313 
       
  3314 static void ChangeTrainDirRandomly(Vehicle *v)
       
  3315 {
       
  3316 	static const DirDiff delta[] = {
       
  3317 		DIRDIFF_45LEFT, DIRDIFF_SAME, DIRDIFF_SAME, DIRDIFF_45RIGHT
       
  3318 	};
       
  3319 
       
  3320 	do {
       
  3321 		/* We don't need to twist around vehicles if they're not visible */
       
  3322 		if (!(v->vehstatus & VS_HIDDEN)) {
       
  3323 			v->direction = ChangeDir(v->direction, delta[GB(Random(), 0, 2)]);
       
  3324 			BeginVehicleMove(v);
       
  3325 			UpdateTrainDeltaXY(v, v->direction);
       
  3326 			v->cur_image = GetTrainImage(v, v->direction);
       
  3327 			/* Refrain from updating the z position of the vehicle when on
       
  3328 			   a bridge, because AfterSetTrainPos will put the vehicle under
       
  3329 			   the bridge in that case */
       
  3330 			if (!(v->u.rail.track & 0x40)) AfterSetTrainPos(v, false);
       
  3331 		}
       
  3332 	} while ((v = v->next) != NULL);
       
  3333 }
       
  3334 
       
  3335 static void HandleCrashedTrain(Vehicle *v)
       
  3336 {
       
  3337 	int state = ++v->u.rail.crash_anim_pos;
       
  3338 	uint32 r;
       
  3339 	Vehicle *u;
       
  3340 
       
  3341 	if (state == 4 && !(v->u.rail.track & VS_HIDDEN)) {
       
  3342 		CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
       
  3343 	}
       
  3344 
       
  3345 	if (state <= 200 && CHANCE16R(1, 7, r)) {
       
  3346 		int index = (r * 10 >> 16);
       
  3347 
       
  3348 		u = v;
       
  3349 		do {
       
  3350 			if (--index < 0) {
       
  3351 				r = Random();
       
  3352 
       
  3353 				CreateEffectVehicleRel(u,
       
  3354 					GB(r,  8, 3) + 2,
       
  3355 					GB(r, 16, 3) + 2,
       
  3356 					GB(r,  0, 3) + 5,
       
  3357 					EV_EXPLOSION_SMALL);
       
  3358 				break;
       
  3359 			}
       
  3360 		} while ((u = u->next) != NULL);
       
  3361 	}
       
  3362 
       
  3363 	if (state <= 240 && !(v->tick_counter & 3)) ChangeTrainDirRandomly(v);
       
  3364 
       
  3365 	if (state >= 4440 && !(v->tick_counter&0x1F)) {
       
  3366 		DeleteLastWagon(v);
       
  3367 		InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train);
       
  3368 	}
       
  3369 }
       
  3370 
       
  3371 static void HandleBrokenTrain(Vehicle *v)
       
  3372 {
       
  3373 	if (v->breakdown_ctr != 1) {
       
  3374 		v->breakdown_ctr = 1;
       
  3375 		v->cur_speed = 0;
       
  3376 
       
  3377 		if (v->breakdowns_since_last_service != 255)
       
  3378 			v->breakdowns_since_last_service++;
       
  3379 
       
  3380 		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
       
  3381 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
       
  3382 
       
  3383 		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
       
  3384 			SndPlayVehicleFx((_opt.landscape != LT_CANDY) ?
       
  3385 				SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
       
  3386 		}
       
  3387 
       
  3388 		if (!(v->vehstatus & VS_HIDDEN)) {
       
  3389 			Vehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
       
  3390 			if (u != NULL) u->u.special.unk0 = v->breakdown_delay * 2;
       
  3391 		}
       
  3392 	}
       
  3393 
       
  3394 	if (!(v->tick_counter & 3)) {
       
  3395 		if (!--v->breakdown_delay) {
       
  3396 			v->breakdown_ctr = 0;
       
  3397 			InvalidateWindow(WC_VEHICLE_VIEW, v->index);
       
  3398 		}
       
  3399 	}
       
  3400 }
       
  3401 
       
  3402 static const byte _breakdown_speeds[16] = {
       
  3403 	225, 210, 195, 180, 165, 150, 135, 120, 105, 90, 75, 60, 45, 30, 15, 15
       
  3404 };
       
  3405 
       
  3406 static bool TrainCheckIfLineEnds(Vehicle *v)
       
  3407 {
       
  3408 	TileIndex tile;
       
  3409 	uint x,y;
       
  3410 	uint16 break_speed;
       
  3411 	DiagDirection dir;
       
  3412 	int t;
       
  3413 	uint32 ts;
       
  3414 
       
  3415 	t = v->breakdown_ctr;
       
  3416 	if (t > 1) {
       
  3417 		v->vehstatus |= VS_TRAIN_SLOWING;
       
  3418 
       
  3419 		break_speed = _breakdown_speeds[GB(~t, 4, 4)];
       
  3420 		if (break_speed < v->cur_speed) v->cur_speed = break_speed;
       
  3421 	} else {
       
  3422 		v->vehstatus &= ~VS_TRAIN_SLOWING;
       
  3423 	}
       
  3424 
       
  3425 	if (v->u.rail.track & 0x40) return true; // exit if inside a tunnel
       
  3426 	if (v->u.rail.track & 0x80) return true; // exit if inside a depot
       
  3427 
       
  3428 	tile = v->tile;
       
  3429 
       
  3430 	if (IsTileType(tile, MP_TUNNEL) && DiagDirToDir(GetTunnelDirection(tile)) == v->direction) return true;
       
  3431 
       
  3432 	if (IsTileType(tile, MP_RAILWAY_BRIDGE)) {
       
  3433 		/* on a bridge ramp, we can always access the bridge body if we are driving in the right direction */
       
  3434 		DiagDirection dir = GetBridgeRampDirection(tile);
       
  3435 		Direction vdir = v->direction;
       
  3436 
       
  3437 		switch (dir) {
       
  3438 			/* XXX - Isn't there a simpler way to do this? */
       
  3439 			case DIAGDIR_NE: if (vdir == DIR_N || vdir == DIR_NE || vdir == DIR_E) return true; break;
       
  3440 			case DIAGDIR_SE: if (vdir == DIR_S || vdir == DIR_SE || vdir == DIR_E) return true; break;
       
  3441 			case DIAGDIR_SW: if (vdir == DIR_S || vdir == DIR_SW || vdir == DIR_W) return true; break;
       
  3442 			case DIAGDIR_NW: if (vdir == DIR_N || vdir == DIR_NW || vdir == DIR_W) return true; break;
       
  3443 			default: NOT_REACHED();
       
  3444 		}
       
  3445 	}
       
  3446 
       
  3447 	// depot?
       
  3448 	/* XXX -- When enabled, this makes it possible to crash trains of others
       
  3449 	     (by building a depot right against a station) */
       
  3450 /*	if (IsTileType(tile, MP_RAILWAY) && GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT)
       
  3451 		return true;*/
       
  3452 
       
  3453 	/* Determine the non-diagonal direction in which we will exit this tile */
       
  3454 	dir = DirToDiagDir(v->direction);
       
  3455 	if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[dir]) {
       
  3456 		dir = ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT);
       
  3457 	}
       
  3458 	/* Calculate next tile */
       
  3459 	tile += TileOffsByDiagDir(dir);
       
  3460 	// determine the track status on the next tile.
       
  3461 	ts = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _reachable_tracks[dir];
       
  3462 
       
  3463 	/* Calc position within the current tile ?? */
       
  3464 	x = v->x_pos & 0xF;
       
  3465 	y = v->y_pos & 0xF;
       
  3466 
       
  3467 	switch (v->direction) {
       
  3468 		case DIR_N : x = ~x + ~y + 24; break;
       
  3469 		case DIR_NW: x = y;            /* FALLTHROUGH */
       
  3470 		case DIR_NE: x = ~x + 16;      break;
       
  3471 		case DIR_E : x = ~x + y + 8;   break;
       
  3472 		case DIR_SE: x = y;            break;
       
  3473 		case DIR_S : x = x + y - 8;    break;
       
  3474 		case DIR_W : x = ~y + x + 8;   break;
       
  3475 	}
       
  3476 
       
  3477 	if (GB(ts, 0, 16) != 0) {
       
  3478 		/* If we approach a rail-piece which we can't enter, or the back of a depot, don't enter it! */
       
  3479 		if (x + 4 >= TILE_SIZE &&
       
  3480 				(!CheckCompatibleRail(v, tile) ||
       
  3481 				(IsTileDepotType(tile, TRANSPORT_RAIL) &&
       
  3482 				GetRailDepotDirection(tile) == dir))) {
       
  3483 			v->cur_speed = 0;
       
  3484 			ReverseTrainDirection(v);
       
  3485 			return false;
       
  3486 		}
       
  3487 		if ((ts &= (ts >> 16)) == 0) {
       
  3488 			// make a rail/road crossing red
       
  3489 			if (IsLevelCrossingTile(tile)) {
       
  3490 				if (!IsCrossingBarred(tile)) {
       
  3491 					BarCrossing(tile);
       
  3492 					SndPlayVehicleFx(SND_0E_LEVEL_CROSSING, v);
       
  3493 					MarkTileDirtyByTile(tile);
       
  3494 				}
       
  3495 			}
       
  3496 			return true;
       
  3497 		}
       
  3498 	} else if (x + 4 >= TILE_SIZE) {
       
  3499 		v->cur_speed = 0;
       
  3500 		ReverseTrainDirection(v);
       
  3501 		return false;
       
  3502 	}
       
  3503 
       
  3504 	// slow down
       
  3505 	v->vehstatus |= VS_TRAIN_SLOWING;
       
  3506 	break_speed = _breakdown_speeds[x & 0xF];
       
  3507 	if (!(v->direction & 1)) break_speed >>= 1;
       
  3508 	if (break_speed < v->cur_speed) v->cur_speed = break_speed;
       
  3509 
       
  3510 	return true;
       
  3511 }
       
  3512 
       
  3513 static void TrainLocoHandler(Vehicle *v, bool mode)
       
  3514 {
       
  3515 	int j;
       
  3516 
       
  3517 	/* train has crashed? */
       
  3518 	if (v->u.rail.crash_anim_pos != 0) {
       
  3519 		if (!mode) HandleCrashedTrain(v);
       
  3520 		return;
       
  3521 	}
       
  3522 
       
  3523 	if (v->u.rail.force_proceed != 0) v->u.rail.force_proceed--;
       
  3524 
       
  3525 	/* train is broken down? */
       
  3526 	if (v->breakdown_ctr != 0) {
       
  3527 		if (v->breakdown_ctr <= 2) {
       
  3528 			HandleBrokenTrain(v);
       
  3529 			return;
       
  3530 		}
       
  3531 		v->breakdown_ctr--;
       
  3532 	}
       
  3533 
       
  3534 	if (HASBIT(v->u.rail.flags, VRF_REVERSING) && v->cur_speed == 0) {
       
  3535 		ReverseTrainDirection(v);
       
  3536 	}
       
  3537 
       
  3538 	/* exit if train is stopped */
       
  3539 	if (v->vehstatus & VS_STOPPED && v->cur_speed == 0) return;
       
  3540 
       
  3541 	if (ProcessTrainOrder(v)) {
       
  3542 		v->load_unload_time_rem = 0;
       
  3543 		v->cur_speed = 0;
       
  3544 		v->subspeed = 0;
       
  3545 		ReverseTrainDirection(v);
       
  3546 		return;
       
  3547 	}
       
  3548 
       
  3549 	HandleTrainLoading(v, mode);
       
  3550 
       
  3551 	if (v->current_order.type == OT_LOADING) return;
       
  3552 
       
  3553 	if (CheckTrainStayInDepot(v)) return;
       
  3554 
       
  3555 	if (!mode) HandleLocomotiveSmokeCloud(v);
       
  3556 
       
  3557 	j = UpdateTrainSpeed(v);
       
  3558 	if (j == 0) {
       
  3559 		// if the vehicle has speed 0, update the last_speed field.
       
  3560 		if (v->cur_speed != 0) return;
       
  3561 	} else {
       
  3562 		TrainCheckIfLineEnds(v);
       
  3563 
       
  3564 		do {
       
  3565 			TrainController(v, true);
       
  3566 			CheckTrainCollision(v);
       
  3567 			if (v->cur_speed <= 0x100)
       
  3568 				break;
       
  3569 		} while (--j != 0);
       
  3570 	}
       
  3571 
       
  3572 	SetLastSpeed(v, v->cur_speed);
       
  3573 }
       
  3574 
       
  3575 
       
  3576 void Train_Tick(Vehicle *v)
       
  3577 {
       
  3578 	if (_age_cargo_skip_counter == 0 && v->cargo_days != 0xff)
       
  3579 		v->cargo_days++;
       
  3580 
       
  3581 	v->tick_counter++;
       
  3582 
       
  3583 	if (IsFrontEngine(v)) {
       
  3584 		TrainLocoHandler(v, false);
       
  3585 
       
  3586 		// make sure vehicle wasn't deleted.
       
  3587 		if (v->type == VEH_Train && IsFrontEngine(v))
       
  3588 			TrainLocoHandler(v, true);
       
  3589 	} else if (IsFreeWagon(v) && HASBITS(v->vehstatus, VS_CRASHED)) {
       
  3590 		// Delete flooded standalone wagon
       
  3591 		if (++v->u.rail.crash_anim_pos >= 4400)
       
  3592 			DeleteVehicle(v);
       
  3593 	}
       
  3594 }
       
  3595 
       
  3596 #define MAX_ACCEPTABLE_DEPOT_DIST 16
       
  3597 
       
  3598 static void CheckIfTrainNeedsService(Vehicle *v)
       
  3599 {
       
  3600 	const Depot* depot;
       
  3601 	TrainFindDepotData tfdd;
       
  3602 
       
  3603 	if (_patches.servint_trains == 0)                   return;
       
  3604 	if (!VehicleNeedsService(v))                        return;
       
  3605 	if (v->vehstatus & VS_STOPPED)                      return;
       
  3606 	if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
       
  3607 
       
  3608 	// Don't interfere with a depot visit scheduled by the user, or a
       
  3609 	// depot visit by the order list.
       
  3610 	if (v->current_order.type == OT_GOTO_DEPOT &&
       
  3611 			(v->current_order.flags & (OF_HALT_IN_DEPOT | OF_PART_OF_ORDERS)) != 0)
       
  3612 		return;
       
  3613 
       
  3614 	if (CheckTrainIsInsideDepot(v)) {
       
  3615 		VehicleServiceInDepot(v);
       
  3616 		return;
       
  3617 	}
       
  3618 
       
  3619 	tfdd = FindClosestTrainDepot(v, MAX_ACCEPTABLE_DEPOT_DIST);
       
  3620 	/* Only go to the depot if it is not too far out of our way. */
       
  3621 	if (tfdd.best_length == (uint)-1 || tfdd.best_length > MAX_ACCEPTABLE_DEPOT_DIST) {
       
  3622 		if (v->current_order.type == OT_GOTO_DEPOT) {
       
  3623 			/* If we were already heading for a depot but it has
       
  3624 			 * suddenly moved farther away, we continue our normal
       
  3625 			 * schedule? */
       
  3626 			v->current_order.type = OT_DUMMY;
       
  3627 			v->current_order.flags = 0;
       
  3628 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
       
  3629 		}
       
  3630 		return;
       
  3631 	}
       
  3632 
       
  3633 	depot = GetDepotByTile(tfdd.tile);
       
  3634 
       
  3635 	if (v->current_order.type == OT_GOTO_DEPOT &&
       
  3636 			v->current_order.dest != depot->index &&
       
  3637 			!CHANCE16(3, 16)) {
       
  3638 		return;
       
  3639 	}
       
  3640 
       
  3641 	v->current_order.type = OT_GOTO_DEPOT;
       
  3642 	v->current_order.flags = OF_NON_STOP;
       
  3643 	v->current_order.dest = depot->index;
       
  3644 	v->dest_tile = tfdd.tile;
       
  3645 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
       
  3646 }
       
  3647 
       
  3648 int32 GetTrainRunningCost(const Vehicle *v)
       
  3649 {
       
  3650 	int32 cost = 0;
       
  3651 
       
  3652 	do {
       
  3653 		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
       
  3654 		if (rvi->running_cost_base > 0)
       
  3655 			cost += rvi->running_cost_base * _price.running_rail[rvi->running_cost_class];
       
  3656 	} while ((v = GetNextVehicle(v)) != NULL);
       
  3657 
       
  3658 	return cost;
       
  3659 }
       
  3660 
       
  3661 void OnNewDay_Train(Vehicle *v)
       
  3662 {
       
  3663 	TileIndex tile;
       
  3664 
       
  3665 	if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
       
  3666 
       
  3667 	if (IsFrontEngine(v)) {
       
  3668 		CheckVehicleBreakdown(v);
       
  3669 		AgeVehicle(v);
       
  3670 
       
  3671 		CheckIfTrainNeedsService(v);
       
  3672 
       
  3673 		CheckOrders(v);
       
  3674 
       
  3675 		/* update destination */
       
  3676 		if (v->current_order.type == OT_GOTO_STATION &&
       
  3677 				(tile = GetStation(v->current_order.dest)->train_tile) != 0) {
       
  3678 			v->dest_tile = tile;
       
  3679 		}
       
  3680 
       
  3681 		if ((v->vehstatus & VS_STOPPED) == 0) {
       
  3682 			/* running costs */
       
  3683 			int32 cost = GetTrainRunningCost(v) / 364;
       
  3684 
       
  3685 			v->profit_this_year -= cost >> 8;
       
  3686 
       
  3687 			SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
       
  3688 			SubtractMoneyFromPlayerFract(v->owner, cost);
       
  3689 
       
  3690 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
       
  3691 			InvalidateWindowClasses(WC_TRAINS_LIST);
       
  3692 		}
       
  3693 	}
       
  3694 }
       
  3695 
       
  3696 void TrainsYearlyLoop(void)
       
  3697 {
       
  3698 	Vehicle *v;
       
  3699 
       
  3700 	FOR_ALL_VEHICLES(v) {
       
  3701 		if (v->type == VEH_Train && IsFrontEngine(v)) {
       
  3702 
       
  3703 			// show warning if train is not generating enough income last 2 years (corresponds to a red icon in the vehicle list)
       
  3704 			if (_patches.train_income_warn && v->owner == _local_player && v->age >= 730 && v->profit_this_year < 0) {
       
  3705 				SetDParam(1, v->profit_this_year);
       
  3706 				SetDParam(0, v->unitnumber);
       
  3707 				AddNewsItem(
       
  3708 					STR_TRAIN_IS_UNPROFITABLE,
       
  3709 					NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0),
       
  3710 					v->index,
       
  3711 					0);
       
  3712 			}
       
  3713 
       
  3714 			v->profit_last_year = v->profit_this_year;
       
  3715 			v->profit_this_year = 0;
       
  3716 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
       
  3717 		}
       
  3718 	}
       
  3719 }
       
  3720 
       
  3721 
       
  3722 void InitializeTrains(void)
       
  3723 {
       
  3724 	_age_cargo_skip_counter = 1;
       
  3725 }
       
  3726 
       
  3727 /*
       
  3728  * Link front and rear multiheaded engines to each other
       
  3729  * This is done when loading a savegame
       
  3730  */
       
  3731 void ConnectMultiheadedTrains(void)
       
  3732 {
       
  3733 	Vehicle *v;
       
  3734 
       
  3735 	FOR_ALL_VEHICLES(v) {
       
  3736 		if (v->type == VEH_Train) {
       
  3737 			v->u.rail.other_multiheaded_part = NULL;
       
  3738 		}
       
  3739 	}
       
  3740 
       
  3741 	FOR_ALL_VEHICLES(v) {
       
  3742 		if (v->type == VEH_Train && IsFrontEngine(v)) {
       
  3743 			Vehicle *u = v;
       
  3744 
       
  3745 			BEGIN_ENUM_WAGONS(u) {
       
  3746 				if (u->u.rail.other_multiheaded_part != NULL) continue; // we already linked this one
       
  3747 
       
  3748 				if (IsMultiheaded(u)) {
       
  3749 					if (!IsTrainEngine(u)) {
       
  3750 						/* we got a rear car without a front car. We will convert it to a front one */
       
  3751 						SetTrainEngine(u);
       
  3752 						u->spritenum--;
       
  3753 					}
       
  3754 
       
  3755 					{
       
  3756 						Vehicle *w;
       
  3757 
       
  3758 						for (w = u->next; w != NULL && (w->engine_type != u->engine_type || w->u.rail.other_multiheaded_part != NULL); w = GetNextVehicle(w));
       
  3759 						if (w != NULL) {
       
  3760 							/* we found a car to partner with this engine. Now we will make sure it face the right way */
       
  3761 							if (IsTrainEngine(w)) {
       
  3762 								ClearTrainEngine(w);
       
  3763 								w->spritenum++;
       
  3764 							}
       
  3765 						}
       
  3766 
       
  3767 						if (w != NULL) {
       
  3768 							w->u.rail.other_multiheaded_part = u;
       
  3769 							u->u.rail.other_multiheaded_part = w;
       
  3770 						} else {
       
  3771 							/* we got a front car and no rear cars. We will fake this one for forget that it should have been multiheaded */
       
  3772 							ClearMultiheaded(u);
       
  3773 						}
       
  3774 					}
       
  3775 				}
       
  3776 			} END_ENUM_WAGONS(u)
       
  3777 		}
       
  3778 	}
       
  3779 }
       
  3780 
       
  3781 /*
       
  3782  *  Converts all trains to the new subtype format introduced in savegame 16.2
       
  3783  *  It also links multiheaded engines or make them forget they are multiheaded if no suitable partner is found
       
  3784  */
       
  3785 void ConvertOldMultiheadToNew(void)
       
  3786 {
       
  3787 	Vehicle *v;
       
  3788 	FOR_ALL_VEHICLES(v) {
       
  3789 		if (v->type == VEH_Train) {
       
  3790 			SETBIT(v->subtype, 7); // indicates that it's the old format and needs to be converted in the next loop
       
  3791 		}
       
  3792 	}
       
  3793 
       
  3794 	FOR_ALL_VEHICLES(v) {
       
  3795 		if (v->type == VEH_Train) {
       
  3796 			if (HASBIT(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) {
       
  3797 				Vehicle *u = v;
       
  3798 
       
  3799 				BEGIN_ENUM_WAGONS(u) {
       
  3800 					const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
       
  3801 
       
  3802 					CLRBIT(u->subtype, 7);
       
  3803 					switch (u->subtype) {
       
  3804 						case 0: /* TS_Front_Engine */
       
  3805 							if (rvi->flags & RVI_MULTIHEAD) SetMultiheaded(u);
       
  3806 							SetFrontEngine(u);
       
  3807 							SetTrainEngine(u);
       
  3808 							break;
       
  3809 
       
  3810 						case 1: /* TS_Artic_Part */
       
  3811 							u->subtype = 0;
       
  3812 							SetArticulatedPart(u);
       
  3813 							break;
       
  3814 
       
  3815 						case 2: /* TS_Not_First */
       
  3816 							u->subtype = 0;
       
  3817 							if (rvi->flags & RVI_WAGON) {
       
  3818 								// normal wagon
       
  3819 								SetTrainWagon(u);
       
  3820 								break;
       
  3821 							}
       
  3822 							if (rvi->flags & RVI_MULTIHEAD && rvi->image_index == u->spritenum - 1) {
       
  3823 								// rear end of a multiheaded engine
       
  3824 								SetMultiheaded(u);
       
  3825 								break;
       
  3826 							}
       
  3827 							if (rvi->flags & RVI_MULTIHEAD) SetMultiheaded(u);
       
  3828 							SetTrainEngine(u);
       
  3829 							break;
       
  3830 
       
  3831 						case 4: /* TS_Free_Car */
       
  3832 							u->subtype = 0;
       
  3833 							SetTrainWagon(u);
       
  3834 							SetFreeWagon(u);
       
  3835 							break;
       
  3836 						default: NOT_REACHED(); break;
       
  3837 					}
       
  3838 				} END_ENUM_WAGONS(u)
       
  3839 			}
       
  3840 		}
       
  3841 	}
       
  3842 }