src/train_cmd.cpp
branchnoai
changeset 9701 d1ac22c62f64
parent 9694 e72987579514
child 9703 d2a6acdbd665
equal deleted inserted replaced
9700:e442ce398e83 9701:d1ac22c62f64
    69 void TrainPowerChanged(Vehicle* v)
    69 void TrainPowerChanged(Vehicle* v)
    70 {
    70 {
    71 	uint32 total_power = 0;
    71 	uint32 total_power = 0;
    72 	uint32 max_te = 0;
    72 	uint32 max_te = 0;
    73 
    73 
    74 	for (const Vehicle *u = v; u != NULL; u = u->next) {
    74 	for (const Vehicle *u = v; u != NULL; u = u->Next()) {
    75 		/* Power is not added for articulated parts */
    75 		/* Power is not added for articulated parts */
    76 		if (IsArticulatedPart(u)) continue;
    76 		if (IsArticulatedPart(u)) continue;
    77 
    77 
    78 		RailType railtype = GetRailType(u->tile);
    78 		RailType railtype = GetRailType(u->tile);
    79 		bool engine_has_power = HasPowerOnRail(u->u.rail.railtype, railtype);
    79 		bool engine_has_power = HasPowerOnRail(u->u.rail.railtype, railtype);
   111  */
   111  */
   112 static void TrainCargoChanged(Vehicle* v)
   112 static void TrainCargoChanged(Vehicle* v)
   113 {
   113 {
   114 	uint32 weight = 0;
   114 	uint32 weight = 0;
   115 
   115 
   116 	for (Vehicle *u = v; u != NULL; u = u->next) {
   116 	for (Vehicle *u = v; u != NULL; u = u->Next()) {
   117 		uint32 vweight = GetCargo(u->cargo_type)->weight * u->cargo.Count() * FreightWagonMult(u->cargo_type) / 16;
   117 		uint32 vweight = GetCargo(u->cargo_type)->weight * u->cargo.Count() * FreightWagonMult(u->cargo_type) / 16;
   118 
   118 
   119 		/* Vehicle weight is not added for articulated parts. */
   119 		/* Vehicle weight is not added for articulated parts. */
   120 		if (!IsArticulatedPart(u)) {
   120 		if (!IsArticulatedPart(u)) {
   121 			/* vehicle weight is the sum of the weight of the vehicle and the weight of its cargo */
   121 			/* vehicle weight is the sum of the weight of the vehicle and the weight of its cargo */
   157 	const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type);
   157 	const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type);
   158 	EngineID first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE;
   158 	EngineID first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_ENGINE;
   159 	v->u.rail.cached_total_length = 0;
   159 	v->u.rail.cached_total_length = 0;
   160 	v->u.rail.compatible_railtypes = 0;
   160 	v->u.rail.compatible_railtypes = 0;
   161 
   161 
   162 	for (Vehicle *u = v; u != NULL; u = u->next) {
   162 	for (Vehicle *u = v; u != NULL; u = u->Next()) {
   163 		const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
   163 		const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
   164 
   164 
   165 		/* Update the v->first cache. This is faster than having to brute force it later. */
   165 		/* Check the v->first cache. */
   166 		if (u->first == NULL) u->first = v;
   166 		assert(u->First() == v);
   167 
   167 
   168 		/* update the 'first engine' */
   168 		/* update the 'first engine' */
   169 		u->u.rail.first_engine = v == u ? INVALID_ENGINE : first_engine;
   169 		u->u.rail.first_engine = v == u ? INVALID_ENGINE : first_engine;
   170 		u->u.rail.railtype = rvi_u->railtype;
   170 		u->u.rail.railtype = rvi_u->railtype;
   171 
   171 
   234 		uint16 veh_len = CALLBACK_FAILED;
   234 		uint16 veh_len = CALLBACK_FAILED;
   235 		if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) {
   235 		if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) {
   236 			veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
   236 			veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
   237 		}
   237 		}
   238 		if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor;
   238 		if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor;
   239 		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
   239 		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
   240 		u->u.rail.cached_veh_length = 8 - veh_len;
   240 		u->u.rail.cached_veh_length = 8 - veh_len;
   241 		v->u.rail.cached_total_length += u->u.rail.cached_veh_length;
   241 		v->u.rail.cached_total_length += u->u.rail.cached_veh_length;
   242 	}
   242 	}
   243 
   243 
   244 	/* store consist weight/max speed in cache */
   244 	/* store consist weight/max speed in cache */
   300 
   300 
   301 /** new acceleration*/
   301 /** new acceleration*/
   302 static int GetTrainAcceleration(Vehicle *v, bool mode)
   302 static int GetTrainAcceleration(Vehicle *v, bool mode)
   303 {
   303 {
   304 	int max_speed = 2000;
   304 	int max_speed = 2000;
   305 	int speed = v->cur_speed * 10 / 16; //[mph]
   305 	int speed = v->GetDisplaySpeed(); //[mph]
   306 	int curvecount[2] = {0, 0};
   306 	int curvecount[2] = {0, 0};
   307 
   307 
   308 	/*first find the curve speed limit */
   308 	/*first find the curve speed limit */
   309 	int numcurve = 0;
   309 	int numcurve = 0;
   310 	int sum = 0;
   310 	int sum = 0;
   311 	int pos = 0;
   311 	int pos = 0;
   312 	int lastpos = -1;
   312 	int lastpos = -1;
   313 	for (const Vehicle *u = v; u->next != NULL; u = u->next, pos++) {
   313 	for (const Vehicle *u = v; u->Next() != NULL; u = u->Next(), pos++) {
   314 		Direction dir = u->direction;
   314 		Direction dir = u->direction;
   315 		Direction ndir = u->next->direction;
   315 		Direction ndir = u->Next()->direction;
   316 		int i;
   316 		int i;
   317 
   317 
   318 		for (i = 0; i < 2; i++) {
   318 		for (i = 0; i < 2; i++) {
   319 			if ( _curve_neighbours45[dir][i] == ndir) {
   319 			if ( _curve_neighbours45[dir][i] == ndir) {
   320 				curvecount[i]++;
   320 				curvecount[i]++;
   370 	max_speed = min(max_speed, v->u.rail.cached_max_speed);
   370 	max_speed = min(max_speed, v->u.rail.cached_max_speed);
   371 
   371 
   372 	int num = 0; //number of vehicles, change this into the number of axles later
   372 	int num = 0; //number of vehicles, change this into the number of axles later
   373 	int incl = 0;
   373 	int incl = 0;
   374 	int drag_coeff = 20; //[1e-4]
   374 	int drag_coeff = 20; //[1e-4]
   375 	for (const Vehicle *u = v; u != NULL; u = u->next) {
   375 	for (const Vehicle *u = v; u != NULL; u = u->Next()) {
   376 		num++;
   376 		num++;
   377 		drag_coeff += 3;
   377 		drag_coeff += 3;
   378 
   378 
   379 		if (u->u.rail.track == TRACK_BIT_DEPOT) max_speed = min(max_speed, 61);
   379 		if (u->u.rail.track == TRACK_BIT_DEPOT) max_speed = min(max_speed, 61);
   380 
   380 
   557 			v = new (v) Train();
   557 			v = new (v) Train();
   558 			v->subtype = 0;
   558 			v->subtype = 0;
   559 			SetTrainWagon(v);
   559 			SetTrainWagon(v);
   560 
   560 
   561 			if (u != NULL) {
   561 			if (u != NULL) {
   562 				u->next = v;
   562 				u->SetNext(v);
   563 			} else {
   563 			} else {
   564 				SetFreeWagon(v);
   564 				SetFreeWagon(v);
   565 				InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   565 				InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   566 			}
   566 			}
   567 
   567 
   582 			AddArticulatedParts(vl, VEH_TRAIN);
   582 			AddArticulatedParts(vl, VEH_TRAIN);
   583 
   583 
   584 			_new_vehicle_id = v->index;
   584 			_new_vehicle_id = v->index;
   585 
   585 
   586 			VehiclePositionChanged(v);
   586 			VehiclePositionChanged(v);
   587 			TrainConsistChanged(GetFirstVehicleInChain(v));
   587 			TrainConsistChanged(v->First());
   588 			UpdateTrainGroupID(GetFirstVehicleInChain(v));
   588 			UpdateTrainGroupID(v->First());
   589 
   589 
   590 			InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   590 			InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   591 			if (IsLocalPlayer()) {
   591 			if (IsLocalPlayer()) {
   592 				InvalidateAutoreplaceWindow(VEH_TRAIN, v->group_id); // updates the replace Train window
   592 				InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Train window
   593 			}
   593 			}
   594 			GetPlayer(_current_player)->num_engines[engine]++;
   594 			GetPlayer(_current_player)->num_engines[engine]++;
   595 		}
   595 		}
   596 	}
   596 	}
   597 
   597 
   619 	return CommandCost(GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5);
   619 	return CommandCost(GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5);
   620 }
   620 }
   621 
   621 
   622 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
   622 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
   623 {
   623 {
       
   624 	u = new (u) Train();
   624 	u->direction = v->direction;
   625 	u->direction = v->direction;
   625 	u->owner = v->owner;
   626 	u->owner = v->owner;
   626 	u->tile = v->tile;
   627 	u->tile = v->tile;
   627 	u->x_pos = v->x_pos;
   628 	u->x_pos = v->x_pos;
   628 	u->y_pos = v->y_pos;
   629 	u->y_pos = v->y_pos;
   629 	u->z_pos = v->z_pos;
   630 	u->z_pos = v->z_pos;
   630 	u->u.rail.track = TRACK_BIT_DEPOT;
   631 	u->u.rail.track = TRACK_BIT_DEPOT;
   631 	u->vehstatus = v->vehstatus & ~VS_STOPPED;
   632 	u->vehstatus = v->vehstatus & ~VS_STOPPED;
   632 	u = new (u) Train();
       
   633 	u->subtype = 0;
   633 	u->subtype = 0;
   634 	SetMultiheaded(u);
   634 	SetMultiheaded(u);
   635 	u->spritenum = v->spritenum + 1;
   635 	u->spritenum = v->spritenum + 1;
   636 	u->cargo_type = v->cargo_type;
   636 	u->cargo_type = v->cargo_type;
   637 	u->cargo_subtype = v->cargo_subtype;
   637 	u->cargo_subtype = v->cargo_subtype;
   638 	u->cargo_cap = v->cargo_cap;
   638 	u->cargo_cap = v->cargo_cap;
   639 	u->u.rail.railtype = v->u.rail.railtype;
   639 	u->u.rail.railtype = v->u.rail.railtype;
   640 	if (building) v->next = u;
   640 	if (building) v->SetNext(u);
   641 	u->engine_type = v->engine_type;
   641 	u->engine_type = v->engine_type;
   642 	u->build_year = v->build_year;
   642 	u->build_year = v->build_year;
   643 	if (building) v->value >>= 1;
   643 	if (building) v->value >>= 1;
   644 	u->value = v->value;
   644 	u->value = v->value;
   645 	u->cur_image = 0xAC2;
   645 	u->cur_image = 0xAC2;
   771 
   771 
   772 			InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   772 			InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   773 			RebuildVehicleLists();
   773 			RebuildVehicleLists();
   774 			InvalidateWindow(WC_COMPANY, v->owner);
   774 			InvalidateWindow(WC_COMPANY, v->owner);
   775 			if (IsLocalPlayer())
   775 			if (IsLocalPlayer())
   776 				InvalidateAutoreplaceWindow(VEH_TRAIN, v->group_id); // updates the replace Train window
   776 				InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Train window
   777 
   777 
   778 			GetPlayer(_current_player)->num_engines[p1]++;
   778 			GetPlayer(_current_player)->num_engines[p1]++;
   779 		}
   779 		}
   780 	}
   780 	}
   781 
   781 
   791 
   791 
   792 	/* check if stopped in a depot */
   792 	/* check if stopped in a depot */
   793 	if (!IsTileDepotType(tile, TRANSPORT_RAIL) || v->cur_speed != 0) return -1;
   793 	if (!IsTileDepotType(tile, TRANSPORT_RAIL) || v->cur_speed != 0) return -1;
   794 
   794 
   795 	int count = 0;
   795 	int count = 0;
   796 	for (; v != NULL; v = v->next) {
   796 	for (; v != NULL; v = v->Next()) {
   797 		/* This count is used by the depot code to determine the number of engines
   797 		/* This count is used by the depot code to determine the number of engines
   798 		 * in the consist. Exclude articulated parts so that autoreplacing to
   798 		 * in the consist. Exclude articulated parts so that autoreplacing to
   799 		 * engines with more articulated parts than before works correctly.
   799 		 * engines with more articulated parts than before works correctly.
   800 		 *
   800 		 *
   801 		 * Also skip counting rear ends of multiheaded engines */
   801 		 * Also skip counting rear ends of multiheaded engines */
   839 		return v;
   839 		return v;
   840 	}
   840 	}
   841 
   841 
   842 	Vehicle *u;
   842 	Vehicle *u;
   843 	for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
   843 	for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
   844 	GetLastEnginePart(u)->next = GetNextVehicle(v);
   844 	GetLastEnginePart(u)->SetNext(GetNextVehicle(v));
   845 	v->first = NULL; // we shouldn't point to the old first, since the vehicle isn't in that chain anymore
       
   846 	return first;
   845 	return first;
   847 }
   846 }
   848 
   847 
   849 static Vehicle *FindGoodVehiclePos(const Vehicle *src)
   848 static Vehicle *FindGoodVehiclePos(const Vehicle *src)
   850 {
   849 {
   856 		if (dst->type == VEH_TRAIN && IsFreeWagon(dst) && dst->tile == tile) {
   855 		if (dst->type == VEH_TRAIN && IsFreeWagon(dst) && dst->tile == tile) {
   857 			/* check so all vehicles in the line have the same engine. */
   856 			/* check so all vehicles in the line have the same engine. */
   858 			Vehicle *v = dst;
   857 			Vehicle *v = dst;
   859 
   858 
   860 			while (v->engine_type == eng) {
   859 			while (v->engine_type == eng) {
   861 				v = v->next;
   860 				v = v->Next();
   862 				if (v == NULL) return dst;
   861 				if (v == NULL) return dst;
   863 			}
   862 			}
   864 		}
   863 		}
   865 	}
   864 	}
   866 
   865 
   871  * add a vehicle v behind vehicle dest
   870  * add a vehicle v behind vehicle dest
   872  * use this function since it sets flags as needed
   871  * use this function since it sets flags as needed
   873  */
   872  */
   874 static void AddWagonToConsist(Vehicle *v, Vehicle *dest)
   873 static void AddWagonToConsist(Vehicle *v, Vehicle *dest)
   875 {
   874 {
   876 	UnlinkWagon(v, GetFirstVehicleInChain(v));
   875 	UnlinkWagon(v, v->First());
   877 	if (dest == NULL) return;
   876 	if (dest == NULL) return;
   878 
   877 
   879 	v->next = dest->next;
   878 	Vehicle *next = dest->Next();
   880 	dest->next = v;
   879 	dest->SetNext(v);
       
   880 	v->SetNext(next);
   881 	ClearFreeWagon(v);
   881 	ClearFreeWagon(v);
   882 	ClearFrontEngine(v);
   882 	ClearFrontEngine(v);
   883 }
   883 }
   884 
   884 
   885 /*
   885 /*
   895 	for (; v != NULL; v = GetNextVehicle(v)) {
   895 	for (; v != NULL; v = GetNextVehicle(v)) {
   896 		if (!IsMultiheaded(v) || !IsTrainEngine(v)) continue;
   896 		if (!IsMultiheaded(v) || !IsTrainEngine(v)) continue;
   897 
   897 
   898 		/* make sure that there are no free cars before next engine */
   898 		/* make sure that there are no free cars before next engine */
   899 		Vehicle *u;
   899 		Vehicle *u;
   900 		for (u = v; u->next != NULL && !IsTrainEngine(u->next); u = u->next) {}
   900 		for (u = v; u->Next() != NULL && !IsTrainEngine(u->Next()); u = u->Next()) {}
   901 
   901 
   902 		if (u == v->u.rail.other_multiheaded_part) continue;
   902 		if (u == v->u.rail.other_multiheaded_part) continue;
   903 		AddWagonToConsist(v->u.rail.other_multiheaded_part, u);
   903 		AddWagonToConsist(v->u.rail.other_multiheaded_part, u);
   904 	}
   904 	}
   905 }
   905 }
   932 		dst = GetVehicle(d);
   932 		dst = GetVehicle(d);
   933 		if (dst->type != VEH_TRAIN || !CheckOwnership(dst->owner)) return CMD_ERROR;
   933 		if (dst->type != VEH_TRAIN || !CheckOwnership(dst->owner)) return CMD_ERROR;
   934 	}
   934 	}
   935 
   935 
   936 	/* if an articulated part is being handled, deal with its parent vehicle */
   936 	/* if an articulated part is being handled, deal with its parent vehicle */
   937 	while (IsArticulatedPart(src)) src = GetPrevVehicleInChain(src);
   937 	while (IsArticulatedPart(src)) src = src->Previous();
   938 	if (dst != NULL) {
   938 	if (dst != NULL) {
   939 		while (IsArticulatedPart(dst)) dst = GetPrevVehicleInChain(dst);
   939 		while (IsArticulatedPart(dst)) dst = dst->Previous();
   940 	}
   940 	}
   941 
   941 
   942 	/* don't move the same vehicle.. */
   942 	/* don't move the same vehicle.. */
   943 	if (src == dst) return CommandCost();
   943 	if (src == dst) return CommandCost();
   944 
   944 
   945 	/* locate the head of the two chains */
   945 	/* locate the head of the two chains */
   946 	Vehicle *src_head = GetFirstVehicleInChain(src);
   946 	Vehicle *src_head = src->First();
   947 	Vehicle *dst_head;
   947 	Vehicle *dst_head;
   948 	if (dst != NULL) {
   948 	if (dst != NULL) {
   949 		dst_head = GetFirstVehicleInChain(dst);
   949 		dst_head = dst->First();
   950 		if (dst_head->tile != src_head->tile) return CMD_ERROR;
   950 		if (dst_head->tile != src_head->tile) return CMD_ERROR;
   951 		/* Now deal with articulated part of destination wagon */
   951 		/* Now deal with articulated part of destination wagon */
   952 		dst = GetLastEnginePart(dst);
   952 		dst = GetLastEnginePart(dst);
   953 	} else {
   953 	} else {
   954 		dst_head = NULL;
   954 		dst_head = NULL;
  1021 		}
  1021 		}
  1022 	}
  1022 	}
  1023 
  1023 
  1024 	/* do it? */
  1024 	/* do it? */
  1025 	if (flags & DC_EXEC) {
  1025 	if (flags & DC_EXEC) {
  1026 		/* clear the ->first cache */
       
  1027 		for (Vehicle *u = src_head; u != NULL; u = u->next) u->first = NULL;
       
  1028 		for (Vehicle *u = dst_head; u != NULL; u = u->next) u->first = NULL;
       
  1029 
       
  1030 		/* If we move the front Engine and if the second vehicle is not an engine
  1026 		/* If we move the front Engine and if the second vehicle is not an engine
  1031 		   add the whole vehicle to the DEFAULT_GROUP */
  1027 		   add the whole vehicle to the DEFAULT_GROUP */
  1032 		if (IsFrontEngine(src) && !IsDefaultGroupID(src->group_id)) {
  1028 		if (IsFrontEngine(src) && !IsDefaultGroupID(src->group_id)) {
  1033 			const Vehicle *v = GetNextVehicle(src);
  1029 			const Vehicle *v = GetNextVehicle(src);
  1034 
  1030 
  1040 		if (HASBIT(p2, 0)) {
  1036 		if (HASBIT(p2, 0)) {
  1041 			/* unlink ALL wagons */
  1037 			/* unlink ALL wagons */
  1042 			if (src != src_head) {
  1038 			if (src != src_head) {
  1043 				Vehicle *v = src_head;
  1039 				Vehicle *v = src_head;
  1044 				while (GetNextVehicle(v) != src) v = GetNextVehicle(v);
  1040 				while (GetNextVehicle(v) != src) v = GetNextVehicle(v);
  1045 				GetLastEnginePart(v)->next = NULL;
  1041 				GetLastEnginePart(v)->SetNext(NULL);
  1046 			} else {
  1042 			} else {
  1047 				InvalidateWindowData(WC_VEHICLE_DEPOT, src_head->tile); // We removed a line
  1043 				InvalidateWindowData(WC_VEHICLE_DEPOT, src_head->tile); // We removed a line
  1048 				src_head = NULL;
  1044 				src_head = NULL;
  1049 			}
  1045 			}
  1050 		} else {
  1046 		} else {
  1051 			/* if moving within the same chain, dont use dst_head as it may get invalidated */
  1047 			/* if moving within the same chain, dont use dst_head as it may get invalidated */
  1052 			if (src_head == dst_head) dst_head = NULL;
  1048 			if (src_head == dst_head) dst_head = NULL;
  1053 			/* unlink single wagon from linked list */
  1049 			/* unlink single wagon from linked list */
  1054 			src_head = UnlinkWagon(src, src_head);
  1050 			src_head = UnlinkWagon(src, src_head);
  1055 			GetLastEnginePart(src)->next = NULL;
  1051 			GetLastEnginePart(src)->SetNext(NULL);
  1056 		}
  1052 		}
  1057 
  1053 
  1058 		if (dst == NULL) {
  1054 		if (dst == NULL) {
  1059 			/* We make a new line in the depot, so we know already that we invalidate the window data */
  1055 			/* We make a new line in the depot, so we know already that we invalidate the window data */
  1060 			InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile);
  1056 			InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile);
  1096 			/* link in the wagon(s) in the chain. */
  1092 			/* link in the wagon(s) in the chain. */
  1097 			{
  1093 			{
  1098 				Vehicle *v;
  1094 				Vehicle *v;
  1099 
  1095 
  1100 				for (v = src; GetNextVehicle(v) != NULL; v = GetNextVehicle(v));
  1096 				for (v = src; GetNextVehicle(v) != NULL; v = GetNextVehicle(v));
  1101 				GetLastEnginePart(v)->next = dst->next;
  1097 				GetLastEnginePart(v)->SetNext(dst->Next());
  1102 			}
  1098 			}
  1103 			dst->next = src;
  1099 			dst->SetNext(src);
  1104 		}
  1100 		}
       
  1101 
  1105 		if (src->u.rail.other_multiheaded_part != NULL) {
  1102 		if (src->u.rail.other_multiheaded_part != NULL) {
  1106 			if (src->u.rail.other_multiheaded_part == src_head) {
  1103 			if (src->u.rail.other_multiheaded_part == src_head) {
  1107 				src_head = src_head->next;
  1104 				src_head = src_head->Next();
  1108 			}
  1105 			}
  1109 			AddWagonToConsist(src->u.rail.other_multiheaded_part, src);
  1106 			AddWagonToConsist(src->u.rail.other_multiheaded_part, src);
  1110 			/* previous line set the front engine to the old front. We need to clear that */
       
  1111 			src->u.rail.other_multiheaded_part->first = NULL;
       
  1112 		}
  1107 		}
  1113 
  1108 
  1114 		/* If there is an engine behind first_engine we moved away, it should become new first_engine
  1109 		/* If there is an engine behind first_engine we moved away, it should become new first_engine
  1115 		 * To do this, CmdMoveRailVehicle must be called once more
  1110 		 * To do this, CmdMoveRailVehicle must be called once more
  1116 		 * we can't loop forever here because next time we reach this line we will have a front engine */
  1111 		 * we can't loop forever here because next time we reach this line we will have a front engine */
  1217 
  1212 
  1218 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  1213 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  1219 
  1214 
  1220 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
  1215 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
  1221 
  1216 
  1222 	while (IsArticulatedPart(v)) v = GetPrevVehicleInChain(v);
  1217 	while (IsArticulatedPart(v)) v = v->Previous();
  1223 	Vehicle *first = GetFirstVehicleInChain(v);
  1218 	Vehicle *first = v->First();
  1224 
  1219 
  1225 	/* make sure the vehicle is stopped in the depot */
  1220 	/* make sure the vehicle is stopped in the depot */
  1226 	if (CheckTrainStoppedInDepot(first) < 0) {
  1221 	if (CheckTrainStoppedInDepot(first) < 0) {
  1227 		return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
  1222 		return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
  1228 	}
  1223 	}
  1260 
  1255 
  1261 			/* 2. We are selling the first engine, some special action might be required
  1256 			/* 2. We are selling the first engine, some special action might be required
  1262 			 * here, so take attention */
  1257 			 * here, so take attention */
  1263 			if ((flags & DC_EXEC) && v == first) {
  1258 			if ((flags & DC_EXEC) && v == first) {
  1264 				Vehicle *new_f = GetNextVehicle(first);
  1259 				Vehicle *new_f = GetNextVehicle(first);
  1265 
       
  1266 				/* 2.1 If the first wagon is sold, update the first-> pointers to NULL */
       
  1267 				for (Vehicle *tmp = first; tmp != NULL; tmp = tmp->next) tmp->first = NULL;
       
  1268 
  1260 
  1269 				/* 2.2 If there are wagons present after the deleted front engine, check
  1261 				/* 2.2 If there are wagons present after the deleted front engine, check
  1270 				 * if the second wagon (which will be first) is an engine. If it is one,
  1262 				 * if the second wagon (which will be first) is an engine. If it is one,
  1271 				 * promote it as a new train, retaining the unitnumber, orders */
  1263 				 * promote it as a new train, retaining the unitnumber, orders */
  1272 				if (new_f != NULL && IsTrainEngine(new_f)) {
  1264 				if (new_f != NULL && IsTrainEngine(new_f)) {
  1298 					first->orders      = NULL;
  1290 					first->orders      = NULL;
  1299 					first->prev_shared = NULL;
  1291 					first->prev_shared = NULL;
  1300 					first->next_shared = NULL;
  1292 					first->next_shared = NULL;
  1301 
  1293 
  1302 					/* If we deleted a window then open a new one for the 'new' train */
  1294 					/* If we deleted a window then open a new one for the 'new' train */
  1303 					if (IsLocalPlayer() && w != NULL) ShowTrainViewWindow(new_f);
  1295 					if (IsLocalPlayer() && w != NULL) ShowVehicleViewWindow(new_f);
  1304 				}
  1296 				}
  1305 			}
  1297 			}
  1306 
  1298 
  1307 			/* 3. Delete the requested wagon */
  1299 			/* 3. Delete the requested wagon */
  1308 			cost.AddCost(-v->value);
  1300 			cost.AddCost(-v->value);
  1469 static void ReverseTrainSwapVeh(Vehicle *v, int l, int r)
  1461 static void ReverseTrainSwapVeh(Vehicle *v, int l, int r)
  1470 {
  1462 {
  1471 	Vehicle *a, *b;
  1463 	Vehicle *a, *b;
  1472 
  1464 
  1473 	/* locate vehicles to swap */
  1465 	/* locate vehicles to swap */
  1474 	for (a = v; l != 0; l--) a = a->next;
  1466 	for (a = v; l != 0; l--) a = a->Next();
  1475 	for (b = v; r != 0; r--) b = b->next;
  1467 	for (b = v; r != 0; r--) b = b->Next();
  1476 
  1468 
  1477 	if (a != b) {
  1469 	if (a != b) {
  1478 		/* swap the hidden bits */
  1470 		/* swap the hidden bits */
  1479 		{
  1471 		{
  1480 			uint16 tmp = (a->vehstatus & ~VS_HIDDEN) | (b->vehstatus&VS_HIDDEN);
  1472 			uint16 tmp = (a->vehstatus & ~VS_HIDDEN) | (b->vehstatus&VS_HIDDEN);
  1538  * @param before Set to true for the call before reversing, false otherwise
  1530  * @param before Set to true for the call before reversing, false otherwise
  1539  */
  1531  */
  1540 static void AdvanceWagons(Vehicle *v, bool before)
  1532 static void AdvanceWagons(Vehicle *v, bool before)
  1541 {
  1533 {
  1542 	Vehicle *base = v;
  1534 	Vehicle *base = v;
  1543 	Vehicle *first = base->next;
  1535 	Vehicle *first = base->Next();
  1544 	uint length = CountVehiclesInChain(v);
  1536 	uint length = CountVehiclesInChain(v);
  1545 
  1537 
  1546 	while (length > 2) {
  1538 	while (length > 2) {
  1547 		/* find pairwise matching wagon
  1539 		/* find pairwise matching wagon
  1548 		 * start<>end, start+1<>end-1, ... */
  1540 		 * start<>end, start+1<>end-1, ... */
  1549 		Vehicle *last = first;
  1541 		Vehicle *last = first;
  1550 		for (uint i = length - 3; i > 0; i--) last = last->next;
  1542 		for (uint i = length - 3; i > 0; i--) last = last->Next();
  1551 
  1543 
  1552 		int differential = last->u.rail.cached_veh_length - base->u.rail.cached_veh_length;
  1544 		int differential = last->u.rail.cached_veh_length - base->u.rail.cached_veh_length;
  1553 		if (before) differential *= -1;
  1545 		if (before) differential *= -1;
  1554 
  1546 
  1555 		if (differential > 0) {
  1547 		if (differential > 0) {
  1556 			/* disconnect last car to make sure only this subset moves */
  1548 			/* disconnect last car to make sure only this subset moves */
  1557 			Vehicle *tempnext = last->next;
  1549 			Vehicle *tempnext = last->Next();
  1558 			last->next = NULL;
  1550 			last->SetNext(NULL);
  1559 
  1551 
  1560 			for (int i = 0; i < differential; i++) TrainController(first, false);
  1552 			for (int i = 0; i < differential; i++) TrainController(first, false);
  1561 
  1553 
  1562 			last->next = tempnext;
  1554 			last->SetNext(tempnext);
  1563 		}
  1555 		}
  1564 
  1556 
  1565 		base = first;
  1557 		base = first;
  1566 		first = first->next;
  1558 		first = first->Next();
  1567 		length -= 2;
  1559 		length -= 2;
  1568 	}
  1560 	}
  1569 }
  1561 }
  1570 
  1562 
  1571 
  1563 
  1592 	}
  1584 	}
  1593 
  1585 
  1594 	/* count number of vehicles */
  1586 	/* count number of vehicles */
  1595 	int r = -1;
  1587 	int r = -1;
  1596 	const Vehicle *u = v;
  1588 	const Vehicle *u = v;
  1597 	do r++; while ( (u = u->next) != NULL );
  1589 	do r++; while ((u = u->Next()) != NULL);
  1598 
  1590 
  1599 	AdvanceWagons(v, true);
  1591 	AdvanceWagons(v, true);
  1600 
  1592 
  1601 	/* swap start<>end, start+1<>end-1, ... */
  1593 	/* swap start<>end, start+1<>end-1, ... */
  1602 	int l = 0;
  1594 	int l = 0;
  1632 
  1624 
  1633 		if (IsMultiheaded(v) || HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) {
  1625 		if (IsMultiheaded(v) || HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) {
  1634 			return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
  1626 			return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
  1635 		}
  1627 		}
  1636 
  1628 
  1637 		Vehicle *front = GetFirstVehicleInChain(v);
  1629 		Vehicle *front = v->First();
  1638 		/* make sure the vehicle is stopped in the depot */
  1630 		/* make sure the vehicle is stopped in the depot */
  1639 		if (CheckTrainStoppedInDepot(front) < 0) {
  1631 		if (CheckTrainStoppedInDepot(front) < 0) {
  1640 			return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
  1632 			return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
  1641 		}
  1633 		}
  1642 
  1634 
  1644 			TOGGLEBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION);
  1636 			TOGGLEBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION);
  1645 			InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1637 			InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1646 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  1638 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  1647 		}
  1639 		}
  1648 	} else {
  1640 	} else {
  1649 		/*turn the whole train around */
  1641 		/* turn the whole train around */
  1650 		if (v->u.rail.crash_anim_pos != 0 || v->breakdown_ctr != 0) return CMD_ERROR;
  1642 		if (v->vehstatus & VS_CRASHED || v->breakdown_ctr != 0) return CMD_ERROR;
  1651 
  1643 
  1652 		if (flags & DC_EXEC) {
  1644 		if (flags & DC_EXEC) {
  1653 			if (_patches.realistic_acceleration && v->cur_speed != 0) {
  1645 			if (_patches.realistic_acceleration && v->cur_speed != 0) {
  1654 				TOGGLEBIT(v->u.rail.flags, VRF_REVERSING);
  1646 				TOGGLEBIT(v->u.rail.flags, VRF_REVERSING);
  1655 			} else {
  1647 			} else {
  1771 					InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1763 					InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1772 					RebuildVehicleLists();
  1764 					RebuildVehicleLists();
  1773 				}
  1765 				}
  1774 			}
  1766 			}
  1775 		}
  1767 		}
  1776 	} while ((v = v->next) != NULL && !only_this);
  1768 	} while ((v = v->Next()) != NULL && !only_this);
  1777 
  1769 
  1778 	_returned_refit_capacity = num;
  1770 	_returned_refit_capacity = num;
  1779 
  1771 
  1780 	/* Update the train's cached variables */
  1772 	/* Update the train's cached variables */
  1781 	if (flags & DC_EXEC) TrainConsistChanged(GetFirstVehicleInChain(GetVehicle(p1)));
  1773 	if (flags & DC_EXEC) TrainConsistChanged(GetVehicle(p1)->First());
  1782 
  1774 
  1783 	return cost;
  1775 	return cost;
  1784 }
  1776 }
  1785 
  1777 
  1786 struct TrainFindDepotData {
  1778 struct TrainFindDepotData {
  2016 				CreateEffectVehicleRel(v, 0, 0, 10, EV_ELECTRIC_SPARK);
  2008 				CreateEffectVehicleRel(v, 0, 0, 10, EV_ELECTRIC_SPARK);
  2017 				sound = true;
  2009 				sound = true;
  2018 			}
  2010 			}
  2019 			break;
  2011 			break;
  2020 		}
  2012 		}
  2021 	} while ((v = v->next) != NULL);
  2013 	} while ((v = v->Next()) != NULL);
  2022 
  2014 
  2023 	if (sound) PlayVehicleSound(u, VSE_TRAIN_EFFECT);
  2015 	if (sound) PlayVehicleSound(u, VSE_TRAIN_EFFECT);
  2024 }
  2016 }
  2025 
  2017 
  2026 static void TrainPlayLeaveStationSound(const Vehicle* v)
  2018 static void TrainPlayLeaveStationSound(const Vehicle* v)
  2045 }
  2037 }
  2046 
  2038 
  2047 static bool CheckTrainStayInDepot(Vehicle *v)
  2039 static bool CheckTrainStayInDepot(Vehicle *v)
  2048 {
  2040 {
  2049 	/* bail out if not all wagons are in the same depot or not in a depot at all */
  2041 	/* bail out if not all wagons are in the same depot or not in a depot at all */
  2050 	for (const Vehicle *u = v; u != NULL; u = u->next) {
  2042 	for (const Vehicle *u = v; u != NULL; u = u->Next()) {
  2051 		if (u->u.rail.track != TRACK_BIT_DEPOT || u->tile != v->tile) return false;
  2043 		if (u->u.rail.track != TRACK_BIT_DEPOT || u->tile != v->tile) return false;
  2052 	}
  2044 	}
  2053 
  2045 
  2054 	/* if the train got no power, then keep it in the depot */
  2046 	/* if the train got no power, then keep it in the depot */
  2055 	if (v->u.rail.cached_power == 0) {
  2047 	if (v->u.rail.cached_power == 0) {
  2469 {
  2461 {
  2470 	Vehicle *v = this;
  2462 	Vehicle *v = this;
  2471 	do {
  2463 	do {
  2472 		v->cur_image = v->GetImage(v->direction);
  2464 		v->cur_image = v->GetImage(v->direction);
  2473 		MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
  2465 		MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
  2474 	} while ((v = v->next) != NULL);
  2466 	} while ((v = v->Next()) != NULL);
  2475 
  2467 
  2476 	/* need to update acceleration and cached values since the goods on the train changed. */
  2468 	/* need to update acceleration and cached values since the goods on the train changed. */
  2477 	TrainCargoChanged(this);
  2469 	TrainCargoChanged(this);
  2478 	UpdateTrainAcceleration(this);
  2470 	UpdateTrainAcceleration(this);
  2479 }
  2471 }
  2717 			v->u.rail.track != TRACK_BIT_DEPOT &&
  2709 			v->u.rail.track != TRACK_BIT_DEPOT &&
  2718 			myabs(v->z_pos - tcc->v->z_pos) < 6 &&
  2710 			myabs(v->z_pos - tcc->v->z_pos) < 6 &&
  2719 			myabs(v->x_pos - tcc->v->x_pos) < 6 &&
  2711 			myabs(v->x_pos - tcc->v->x_pos) < 6 &&
  2720 			myabs(v->y_pos - tcc->v->y_pos) < 6 ) {
  2712 			myabs(v->y_pos - tcc->v->y_pos) < 6 ) {
  2721 
  2713 
  2722 		Vehicle *coll = GetFirstVehicleInChain(v);
  2714 		Vehicle *coll = v->First();
  2723 
  2715 
  2724 		/* it can't collide with its own wagons */
  2716 		/* it can't collide with its own wagons */
  2725 		if (tcc->v == coll ||
  2717 		if (tcc->v == coll ||
  2726 			(tcc->v->u.rail.track == TRACK_BIT_WORMHOLE && (tcc->v->direction & 2) != (v->direction & 2)))
  2718 			(tcc->v->u.rail.track == TRACK_BIT_WORMHOLE && (tcc->v->direction & 2) != (v->direction & 2)))
  2727 			return NULL;
  2719 			return NULL;
  2755 
  2747 
  2756 	assert(v->u.rail.track == TRACK_BIT_WORMHOLE || TileVirtXY(v->x_pos, v->y_pos) == v->tile);
  2748 	assert(v->u.rail.track == TRACK_BIT_WORMHOLE || TileVirtXY(v->x_pos, v->y_pos) == v->tile);
  2757 
  2749 
  2758 	TrainCollideChecker tcc;
  2750 	TrainCollideChecker tcc;
  2759 	tcc.v = v;
  2751 	tcc.v = v;
  2760 	tcc.v_skip = v->next;
  2752 	tcc.v_skip = v->Next();
  2761 	tcc.num = 0;
  2753 	tcc.num = 0;
  2762 
  2754 
  2763 	/* find colliding vehicles */
  2755 	/* find colliding vehicles */
  2764 	if (v->u.rail.track == TRACK_BIT_WORMHOLE) {
  2756 	if (v->u.rail.track == TRACK_BIT_WORMHOLE) {
  2765 		VehicleFromPos(v->tile, &tcc, FindTrainCollideEnum);
  2757 		VehicleFromPos(v->tile, &tcc, FindTrainCollideEnum);
  2807 static void TrainController(Vehicle *v, bool update_image)
  2799 static void TrainController(Vehicle *v, bool update_image)
  2808 {
  2800 {
  2809 	Vehicle *prev;
  2801 	Vehicle *prev;
  2810 
  2802 
  2811 	/* For every vehicle after and including the given vehicle */
  2803 	/* For every vehicle after and including the given vehicle */
  2812 	for (prev = GetPrevVehicleInChain(v); v != NULL; prev = v, v = v->next) {
  2804 	for (prev = v->Previous(); v != NULL; prev = v, v = v->Next()) {
  2813 		DiagDirection enterdir = DIAGDIR_BEGIN;
  2805 		DiagDirection enterdir = DIAGDIR_BEGIN;
  2814 		bool update_signals = false;
  2806 		bool update_signals = false;
  2815 		BeginVehicleMove(v);
  2807 		BeginVehicleMove(v);
  2816 
  2808 
  2817 		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
  2809 		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
  2934 				uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2926 				uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2935 				if (HASBIT(r, VETS_CANNOT_ENTER)) {
  2927 				if (HASBIT(r, VETS_CANNOT_ENTER)) {
  2936 					goto invalid_rail;
  2928 					goto invalid_rail;
  2937 				}
  2929 				}
  2938 
  2930 
  2939 				if (IsLevelCrossingTile(v->tile) && v->next == NULL) {
  2931 				if (IsLevelCrossingTile(v->tile) && v->Next() == NULL) {
  2940 					UnbarCrossing(v->tile);
  2932 					UnbarCrossing(v->tile);
  2941 					MarkTileDirtyByTile(v->tile);
  2933 					MarkTileDirtyByTile(v->tile);
  2942 				}
  2934 				}
  2943 
  2935 
  2944 				if (IsFrontEngine(v)) v->load_unload_time_rem = 0;
  2936 				if (IsFrontEngine(v)) v->load_unload_time_rem = 0;
  2945 
  2937 
  2946 				if (!HASBIT(r, VETS_ENTERED_WORMHOLE)) {
  2938 				if (!HASBIT(r, VETS_ENTERED_WORMHOLE)) {
  2947 					v->tile = gp.new_tile;
  2939 					v->tile = gp.new_tile;
  2948 
  2940 
  2949 					if (GetTileRailType(gp.new_tile) != GetTileRailType(gp.old_tile)) {
  2941 					if (GetTileRailType(gp.new_tile) != GetTileRailType(gp.old_tile)) {
  2950 						TrainPowerChanged(GetFirstVehicleInChain(v));
  2942 						TrainPowerChanged(v->First());
  2951 					}
  2943 					}
  2952 
  2944 
  2953 					v->u.rail.track = chosen_track;
  2945 					v->u.rail.track = chosen_track;
  2954 					assert(v->u.rail.track);
  2946 					assert(v->u.rail.track);
  2955 				}
  2947 				}
  2997 		if (update_signals) {
  2989 		if (update_signals) {
  2998 			if (IsFrontEngine(v)) TrainMovedChangeSignals(gp.new_tile, enterdir);
  2990 			if (IsFrontEngine(v)) TrainMovedChangeSignals(gp.new_tile, enterdir);
  2999 
  2991 
  3000 			/* Signals can only change when the first
  2992 			/* Signals can only change when the first
  3001 			 * (above) or the last vehicle moves. */
  2993 			 * (above) or the last vehicle moves. */
  3002 			if (v->next == NULL) TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir));
  2994 			if (v->Next() == NULL) TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir));
  3003 		}
  2995 		}
  3004 	}
  2996 	}
  3005 	return;
  2997 	return;
  3006 
  2998 
  3007 invalid_rail:
  2999 invalid_rail:
  3028 {
  3020 {
  3029 	/* Go to the last wagon and delete the link pointing there
  3021 	/* Go to the last wagon and delete the link pointing there
  3030 	 * *u is then the one-before-last wagon, and *v the last
  3022 	 * *u is then the one-before-last wagon, and *v the last
  3031 	 * one which will physicially be removed */
  3023 	 * one which will physicially be removed */
  3032 	Vehicle *u = v;
  3024 	Vehicle *u = v;
  3033 	for (; v->next != NULL; v = v->next) u = v;
  3025 	for (; v->Next() != NULL; v = v->Next()) u = v;
  3034 	u->next = NULL;
  3026 	u->SetNext(NULL);
  3035 
  3027 
  3036 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  3028 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  3037 	DeleteWindowById(WC_VEHICLE_VIEW, v->index);
  3029 	DeleteWindowById(WC_VEHICLE_VIEW, v->index);
  3038 	RebuildVehicleLists();
  3030 	RebuildVehicleLists();
  3039 	InvalidateWindow(WC_COMPANY, v->owner);
  3031 	InvalidateWindow(WC_COMPANY, v->owner);
  3090 			/* Refrain from updating the z position of the vehicle when on
  3082 			/* Refrain from updating the z position of the vehicle when on
  3091 			   a bridge, because AfterSetTrainPos will put the vehicle under
  3083 			   a bridge, because AfterSetTrainPos will put the vehicle under
  3092 			   the bridge in that case */
  3084 			   the bridge in that case */
  3093 			if (v->u.rail.track != TRACK_BIT_WORMHOLE) AfterSetTrainPos(v, false);
  3085 			if (v->u.rail.track != TRACK_BIT_WORMHOLE) AfterSetTrainPos(v, false);
  3094 		}
  3086 		}
  3095 	} while ((v = v->next) != NULL);
  3087 	} while ((v = v->Next()) != NULL);
  3096 }
  3088 }
  3097 
  3089 
  3098 static void HandleCrashedTrain(Vehicle *v)
  3090 static void HandleCrashedTrain(Vehicle *v)
  3099 {
  3091 {
  3100 	int state = ++v->u.rail.crash_anim_pos;
  3092 	int state = ++v->u.rail.crash_anim_pos;
  3117 					GB(r, 16, 3) + 2,
  3109 					GB(r, 16, 3) + 2,
  3118 					GB(r,  0, 3) + 5,
  3110 					GB(r,  0, 3) + 5,
  3119 					EV_EXPLOSION_SMALL);
  3111 					EV_EXPLOSION_SMALL);
  3120 				break;
  3112 				break;
  3121 			}
  3113 			}
  3122 		} while ((u = u->next) != NULL);
  3114 		} while ((u = u->Next()) != NULL);
  3123 	}
  3115 	}
  3124 
  3116 
  3125 	if (state <= 240 && !(v->tick_counter & 3)) ChangeTrainDirRandomly(v);
  3117 	if (state <= 240 && !(v->tick_counter & 3)) ChangeTrainDirRandomly(v);
  3126 
  3118 
  3127 	if (state >= 4440 && !(v->tick_counter&0x1F)) {
  3119 	if (state >= 4440 && !(v->tick_counter&0x1F)) {
  3255 }
  3247 }
  3256 
  3248 
  3257 static void TrainLocoHandler(Vehicle *v, bool mode)
  3249 static void TrainLocoHandler(Vehicle *v, bool mode)
  3258 {
  3250 {
  3259 	/* train has crashed? */
  3251 	/* train has crashed? */
  3260 	if (v->u.rail.crash_anim_pos != 0) {
  3252 	if (v->vehstatus & VS_CRASHED) {
  3261 		if (!mode) HandleCrashedTrain(v);
  3253 		if (!mode) HandleCrashedTrain(v);
  3262 		return;
  3254 		return;
  3263 	}
  3255 	}
  3264 
  3256 
  3265 	if (v->u.rail.force_proceed != 0) v->u.rail.force_proceed--;
  3257 	if (v->u.rail.force_proceed != 0) v->u.rail.force_proceed--;
  3313 
  3305 
  3314 	SetLastSpeed(v, v->cur_speed);
  3306 	SetLastSpeed(v, v->cur_speed);
  3315 }
  3307 }
  3316 
  3308 
  3317 
  3309 
       
  3310 
       
  3311 Money Train::GetRunningCost() const
       
  3312 {
       
  3313 	Money cost = 0;
       
  3314 	const Vehicle *v = this;
       
  3315 
       
  3316 	do {
       
  3317 		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
       
  3318 
       
  3319 		byte cost_factor = GetVehicleProperty(v, 0x0D, rvi->running_cost_base);
       
  3320 		if (cost_factor == 0) continue;
       
  3321 
       
  3322 		cost += cost_factor * _price.running_rail[rvi->running_cost_class];
       
  3323 	} while ((v = GetNextVehicle(v)) != NULL);
       
  3324 
       
  3325 	return cost;
       
  3326 }
       
  3327 
       
  3328 
  3318 void Train::Tick()
  3329 void Train::Tick()
  3319 {
  3330 {
  3320 	if (_age_cargo_skip_counter == 0) this->cargo.AgeCargo();
  3331 	if (_age_cargo_skip_counter == 0) this->cargo.AgeCargo();
  3321 
  3332 
  3322 	this->tick_counter++;
  3333 	this->tick_counter++;
  3337 
  3348 
  3338 #define MAX_ACCEPTABLE_DEPOT_DIST 16
  3349 #define MAX_ACCEPTABLE_DEPOT_DIST 16
  3339 
  3350 
  3340 static void CheckIfTrainNeedsService(Vehicle *v)
  3351 static void CheckIfTrainNeedsService(Vehicle *v)
  3341 {
  3352 {
  3342 	if (_patches.servint_trains == 0)                   return;
  3353 	if (_patches.servint_trains == 0 || !VehicleNeedsService(v)) return;
  3343 	if (!VehicleNeedsService(v))                        return;
  3354 	if (v->IsInDepot()) {
  3344 	if (v->vehstatus & VS_STOPPED)                      return;
       
  3345 	if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
       
  3346 
       
  3347 	/* Don't interfere with a depot visit scheduled by the user, or a
       
  3348 	 * depot visit by the order list. */
       
  3349 	if (v->current_order.type == OT_GOTO_DEPOT &&
       
  3350 			(v->current_order.flags & (OF_HALT_IN_DEPOT | OF_PART_OF_ORDERS)) != 0)
       
  3351 		return;
       
  3352 
       
  3353 	if (CheckTrainIsInsideDepot(v)) {
       
  3354 		VehicleServiceInDepot(v);
  3355 		VehicleServiceInDepot(v);
  3355 		return;
  3356 		return;
  3356 	}
  3357 	}
  3357 
  3358 
  3358 	TrainFindDepotData tfdd = FindClosestTrainDepot(v, MAX_ACCEPTABLE_DEPOT_DIST);
  3359 	TrainFindDepotData tfdd = FindClosestTrainDepot(v, MAX_ACCEPTABLE_DEPOT_DIST);
  3375 			v->current_order.dest != depot->index &&
  3376 			v->current_order.dest != depot->index &&
  3376 			!CHANCE16(3, 16)) {
  3377 			!CHANCE16(3, 16)) {
  3377 		return;
  3378 		return;
  3378 	}
  3379 	}
  3379 
  3380 
  3380 	if (v->current_order.type == OT_LOADING) v->LeaveStation();
       
  3381 
       
  3382 	v->current_order.type = OT_GOTO_DEPOT;
  3381 	v->current_order.type = OT_GOTO_DEPOT;
  3383 	v->current_order.flags = OF_NON_STOP;
  3382 	v->current_order.flags = OF_NON_STOP;
  3384 	v->current_order.dest = depot->index;
  3383 	v->current_order.dest = depot->index;
  3385 	v->dest_tile = tfdd.tile;
  3384 	v->dest_tile = tfdd.tile;
  3386 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  3385 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  3387 }
  3386 }
  3388 
  3387 
  3389 Money GetTrainRunningCost(const Vehicle *v)
       
  3390 {
       
  3391 	Money cost = 0;
       
  3392 
       
  3393 	do {
       
  3394 		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
       
  3395 
       
  3396 		byte cost_factor = GetVehicleProperty(v, 0x0D, rvi->running_cost_base);
       
  3397 		if (cost_factor == 0) continue;
       
  3398 
       
  3399 		cost += cost_factor * _price.running_rail[rvi->running_cost_class];
       
  3400 	} while ((v = GetNextVehicle(v)) != NULL);
       
  3401 
       
  3402 	return cost;
       
  3403 }
       
  3404 
       
  3405 void OnNewDay_Train(Vehicle *v)
  3388 void OnNewDay_Train(Vehicle *v)
  3406 {
  3389 {
  3407 	if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
  3390 	if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
  3408 
  3391 
  3409 	if (IsFrontEngine(v)) {
  3392 	if (IsFrontEngine(v)) {
  3420 			if (tile != 0) v->dest_tile = tile;
  3403 			if (tile != 0) v->dest_tile = tile;
  3421 		}
  3404 		}
  3422 
  3405 
  3423 		if ((v->vehstatus & VS_STOPPED) == 0) {
  3406 		if ((v->vehstatus & VS_STOPPED) == 0) {
  3424 			/* running costs */
  3407 			/* running costs */
  3425 			CommandCost cost(GetTrainRunningCost(v) / 364);
  3408 			CommandCost cost(v->GetRunningCost() / 364);
  3426 
  3409 
  3427 			v->profit_this_year -= cost.GetCost() >> 8;
  3410 			v->profit_this_year -= cost.GetCost() >> 8;
  3428 
  3411 
  3429 			SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
  3412 			SET_EXPENSES_TYPE(EXPENSES_TRAIN_RUN);
  3430 			SubtractMoneyFromPlayerFract(v->owner, cost);
  3413 			SubtractMoneyFromPlayerFract(v->owner, cost);
  3495 						SetTrainEngine(u);
  3478 						SetTrainEngine(u);
  3496 						u->spritenum--;
  3479 						u->spritenum--;
  3497 					}
  3480 					}
  3498 
  3481 
  3499 					Vehicle *w;
  3482 					Vehicle *w;
  3500 					for (w = u->next; w != NULL && (w->engine_type != u->engine_type || w->u.rail.other_multiheaded_part != NULL); w = GetNextVehicle(w));
  3483 					for (w = u->Next(); w != NULL && (w->engine_type != u->engine_type || w->u.rail.other_multiheaded_part != NULL); w = GetNextVehicle(w));
  3501 					if (w != NULL) {
  3484 					if (w != NULL) {
  3502 						/* we found a car to partner with this engine. Now we will make sure it face the right way */
  3485 						/* we found a car to partner with this engine. Now we will make sure it face the right way */
  3503 						if (IsTrainEngine(w)) {
  3486 						if (IsTrainEngine(w)) {
  3504 							ClearTrainEngine(w);
  3487 							ClearTrainEngine(w);
  3505 							w->spritenum++;
  3488 							w->spritenum++;