train_cmd.c
changeset 2676 59b65b4fb480
parent 2666 ae363cb59955
child 2677 ad9006e0bbf4
equal deleted inserted replaced
2675:010fe459fc1d 2676:59b65b4fb480
    20 #include "sound.h"
    20 #include "sound.h"
    21 #include "depot.h"
    21 #include "depot.h"
    22 #include "debug.h"
    22 #include "debug.h"
    23 #include "waypoint.h"
    23 #include "waypoint.h"
    24 #include "vehicle_gui.h"
    24 #include "vehicle_gui.h"
    25 
    25 #include "train.h"
    26 #define IS_FIRSTHEAD_SPRITE(spritenum) \
       
    27 	(is_custom_sprite(spritenum) ? IS_CUSTOM_FIRSTHEAD_SPRITE(spritenum) : _engine_sprite_add[spritenum] == 0)
       
    28 
    26 
    29 static bool TrainCheckIfLineEnds(Vehicle *v);
    27 static bool TrainCheckIfLineEnds(Vehicle *v);
    30 static void TrainController(Vehicle *v);
    28 static void TrainController(Vehicle *v);
    31 
    29 
    32 static const byte _vehicle_initial_x_fract[4] = {10,8,4,8};
    30 static const byte _vehicle_initial_x_fract[4] = {10,8,4,8};
    48 		uint16 vweight = 0;
    46 		uint16 vweight = 0;
    49 
    47 
    50 		vweight += (_cargoc.weights[u->cargo_type] * u->cargo_count) / 16;
    48 		vweight += (_cargoc.weights[u->cargo_type] * u->cargo_count) / 16;
    51 
    49 
    52 		// Vehicle weight is not added for articulated parts.
    50 		// Vehicle weight is not added for articulated parts.
    53 		if (u->subtype != TS_Artic_Part) {
    51 		if (!IsArticulatedPart(u)) {
    54 			// vehicle weight is the sum of the weight of the vehicle and the weight of its cargo
    52 			// vehicle weight is the sum of the weight of the vehicle and the weight of its cargo
    55 			vweight += rvi->weight;
    53 			vweight += rvi->weight;
    56 
    54 
    57 			// powered wagons have extra weight added
    55 			// powered wagons have extra weight added
    58 			if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON))
    56 			if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON))
    84 	uint32 power = 0;
    82 	uint32 power = 0;
    85 	EngineID first_engine;
    83 	EngineID first_engine;
    86 
    84 
    87 	assert(v->type == VEH_Train);
    85 	assert(v->type == VEH_Train);
    88 
    86 
    89 	assert(v->subtype == TS_Front_Engine || v->subtype == TS_Free_Car);
    87 	assert(IsFrontEngine(v) || IsFreeWagon(v));
    90 
    88 
    91 	rvi_v = RailVehInfo(v->engine_type);
    89 	rvi_v = RailVehInfo(v->engine_type);
    92 	first_engine = (v->subtype == TS_Front_Engine) ? v->engine_type : INVALID_VEHICLE;
    90 	first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_VEHICLE;
    93 	v->u.rail.cached_total_length = 0;
    91 	v->u.rail.cached_total_length = 0;
    94 
    92 
    95 	for (u = v; u != NULL; u = u->next) {
    93 	for (u = v; u != NULL; u = u->next) {
    96 		const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
    94 		const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
    97 		uint16 veh_len;
    95 		uint16 veh_len;
   100 		u->u.rail.first_engine = (v == u) ? INVALID_VEHICLE : first_engine;
    98 		u->u.rail.first_engine = (v == u) ? INVALID_VEHICLE : first_engine;
   101 
    99 
   102 		if (rvi_u->visual_effect != 0) {
   100 		if (rvi_u->visual_effect != 0) {
   103 			u->u.rail.cached_vis_effect = rvi_u->visual_effect;
   101 			u->u.rail.cached_vis_effect = rvi_u->visual_effect;
   104 		} else {
   102 		} else {
   105 			if (rvi_u->flags & RVI_WAGON || u->subtype == TS_Artic_Part) {
   103 			if (IsTrainWagon(u) || IsArticulatedPart(u)) {
   106 				// Wagons and articulated parts have no effect by default
   104 				// Wagons and articulated parts have no effect by default
   107 				u->u.rail.cached_vis_effect = 0x40;
   105 				u->u.rail.cached_vis_effect = 0x40;
   108 			} else if (rvi_u->engclass == 0) {
   106 			} else if (rvi_u->engclass == 0) {
   109 				// Steam is offset by -4 units
   107 				// Steam is offset by -4 units
   110 				u->u.rail.cached_vis_effect = 4;
   108 				u->u.rail.cached_vis_effect = 4;
   112 				// Diesel fumes and sparks come from the centre
   110 				// Diesel fumes and sparks come from the centre
   113 				u->u.rail.cached_vis_effect = 8;
   111 				u->u.rail.cached_vis_effect = 8;
   114 			}
   112 			}
   115 		}
   113 		}
   116 
   114 
   117 		if (u->subtype != TS_Artic_Part) {
   115 		if (!IsArticulatedPart(u)) {
   118 			// power is the sum of the powers of all engines and powered wagons in the consist
   116 			// power is the sum of the powers of all engines and powered wagons in the consist
   119 			power += rvi_u->power;
   117 			power += rvi_u->power;
   120 
   118 
   121 			// check if its a powered wagon
   119 			// check if its a powered wagon
   122 			CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON);
   120 			CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON);
   275 		}
   273 		}
   276 	}
   274 	}
   277 
   275 
   278 	max_speed += (max_speed / 2) * v->u.rail.railtype;
   276 	max_speed += (max_speed / 2) * v->u.rail.railtype;
   279 
   277 
   280 	if (IsTileType(v->tile, MP_STATION) && v->subtype == TS_Front_Engine) {
   278 	if (IsTileType(v->tile, MP_STATION) && IsFrontEngine(v)) {
   281 		if (TrainShouldStop(v, v->tile)) {
   279 		if (TrainShouldStop(v, v->tile)) {
   282 			int station_length = 0;
   280 			int station_length = 0;
   283 			TileIndex tile = v->tile;
   281 			TileIndex tile = v->tile;
   284 			int delta_v;
   282 			int delta_v;
   285 
   283 
   359 void UpdateTrainAcceleration(Vehicle *v)
   357 void UpdateTrainAcceleration(Vehicle *v)
   360 {
   358 {
   361 	uint power = 0;
   359 	uint power = 0;
   362 	uint weight = 0;
   360 	uint weight = 0;
   363 
   361 
   364 	assert(v->subtype == TS_Front_Engine);
   362 	assert(IsFrontEngine(v));
   365 
   363 
   366 	weight = v->u.rail.cached_weight;
   364 	weight = v->u.rail.cached_weight;
   367 	power = v->u.rail.cached_power;
   365 	power = v->u.rail.cached_power;
   368 	v->max_speed = v->u.rail.cached_max_speed;
   366 	v->max_speed = v->u.rail.cached_max_speed;
   369 
   367 
   489 		u->max_speed = 0;
   487 		u->max_speed = 0;
   490 		u->max_age = 0;
   488 		u->max_age = 0;
   491 		u->engine_type = engine_type;
   489 		u->engine_type = engine_type;
   492 		u->value = 0;
   490 		u->value = 0;
   493 		u->type = VEH_Train;
   491 		u->type = VEH_Train;
   494 		u->subtype = TS_Artic_Part;
   492 		u->subtype = 0;
       
   493 		SetArticulatedPart(u);
   495 		u->cur_image = 0xAC2;
   494 		u->cur_image = 0xAC2;
   496 
   495 
   497 		VehiclePositionChanged(u);
   496 		VehiclePositionChanged(u);
   498 	}
   497 	}
   499 }
   498 }
   529 
   528 
   530 			u = NULL;
   529 			u = NULL;
   531 
   530 
   532 			FOR_ALL_VEHICLES(w) {
   531 			FOR_ALL_VEHICLES(w) {
   533 				if (w->type == VEH_Train && w->tile == tile &&
   532 				if (w->type == VEH_Train && w->tile == tile &&
   534 				    w->subtype == TS_Free_Car && w->engine_type == engine) {
   533 				    IsFreeWagon(w) && w->engine_type == engine) {
   535 					u = GetLastVehicleInChain(w);
   534 					u = GetLastVehicleInChain(w);
   536 					break;
   535 					break;
   537 				}
   536 				}
   538 			}
   537 			}
   539 
   538 
   553 			v->owner = _current_player;
   552 			v->owner = _current_player;
   554 			v->z_height = 6;
   553 			v->z_height = 6;
   555 			v->u.rail.track = 0x80;
   554 			v->u.rail.track = 0x80;
   556 			v->vehstatus = VS_HIDDEN | VS_DEFPAL;
   555 			v->vehstatus = VS_HIDDEN | VS_DEFPAL;
   557 
   556 
   558 			v->subtype = TS_Free_Car;
   557 			v->subtype = 0;
       
   558 			SetTrainWagon(v);
   559 			if (u != NULL) {
   559 			if (u != NULL) {
   560 				u->next = v;
   560 				u->next = v;
   561 				v->subtype = TS_Not_First;
   561 			} else {
       
   562 				SetFreeWagon(v);
   562 			}
   563 			}
   563 
   564 
   564 			v->cargo_type = rvi->cargo_type;
   565 			v->cargo_type = rvi->cargo_type;
   565 			v->cargo_cap = rvi->capacity;
   566 			v->cargo_cap = rvi->capacity;
   566 			v->value = value;
   567 			v->value = value;
   591 static void NormalizeTrainVehInDepot(const Vehicle* u)
   592 static void NormalizeTrainVehInDepot(const Vehicle* u)
   592 {
   593 {
   593 	const Vehicle* v;
   594 	const Vehicle* v;
   594 
   595 
   595 	FOR_ALL_VEHICLES(v) {
   596 	FOR_ALL_VEHICLES(v) {
   596 		if (v->type == VEH_Train && v->subtype == TS_Free_Car &&
   597 		if (v->type == VEH_Train && IsFreeWagon(v) &&
   597 				v->tile == u->tile &&
   598 				v->tile == u->tile &&
   598 				v->u.rail.track == 0x80) {
   599 				v->u.rail.track == 0x80) {
   599 			if (DoCommandByTile(0, v->index | (u->index << 16), 1, DC_EXEC,
   600 			if (CmdFailed(DoCommandByTile(0, v->index | (u->index << 16), 1, DC_EXEC,
   600 					CMD_MOVE_RAIL_VEHICLE) == CMD_ERROR)
   601 					CMD_MOVE_RAIL_VEHICLE)))
   601 				break;
   602 				break;
   602 		}
   603 		}
   603 	}
   604 	}
   604 }
   605 }
   605 
   606 
   636 	u->y_pos = v->y_pos;
   637 	u->y_pos = v->y_pos;
   637 	u->z_pos = v->z_pos;
   638 	u->z_pos = v->z_pos;
   638 	u->z_height = 6;
   639 	u->z_height = 6;
   639 	u->u.rail.track = 0x80;
   640 	u->u.rail.track = 0x80;
   640 	u->vehstatus = v->vehstatus & ~VS_STOPPED;
   641 	u->vehstatus = v->vehstatus & ~VS_STOPPED;
   641 	u->subtype = TS_Not_First;
   642 	u->subtype = 0;
       
   643 	SetMultiheaded(u);
   642 	u->spritenum = v->spritenum + 1;
   644 	u->spritenum = v->spritenum + 1;
   643 	u->cargo_type = v->cargo_type;
   645 	u->cargo_type = v->cargo_type;
   644 	u->cargo_cap = v->cargo_cap;
   646 	u->cargo_cap = v->cargo_cap;
   645 	u->u.rail.railtype = v->u.rail.railtype;
   647 	u->u.rail.railtype = v->u.rail.railtype;
   646 	if (building) v->next = u;
   648 	if (building) v->next = u;
   748 			v->date_of_last_service = _date;
   750 			v->date_of_last_service = _date;
   749 			v->build_year = _cur_year;
   751 			v->build_year = _cur_year;
   750 			v->type = VEH_Train;
   752 			v->type = VEH_Train;
   751 			v->cur_image = 0xAC2;
   753 			v->cur_image = 0xAC2;
   752 
   754 
       
   755 			v->subtype = 0;
       
   756 			SetFrontEngine(v);
       
   757 			SetTrainEngine(v);
       
   758 
   753 			v->u.rail.shortest_platform[0] = 255;
   759 			v->u.rail.shortest_platform[0] = 255;
   754 			v->u.rail.shortest_platform[1] = 0;
   760 			v->u.rail.shortest_platform[1] = 0;
   755 
   761 
   756 			VehiclePositionChanged(v);
   762 			VehiclePositionChanged(v);
   757 
   763 
   758 			if (rvi->flags & RVI_MULTIHEAD && !HASBIT(p2, 0)) {
   764 			if (rvi->flags & RVI_MULTIHEAD && !HASBIT(p2, 0)) {
       
   765 				SetMultiheaded(v);
   759 				AddRearEngineToMultiheadedTrain(vl[0], vl[1], true);
   766 				AddRearEngineToMultiheadedTrain(vl[0], vl[1], true);
       
   767 				/* Now we need to link the front and rear engines together
       
   768 				 * other_multiheaded_part is the pointer that links to the other half of the engine
       
   769 				 * vl[0] is the front and vl[1] is the rear
       
   770 				 */
       
   771 				vl[0]->u.rail.other_multiheaded_part = vl[1];
       
   772 				vl[1]->u.rail.other_multiheaded_part = vl[0];
   760 			} else {
   773 			} else {
   761 				AddArticulatedParts(rvi, vl);
   774 				AddArticulatedParts(rvi, vl);
   762 			}
   775 			}
   763 
   776 
   764 			TrainConsistChanged(v);
   777 			TrainConsistChanged(v);
   798 
   811 
   799 	count = 0;
   812 	count = 0;
   800 	for (; v != NULL; v = v->next) {
   813 	for (; v != NULL; v = v->next) {
   801 		count++;
   814 		count++;
   802 		if (v->u.rail.track != 0x80 || v->tile != tile ||
   815 		if (v->u.rail.track != 0x80 || v->tile != tile ||
   803 				(v->subtype == TS_Front_Engine && !(v->vehstatus & VS_STOPPED))) {
   816 				(IsFrontEngine(v) && !(v->vehstatus & VS_STOPPED))) {
   804 			_error_message = STR_881A_TRAINS_CAN_ONLY_BE_ALTERED;
   817 			_error_message = STR_881A_TRAINS_CAN_ONLY_BE_ALTERED;
   805 			return -1;
   818 			return -1;
   806 		}
   819 		}
   807 	}
   820 	}
   808 
   821 
   822 	// unlinking the first vehicle of the chain?
   835 	// unlinking the first vehicle of the chain?
   823 	if (v == first) {
   836 	if (v == first) {
   824 		v = GetNextVehicle(v);
   837 		v = GetNextVehicle(v);
   825 		if (v == NULL) return NULL;
   838 		if (v == NULL) return NULL;
   826 
   839 
   827 		v->subtype = TS_Free_Car;
   840 		if (IsTrainWagon(v)) SetFreeWagon(v);
       
   841 
   828 		return v;
   842 		return v;
   829 	}
   843 	}
   830 
   844 
   831 	for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
   845 	for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
   832 	GetLastEnginePart(u)->next = GetNextVehicle(v);
   846 	GetLastEnginePart(u)->next = GetNextVehicle(v);
   838 	Vehicle *dst;
   852 	Vehicle *dst;
   839 	EngineID eng = src->engine_type;
   853 	EngineID eng = src->engine_type;
   840 	TileIndex tile = src->tile;
   854 	TileIndex tile = src->tile;
   841 
   855 
   842 	FOR_ALL_VEHICLES(dst) {
   856 	FOR_ALL_VEHICLES(dst) {
   843 		if (dst->type == VEH_Train && dst->subtype == TS_Free_Car &&
   857 		if (dst->type == VEH_Train && IsFreeWagon(dst) &&
   844 				dst->tile == tile) {
   858 				dst->tile == tile) {
   845 			// check so all vehicles in the line have the same engine.
   859 			// check so all vehicles in the line have the same engine.
   846 			Vehicle *v = dst;
   860 			Vehicle *v = dst;
   847 
   861 
   848 			while (v->engine_type == eng) {
   862 			while (v->engine_type == eng) {
   851 			}
   865 			}
   852 		}
   866 		}
   853 	}
   867 	}
   854 
   868 
   855 	return NULL;
   869 	return NULL;
       
   870 }
       
   871 
       
   872 /*
       
   873  * add a vehicle v behind vehicle dest
       
   874  * use this function since it sets flags as needed
       
   875  */
       
   876 static void AddWagonToConsist(Vehicle *v, Vehicle *dest)
       
   877 {
       
   878 	UnlinkWagon(v, GetFirstVehicleInChain(v));
       
   879 	if (dest == NULL) return;
       
   880 
       
   881 	v->next = dest->next;
       
   882 	dest->next = v;
       
   883 	ClearFreeWagon(v);
       
   884 	ClearFrontEngine(v);
       
   885 }
       
   886 
       
   887 /*
       
   888  * move around on the train so rear engines are placed correctly according to the other engines
       
   889  * always call with the front engine
       
   890  */
       
   891 static void NormaliseTrainConsist(Vehicle *v)
       
   892 {
       
   893 	Vehicle *u;
       
   894 
       
   895 	if (IsFreeWagon(v)) return;
       
   896 
       
   897 	assert(IsFrontEngine(v));
       
   898 
       
   899 	for(; v != NULL; v = GetNextVehicle(v)) {
       
   900 		if (!IsMultiheaded(v) || !IsTrainEngine(v)) continue;
       
   901 
       
   902 		/* make sure that there are no free cars before next engine */
       
   903 		for(u = v; u->next != NULL && !IsTrainEngine(u->next); u = u->next);
       
   904 
       
   905 		if (u == v->u.rail.other_multiheaded_part) continue;
       
   906 		AddWagonToConsist(v->u.rail.other_multiheaded_part, u);
       
   907 
       
   908 	}
   856 }
   909 }
   857 
   910 
   858 /** Move a rail vehicle around inside the depot.
   911 /** Move a rail vehicle around inside the depot.
   859  * @param x,y unused
   912  * @param x,y unused
   860  * @param p1 various bitstuffed elements
   913  * @param p1 various bitstuffed elements
   865 int32 CmdMoveRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   918 int32 CmdMoveRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   866 {
   919 {
   867 	VehicleID s = GB(p1, 0, 16);
   920 	VehicleID s = GB(p1, 0, 16);
   868 	VehicleID d = GB(p1, 16, 16);
   921 	VehicleID d = GB(p1, 16, 16);
   869 	Vehicle *src, *dst, *src_head, *dst_head;
   922 	Vehicle *src, *dst, *src_head, *dst_head;
   870 	bool is_loco;
       
   871 
   923 
   872 	if (!IsVehicleIndex(s)) return CMD_ERROR;
   924 	if (!IsVehicleIndex(s)) return CMD_ERROR;
   873 
   925 
   874 	src = GetVehicle(s);
   926 	src = GetVehicle(s);
   875 
   927 
   876 	if (src->type != VEH_Train) return CMD_ERROR;
   928 	if (src->type != VEH_Train) return CMD_ERROR;
   877 
       
   878 	is_loco = !(RailVehInfo(src->engine_type)->flags & RVI_WAGON) && IS_FIRSTHEAD_SPRITE(src->spritenum);
       
   879 
   929 
   880 	// if nothing is selected as destination, try and find a matching vehicle to drag to.
   930 	// if nothing is selected as destination, try and find a matching vehicle to drag to.
   881 	if (d == INVALID_VEHICLE) {
   931 	if (d == INVALID_VEHICLE) {
   882 		dst = NULL;
   932 		dst = NULL;
   883 		if (!is_loco) dst = FindGoodVehiclePos(src);
   933 		if (!IsTrainEngine(src)) dst = FindGoodVehiclePos(src);
   884 	} else {
   934 	} else {
   885 		dst = GetVehicle(d);
   935 		dst = GetVehicle(d);
   886 	}
   936 	}
   887 
   937 
   888 	// if an articulated part is being handled, deal with its parent vehicle
   938 	// if an articulated part is being handled, deal with its parent vehicle
   889 	while (src->subtype == TS_Artic_Part) src = GetPrevVehicleInChain(src);
   939 	while (IsArticulatedPart(src)) src = GetPrevVehicleInChain(src);
   890 	if (dst != NULL) {
   940 	if (dst != NULL) {
   891 		while (dst->subtype == TS_Artic_Part) dst = GetPrevVehicleInChain(dst);
   941 		while (IsArticulatedPart(dst)) dst = GetPrevVehicleInChain(dst);
   892 	}
   942 	}
   893 
   943 
   894 	// don't move the same vehicle..
   944 	// don't move the same vehicle..
   895 	if (src == dst) return 0;
   945 	if (src == dst) return 0;
   896 
   946 
   905 		dst_head = GetFirstVehicleInChain(dst);
   955 		dst_head = GetFirstVehicleInChain(dst);
   906 		// Now deal with articulated part of destination wagon
   956 		// Now deal with articulated part of destination wagon
   907 		dst = GetLastEnginePart(dst);
   957 		dst = GetLastEnginePart(dst);
   908 	}
   958 	}
   909 
   959 
   910 	/* clear the ->first cache */
   960 	if (dst != NULL && IsMultiheaded(dst) && !IsTrainEngine(dst) && IsTrainWagon(src)) {
   911 	{
   961 		/* We are moving a wagon to the rear part of a multiheaded engine */
   912 		Vehicle *u;
   962 		if (dst->next == NULL) {
   913 
   963 			/* It's the last one, so we will add the wagon just before the rear engine */
   914 		for (u = src_head; u != NULL; u = u->next) u->first = NULL;
   964 			dst = GetPrevVehicleInChain(dst);
   915 		for (u = dst_head; u != NULL; u = u->next) u->first = NULL;
   965 			// if dst is NULL, it means that dst got a rear multiheaded engine as first engine. We can't use that
   916 	}
   966 			if (dst == NULL) return CMD_ERROR;
       
   967 		} else {
       
   968 			/* there are more units on this train, so we will add the wagon after the next one*/
       
   969 			dst = dst->next;
       
   970 		}
       
   971 	}
       
   972 
       
   973 	if (IsTrainEngine(src) && dst_head != NULL) {
       
   974 		/* we need to make sure that we didn't place it between a pair of multiheaded engines */
       
   975 		Vehicle *u, *engine = NULL;
       
   976 
       
   977 		for(u = dst_head; u != NULL; u = u->next) {
       
   978 			if (IsTrainEngine(u) && IsMultiheaded(u) && u->u.rail.other_multiheaded_part != NULL) {
       
   979 				engine = u;
       
   980 			}
       
   981 				if (engine != NULL && engine->u.rail.other_multiheaded_part == u) {
       
   982 					engine = NULL;
       
   983 				}
       
   984 				if (u == dst) {
       
   985 					if (engine != NULL) {
       
   986 					dst = engine->u.rail.other_multiheaded_part;
       
   987 					}
       
   988 					break;
       
   989 				}
       
   990 
       
   991 		}
       
   992 	}
       
   993 
       
   994 	if (IsMultiheaded(src) && !IsTrainEngine(src)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR);
   917 
   995 
   918 	/* check if all vehicles in the source train are stopped inside a depot */
   996 	/* check if all vehicles in the source train are stopped inside a depot */
   919 	if (CheckTrainStoppedInDepot(src_head) < 0) return CMD_ERROR;
   997 	if (CheckTrainStoppedInDepot(src_head) < 0) return CMD_ERROR;
   920 
   998 
   921 	/* check if all the vehicles in the dest train are stopped,
   999 	/* check if all the vehicles in the dest train are stopped,
   922 	 * and that the length of the dest train is no longer than XXX vehicles */
  1000 	 * and that the length of the dest train is no longer than XXX vehicles */
   923 	if (dst_head != NULL) {
  1001 	if (dst_head != NULL) {
   924 		int num = CheckTrainStoppedInDepot(dst_head);
  1002 		int num = CheckTrainStoppedInDepot(dst_head);
   925 		if (num < 0) return CMD_ERROR;
  1003 		if (num < 0) return CMD_ERROR;
   926 
  1004 
   927 		if (num > (_patches.mammoth_trains ? 100 : 9) && dst_head->subtype == TS_Front_Engine )
  1005 		if (num > (_patches.mammoth_trains ? 100 : 9) && IsFrontEngine(dst_head))
   928 			return_cmd_error(STR_8819_TRAIN_TOO_LONG);
  1006 			return_cmd_error(STR_8819_TRAIN_TOO_LONG);
   929 
       
   930 		// if it's a multiheaded vehicle we're dragging to, drag to the vehicle before..
       
   931 		while (IS_CUSTOM_SECONDHEAD_SPRITE(dst->spritenum) || (
       
   932 			!is_custom_sprite(dst->spritenum) && _engine_sprite_add[dst->spritenum] != 0)
       
   933 		) {
       
   934 			Vehicle *v = GetPrevVehicleInChain(dst);
       
   935 			if (v == NULL || src == v) break;
       
   936 			dst = v;
       
   937 		}
       
   938 
  1007 
   939 		assert(dst_head->tile == src_head->tile);
  1008 		assert(dst_head->tile == src_head->tile);
   940 	}
  1009 	}
   941 
  1010 
   942 	// when moving all wagons, we can't have the same src_head and dst_head
  1011 	// when moving all wagons, we can't have the same src_head and dst_head
   943 	if (HASBIT(p2, 0) && src_head == dst_head) return 0;
  1012 	if (HASBIT(p2, 0) && src_head == dst_head) return 0;
   944 
  1013 
   945 	// moving a loco to a new line?, then we need to assign a unitnumber.
  1014 	// moving a loco to a new line?, then we need to assign a unitnumber.
   946 	if (dst == NULL && src->subtype != TS_Front_Engine && is_loco) {
  1015 	if (dst == NULL && !IsFrontEngine(src) && IsTrainEngine(src)) {
   947 		UnitID unit_num = GetFreeUnitNumber(VEH_Train);
  1016 		UnitID unit_num = GetFreeUnitNumber(VEH_Train);
   948 		if (unit_num > _patches.max_trains)
  1017 		if (unit_num > _patches.max_trains)
   949 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
  1018 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   950 
  1019 
   951 		if (flags & DC_EXEC)
  1020 		if (flags & DC_EXEC)
   953 	}
  1022 	}
   954 
  1023 
   955 
  1024 
   956 	/* do it? */
  1025 	/* do it? */
   957 	if (flags & DC_EXEC) {
  1026 	if (flags & DC_EXEC) {
   958 		Vehicle *new_front = GetNextVehicle(src);	//used if next in line should make a train on it's own
  1027 		/* clear the ->first cache */
   959 		bool make_new_front = src->subtype == TS_Front_Engine;
  1028 		{
       
  1029 			Vehicle *u;
       
  1030 
       
  1031 			for (u = src_head; u != NULL; u = u->next) u->first = NULL;
       
  1032 			for (u = dst_head; u != NULL; u = u->next) u->first = NULL;
       
  1033 		}
   960 
  1034 
   961 		if (HASBIT(p2, 0)) {
  1035 		if (HASBIT(p2, 0)) {
   962 			// unlink ALL wagons
  1036 			// unlink ALL wagons
   963 			if (src != src_head) {
  1037 			if (src != src_head) {
   964 				Vehicle *v = src_head;
  1038 				Vehicle *v = src_head;
   975 			src_head = UnlinkWagon(src, src_head);
  1049 			src_head = UnlinkWagon(src, src_head);
   976 			GetLastEnginePart(src)->next = NULL;
  1050 			GetLastEnginePart(src)->next = NULL;
   977 		}
  1051 		}
   978 
  1052 
   979 		if (dst == NULL) {
  1053 		if (dst == NULL) {
   980 			// move the train to an empty line. for locomotives, we set the type to 0. for wagons, 4.
  1054 			// move the train to an empty line. for locomotives, we set the type to TS_Front. for wagons, 4.
   981 			if (is_loco) {
  1055 			if (IsTrainEngine(src)) {
   982 				if (src->subtype != TS_Front_Engine) {
  1056 				if (!IsFrontEngine(src)) {
   983 					// setting the type to 0 also involves setting up the orders field.
  1057 					// setting the type to 0 also involves setting up the orders field.
   984 					src->subtype = TS_Front_Engine;
  1058 					SetFrontEngine(src);
   985 					assert(src->orders == NULL);
  1059 					assert(src->orders == NULL);
   986 					src->num_orders = 0;
  1060 					src->num_orders = 0;
   987 				}
  1061 				}
   988 			} else {
  1062 			} else {
   989 				src->subtype = TS_Free_Car;
  1063 				SetFreeWagon(src);
   990 			}
  1064 			}
   991 			dst_head = src;
  1065 			dst_head = src;
   992 		} else {
  1066 		} else {
   993 			if (src->subtype == TS_Front_Engine) {
  1067 			if (IsFrontEngine(src)) {
   994 				// the vehicle was previously a loco. need to free the order list and delete vehicle windows etc.
  1068 				// the vehicle was previously a loco. need to free the order list and delete vehicle windows etc.
   995 				DeleteWindowById(WC_VEHICLE_VIEW, src->index);
  1069 				DeleteWindowById(WC_VEHICLE_VIEW, src->index);
   996 				DeleteVehicleOrders(src);
  1070 				DeleteVehicleOrders(src);
   997 			}
  1071 			}
   998 
  1072 
   999 			src->subtype = TS_Not_First;
  1073 			ClearFrontEngine(src);
       
  1074 			ClearFreeWagon(src);
  1000 			src->unitnumber = 0; // doesn't occupy a unitnumber anymore.
  1075 			src->unitnumber = 0; // doesn't occupy a unitnumber anymore.
  1001 
  1076 
  1002 			// link in the wagon(s) in the chain.
  1077 			// link in the wagon(s) in the chain.
  1003 			{
  1078 			{
  1004 				Vehicle *v;
  1079 				Vehicle *v;
  1006 				for (v = src; GetNextVehicle(v) != NULL; v = GetNextVehicle(v));
  1081 				for (v = src; GetNextVehicle(v) != NULL; v = GetNextVehicle(v));
  1007 				GetLastEnginePart(v)->next = dst->next;
  1082 				GetLastEnginePart(v)->next = dst->next;
  1008 			}
  1083 			}
  1009 			dst->next = src;
  1084 			dst->next = src;
  1010 		}
  1085 		}
       
  1086 		if (src->u.rail.other_multiheaded_part != NULL) {
       
  1087 			if (src->u.rail.other_multiheaded_part == src_head) {
       
  1088 				src_head = src_head->next;
       
  1089 			}
       
  1090 			AddWagonToConsist(src->u.rail.other_multiheaded_part, src);
       
  1091 		}
       
  1092 
       
  1093 		if (HASBIT(p2, 0) && src_head != NULL && src_head != src) {
       
  1094 			/* if we stole a rear multiheaded engine, we better give it back to the front end */
       
  1095 			Vehicle *engine = NULL, *u;
       
  1096 			for (u = src_head; u != NULL; u = u->next) {
       
  1097 				if (IsMultiheaded(u)) {
       
  1098 					if (IsTrainEngine(u)) {
       
  1099 						engine = u;
       
  1100 						continue;
       
  1101 					}
       
  1102 					/* we got the rear engine to match with the front one */
       
  1103 					engine = NULL;
       
  1104 				}
       
  1105 			}
       
  1106 			if (engine != NULL && engine->u.rail.other_multiheaded_part != NULL) {
       
  1107 				AddWagonToConsist(engine->u.rail.other_multiheaded_part, engine);
       
  1108 				// previous line set the front engine to the old front. We need to clear that
       
  1109 				engine->u.rail.other_multiheaded_part->first = NULL;
       
  1110 			}
       
  1111 		}
  1011 
  1112 
  1012 		/* If there is an engine behind first_engine we moved away, it should become new first_engine
  1113 		/* If there is an engine behind first_engine we moved away, it should become new first_engine
  1013 		 * To do this, CmdMoveRailVehicle must be called once more
  1114 		 * To do this, CmdMoveRailVehicle must be called once more
  1014 		 * since we set p2 to a condition that makes the statement false, we can't loop forever with this one */
  1115 		 * we can't loop forever here because next time we reach this line we will have a front engine */
  1015 		if (make_new_front && new_front != NULL && !(HASBIT(p2, 0))) {
  1116 		if (src_head != NULL && !IsFrontEngine(src_head) && IsTrainEngine(src_head)) {
  1016 			if (!(RailVehInfo(new_front->engine_type)->flags & RVI_WAGON)) {
  1117 			CmdMoveRailVehicle(x, y, flags, src_head->index | (INVALID_VEHICLE << 16), 1);
  1017 				CmdMoveRailVehicle(x, y, flags, new_front->index | (INVALID_VEHICLE << 16), 1);
  1118 			src_head = NULL;	// don't do anything more to this train since the new call will do it
  1018 			}
       
  1019 		}
  1119 		}
  1020 
  1120 
  1021 		if (src_head) {
  1121 		if (src_head) {
       
  1122 			NormaliseTrainConsist(src_head);
  1022 			TrainConsistChanged(src_head);
  1123 			TrainConsistChanged(src_head);
  1023 			if (src_head->subtype == TS_Front_Engine) {
  1124 			if (IsFrontEngine(src_head)) {
  1024 				UpdateTrainAcceleration(src_head);
  1125 				UpdateTrainAcceleration(src_head);
  1025 				InvalidateWindow(WC_VEHICLE_DETAILS, src_head->index);
  1126 				InvalidateWindow(WC_VEHICLE_DETAILS, src_head->index);
  1026 				/* Update the refit button and window */
  1127 				/* Update the refit button and window */
  1027 				InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
  1128 				InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
  1028 				InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, 12);
  1129 				InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, 12);
  1030 			/* Update the depot window */
  1131 			/* Update the depot window */
  1031 			InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
  1132 			InvalidateWindow(WC_VEHICLE_DEPOT, src_head->tile);
  1032 		};
  1133 		};
  1033 
  1134 
  1034 		if (dst_head) {
  1135 		if (dst_head) {
       
  1136 			NormaliseTrainConsist(dst_head);
  1035 			TrainConsistChanged(dst_head);
  1137 			TrainConsistChanged(dst_head);
  1036 			if (dst_head->subtype == TS_Front_Engine) {
  1138 			if (IsFrontEngine(dst_head)) {
  1037 				UpdateTrainAcceleration(dst_head);
  1139 				UpdateTrainAcceleration(dst_head);
  1038 				InvalidateWindow(WC_VEHICLE_DETAILS, dst_head->index);
  1140 				InvalidateWindow(WC_VEHICLE_DETAILS, dst_head->index);
  1039 				/* Update the refit button and window */
  1141 				/* Update the refit button and window */
  1040 				InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, 12);
  1142 				InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, 12);
  1041 				InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
  1143 				InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
  1070 		v->vehstatus ^= VS_STOPPED;
  1172 		v->vehstatus ^= VS_STOPPED;
  1071 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  1173 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  1072 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1174 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1073 	}
  1175 	}
  1074 	return 0;
  1176 	return 0;
  1075 }
       
  1076 
       
  1077 /**
       
  1078  * Search for a matching rear-engine of a dual-headed train.
       
  1079  * Do this as if you would find matching parentheses. If a new
       
  1080  * engine is 'started', first 'close' that before 'closing' our
       
  1081  * searched engine
       
  1082  */
       
  1083 Vehicle* GetRearEngine(const Vehicle* v)
       
  1084 {
       
  1085 	Vehicle *u;
       
  1086 	int en_count = 1;
       
  1087 
       
  1088 	for (u = v->next; u != NULL; u = u->next) {
       
  1089 		if (u->engine_type == v->engine_type) { // find matching engine
       
  1090 			en_count += (IS_FIRSTHEAD_SPRITE(u->spritenum)) ? +1 : -1;
       
  1091 
       
  1092 			if (en_count == 0) return (Vehicle *)u;
       
  1093 		}
       
  1094 	}
       
  1095 	return NULL;
       
  1096 }
  1177 }
  1097 
  1178 
  1098 /** Sell a (single) train wagon/engine.
  1179 /** Sell a (single) train wagon/engine.
  1099  * @param x,y unused
  1180  * @param x,y unused
  1100  * @param p1 the wagon/engine index
  1181  * @param p1 the wagon/engine index
  1106  *           all wagons of the same type will go on the same line. Used by the AI currently
  1187  *           all wagons of the same type will go on the same line. Used by the AI currently
  1107  */
  1188  */
  1108 int32 CmdSellRailWagon(int x, int y, uint32 flags, uint32 p1, uint32 p2)
  1189 int32 CmdSellRailWagon(int x, int y, uint32 flags, uint32 p1, uint32 p2)
  1109 {
  1190 {
  1110 	Vehicle *v, *tmp, *first;
  1191 	Vehicle *v, *tmp, *first;
       
  1192 	Vehicle *new_f = NULL;
  1111 	int32 cost = 0;
  1193 	int32 cost = 0;
  1112 
  1194 
  1113 	if (!IsVehicleIndex(p1) || p2 > 2) return CMD_ERROR;
  1195 	if (!IsVehicleIndex(p1) || p2 > 2) return CMD_ERROR;
  1114 
  1196 
  1115 	v = GetVehicle(p1);
  1197 	v = GetVehicle(p1);
  1116 
  1198 
  1117 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  1199 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
  1118 
  1200 
  1119 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
  1201 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
  1120 
  1202 
  1121 	while (v->subtype == TS_Artic_Part) v = GetPrevVehicleInChain(v);
  1203 	while (IsArticulatedPart(v)) v = GetPrevVehicleInChain(v);
  1122 	first = GetFirstVehicleInChain(v);
  1204 	first = GetFirstVehicleInChain(v);
  1123 
  1205 
  1124 	// make sure the vehicle is stopped in the depot
  1206 	// make sure the vehicle is stopped in the depot
  1125 	if (CheckTrainStoppedInDepot(first) < 0) return CMD_ERROR;
  1207 	if (CheckTrainStoppedInDepot(first) < 0) return CMD_ERROR;
  1126 
  1208 
       
  1209 	if (IsMultiheaded(v) && !IsTrainEngine(v)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR);
       
  1210 
  1127 	if (flags & DC_EXEC) {
  1211 	if (flags & DC_EXEC) {
  1128 		if (v == first && first->subtype == TS_Front_Engine) {
  1212 		if (v == first && IsFrontEngine(first)) {
  1129 			DeleteWindowById(WC_VEHICLE_VIEW, first->index);
  1213 			DeleteWindowById(WC_VEHICLE_VIEW, first->index);
  1130 		}
  1214 		}
  1131 		if (IsLocalPlayer() && (p1 == 1 || !(RailVehInfo(v->engine_type)->flags & RVI_WAGON))) {
  1215 		if (IsLocalPlayer() && (p1 == 1 || !(RailVehInfo(v->engine_type)->flags & RVI_WAGON))) {
  1132 			InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train);
  1216 			InvalidateWindow(WC_REPLACE_VEHICLE, VEH_Train);
  1133 		}
  1217 		}
  1139 		case 0: case 2: { /* Delete given wagon */
  1223 		case 0: case 2: { /* Delete given wagon */
  1140 			bool switch_engine = false;    // update second wagon to engine?
  1224 			bool switch_engine = false;    // update second wagon to engine?
  1141 			byte ori_subtype = v->subtype; // backup subtype of deleted wagon in case DeleteVehicle() changes
  1225 			byte ori_subtype = v->subtype; // backup subtype of deleted wagon in case DeleteVehicle() changes
  1142 
  1226 
  1143 			/* 1. Delete the engine, if it is dualheaded also delete the matching
  1227 			/* 1. Delete the engine, if it is dualheaded also delete the matching
  1144 			* rear engine of the loco (from the point of deletion onwards) */
  1228 			 * rear engine of the loco (from the point of deletion onwards) */
  1145 			Vehicle* rear = (RailVehInfo(v->engine_type)->flags & RVI_MULTIHEAD) ? GetRearEngine(v) : NULL;
  1229 			Vehicle *rear = (IsMultiheaded(v) &&
       
  1230 				IsTrainEngine(v)) ? v->u.rail.other_multiheaded_part : NULL;
       
  1231 
  1146 			if (rear != NULL) {
  1232 			if (rear != NULL) {
  1147 				cost -= v->value;
  1233 				cost -= rear->value;
  1148 				if (flags & DC_EXEC) {
  1234 				if (flags & DC_EXEC) {
  1149 					v = UnlinkWagon(rear, v);
  1235 					UnlinkWagon(rear, first);
  1150 					DeleteVehicle(rear);
  1236 					DeleteVehicle(rear);
  1151 				}
  1237 				}
  1152 			}
  1238 			}
  1153 
  1239 
  1154 			/* 2. We are selling the first engine, some special action might be required
  1240 			/* 2. We are selling the first engine, some special action might be required
  1155 				* here, so take attention */
  1241 			 * here, so take attention */
  1156 			if ((flags & DC_EXEC) && v == first) {
  1242 			if ((flags & DC_EXEC) && v == first) {
  1157 				Vehicle *new_f = GetNextVehicle(first);
  1243 				new_f = GetNextVehicle(first);
  1158 
  1244 
  1159 				/* 2.1 If the first wagon is sold, update the first-> pointers to NULL */
  1245 				/* 2.1 If the first wagon is sold, update the first-> pointers to NULL */
  1160 				for (tmp = first; tmp != NULL; tmp = tmp->next) tmp->first = NULL;
  1246 				for (tmp = first; tmp != NULL; tmp = tmp->next) tmp->first = NULL;
  1161 
  1247 
  1162 				/* 2.2 If there are wagons present after the deleted front engine, check
  1248 				/* 2.2 If there are wagons present after the deleted front engine, check
  1163 					* if the second wagon (which will be first) is an engine. If it is one,
  1249 					* if the second wagon (which will be first) is an engine. If it is one,
  1164 					* promote it as a new train, retaining the unitnumber, orders */
  1250 					* promote it as a new train, retaining the unitnumber, orders */
  1165 				if (new_f != NULL) {
  1251 				if (new_f != NULL) {
  1166 					if (!(RailVehInfo(new_f->engine_type)->flags & RVI_WAGON) && IS_FIRSTHEAD_SPRITE(new_f->spritenum)) {
  1252 					if (IsTrainEngine(new_f)) {
  1167 						switch_engine = true;
  1253 						switch_engine = true;
  1168 						/* Copy important data from the front engine */
  1254 						/* Copy important data from the front engine */
  1169 						new_f->unitnumber = first->unitnumber;
  1255 						new_f->unitnumber = first->unitnumber;
  1170 						new_f->current_order = first->current_order;
  1256 						new_f->current_order = first->current_order;
  1171 						new_f->cur_order_index = first->cur_order_index;
  1257 						new_f->cur_order_index = first->cur_order_index;
  1183 				first = UnlinkWagon(v, first);
  1269 				first = UnlinkWagon(v, first);
  1184 				DeleteVehicle(v);
  1270 				DeleteVehicle(v);
  1185 
  1271 
  1186 				/* 4 If the second wagon was an engine, update it to front_engine
  1272 				/* 4 If the second wagon was an engine, update it to front_engine
  1187 					* which UnlinkWagon() has changed to TS_Free_Car */
  1273 					* which UnlinkWagon() has changed to TS_Free_Car */
  1188 				if (switch_engine) first->subtype = TS_Front_Engine;
  1274 				if (switch_engine) SetFrontEngine(first);
  1189 
  1275 
  1190 				/* 5. If the train still exists, update its acceleration, window, etc. */
  1276 				/* 5. If the train still exists, update its acceleration, window, etc. */
  1191 				if (first != NULL) {
  1277 				if (first != NULL) {
       
  1278 					NormaliseTrainConsist(first);
  1192 					TrainConsistChanged(first);
  1279 					TrainConsistChanged(first);
  1193 					if (first->subtype == TS_Front_Engine) {
  1280 					if (IsFrontEngine(first)) {
  1194 						InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
  1281 						InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
  1195 						InvalidateWindow(WC_VEHICLE_REFIT, first->index);
  1282 						InvalidateWindow(WC_VEHICLE_REFIT, first->index);
  1196 						UpdateTrainAcceleration(first);
  1283 						UpdateTrainAcceleration(first);
  1197 					}
  1284 					}
  1198 				}
  1285 				}
  1199 
  1286 
  1200 
  1287 
  1201 				/* (6.) Borked AI. If it sells an engine it expects all wagons lined
  1288 				/* (6.) Borked AI. If it sells an engine it expects all wagons lined
  1202 				* up on a new line to be added to the newly built loco. Replace it is.
  1289 				 * up on a new line to be added to the newly built loco. Replace it is.
  1203 				* Totally braindead cause building a new engine adds all loco-less
  1290 				 * Totally braindead cause building a new engine adds all loco-less
  1204 				* engines to its train anyways */
  1291 				 * engines to its train anyways */
  1205 				if (p2 == 2 && ori_subtype == TS_Front_Engine) {
  1292 				if (p2 == 2 && HASBIT(ori_subtype, Train_Front)) {
  1206 					for (v = first; v != NULL; v = tmp) {
  1293 					for (v = first; v != NULL; v = tmp) {
  1207 						tmp = GetNextVehicle(v);
  1294 						tmp = GetNextVehicle(v);
  1208 						DoCommandByTile(v->tile, v->index | INVALID_VEHICLE << 16, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
  1295 						DoCommandByTile(v->tile, v->index | INVALID_VEHICLE << 16, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
  1209 					}
  1296 					}
  1210 				}
  1297 				}
  1211 			}
  1298 			}
  1212 		} break;
  1299 		} break;
  1213 		case 1: { /* Delete wagon and all wagons after it given certain criteria */
  1300 		case 1: { /* Delete wagon and all wagons after it given certain criteria */
  1214 			/* 1. Count the number for first and rear engines for dualheads
  1301 			/* Start deleting every vehicle after the selected one
  1215 			* to be able to deduce which ones go with which ones */
  1302 			 * If we encounter a matching rear-engine to a front-engine
  1216 			int enf_count = 0;
  1303 			 * earlier in the chain (before deletion), leave it alone */
  1217 			int enr_count = 0;
       
  1218 			for (tmp = first; tmp != NULL; tmp = GetNextVehicle(tmp)) {
       
  1219 				if (RailVehInfo(tmp->engine_type)->flags & RVI_MULTIHEAD)
       
  1220 					(IS_FIRSTHEAD_SPRITE(tmp->spritenum)) ? enf_count++ : enr_count++;
       
  1221 			}
       
  1222 
       
  1223 			/* 2. Start deleting every vehicle after the selected one
       
  1224 			* If we encounter a matching rear-engine to a front-engine
       
  1225 			* earlier in the chain (before deletion), leave it alone */
       
  1226 			for (; v != NULL; v = tmp) {
  1304 			for (; v != NULL; v = tmp) {
  1227 				tmp = GetNextVehicle(v);
  1305 				tmp = GetNextVehicle(v);
  1228 
  1306 
  1229 				if (RailVehInfo(v->engine_type)->flags & RVI_MULTIHEAD) {
  1307 				if (IsMultiheaded(v)) {
  1230 					if (IS_FIRSTHEAD_SPRITE(v->spritenum)) {
  1308 					if (IsTrainEngine(v)) {
  1231 						/* Always delete newly encountered front-engines */
  1309 						/* We got a front engine of a multiheaded set. Now we will sell the rear end too */
  1232 						enf_count--;
  1310 						Vehicle *rear = v->u.rail.other_multiheaded_part;
  1233 					} else if (enr_count > enf_count) {
  1311 
  1234 						/* More rear engines than front engines means this rear-engine does
  1312 						if (rear != NULL) {
  1235 						 * not belong to any front-engine; delete */
  1313 							cost -= rear->value;
  1236 						enr_count--;
  1314 							if (flags & DC_EXEC) {
  1237 					} else {
  1315 								first = UnlinkWagon(rear, first);
  1238 						/* Otherwise leave it alone */
  1316 								DeleteVehicle(rear);
       
  1317 							}
       
  1318 						}
       
  1319 					} else if (v->u.rail.other_multiheaded_part != NULL) {
       
  1320 						/* The front to this engine is earlier in this train. Do nothing */
  1239 						continue;
  1321 						continue;
  1240 					}
  1322 					}
  1241 				}
  1323 				}
  1242 
  1324 
  1243 				cost -= v->value;
  1325 				cost -= v->value;
  1247 				}
  1329 				}
  1248 			}
  1330 			}
  1249 
  1331 
  1250 			/* 3. If it is still a valid train after selling, update its acceleration and cached values */
  1332 			/* 3. If it is still a valid train after selling, update its acceleration and cached values */
  1251 			if ((flags & DC_EXEC) && first != NULL) {
  1333 			if ((flags & DC_EXEC) && first != NULL) {
       
  1334 				NormaliseTrainConsist(first);
  1252 				TrainConsistChanged(first);
  1335 				TrainConsistChanged(first);
  1253 				if (first->subtype == TS_Front_Engine)
  1336 				if (IsFrontEngine(first))
  1254 					UpdateTrainAcceleration(first);
  1337 					UpdateTrainAcceleration(first);
       
  1338 				InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
       
  1339 				InvalidateWindow(WC_VEHICLE_REFIT, first->index);
  1255 			}
  1340 			}
  1256 		} break;
  1341 		} break;
  1257 	}
  1342 	}
  1258 	return cost;
  1343 	return cost;
  1259 }
  1344 }
  2618 
  2703 
  2619 		case MP_STREET:
  2704 		case MP_STREET:
  2620 			// tracks over roads, do owner check of tracks
  2705 			// tracks over roads, do owner check of tracks
  2621 			return
  2706 			return
  2622 				IsTileOwner(tile, v->owner) && (
  2707 				IsTileOwner(tile, v->owner) && (
  2623 					v->subtype != TS_Front_Engine ||
  2708 					!IsFrontEngine(v) ||
  2624 					IsCompatibleRail(v->u.rail.railtype, GB(_m[tile].m4, 0, 4))
  2709 					IsCompatibleRail(v->u.rail.railtype, GB(_m[tile].m4, 0, 4))
  2625 				);
  2710 				);
  2626 
  2711 
  2627 		default:
  2712 		default:
  2628 			return true;
  2713 			return true;
  2629 	}
  2714 	}
  2630 
  2715 
  2631 	return
  2716 	return
  2632 		IsTileOwner(tile, v->owner) && (
  2717 		IsTileOwner(tile, v->owner) && (
  2633 			v->subtype != TS_Front_Engine ||
  2718 			!IsFrontEngine(v) ||
  2634 			IsCompatibleRail(v->u.rail.railtype, GetRailType(tile))
  2719 			IsCompatibleRail(v->u.rail.railtype, GetRailType(tile))
  2635 		);
  2720 		);
  2636 }
  2721 }
  2637 
  2722 
  2638 typedef struct {
  2723 typedef struct {
  2739 	return num;
  2824 	return num;
  2740 }
  2825 }
  2741 
  2826 
  2742 /*
  2827 /*
  2743  * Checks whether the specified train has a collision with another vehicle. If
  2828  * Checks whether the specified train has a collision with another vehicle. If
  2744  * so, destroys this vehicle, and the other vehicle if its subtype is 0 (TS_Front_Engine).
  2829  * so, destroys this vehicle, and the other vehicle if its subtype has TS_Front.
  2745  * Reports the incident in a flashy news item, modifies station ratings and
  2830  * Reports the incident in a flashy news item, modifies station ratings and
  2746  * plays a sound.
  2831  * plays a sound.
  2747  */
  2832  */
  2748 static void CheckTrainCollision(Vehicle *v)
  2833 static void CheckTrainCollision(Vehicle *v)
  2749 {
  2834 {
  2776 	if (!(coll->vehstatus & VS_CRASHED))
  2861 	if (!(coll->vehstatus & VS_CRASHED))
  2777 		//two drivers + passangers killed in train coll (if it was not crashed already)
  2862 		//two drivers + passangers killed in train coll (if it was not crashed already)
  2778 		num += 2 + CountPassengersInTrain(coll);
  2863 		num += 2 + CountPassengersInTrain(coll);
  2779 
  2864 
  2780 	SetVehicleCrashed(v);
  2865 	SetVehicleCrashed(v);
  2781 	if (coll->subtype == TS_Front_Engine) SetVehicleCrashed(coll);
  2866 	if (IsFrontEngine(coll)) SetVehicleCrashed(coll);
  2782 
  2867 
  2783 	SetDParam(0, num);
  2868 	SetDParam(0, num);
  2784 	AddNewsItem(STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL,
  2869 	AddNewsItem(STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL,
  2785 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ACCIDENT, 0),
  2870 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ACCIDENT, 0),
  2786 		v->index,
  2871 		v->index,
  2798 
  2883 
  2799 static void *CheckVehicleAtSignal(Vehicle *v, void *data)
  2884 static void *CheckVehicleAtSignal(Vehicle *v, void *data)
  2800 {
  2885 {
  2801 	const VehicleAtSignalData* vasd = data;
  2886 	const VehicleAtSignalData* vasd = data;
  2802 
  2887 
  2803 	if (v->type == VEH_Train && v->subtype == TS_Front_Engine &&
  2888 	if (v->type == VEH_Train && IsFrontEngine(v) &&
  2804 			v->tile == vasd->tile) {
  2889 			v->tile == vasd->tile) {
  2805 		byte diff = (v->direction - vasd->direction + 2) & 7;
  2890 		byte diff = (v->direction - vasd->direction + 2) & 7;
  2806 
  2891 
  2807 		if (diff == 2 || (v->cur_speed <= 5 && diff <= 4))
  2892 		if (diff == 2 || (v->cur_speed <= 5 && diff <= 4))
  2808 			return v;
  2893 			return v;
  2968 				if (r&0x8){
  3053 				if (r&0x8){
  2969 					//debug("%x & 0x8", r);
  3054 					//debug("%x & 0x8", r);
  2970 					goto invalid_rail;
  3055 					goto invalid_rail;
  2971 				}
  3056 				}
  2972 
  3057 
  2973 				if (v->subtype == TS_Front_Engine) v->load_unload_time_rem = 0;
  3058 				if (IsFrontEngine(v)) v->load_unload_time_rem = 0;
  2974 
  3059 
  2975 				if (!(r&0x4)) {
  3060 				if (!(r&0x4)) {
  2976 					v->tile = gp.new_tile;
  3061 					v->tile = gp.new_tile;
  2977 					v->u.rail.track = chosen_track;
  3062 					v->u.rail.track = chosen_track;
  2978 					assert(v->u.rail.track);
  3063 					assert(v->u.rail.track);
  2979 				}
  3064 				}
  2980 
  3065 
  2981 				if (v->subtype == TS_Front_Engine)
  3066 				if (IsFrontEngine(v))
  2982 				TrainMovedChangeSignals(gp.new_tile, enterdir);
  3067 				TrainMovedChangeSignals(gp.new_tile, enterdir);
  2983 
  3068 
  2984 				/* Signals can only change when the first
  3069 				/* Signals can only change when the first
  2985 				 * (above) or the last vehicle moves. */
  3070 				 * (above) or the last vehicle moves. */
  2986 				if (v->next == NULL)
  3071 				if (v->next == NULL)
  3431 	if (_age_cargo_skip_counter == 0 && v->cargo_days != 0xff)
  3516 	if (_age_cargo_skip_counter == 0 && v->cargo_days != 0xff)
  3432 		v->cargo_days++;
  3517 		v->cargo_days++;
  3433 
  3518 
  3434 	v->tick_counter++;
  3519 	v->tick_counter++;
  3435 
  3520 
  3436 	if (v->subtype == TS_Front_Engine) {
  3521 	if (IsFrontEngine(v)) {
  3437 		TrainLocoHandler(v, false);
  3522 		TrainLocoHandler(v, false);
  3438 
  3523 
  3439 		// make sure vehicle wasn't deleted.
  3524 		// make sure vehicle wasn't deleted.
  3440 		if (v->type == VEH_Train && v->subtype == TS_Front_Engine)
  3525 		if (v->type == VEH_Train && IsFrontEngine(v))
  3441 			TrainLocoHandler(v, true);
  3526 			TrainLocoHandler(v, true);
  3442 	} else if (v->subtype == TS_Free_Car && HASBITS(v->vehstatus, VS_CRASHED)) {
  3527 	} else if (IsFreeWagon(v) && HASBITS(v->vehstatus, VS_CRASHED)) {
  3443 		// Delete flooded standalone wagon
  3528 		// Delete flooded standalone wagon
  3444 		if (++v->u.rail.crash_anim_pos >= 4400)
  3529 		if (++v->u.rail.crash_anim_pos >= 4400)
  3445 			DeleteVehicle(v);
  3530 			DeleteVehicle(v);
  3446 	}
  3531 	}
  3447 }
  3532 }
  3458 
  3543 
  3459 void TrainEnterDepot(Vehicle *v, TileIndex tile)
  3544 void TrainEnterDepot(Vehicle *v, TileIndex tile)
  3460 {
  3545 {
  3461 	SetSignalsOnBothDir(tile, _depot_track_ind[GB(_m[tile].m5, 0, 2)]);
  3546 	SetSignalsOnBothDir(tile, _depot_track_ind[GB(_m[tile].m5, 0, 2)]);
  3462 
  3547 
  3463 	if (v->subtype != TS_Front_Engine) v = GetFirstVehicleInChain(v);
  3548 	if (!IsFrontEngine(v)) v = GetFirstVehicleInChain(v);
  3464 
  3549 
  3465 	VehicleServiceInDepot(v);
  3550 	VehicleServiceInDepot(v);
  3466 
  3551 
  3467 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  3552 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  3468 
  3553 
  3563 	TileIndex tile;
  3648 	TileIndex tile;
  3564 
  3649 
  3565 	if ((++v->day_counter & 7) == 0)
  3650 	if ((++v->day_counter & 7) == 0)
  3566 		DecreaseVehicleValue(v);
  3651 		DecreaseVehicleValue(v);
  3567 
  3652 
  3568 	if (v->subtype == TS_Front_Engine) {
  3653 	if (IsFrontEngine(v)) {
  3569 		CheckVehicleBreakdown(v);
  3654 		CheckVehicleBreakdown(v);
  3570 		AgeVehicle(v);
  3655 		AgeVehicle(v);
  3571 
  3656 
  3572 		CheckIfTrainNeedsService(v);
  3657 		CheckIfTrainNeedsService(v);
  3573 
  3658 
  3608 void TrainsYearlyLoop(void)
  3693 void TrainsYearlyLoop(void)
  3609 {
  3694 {
  3610 	Vehicle *v;
  3695 	Vehicle *v;
  3611 
  3696 
  3612 	FOR_ALL_VEHICLES(v) {
  3697 	FOR_ALL_VEHICLES(v) {
  3613 		if (v->type == VEH_Train && v->subtype == TS_Front_Engine) {
  3698 		if (v->type == VEH_Train && IsFrontEngine(v)) {
  3614 
  3699 
  3615 			// show warning if train is not generating enough income last 2 years (corresponds to a red icon in the vehicle list)
  3700 			// show warning if train is not generating enough income last 2 years (corresponds to a red icon in the vehicle list)
  3616 			if (_patches.train_income_warn && v->owner == _local_player && v->age >= 730 && v->profit_this_year < 0) {
  3701 			if (_patches.train_income_warn && v->owner == _local_player && v->age >= 730 && v->profit_this_year < 0) {
  3617 				SetDParam(1, v->profit_this_year);
  3702 				SetDParam(1, v->profit_this_year);
  3618 				SetDParam(0, v->unitnumber);
  3703 				SetDParam(0, v->unitnumber);