src/train_cmd.cpp
changeset 7928 63e18de69e50
parent 7923 91982bd3c549
child 7929 6c9b25842b0f
equal deleted inserted replaced
7927:3a3289a049f9 7928:63e18de69e50
    88 				/* Tractive effort in (tonnes * 1000 * 10 =) N */
    88 				/* Tractive effort in (tonnes * 1000 * 10 =) N */
    89 				max_te += (u->u.rail.cached_veh_weight * 10000 * GetVehicleProperty(u, 0x1F, rvi_u->tractive_effort)) / 256;
    89 				max_te += (u->u.rail.cached_veh_weight * 10000 * GetVehicleProperty(u, 0x1F, rvi_u->tractive_effort)) / 256;
    90 			}
    90 			}
    91 		}
    91 		}
    92 
    92 
    93 		if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) {
    93 		if (HasBit(u->u.rail.flags, VRF_POWEREDWAGON) && (wagon_has_power)) {
    94 			total_power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power;
    94 			total_power += RailVehInfo(u->u.rail.first_engine)->pow_wag_power;
    95 		}
    95 		}
    96 	}
    96 	}
    97 
    97 
    98 	if (v->u.rail.cached_power != total_power || v->u.rail.cached_max_te != max_te) {
    98 	if (v->u.rail.cached_power != total_power || v->u.rail.cached_max_te != max_te) {
   123 		if (!IsArticulatedPart(u)) {
   123 		if (!IsArticulatedPart(u)) {
   124 			/* vehicle weight is the sum of the weight of the vehicle and the weight of its cargo */
   124 			/* vehicle weight is the sum of the weight of the vehicle and the weight of its cargo */
   125 			vweight += GetVehicleProperty(u, 0x16, RailVehInfo(u->engine_type)->weight);
   125 			vweight += GetVehicleProperty(u, 0x16, RailVehInfo(u->engine_type)->weight);
   126 
   126 
   127 			/* powered wagons have extra weight added */
   127 			/* powered wagons have extra weight added */
   128 			if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON))
   128 			if (HasBit(u->u.rail.flags, VRF_POWEREDWAGON))
   129 				vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight;
   129 				vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight;
   130 		}
   130 		}
   131 
   131 
   132 		/* consist weight is the sum of the weight of all vehicles in the consist */
   132 		/* consist weight is the sum of the weight of all vehicles in the consist */
   133 		weight += vweight;
   133 		weight += vweight;
   195 			}
   195 			}
   196 		}
   196 		}
   197 
   197 
   198 		if (!IsArticulatedPart(u)) {
   198 		if (!IsArticulatedPart(u)) {
   199 			/* Check powered wagon / visual effect callback */
   199 			/* Check powered wagon / visual effect callback */
   200 			if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_TRAIN_WAGON_POWER)) {
   200 			if (HasBit(EngInfo(u->engine_type)->callbackmask, CBM_TRAIN_WAGON_POWER)) {
   201 				uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u);
   201 				uint16 callback = GetVehicleCallback(CBID_TRAIN_WAGON_POWER, 0, 0, u->engine_type, u);
   202 
   202 
   203 				if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback;
   203 				if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback;
   204 			}
   204 			}
   205 
   205 
   206 			if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON &&
   206 			if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON &&
   207 				UsesWagonOverride(u) && !HASBIT(u->u.rail.cached_vis_effect, 7)) {
   207 				UsesWagonOverride(u) && !HasBit(u->u.rail.cached_vis_effect, 7)) {
   208 				/* wagon is powered */
   208 				/* wagon is powered */
   209 				SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status
   209 				SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status
   210 			} else {
   210 			} else {
   211 				CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON);
   211 				CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON);
   212 			}
   212 			}
   217 				v->u.rail.compatible_railtypes |= GetRailTypeInfo(u->u.rail.railtype)->powered_railtypes;
   217 				v->u.rail.compatible_railtypes |= GetRailTypeInfo(u->u.rail.railtype)->powered_railtypes;
   218 			}
   218 			}
   219 
   219 
   220 			/* Some electric engines can be allowed to run on normal rail. It happens to all
   220 			/* Some electric engines can be allowed to run on normal rail. It happens to all
   221 			 * existing electric engines when elrails are disabled and then re-enabled */
   221 			 * existing electric engines when elrails are disabled and then re-enabled */
   222 			if (HASBIT(u->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL)) {
   222 			if (HasBit(u->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL)) {
   223 				u->u.rail.railtype = RAILTYPE_RAIL;
   223 				u->u.rail.railtype = RAILTYPE_RAIL;
   224 				u->u.rail.compatible_railtypes |= (1 << RAILTYPE_RAIL);
   224 				u->u.rail.compatible_railtypes |= (1 << RAILTYPE_RAIL);
   225 			}
   225 			}
   226 
   226 
   227 			/* max speed is the minimum of the speed limits of all vehicles in the consist */
   227 			/* max speed is the minimum of the speed limits of all vehicles in the consist */
   238 
   238 
   239 		u->u.rail.user_def_data = GetVehicleProperty(u, 0x25, rvi_u->user_def_data);
   239 		u->u.rail.user_def_data = GetVehicleProperty(u, 0x25, rvi_u->user_def_data);
   240 
   240 
   241 		/* check the vehicle length (callback) */
   241 		/* check the vehicle length (callback) */
   242 		uint16 veh_len = CALLBACK_FAILED;
   242 		uint16 veh_len = CALLBACK_FAILED;
   243 		if (HASBIT(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) {
   243 		if (HasBit(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) {
   244 			veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
   244 			veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
   245 		}
   245 		}
   246 		if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor;
   246 		if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor;
   247 		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
   247 		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
   248 		u->u.rail.cached_veh_length = 8 - veh_len;
   248 		u->u.rail.cached_veh_length = 8 - veh_len;
   384 		num++;
   384 		num++;
   385 		drag_coeff += 3;
   385 		drag_coeff += 3;
   386 
   386 
   387 		if (u->u.rail.track == TRACK_BIT_DEPOT) max_speed = min(max_speed, 61);
   387 		if (u->u.rail.track == TRACK_BIT_DEPOT) max_speed = min(max_speed, 61);
   388 
   388 
   389 		if (HASBIT(u->u.rail.flags, VRF_GOINGUP)) {
   389 		if (HasBit(u->u.rail.flags, VRF_GOINGUP)) {
   390 			incl += u->u.rail.cached_veh_weight * 60; //3% slope, quite a bit actually
   390 			incl += u->u.rail.cached_veh_weight * 60; //3% slope, quite a bit actually
   391 		} else if (HASBIT(u->u.rail.flags, VRF_GOINGDOWN)) {
   391 		} else if (HasBit(u->u.rail.flags, VRF_GOINGDOWN)) {
   392 			incl -= u->u.rail.cached_veh_weight * 60;
   392 			incl -= u->u.rail.cached_veh_weight * 60;
   393 		}
   393 		}
   394 	}
   394 	}
   395 
   395 
   396 	v->max_speed = max_speed;
   396 	v->max_speed = max_speed;
   461 int Train::GetImage(Direction direction) const
   461 int Train::GetImage(Direction direction) const
   462 {
   462 {
   463 	int img = this->spritenum;
   463 	int img = this->spritenum;
   464 	int base;
   464 	int base;
   465 
   465 
   466 	if (HASBIT(this->u.rail.flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction);
   466 	if (HasBit(this->u.rail.flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction);
   467 
   467 
   468 	if (is_custom_sprite(img)) {
   468 	if (is_custom_sprite(img)) {
   469 		base = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img)));
   469 		base = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img)));
   470 		if (base != 0) return base;
   470 		if (base != 0) return base;
   471 		img = orig_rail_vehicle_info[this->engine_type].image_index;
   471 		img = orig_rail_vehicle_info[this->engine_type].image_index;
   699 		if (!Vehicle::AllocateList(vl, num_vehicles))
   699 		if (!Vehicle::AllocateList(vl, num_vehicles))
   700 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   700 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   701 
   701 
   702 		Vehicle *v = vl[0];
   702 		Vehicle *v = vl[0];
   703 
   703 
   704 		UnitID unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_TRAIN);
   704 		UnitID unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_TRAIN);
   705 		if (unit_num > _patches.max_trains)
   705 		if (unit_num > _patches.max_trains)
   706 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   706 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   707 
   707 
   708 		if (flags & DC_EXEC) {
   708 		if (flags & DC_EXEC) {
   709 			DiagDirection dir = GetRailDepotDirection(tile);
   709 			DiagDirection dir = GetRailDepotDirection(tile);
   772 
   772 
   773 			TrainConsistChanged(v);
   773 			TrainConsistChanged(v);
   774 			UpdateTrainAcceleration(v);
   774 			UpdateTrainAcceleration(v);
   775 			UpdateTrainGroupID(v);
   775 			UpdateTrainGroupID(v);
   776 
   776 
   777 			if (!HASBIT(p2, 1)) { // check if the cars should be added to the new vehicle
   777 			if (!HasBit(p2, 1)) { // check if the cars should be added to the new vehicle
   778 				NormalizeTrainVehInDepot(v);
   778 				NormalizeTrainVehInDepot(v);
   779 			}
   779 			}
   780 
   780 
   781 			InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   781 			InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   782 			RebuildVehicleLists();
   782 			RebuildVehicleLists();
   970 	}
   970 	}
   971 
   971 
   972 	if (IsRearDualheaded(src)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR);
   972 	if (IsRearDualheaded(src)) return_cmd_error(STR_REAR_ENGINE_FOLLOW_FRONT_ERROR);
   973 
   973 
   974 	/* when moving all wagons, we can't have the same src_head and dst_head */
   974 	/* when moving all wagons, we can't have the same src_head and dst_head */
   975 	if (HASBIT(p2, 0) && src_head == dst_head) return CommandCost();
   975 	if (HasBit(p2, 0) && src_head == dst_head) return CommandCost();
   976 
   976 
   977 	{
   977 	{
   978 		int max_len = _patches.mammoth_trains ? 100 : 9;
   978 		int max_len = _patches.mammoth_trains ? 100 : 9;
   979 
   979 
   980 		/* check if all vehicles in the source train are stopped inside a depot. */
   980 		/* check if all vehicles in the source train are stopped inside a depot. */
   991 				if (dst_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
   991 				if (dst_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
   992 			}
   992 			}
   993 
   993 
   994 			/* We are moving between rows, so only count the wagons from the source
   994 			/* We are moving between rows, so only count the wagons from the source
   995 			 * row that are being moved. */
   995 			 * row that are being moved. */
   996 			if (HASBIT(p2, 0)) {
   996 			if (HasBit(p2, 0)) {
   997 				const Vehicle *u;
   997 				const Vehicle *u;
   998 				for (u = src_head; u != src && u != NULL; u = GetNextVehicle(u))
   998 				for (u = src_head; u != src && u != NULL; u = GetNextVehicle(u))
   999 					src_len--;
   999 					src_len--;
  1000 			} else {
  1000 			} else {
  1001 				/* If moving only one vehicle, just count that. */
  1001 				/* If moving only one vehicle, just count that. */
  1047 				v->group_id   = src->group_id;
  1047 				v->group_id   = src->group_id;
  1048 				src->group_id = DEFAULT_GROUP;
  1048 				src->group_id = DEFAULT_GROUP;
  1049 			}
  1049 			}
  1050 		}
  1050 		}
  1051 
  1051 
  1052 		if (HASBIT(p2, 0)) {
  1052 		if (HasBit(p2, 0)) {
  1053 			/* unlink ALL wagons */
  1053 			/* unlink ALL wagons */
  1054 			if (src != src_head) {
  1054 			if (src != src_head) {
  1055 				Vehicle *v = src_head;
  1055 				Vehicle *v = src_head;
  1056 				while (GetNextVehicle(v) != src) v = GetNextVehicle(v);
  1056 				while (GetNextVehicle(v) != src) v = GetNextVehicle(v);
  1057 				GetLastEnginePart(v)->SetNext(NULL);
  1057 				GetLastEnginePart(v)->SetNext(NULL);
  1341 
  1341 
  1342 				/* (6.) Borked AI. If it sells an engine it expects all wagons lined
  1342 				/* (6.) Borked AI. If it sells an engine it expects all wagons lined
  1343 				 * up on a new line to be added to the newly built loco. Replace it is.
  1343 				 * up on a new line to be added to the newly built loco. Replace it is.
  1344 				 * Totally braindead cause building a new engine adds all loco-less
  1344 				 * Totally braindead cause building a new engine adds all loco-less
  1345 				 * engines to its train anyways */
  1345 				 * engines to its train anyways */
  1346 				if (p2 == 2 && HASBIT(ori_subtype, Train_Front)) {
  1346 				if (p2 == 2 && HasBit(ori_subtype, Train_Front)) {
  1347 					Vehicle *tmp;
  1347 					Vehicle *tmp;
  1348 					for (v = first; v != NULL; v = tmp) {
  1348 					for (v = first; v != NULL; v = tmp) {
  1349 						tmp = GetNextVehicle(v);
  1349 						tmp = GetNextVehicle(v);
  1350 						DoCommand(v->tile, v->index | INVALID_VEHICLE << 16, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
  1350 						DoCommand(v->tile, v->index | INVALID_VEHICLE << 16, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
  1351 					}
  1351 					}
  1462 	CLRBIT(*swap_flag1, VRF_GOINGDOWN);
  1462 	CLRBIT(*swap_flag1, VRF_GOINGDOWN);
  1463 	CLRBIT(*swap_flag2, VRF_GOINGUP);
  1463 	CLRBIT(*swap_flag2, VRF_GOINGUP);
  1464 	CLRBIT(*swap_flag2, VRF_GOINGDOWN);
  1464 	CLRBIT(*swap_flag2, VRF_GOINGDOWN);
  1465 
  1465 
  1466 	/* Reverse the rail-flags (if needed) */
  1466 	/* Reverse the rail-flags (if needed) */
  1467 	if (HASBIT(flag1, VRF_GOINGUP)) {
  1467 	if (HasBit(flag1, VRF_GOINGUP)) {
  1468 		SETBIT(*swap_flag2, VRF_GOINGDOWN);
  1468 		SETBIT(*swap_flag2, VRF_GOINGDOWN);
  1469 	} else if (HASBIT(flag1, VRF_GOINGDOWN)) {
  1469 	} else if (HasBit(flag1, VRF_GOINGDOWN)) {
  1470 		SETBIT(*swap_flag2, VRF_GOINGUP);
  1470 		SETBIT(*swap_flag2, VRF_GOINGUP);
  1471 	}
  1471 	}
  1472 	if (HASBIT(flag2, VRF_GOINGUP)) {
  1472 	if (HasBit(flag2, VRF_GOINGUP)) {
  1473 		SETBIT(*swap_flag1, VRF_GOINGDOWN);
  1473 		SETBIT(*swap_flag1, VRF_GOINGDOWN);
  1474 	} else if (HASBIT(flag2, VRF_GOINGDOWN)) {
  1474 	} else if (HasBit(flag2, VRF_GOINGDOWN)) {
  1475 		SETBIT(*swap_flag1, VRF_GOINGUP);
  1475 		SETBIT(*swap_flag1, VRF_GOINGUP);
  1476 	}
  1476 	}
  1477 }
  1477 }
  1478 
  1478 
  1479 static void ReverseTrainSwapVeh(Vehicle *v, int l, int r)
  1479 static void ReverseTrainSwapVeh(Vehicle *v, int l, int r)
  1638 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  1638 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  1639 
  1639 
  1640 	if (p2) {
  1640 	if (p2) {
  1641 		/* turn a single unit around */
  1641 		/* turn a single unit around */
  1642 
  1642 
  1643 		if (IsMultiheaded(v) || HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) {
  1643 		if (IsMultiheaded(v) || HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) {
  1644 			return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
  1644 			return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
  1645 		}
  1645 		}
  1646 
  1646 
  1647 		Vehicle *front = v->First();
  1647 		Vehicle *front = v->First();
  1648 		/* make sure the vehicle is stopped in the depot */
  1648 		/* make sure the vehicle is stopped in the depot */
  1703  */
  1703  */
  1704 CommandCost CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1704 CommandCost CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1705 {
  1705 {
  1706 	CargoID new_cid = GB(p2, 0, 8);
  1706 	CargoID new_cid = GB(p2, 0, 8);
  1707 	byte new_subtype = GB(p2, 8, 8);
  1707 	byte new_subtype = GB(p2, 8, 8);
  1708 	bool only_this = HASBIT(p2, 16);
  1708 	bool only_this = HasBit(p2, 16);
  1709 
  1709 
  1710 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1710 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1711 
  1711 
  1712 	Vehicle *v = GetVehicle(p1);
  1712 	Vehicle *v = GetVehicle(p1);
  1713 
  1713 
  1729 		if (!CanRefitTo(v->engine_type, new_cid)) continue;
  1729 		if (!CanRefitTo(v->engine_type, new_cid)) continue;
  1730 
  1730 
  1731 		if (v->cargo_cap != 0) {
  1731 		if (v->cargo_cap != 0) {
  1732 			uint16 amount = CALLBACK_FAILED;
  1732 			uint16 amount = CALLBACK_FAILED;
  1733 
  1733 
  1734 			if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) {
  1734 			if (HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) {
  1735 				/* Back up the vehicle's cargo type */
  1735 				/* Back up the vehicle's cargo type */
  1736 				CargoID temp_cid = v->cargo_type;
  1736 				CargoID temp_cid = v->cargo_type;
  1737 				byte temp_subtype = v->cargo_subtype;
  1737 				byte temp_subtype = v->cargo_subtype;
  1738 				v->cargo_type = new_cid;
  1738 				v->cargo_type = new_cid;
  1739 				v->cargo_subtype = new_subtype;
  1739 				v->cargo_subtype = new_subtype;
  1900 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  1900 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  1901 
  1901 
  1902 	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
  1902 	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
  1903 
  1903 
  1904 	if (v->current_order.type == OT_GOTO_DEPOT) {
  1904 	if (v->current_order.type == OT_GOTO_DEPOT) {
  1905 		if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
  1905 		if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
  1906 			/* We called with a different DEPOT_SERVICE setting.
  1906 			/* We called with a different DEPOT_SERVICE setting.
  1907 			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
  1907 			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
  1908 			 * Note: the if is (true for requesting service == true for ordered to stop in depot)          */
  1908 			 * Note: the if is (true for requesting service == true for ordered to stop in depot)          */
  1909 			if (flags & DC_EXEC) {
  1909 			if (flags & DC_EXEC) {
  1910 				CLRBIT(v->current_order.flags, OFB_PART_OF_ORDERS);
  1910 				CLRBIT(v->current_order.flags, OFB_PART_OF_ORDERS);
  1914 			return CommandCost();
  1914 			return CommandCost();
  1915 		}
  1915 		}
  1916 
  1916 
  1917 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
  1917 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
  1918 		if (flags & DC_EXEC) {
  1918 		if (flags & DC_EXEC) {
  1919 			if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
  1919 			if (HasBit(v->current_order.flags, OFB_PART_OF_ORDERS)) {
  1920 				v->cur_order_index++;
  1920 				v->cur_order_index++;
  1921 			}
  1921 			}
  1922 
  1922 
  1923 			v->current_order.type = OT_DUMMY;
  1923 			v->current_order.type = OT_DUMMY;
  1924 			v->current_order.flags = 0;
  1924 			v->current_order.flags = 0;
  1972 
  1972 
  1973 	do {
  1973 	do {
  1974 		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
  1974 		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
  1975 		int effect_offset = GB(v->u.rail.cached_vis_effect, 0, 4) - 8;
  1975 		int effect_offset = GB(v->u.rail.cached_vis_effect, 0, 4) - 8;
  1976 		byte effect_type = GB(v->u.rail.cached_vis_effect, 4, 2);
  1976 		byte effect_type = GB(v->u.rail.cached_vis_effect, 4, 2);
  1977 		bool disable_effect = HASBIT(v->u.rail.cached_vis_effect, 6);
  1977 		bool disable_effect = HasBit(v->u.rail.cached_vis_effect, 6);
  1978 
  1978 
  1979 		/* no smoke? */
  1979 		/* no smoke? */
  1980 		if ((rvi->railveh_type == RAILVEH_WAGON && effect_type == 0) ||
  1980 		if ((rvi->railveh_type == RAILVEH_WAGON && effect_type == 0) ||
  1981 				disable_effect ||
  1981 				disable_effect ||
  1982 				v->vehstatus & VS_HIDDEN) {
  1982 				v->vehstatus & VS_HIDDEN) {
  1997 		}
  1997 		}
  1998 
  1998 
  1999 		int x = _vehicle_smoke_pos[v->direction] * effect_offset;
  1999 		int x = _vehicle_smoke_pos[v->direction] * effect_offset;
  2000 		int y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
  2000 		int y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
  2001 
  2001 
  2002 		if (HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
  2002 		if (HasBit(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
  2003 			x = -x;
  2003 			x = -x;
  2004 			y = -y;
  2004 			y = -y;
  2005 		}
  2005 		}
  2006 
  2006 
  2007 		switch (effect_type) {
  2007 		switch (effect_type) {
  2258 		DEBUG(yapf, 4, "[NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0);
  2258 		DEBUG(yapf, 4, "[NTPT] %d us - %d rounds - %d open - %d closed -- ", time, 0, 0, 0);
  2259 	}
  2259 	}
  2260 	/* handle "path not found" state */
  2260 	/* handle "path not found" state */
  2261 	if (path_not_found) {
  2261 	if (path_not_found) {
  2262 		/* PF didn't find the route */
  2262 		/* PF didn't find the route */
  2263 		if (!HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
  2263 		if (!HasBit(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
  2264 			/* it is first time the problem occurred, set the "path not found" flag */
  2264 			/* it is first time the problem occurred, set the "path not found" flag */
  2265 			SETBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
  2265 			SETBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
  2266 			/* and notify user about the event */
  2266 			/* and notify user about the event */
  2267 			if (_patches.lost_train_warn && v->owner == _local_player) {
  2267 			if (_patches.lost_train_warn && v->owner == _local_player) {
  2268 				SetDParam(0, v->unitnumber);
  2268 				SetDParam(0, v->unitnumber);
  2273 					0);
  2273 					0);
  2274 			}
  2274 			}
  2275 		}
  2275 		}
  2276 	} else {
  2276 	} else {
  2277 		/* route found, is the train marked with "path not found" flag? */
  2277 		/* route found, is the train marked with "path not found" flag? */
  2278 		if (HASBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
  2278 		if (HasBit(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
  2279 			/* clear the flag as the PF's problem was solved */
  2279 			/* clear the flag as the PF's problem was solved */
  2280 			CLRBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
  2280 			CLRBIT(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
  2281 			/* can we also delete the "News" item somehow? */
  2281 			/* can we also delete the "News" item somehow? */
  2282 		}
  2282 		}
  2283 	}
  2283 	}
  2491 
  2491 
  2492 static int UpdateTrainSpeed(Vehicle *v)
  2492 static int UpdateTrainSpeed(Vehicle *v)
  2493 {
  2493 {
  2494 	uint accel;
  2494 	uint accel;
  2495 
  2495 
  2496 	if (v->vehstatus & VS_STOPPED || HASBIT(v->u.rail.flags, VRF_REVERSING)) {
  2496 	if (v->vehstatus & VS_STOPPED || HasBit(v->u.rail.flags, VRF_REVERSING)) {
  2497 		if (_patches.realistic_acceleration) {
  2497 		if (_patches.realistic_acceleration) {
  2498 			accel = GetTrainAcceleration(v, AM_BRAKE) * 2;
  2498 			accel = GetTrainAcceleration(v, AM_BRAKE) * 2;
  2499 		} else {
  2499 		} else {
  2500 			accel = v->acceleration * -2;
  2500 			accel = v->acceleration * -2;
  2501 		}
  2501 		}
  2627 static bool CheckCompatibleRail(const Vehicle *v, TileIndex tile)
  2627 static bool CheckCompatibleRail(const Vehicle *v, TileIndex tile)
  2628 {
  2628 {
  2629 	return
  2629 	return
  2630 		IsTileOwner(tile, v->owner) && (
  2630 		IsTileOwner(tile, v->owner) && (
  2631 			!IsFrontEngine(v) ||
  2631 			!IsFrontEngine(v) ||
  2632 			HASBIT(v->u.rail.compatible_railtypes, GetRailType(tile))
  2632 			HasBit(v->u.rail.compatible_railtypes, GetRailType(tile))
  2633 		);
  2633 		);
  2634 }
  2634 }
  2635 
  2635 
  2636 struct RailtypeSlowdownParams {
  2636 struct RailtypeSlowdownParams {
  2637 	byte small_turn, large_turn;
  2637 	byte small_turn, large_turn;
  2837 					/* Not inside depot */
  2837 					/* Not inside depot */
  2838 
  2838 
  2839 					if (IsFrontEngine(v) && !TrainCheckIfLineEnds(v)) return;
  2839 					if (IsFrontEngine(v) && !TrainCheckIfLineEnds(v)) return;
  2840 
  2840 
  2841 					uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2841 					uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2842 					if (HASBIT(r, VETS_CANNOT_ENTER)) {
  2842 					if (HasBit(r, VETS_CANNOT_ENTER)) {
  2843 						goto invalid_rail;
  2843 						goto invalid_rail;
  2844 					}
  2844 					}
  2845 					if (HASBIT(r, VETS_ENTERED_STATION)) {
  2845 					if (HasBit(r, VETS_ENTERED_STATION)) {
  2846 						TrainEnterStation(v, r >> VETS_STATION_ID_OFFSET);
  2846 						TrainEnterStation(v, r >> VETS_STATION_ID_OFFSET);
  2847 						return;
  2847 						return;
  2848 					}
  2848 					}
  2849 
  2849 
  2850 					if (v->current_order.type == OT_LEAVESTATION) {
  2850 					if (v->current_order.type == OT_LEAVESTATION) {
  2940 				gp.y = (gp.y & ~0xF) | b[1];
  2940 				gp.y = (gp.y & ~0xF) | b[1];
  2941 				Direction chosen_dir = (Direction)b[2];
  2941 				Direction chosen_dir = (Direction)b[2];
  2942 
  2942 
  2943 				/* Call the landscape function and tell it that the vehicle entered the tile */
  2943 				/* Call the landscape function and tell it that the vehicle entered the tile */
  2944 				uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2944 				uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2945 				if (HASBIT(r, VETS_CANNOT_ENTER)) {
  2945 				if (HasBit(r, VETS_CANNOT_ENTER)) {
  2946 					goto invalid_rail;
  2946 					goto invalid_rail;
  2947 				}
  2947 				}
  2948 
  2948 
  2949 				if (IsLevelCrossingTile(v->tile) && v->Next() == NULL) {
  2949 				if (IsLevelCrossingTile(v->tile) && v->Next() == NULL) {
  2950 					UnbarCrossing(v->tile);
  2950 					UnbarCrossing(v->tile);
  2951 					MarkTileDirtyByTile(v->tile);
  2951 					MarkTileDirtyByTile(v->tile);
  2952 				}
  2952 				}
  2953 
  2953 
  2954 				if (IsFrontEngine(v)) v->load_unload_time_rem = 0;
  2954 				if (IsFrontEngine(v)) v->load_unload_time_rem = 0;
  2955 
  2955 
  2956 				if (!HASBIT(r, VETS_ENTERED_WORMHOLE)) {
  2956 				if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
  2957 					v->tile = gp.new_tile;
  2957 					v->tile = gp.new_tile;
  2958 
  2958 
  2959 					if (GetTileRailType(gp.new_tile) != GetTileRailType(gp.old_tile)) {
  2959 					if (GetTileRailType(gp.new_tile) != GetTileRailType(gp.old_tile)) {
  2960 						TrainPowerChanged(v->First());
  2960 						TrainPowerChanged(v->First());
  2961 					}
  2961 					}
  2977 			if (!(v->vehstatus & VS_HIDDEN)) {
  2977 			if (!(v->vehstatus & VS_HIDDEN)) {
  2978 				v->cur_speed =
  2978 				v->cur_speed =
  2979 					min(v->cur_speed, GetBridge(GetBridgeType(v->tile))->speed);
  2979 					min(v->cur_speed, GetBridge(GetBridgeType(v->tile))->speed);
  2980 			}
  2980 			}
  2981 
  2981 
  2982 			if (!(IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) || !HASBIT(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
  2982 			if (!(IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) || !HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
  2983 				v->x_pos = gp.x;
  2983 				v->x_pos = gp.x;
  2984 				v->y_pos = gp.y;
  2984 				v->y_pos = gp.y;
  2985 				VehiclePositionChanged(v);
  2985 				VehiclePositionChanged(v);
  2986 				if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
  2986 				if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
  2987 				continue;
  2987 				continue;
  3281 			return;
  3281 			return;
  3282 		}
  3282 		}
  3283 		v->breakdown_ctr--;
  3283 		v->breakdown_ctr--;
  3284 	}
  3284 	}
  3285 
  3285 
  3286 	if (HASBIT(v->u.rail.flags, VRF_REVERSING) && v->cur_speed == 0) {
  3286 	if (HasBit(v->u.rail.flags, VRF_REVERSING) && v->cur_speed == 0) {
  3287 		ReverseTrainDirection(v);
  3287 		ReverseTrainDirection(v);
  3288 	}
  3288 	}
  3289 
  3289 
  3290 	/* exit if train is stopped */
  3290 	/* exit if train is stopped */
  3291 	if (v->vehstatus & VS_STOPPED && v->cur_speed == 0) return;
  3291 	if (v->vehstatus & VS_STOPPED && v->cur_speed == 0) return;
  3530 		}
  3530 		}
  3531 	}
  3531 	}
  3532 
  3532 
  3533 	FOR_ALL_VEHICLES(v) {
  3533 	FOR_ALL_VEHICLES(v) {
  3534 		if (v->type == VEH_TRAIN) {
  3534 		if (v->type == VEH_TRAIN) {
  3535 			if (HASBIT(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) {
  3535 			if (HasBit(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) {
  3536 				Vehicle *u = v;
  3536 				Vehicle *u = v;
  3537 
  3537 
  3538 				BEGIN_ENUM_WAGONS(u) {
  3538 				BEGIN_ENUM_WAGONS(u) {
  3539 					const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
  3539 					const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
  3540 
  3540