src/train_cmd.cpp
branchNewGRF_ports
changeset 10184 fcf5fb2548eb
parent 6878 7d1ff2f621c7
child 10200 aba3af04cdbd
equal deleted inserted replaced
10179:eec5a7dcbf61 10184:fcf5fb2548eb
     9 #include "tile_cmd.h"
     9 #include "tile_cmd.h"
    10 #include "landscape.h"
    10 #include "landscape.h"
    11 #include "gui.h"
    11 #include "gui.h"
    12 #include "station_map.h"
    12 #include "station_map.h"
    13 #include "tunnel_map.h"
    13 #include "tunnel_map.h"
    14 #include "timetable.h"
       
    15 #include "articulated_vehicles.h"
    14 #include "articulated_vehicles.h"
    16 #include "command_func.h"
    15 #include "command_func.h"
    17 #include "pathfind.h"
    16 #include "pathfind.h"
    18 #include "npf.h"
    17 #include "npf.h"
    19 #include "station.h"
    18 #include "station_base.h"
    20 #include "news.h"
    19 #include "news_func.h"
    21 #include "engine.h"
    20 #include "engine_func.h"
    22 #include "player_func.h"
    21 #include "player_func.h"
    23 #include "player_base.h"
    22 #include "player_base.h"
    24 #include "depot.h"
    23 #include "depot.h"
    25 #include "waypoint.h"
    24 #include "waypoint.h"
    26 #include "vehicle_gui.h"
    25 #include "vehicle_gui.h"
    45 #include "signal_func.h"
    44 #include "signal_func.h"
    46 #include "variables.h"
    45 #include "variables.h"
    47 #include "autoreplace_gui.h"
    46 #include "autoreplace_gui.h"
    48 #include "gfx_func.h"
    47 #include "gfx_func.h"
    49 #include "settings_type.h"
    48 #include "settings_type.h"
       
    49 #include "order_func.h"
    50 
    50 
    51 #include "table/strings.h"
    51 #include "table/strings.h"
    52 #include "table/train_cmd.h"
    52 #include "table/train_cmd.h"
    53 
    53 
    54 static bool TrainCheckIfLineEnds(Vehicle *v);
    54 static bool TrainCheckIfLineEnds(Vehicle *v);
    55 static void TrainController(Vehicle *v, bool update_image);
    55 static void TrainController(Vehicle *v, Vehicle *nomove, bool update_image);
    56 static TileIndex TrainApproachingCrossingTile(const Vehicle *v);
    56 static TileIndex TrainApproachingCrossingTile(const Vehicle *v);
    57 
    57 
    58 static const byte _vehicle_initial_x_fract[4] = {10, 8, 4,  8};
    58 static const byte _vehicle_initial_x_fract[4] = {10, 8, 4,  8};
    59 static const byte _vehicle_initial_y_fract[4] = { 8, 4, 8, 10};
    59 static const byte _vehicle_initial_y_fract[4] = { 8, 4, 8, 10};
    60 
    60 
    94 
    94 
    95 /**
    95 /**
    96  * Recalculates the cached total power of a train. Should be called when the consist is changed
    96  * Recalculates the cached total power of a train. Should be called when the consist is changed
    97  * @param v First vehicle of the consist.
    97  * @param v First vehicle of the consist.
    98  */
    98  */
    99 void TrainPowerChanged(Vehicle* v)
    99 void TrainPowerChanged(Vehicle *v)
   100 {
   100 {
   101 	uint32 total_power = 0;
   101 	uint32 total_power = 0;
   102 	uint32 max_te = 0;
   102 	uint32 max_te = 0;
   103 
   103 
   104 	for (const Vehicle *u = v; u != NULL; u = u->Next()) {
   104 	for (const Vehicle *u = v; u != NULL; u = u->Next()) {
   140 /**
   140 /**
   141  * Recalculates the cached weight of a train and its vehicles. Should be called each time the cargo on
   141  * Recalculates the cached weight of a train and its vehicles. Should be called each time the cargo on
   142  * the consist changes.
   142  * the consist changes.
   143  * @param v First vehicle of the consist.
   143  * @param v First vehicle of the consist.
   144  */
   144  */
   145 static void TrainCargoChanged(Vehicle* v)
   145 static void TrainCargoChanged(Vehicle *v)
   146 {
   146 {
   147 	uint32 weight = 0;
   147 	uint32 weight = 0;
   148 
   148 
   149 	for (Vehicle *u = v; u != NULL; u = u->Next()) {
   149 	for (Vehicle *u = v; u != NULL; u = u->Next()) {
   150 		uint32 vweight = GetCargo(u->cargo_type)->weight * u->cargo.Count() * FreightWagonMult(u->cargo_type) / 16;
   150 		uint32 vweight = GetCargo(u->cargo_type)->weight * u->cargo.Count() * FreightWagonMult(u->cargo_type) / 16;
   178  * Recalculates the cached stuff of a train. Should be called each time a vehicle is added
   178  * Recalculates the cached stuff of a train. Should be called each time a vehicle is added
   179  * to/removed from the chain, and when the game is loaded.
   179  * to/removed from the chain, and when the game is loaded.
   180  * Note: this needs to be called too for 'wagon chains' (in the depot, without an engine)
   180  * Note: this needs to be called too for 'wagon chains' (in the depot, without an engine)
   181  * @param v First vehicle of the chain.
   181  * @param v First vehicle of the chain.
   182  */
   182  */
   183 void TrainConsistChanged(Vehicle* v)
   183 void TrainConsistChanged(Vehicle *v)
   184 {
   184 {
   185 	uint16 max_speed = 0xFFFF;
   185 	uint16 max_speed = UINT16_MAX;
   186 
   186 
   187 	assert(v->type == VEH_TRAIN);
   187 	assert(v->type == VEH_TRAIN);
   188 	assert(IsFrontEngine(v) || IsFreeWagon(v));
   188 	assert(IsFrontEngine(v) || IsFreeWagon(v));
   189 
   189 
   190 	const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type);
   190 	const RailVehicleInfo *rvi_v = RailVehInfo(v->engine_type);
   211 		/* Cache wagon override sprite group. NULL is returned if there is none */
   211 		/* Cache wagon override sprite group. NULL is returned if there is none */
   212 		u->u.rail.cached_override = GetWagonOverrideSpriteSet(u->engine_type, u->cargo_type, u->u.rail.first_engine);
   212 		u->u.rail.cached_override = GetWagonOverrideSpriteSet(u->engine_type, u->cargo_type, u->u.rail.first_engine);
   213 
   213 
   214 		/* Reset color map */
   214 		/* Reset color map */
   215 		u->colormap = PAL_NONE;
   215 		u->colormap = PAL_NONE;
       
   216 
       
   217 		/* Set user defined data (must be done before other properties) */
       
   218 		u->u.rail.user_def_data = GetVehicleProperty(u, 0x25, rvi_u->user_def_data);
   216 
   219 
   217 		if (rvi_u->visual_effect != 0) {
   220 		if (rvi_u->visual_effect != 0) {
   218 			u->u.rail.cached_vis_effect = rvi_u->visual_effect;
   221 			u->u.rail.cached_vis_effect = rvi_u->visual_effect;
   219 		} else {
   222 		} else {
   220 			if (IsTrainWagon(u) || IsArticulatedPart(u)) {
   223 			if (IsTrainWagon(u) || IsArticulatedPart(u)) {
   268 		if (u->cargo_type == rvi_u->cargo_type && u->cargo_subtype == 0) {
   271 		if (u->cargo_type == rvi_u->cargo_type && u->cargo_subtype == 0) {
   269 			/* Set cargo capacity if we've not been refitted */
   272 			/* Set cargo capacity if we've not been refitted */
   270 			u->cargo_cap = GetVehicleProperty(u, 0x14, rvi_u->capacity);
   273 			u->cargo_cap = GetVehicleProperty(u, 0x14, rvi_u->capacity);
   271 		}
   274 		}
   272 
   275 
   273 		u->u.rail.user_def_data = GetVehicleProperty(u, 0x25, rvi_u->user_def_data);
       
   274 
       
   275 		/* check the vehicle length (callback) */
   276 		/* check the vehicle length (callback) */
   276 		uint16 veh_len = CALLBACK_FAILED;
   277 		uint16 veh_len = CALLBACK_FAILED;
   277 		if (HasBit(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) {
   278 		if (HasBit(EngInfo(u->engine_type)->callbackmask, CBM_VEHICLE_LENGTH)) {
   278 			veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
   279 			veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
   279 		}
   280 		}
   287 	v->u.rail.cached_max_speed = max_speed;
   288 	v->u.rail.cached_max_speed = max_speed;
   288 	v->u.rail.cached_tilt = train_can_tilt;
   289 	v->u.rail.cached_tilt = train_can_tilt;
   289 
   290 
   290 	/* recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added) */
   291 	/* recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added) */
   291 	TrainCargoChanged(v);
   292 	TrainCargoChanged(v);
       
   293 
       
   294 	if (IsFrontEngine(v)) {
       
   295 		UpdateTrainAcceleration(v);
       
   296 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
       
   297 	}
   292 }
   298 }
   293 
   299 
   294 enum AccelType {
   300 enum AccelType {
   295 	AM_ACCEL,
   301 	AM_ACCEL,
   296 	AM_BRAKE
   302 	AM_BRAKE
   297 };
   303 };
   298 
   304 
   299 static bool TrainShouldStop(const Vehicle* v, TileIndex tile)
       
   300 {
       
   301 	const Order* o = &v->current_order;
       
   302 	StationID sid = GetStationIndex(tile);
       
   303 
       
   304 	assert(v->type == VEH_TRAIN);
       
   305 	/* When does a train drive through a station
       
   306 	 * first we deal with the "new nonstop handling" */
       
   307 	if (_patches.new_nonstop && o->flags & OFB_NON_STOP && sid == o->dest) {
       
   308 		return false;
       
   309 	}
       
   310 
       
   311 	if (v->last_station_visited == sid) return false;
       
   312 
       
   313 	if (sid != o->dest && (o->flags & OFB_NON_STOP || _patches.new_nonstop)) {
       
   314 		return false;
       
   315 	}
       
   316 
       
   317 	return true;
       
   318 }
       
   319 
       
   320 /** new acceleration*/
   305 /** new acceleration*/
   321 static int GetTrainAcceleration(Vehicle *v, bool mode)
   306 static int GetTrainAcceleration(Vehicle *v, bool mode)
   322 {
   307 {
   323 	static const int absolute_max_speed = 2000;
   308 	static const int absolute_max_speed = UINT16_MAX;
   324 	int max_speed = absolute_max_speed;
   309 	int max_speed = absolute_max_speed;
   325 	int speed = v->cur_speed * 10 / 16; // km-ish/h -> mp/h
   310 	int speed = v->cur_speed * 10 / 16; // km-ish/h -> mp/h
   326 	int curvecount[2] = {0, 0};
   311 	int curvecount[2] = {0, 0};
   327 
   312 
   328 	/*first find the curve speed limit */
   313 	/*first find the curve speed limit */
   377 			max_speed += max_speed / 5;
   362 			max_speed += max_speed / 5;
   378 		}
   363 		}
   379 	}
   364 	}
   380 
   365 
   381 	if (IsTileType(v->tile, MP_STATION) && IsFrontEngine(v)) {
   366 	if (IsTileType(v->tile, MP_STATION) && IsFrontEngine(v)) {
   382 		if (TrainShouldStop(v, v->tile)) {
   367 		if (v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile))) {
   383 			int station_length = GetStationByTile(v->tile)->GetPlatformLength(v->tile, DirToDiagDir(v->direction));
   368 			int station_length = GetStationByTile(v->tile)->GetPlatformLength(v->tile, DirToDiagDir(v->direction));
   384 
   369 
   385 			int st_max_speed = 120;
   370 			int st_max_speed = 120;
   386 
   371 
   387 			int delta_v = v->cur_speed / (station_length + 1);
   372 			int delta_v = v->cur_speed / (station_length + 1);
   465 	} else {
   450 	} else {
   466 		return min((-force - resistance) / (mass * 4), -10000 / (mass * 4));
   451 		return min((-force - resistance) / (mass * 4), -10000 / (mass * 4));
   467 	}
   452 	}
   468 }
   453 }
   469 
   454 
   470 static void UpdateTrainAcceleration(Vehicle* v)
   455 void UpdateTrainAcceleration(Vehicle *v)
   471 {
   456 {
   472 	assert(IsFrontEngine(v));
   457 	assert(IsFrontEngine(v));
   473 
   458 
   474 	v->max_speed = v->u.rail.cached_max_speed;
   459 	v->max_speed = v->u.rail.cached_max_speed;
   475 
   460 
   540 	CommandCost value(EXPENSES_NEW_VEHICLES, (GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8);
   525 	CommandCost value(EXPENSES_NEW_VEHICLES, (GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8);
   541 
   526 
   542 	uint num_vehicles = 1 + CountArticulatedParts(engine, false);
   527 	uint num_vehicles = 1 + CountArticulatedParts(engine, false);
   543 
   528 
   544 	if (!(flags & DC_QUERY_COST)) {
   529 	if (!(flags & DC_QUERY_COST)) {
       
   530 		/* Check that the wagon can drive on the track in question */
       
   531 		if (!IsCompatibleRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
       
   532 
   545 		/* Allow for the wagon and the articulated parts, plus one to "terminate" the list. */
   533 		/* Allow for the wagon and the articulated parts, plus one to "terminate" the list. */
   546 		Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1));
   534 		Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1));
   547 		memset(vl, 0, sizeof(*vl) * (num_vehicles + 1));
   535 		memset(vl, 0, sizeof(*vl) * (num_vehicles + 1));
   548 
   536 
   549 		if (!Vehicle::AllocateList(vl, num_vehicles))
   537 		if (!Vehicle::AllocateList(vl, num_vehicles))
   581 			v->z_pos = GetSlopeZ(x, y);
   569 			v->z_pos = GetSlopeZ(x, y);
   582 			v->owner = _current_player;
   570 			v->owner = _current_player;
   583 			v->u.rail.track = TRACK_BIT_DEPOT;
   571 			v->u.rail.track = TRACK_BIT_DEPOT;
   584 			v->vehstatus = VS_HIDDEN | VS_DEFPAL;
   572 			v->vehstatus = VS_HIDDEN | VS_DEFPAL;
   585 
   573 
   586 			v->subtype = 0;
   574 //			v->subtype = 0;
   587 			SetTrainWagon(v);
   575 			SetTrainWagon(v);
   588 
   576 
   589 			if (u != NULL) {
   577 			if (u != NULL) {
   590 				u->SetNext(v);
   578 				u->SetNext(v);
   591 			} else {
   579 			} else {
   592 				SetFreeWagon(v);
   580 				SetFreeWagon(v);
   593 				InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   581 				InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   594 			}
   582 			}
   595 
   583 
   596 			v->cargo_type = rvi->cargo_type;
   584 			v->cargo_type = rvi->cargo_type;
   597 			v->cargo_subtype = 0;
   585 //			v->cargo_subtype = 0;
   598 			v->cargo_cap = rvi->capacity;
   586 			v->cargo_cap = rvi->capacity;
   599 			v->value = value.GetCost();
   587 			v->value = value.GetCost();
   600 //			v->day_counter = 0;
   588 //			v->day_counter = 0;
   601 
   589 
   602 			v->u.rail.railtype = rvi->railtype;
   590 			v->u.rail.railtype = rvi->railtype;
   625 
   613 
   626 	return value;
   614 	return value;
   627 }
   615 }
   628 
   616 
   629 /** Move all free vehicles in the depot to the train */
   617 /** Move all free vehicles in the depot to the train */
   630 static void NormalizeTrainVehInDepot(const Vehicle* u)
   618 static void NormalizeTrainVehInDepot(const Vehicle *u)
   631 {
   619 {
   632 	const Vehicle* v;
   620 	const Vehicle *v;
   633 
   621 
   634 	FOR_ALL_VEHICLES(v) {
   622 	FOR_ALL_VEHICLES(v) {
   635 		if (v->type == VEH_TRAIN && IsFreeWagon(v) &&
   623 		if (v->type == VEH_TRAIN && IsFreeWagon(v) &&
   636 				v->tile == u->tile &&
   624 				v->tile == u->tile &&
   637 				v->u.rail.track == TRACK_BIT_DEPOT) {
   625 				v->u.rail.track == TRACK_BIT_DEPOT) {
   640 				break;
   628 				break;
   641 		}
   629 		}
   642 	}
   630 	}
   643 }
   631 }
   644 
   632 
   645 static CommandCost EstimateTrainCost(EngineID engine, const RailVehicleInfo* rvi)
   633 static CommandCost EstimateTrainCost(EngineID engine, const RailVehicleInfo *rvi)
   646 {
   634 {
   647 	return CommandCost(EXPENSES_NEW_VEHICLES, GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5);
   635 	return CommandCost(EXPENSES_NEW_VEHICLES, GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5);
   648 }
   636 }
   649 
   637 
   650 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
   638 static void AddRearEngineToMultiheadedTrain(Vehicle *v, Vehicle *u, bool building)
   651 {
   639 {
   652 	u = new (u) Train();
   640 	u = new (u) Train();
   653 	u->direction = v->direction;
   641 	u->direction = v->direction;
   654 	u->owner = v->owner;
   642 	u->owner = v->owner;
   655 	u->tile = v->tile;
   643 	u->tile = v->tile;
   656 	u->x_pos = v->x_pos;
   644 	u->x_pos = v->x_pos;
   657 	u->y_pos = v->y_pos;
   645 	u->y_pos = v->y_pos;
   658 	u->z_pos = v->z_pos;
   646 	u->z_pos = v->z_pos;
   659 	u->u.rail.track = TRACK_BIT_DEPOT;
   647 	u->u.rail.track = TRACK_BIT_DEPOT;
   660 	u->vehstatus = v->vehstatus & ~VS_STOPPED;
   648 	u->vehstatus = v->vehstatus & ~VS_STOPPED;
   661 	u->subtype = 0;
   649 //	u->subtype = 0;
   662 	SetMultiheaded(u);
   650 	SetMultiheaded(u);
   663 	u->spritenum = v->spritenum + 1;
   651 	u->spritenum = v->spritenum + 1;
   664 	u->cargo_type = v->cargo_type;
   652 	u->cargo_type = v->cargo_type;
   665 	u->cargo_subtype = v->cargo_subtype;
   653 	u->cargo_subtype = v->cargo_subtype;
   666 	u->cargo_cap = v->cargo_cap;
   654 	u->cargo_cap = v->cargo_cap;
   694 		if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
   682 		if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
   695 	}
   683 	}
   696 
   684 
   697 	const RailVehicleInfo *rvi = RailVehInfo(p1);
   685 	const RailVehicleInfo *rvi = RailVehInfo(p1);
   698 
   686 
   699 	/* Check if depot and new engine uses the same kind of tracks */
       
   700 	/* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
       
   701 	if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
       
   702 
       
   703 	if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(p1, tile, flags);
   687 	if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(p1, tile, flags);
   704 
   688 
   705 	CommandCost value = EstimateTrainCost(p1, rvi);
   689 	CommandCost value = EstimateTrainCost(p1, rvi);
   706 
   690 
   707 	uint num_vehicles =
   691 	uint num_vehicles =
   708 		(rvi->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) +
   692 		(rvi->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) +
   709 		CountArticulatedParts(p1, false);
   693 		CountArticulatedParts(p1, false);
   710 
   694 
   711 	if (!(flags & DC_QUERY_COST)) {
   695 	if (!(flags & DC_QUERY_COST)) {
       
   696 		/* Check if depot and new engine uses the same kind of tracks *
       
   697 		 * We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
       
   698 		if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
       
   699 
   712 		/* Allow for the dual-heads and the articulated parts, plus one to "terminate" the list. */
   700 		/* Allow for the dual-heads and the articulated parts, plus one to "terminate" the list. */
   713 		Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1));
   701 		Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1));
   714 		memset(vl, 0, sizeof(*vl) * (num_vehicles + 1));
   702 		memset(vl, 0, sizeof(*vl) * (num_vehicles + 1));
   715 
   703 
   716 		if (!Vehicle::AllocateList(vl, num_vehicles))
   704 		if (!Vehicle::AllocateList(vl, num_vehicles)) {
   717 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   705 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
       
   706 		}
   718 
   707 
   719 		Vehicle *v = vl[0];
   708 		Vehicle *v = vl[0];
   720 
   709 
   721 		UnitID unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_TRAIN);
   710 		UnitID unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_TRAIN);
   722 		if (unit_num > _patches.max_trains)
   711 		if (unit_num > _patches.max_trains)
   733 			v->tile = tile;
   722 			v->tile = tile;
   734 			v->owner = _current_player;
   723 			v->owner = _current_player;
   735 			v->x_pos = x;
   724 			v->x_pos = x;
   736 			v->y_pos = y;
   725 			v->y_pos = y;
   737 			v->z_pos = GetSlopeZ(x, y);
   726 			v->z_pos = GetSlopeZ(x, y);
   738 			v->running_ticks = 0;
   727 //			v->running_ticks = 0;
   739 			v->u.rail.track = TRACK_BIT_DEPOT;
   728 			v->u.rail.track = TRACK_BIT_DEPOT;
   740 			v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
   729 			v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
   741 			v->spritenum = rvi->image_index;
   730 			v->spritenum = rvi->image_index;
   742 			v->cargo_type = rvi->cargo_type;
   731 			v->cargo_type = rvi->cargo_type;
   743 			v->cargo_subtype = 0;
   732 //			v->cargo_subtype = 0;
   744 			v->cargo_cap = rvi->capacity;
   733 			v->cargo_cap = rvi->capacity;
   745 			v->max_speed = rvi->max_speed;
   734 			v->max_speed = rvi->max_speed;
   746 			v->value = value.GetCost();
   735 			v->value = value.GetCost();
   747 			v->last_station_visited = INVALID_STATION;
   736 			v->last_station_visited = INVALID_STATION;
   748 			v->dest_tile = 0;
   737 //			v->dest_tile = 0;
   749 
   738 
   750 			v->engine_type = p1;
   739 			v->engine_type = p1;
   751 
   740 
   752 			const Engine *e = GetEngine(p1);
   741 			const Engine *e = GetEngine(p1);
   753 			v->reliability = e->reliability;
   742 			v->reliability = e->reliability;
   762 			v->date_of_last_service = _date;
   751 			v->date_of_last_service = _date;
   763 			v->build_year = _cur_year;
   752 			v->build_year = _cur_year;
   764 			v->cur_image = 0xAC2;
   753 			v->cur_image = 0xAC2;
   765 			v->random_bits = VehicleRandomBits();
   754 			v->random_bits = VehicleRandomBits();
   766 
   755 
   767 			v->vehicle_flags = 0;
   756 //			v->vehicle_flags = 0;
   768 			if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
   757 			if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
   769 
   758 
   770 			v->group_id = DEFAULT_GROUP;
   759 			v->group_id = DEFAULT_GROUP;
   771 
   760 
   772 			v->subtype = 0;
   761 //			v->subtype = 0;
   773 			SetFrontEngine(v);
   762 			SetFrontEngine(v);
   774 			SetTrainEngine(v);
   763 			SetTrainEngine(v);
   775 
   764 
   776 			VehiclePositionChanged(v);
   765 			VehiclePositionChanged(v);
   777 
   766 
   787 			} else {
   776 			} else {
   788 				AddArticulatedParts(vl, VEH_TRAIN);
   777 				AddArticulatedParts(vl, VEH_TRAIN);
   789 			}
   778 			}
   790 
   779 
   791 			TrainConsistChanged(v);
   780 			TrainConsistChanged(v);
   792 			UpdateTrainAcceleration(v);
       
   793 			UpdateTrainGroupID(v);
   781 			UpdateTrainGroupID(v);
   794 
   782 
   795 			if (!HasBit(p2, 1)) { // check if the cars should be added to the new vehicle
   783 			if (!HasBit(p2, 1)) { // check if the cars should be added to the new vehicle
   796 				NormalizeTrainVehInDepot(v);
   784 				NormalizeTrainVehInDepot(v);
   797 			}
   785 			}
   798 
   786 
   799 			InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   787 			InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   800 			RebuildVehicleLists();
   788 			RebuildVehicleLists();
   801 			InvalidateWindow(WC_COMPANY, v->owner);
   789 			InvalidateWindow(WC_COMPANY, v->owner);
   802 			if (IsLocalPlayer())
   790 			if (IsLocalPlayer()) {
   803 				InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Train window
   791 				InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Train window
       
   792 			}
   804 
   793 
   805 			GetPlayer(_current_player)->num_engines[p1]++;
   794 			GetPlayer(_current_player)->num_engines[p1]++;
   806 		}
   795 		}
   807 	}
   796 	}
   808 
   797 
  1181 					/* setting the type to 0 also involves setting up the orders field. */
  1170 					/* setting the type to 0 also involves setting up the orders field. */
  1182 					SetFrontEngine(src);
  1171 					SetFrontEngine(src);
  1183 					assert(src->orders == NULL);
  1172 					assert(src->orders == NULL);
  1184 					src->num_orders = 0;
  1173 					src->num_orders = 0;
  1185 
  1174 
  1186 					// Decrease the engines number of the src engine_type
  1175 					/* Decrease the engines number of the src engine_type */
  1187 					if (!IsDefaultGroupID(src->group_id) && IsValidGroupID(src->group_id)) {
  1176 					if (!IsDefaultGroupID(src->group_id) && IsValidGroupID(src->group_id)) {
  1188 						GetGroup(src->group_id)->num_engines[src->engine_type]--;
  1177 						GetGroup(src->group_id)->num_engines[src->engine_type]--;
  1189 					}
  1178 					}
  1190 
  1179 
  1191 					// If we move an engine to a new line affect it to the DEFAULT_GROUP
  1180 					/* If we move an engine to a new line affect it to the DEFAULT_GROUP */
  1192 					src->group_id = DEFAULT_GROUP;
  1181 					src->group_id = DEFAULT_GROUP;
  1193 				}
  1182 				}
  1194 			} else {
  1183 			} else {
  1195 				SetFreeWagon(src);
  1184 				SetFreeWagon(src);
  1196 			}
  1185 			}
  1212 
  1201 
  1213 			/* link in the wagon(s) in the chain. */
  1202 			/* link in the wagon(s) in the chain. */
  1214 			{
  1203 			{
  1215 				Vehicle *v;
  1204 				Vehicle *v;
  1216 
  1205 
  1217 				for (v = src; GetNextVehicle(v) != NULL; v = GetNextVehicle(v));
  1206 				for (v = src; GetNextVehicle(v) != NULL; v = GetNextVehicle(v)) {}
  1218 				GetLastEnginePart(v)->SetNext(dst->Next());
  1207 				GetLastEnginePart(v)->SetNext(dst->Next());
  1219 			}
  1208 			}
  1220 			dst->SetNext(src);
  1209 			dst->SetNext(src);
  1221 		}
  1210 		}
  1222 
  1211 
  1242 		if (src_head != NULL) {
  1231 		if (src_head != NULL) {
  1243 			NormaliseTrainConsist(src_head);
  1232 			NormaliseTrainConsist(src_head);
  1244 			TrainConsistChanged(src_head);
  1233 			TrainConsistChanged(src_head);
  1245 			UpdateTrainGroupID(src_head);
  1234 			UpdateTrainGroupID(src_head);
  1246 			if (IsFrontEngine(src_head)) {
  1235 			if (IsFrontEngine(src_head)) {
  1247 				UpdateTrainAcceleration(src_head);
       
  1248 				InvalidateWindow(WC_VEHICLE_DETAILS, src_head->index);
       
  1249 				/* Update the refit button and window */
  1236 				/* Update the refit button and window */
  1250 				InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
  1237 				InvalidateWindow(WC_VEHICLE_REFIT, src_head->index);
  1251 				InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, VVW_WIDGET_REFIT_VEH);
  1238 				InvalidateWindowWidget(WC_VEHICLE_VIEW, src_head->index, VVW_WIDGET_REFIT_VEH);
  1252 			}
  1239 			}
  1253 			/* Update the depot window */
  1240 			/* Update the depot window */
  1257 		if (dst_head != NULL) {
  1244 		if (dst_head != NULL) {
  1258 			NormaliseTrainConsist(dst_head);
  1245 			NormaliseTrainConsist(dst_head);
  1259 			TrainConsistChanged(dst_head);
  1246 			TrainConsistChanged(dst_head);
  1260 			UpdateTrainGroupID(dst_head);
  1247 			UpdateTrainGroupID(dst_head);
  1261 			if (IsFrontEngine(dst_head)) {
  1248 			if (IsFrontEngine(dst_head)) {
  1262 				UpdateTrainAcceleration(dst_head);
       
  1263 				InvalidateWindow(WC_VEHICLE_DETAILS, dst_head->index);
       
  1264 				/* Update the refit button and window */
  1249 				/* Update the refit button and window */
  1265 				InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, VVW_WIDGET_REFIT_VEH);
  1250 				InvalidateWindowWidget(WC_VEHICLE_VIEW, dst_head->index, VVW_WIDGET_REFIT_VEH);
  1266 				InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
  1251 				InvalidateWindow(WC_VEHICLE_REFIT, dst_head->index);
  1267 			}
  1252 			}
  1268 			/* Update the depot window */
  1253 			/* Update the depot window */
  1423 				first = UnlinkWagon(v, first);
  1408 				first = UnlinkWagon(v, first);
  1424 				DeleteDepotHighlightOfVehicle(v);
  1409 				DeleteDepotHighlightOfVehicle(v);
  1425 				delete v;
  1410 				delete v;
  1426 
  1411 
  1427 				/* 4 If the second wagon was an engine, update it to front_engine
  1412 				/* 4 If the second wagon was an engine, update it to front_engine
  1428 					* which UnlinkWagon() has changed to TS_Free_Car */
  1413 				 * which UnlinkWagon() has changed to TS_Free_Car */
  1429 				if (switch_engine) SetFrontEngine(first);
  1414 				if (switch_engine) SetFrontEngine(first);
  1430 
  1415 
  1431 				/* 5. If the train still exists, update its acceleration, window, etc. */
  1416 				/* 5. If the train still exists, update its acceleration, window, etc. */
  1432 				if (first != NULL) {
  1417 				if (first != NULL) {
  1433 					NormaliseTrainConsist(first);
  1418 					NormaliseTrainConsist(first);
  1434 					TrainConsistChanged(first);
  1419 					TrainConsistChanged(first);
  1435 					UpdateTrainGroupID(first);
  1420 					UpdateTrainGroupID(first);
  1436 					if (IsFrontEngine(first)) {
  1421 					if (IsFrontEngine(first)) InvalidateWindow(WC_VEHICLE_REFIT, first->index);
  1437 						InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
       
  1438 						InvalidateWindow(WC_VEHICLE_REFIT, first->index);
       
  1439 						UpdateTrainAcceleration(first);
       
  1440 					}
       
  1441 				}
  1422 				}
  1442 
  1423 
  1443 
  1424 
  1444 				/* (6.) Borked AI. If it sells an engine it expects all wagons lined
  1425 				/* (6.) Borked AI. If it sells an engine it expects all wagons lined
  1445 				 * up on a new line to be added to the newly built loco. Replace it is.
  1426 				 * up on a new line to be added to the newly built loco. Replace it is.
  1446 				 * Totally braindead cause building a new engine adds all loco-less
  1427 				 * Totally braindead cause building a new engine adds all loco-less
  1447 				 * engines to its train anyways */
  1428 				 * engines to its train anyways */
  1448 				if (p2 == 2 && HasBit(ori_subtype, TS_FRONT)) {
  1429 				if (p2 == 2 && HasBit(ori_subtype, TS_FRONT)) {
  1449 					Vehicle *tmp;
  1430 					for (v = first; v != NULL;) {
  1450 					for (v = first; v != NULL; v = tmp) {
  1431 						Vehicle *tmp = GetNextVehicle(v);
  1451 						tmp = GetNextVehicle(v);
       
  1452 						DoCommand(v->tile, v->index | INVALID_VEHICLE << 16, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
  1432 						DoCommand(v->tile, v->index | INVALID_VEHICLE << 16, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
       
  1433 						v = tmp;
  1453 					}
  1434 					}
  1454 				}
  1435 				}
  1455 			}
  1436 			}
  1456 		} break;
  1437 		} break;
  1457 		case 1: { /* Delete wagon and all wagons after it given certain criteria */
  1438 		case 1: { /* Delete wagon and all wagons after it given certain criteria */
  1458 			/* Start deleting every vehicle after the selected one
  1439 			/* Start deleting every vehicle after the selected one
  1459 			 * If we encounter a matching rear-engine to a front-engine
  1440 			 * If we encounter a matching rear-engine to a front-engine
  1460 			 * earlier in the chain (before deletion), leave it alone */
  1441 			 * earlier in the chain (before deletion), leave it alone */
  1461 			Vehicle *tmp;
  1442 			for (Vehicle *tmp; v != NULL; v = tmp) {
  1462 			for (; v != NULL; v = tmp) {
       
  1463 				tmp = GetNextVehicle(v);
  1443 				tmp = GetNextVehicle(v);
  1464 
  1444 
  1465 				if (IsMultiheaded(v)) {
  1445 				if (IsMultiheaded(v)) {
  1466 					if (IsTrainEngine(v)) {
  1446 					if (IsTrainEngine(v)) {
  1467 						/* We got a front engine of a multiheaded set. Now we will sell the rear end too */
  1447 						/* We got a front engine of a multiheaded set. Now we will sell the rear end too */
  1501 			/* 3. If it is still a valid train after selling, update its acceleration and cached values */
  1481 			/* 3. If it is still a valid train after selling, update its acceleration and cached values */
  1502 			if (flags & DC_EXEC && first != NULL) {
  1482 			if (flags & DC_EXEC && first != NULL) {
  1503 				NormaliseTrainConsist(first);
  1483 				NormaliseTrainConsist(first);
  1504 				TrainConsistChanged(first);
  1484 				TrainConsistChanged(first);
  1505 				UpdateTrainGroupID(first);
  1485 				UpdateTrainGroupID(first);
  1506 				if (IsFrontEngine(first)) UpdateTrainAcceleration(first);
       
  1507 				InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
       
  1508 				InvalidateWindow(WC_VEHICLE_REFIT, first->index);
  1486 				InvalidateWindow(WC_VEHICLE_REFIT, first->index);
  1509 			}
  1487 			}
  1510 		} break;
  1488 		} break;
  1511 	}
  1489 	}
  1512 	return cost;
  1490 	return cost;
  1528 #undef MKIT
  1506 #undef MKIT
  1529 
  1507 
  1530 	uint32 x = _delta_xy_table[direction];
  1508 	uint32 x = _delta_xy_table[direction];
  1531 	this->x_offs        = GB(x,  0, 8);
  1509 	this->x_offs        = GB(x,  0, 8);
  1532 	this->y_offs        = GB(x,  8, 8);
  1510 	this->y_offs        = GB(x,  8, 8);
  1533 	this->sprite_width  = GB(x, 16, 8);
  1511 	this->x_extent      = GB(x, 16, 8);
  1534 	this->sprite_height = GB(x, 24, 8);
  1512 	this->y_extent      = GB(x, 24, 8);
  1535 	this->z_height      = 6;
  1513 	this->z_extent      = 6;
  1536 }
  1514 }
  1537 
  1515 
  1538 static void UpdateVarsAfterSwap(Vehicle *v)
  1516 static void UpdateVarsAfterSwap(Vehicle *v)
  1539 {
  1517 {
  1540 	v->UpdateDeltaXY(v->direction);
  1518 	v->UpdateDeltaXY(v->direction);
  1542 	BeginVehicleMove(v);
  1520 	BeginVehicleMove(v);
  1543 	VehiclePositionChanged(v);
  1521 	VehiclePositionChanged(v);
  1544 	EndVehicleMove(v);
  1522 	EndVehicleMove(v);
  1545 }
  1523 }
  1546 
  1524 
  1547 static inline void SetLastSpeed(Vehicle* v, int spd)
  1525 static inline void SetLastSpeed(Vehicle *v, int spd)
  1548 {
  1526 {
  1549 	int old = v->u.rail.last_speed;
  1527 	int old = v->u.rail.last_speed;
  1550 	if (spd != old) {
  1528 	if (spd != old) {
  1551 		v->u.rail.last_speed = spd;
  1529 		v->u.rail.last_speed = spd;
  1552 		if (_patches.vehicle_speed || (old == 0) != (spd == 0))
  1530 		if (_patches.vehicle_speed || (old == 0) != (spd == 0)) {
  1553 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  1531 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
       
  1532 		}
  1554 	}
  1533 	}
  1555 }
  1534 }
  1556 
  1535 
  1557 static void SwapTrainFlags(byte *swap_flag1, byte *swap_flag2)
  1536 static void SwapTrainFlags(byte *swap_flag1, byte *swap_flag2)
  1558 {
  1537 {
  1668 	assert(IsLevelCrossingTile(tile));
  1647 	assert(IsLevelCrossingTile(tile));
  1669 
  1648 
  1670 	DiagDirection dir = AxisToDiagDir(GetCrossingRailAxis(tile));
  1649 	DiagDirection dir = AxisToDiagDir(GetCrossingRailAxis(tile));
  1671 	TileIndex tile_from = tile + TileOffsByDiagDir(dir);
  1650 	TileIndex tile_from = tile + TileOffsByDiagDir(dir);
  1672 
  1651 
  1673 	Vehicle *v = (Vehicle *)VehicleFromPos(tile_from, &tile, &TrainApproachingCrossingEnum);
  1652 	Vehicle *v = (Vehicle*)VehicleFromPos(tile_from, &tile, &TrainApproachingCrossingEnum);
  1674 
  1653 
  1675 	if (v != NULL) return v;
  1654 	if (v != NULL) return v;
  1676 
  1655 
  1677 	dir = ReverseDiagDir(dir);
  1656 	dir = ReverseDiagDir(dir);
  1678 	tile_from = tile + TileOffsByDiagDir(dir);
  1657 	tile_from = tile + TileOffsByDiagDir(dir);
  1679 
  1658 
  1680 	return (Vehicle *)VehicleFromPos(tile_from, &tile, &TrainApproachingCrossingEnum);
  1659 	return (Vehicle*)VehicleFromPos(tile_from, &tile, &TrainApproachingCrossingEnum);
  1681 }
  1660 }
  1682 
  1661 
  1683 
  1662 
  1684 /**
  1663 /**
  1685  * Sets correct crossing state
  1664  * Sets correct crossing state
  1719 }
  1698 }
  1720 
  1699 
  1721 
  1700 
  1722 /**
  1701 /**
  1723  * Advances wagons for train reversing, needed for variable length wagons.
  1702  * Advances wagons for train reversing, needed for variable length wagons.
  1724  * Needs to be called once before the train is reversed, and once after it.
  1703  * This one is called before the train is reversed.
  1725  * @param v First vehicle in chain
  1704  * @param v First vehicle in chain
  1726  * @param before Set to true for the call before reversing, false otherwise
       
  1727  */
  1705  */
  1728 static void AdvanceWagons(Vehicle *v, bool before)
  1706 static void AdvanceWagonsBeforeSwap(Vehicle *v)
  1729 {
  1707 {
  1730 	Vehicle *base = v;
  1708 	Vehicle *base = v;
  1731 	Vehicle *first = base->Next();
  1709 	Vehicle *first = base;                    // first vehicle to move
       
  1710 	Vehicle *last = GetLastVehicleInChain(v); // last vehicle to move
  1732 	uint length = CountVehiclesInChain(v);
  1711 	uint length = CountVehiclesInChain(v);
  1733 
  1712 
  1734 	while (length > 2) {
  1713 	while (length > 2) {
  1735 		/* find pairwise matching wagon
  1714 		last = last->Previous();
  1736 		 * start<>end, start+1<>end-1, ... */
  1715 		first = first->Next();
  1737 		Vehicle *last = first;
  1716 
  1738 		for (uint i = length - 3; i > 0; i--) last = last->Next();
  1717 		int differential = base->u.rail.cached_veh_length - last->u.rail.cached_veh_length;
       
  1718 
       
  1719 		/* do not update images now
       
  1720 		 * negative differential will be handled in AdvanceWagonsAfterSwap() */
       
  1721 		for (int i = 0; i < differential; i++) TrainController(first, last->Next(), false);
       
  1722 
       
  1723 		base = first; // == base->Next()
       
  1724 		length -= 2;
       
  1725 	}
       
  1726 }
       
  1727 
       
  1728 
       
  1729 /**
       
  1730  * Advances wagons for train reversing, needed for variable length wagons.
       
  1731  * This one is called after the train is reversed.
       
  1732  * @param v First vehicle in chain
       
  1733  */
       
  1734 static void AdvanceWagonsAfterSwap(Vehicle *v)
       
  1735 {
       
  1736 	/* first of all, fix the situation when the train was entering a depot */
       
  1737 	Vehicle *dep = v; // last vehicle in front of just left depot
       
  1738 	while (dep->Next() != NULL && (dep->u.rail.track == TRACK_BIT_DEPOT || dep->Next()->u.rail.track != TRACK_BIT_DEPOT)) {
       
  1739 		dep = dep->Next(); // find first vehicle outside of a depot, with next vehicle inside a depot
       
  1740 	}
       
  1741 
       
  1742 	Vehicle *leave = dep->Next(); // first vehicle in a depot we are leaving now
       
  1743 
       
  1744 	if (leave != NULL) {
       
  1745 		/* 'pull' next wagon out of the depot, so we won't miss it (it could stay in depot forever) */
       
  1746 		int d = TicksToLeaveDepot(dep);
       
  1747 
       
  1748 		if (d <= 0) {
       
  1749 			leave->vehstatus &= ~VS_HIDDEN; // move it out of the depot
       
  1750 			leave->u.rail.track = AxisToTrackBits(DiagDirToAxis(GetRailDepotDirection(leave->tile)));
       
  1751 			for (int i = 0; i >= d; i--) TrainController(leave, NULL, false); // maybe move it, and maybe let another wagon leave
       
  1752 		}
       
  1753 	} else {
       
  1754 		dep = NULL; // no vehicle in a depot, so no vehicle leaving a depot
       
  1755 	}
       
  1756 
       
  1757 	Vehicle *base = v;
       
  1758 	Vehicle *first = base;                    // first vehicle to move
       
  1759 	Vehicle *last = GetLastVehicleInChain(v); // last vehicle to move
       
  1760 	uint length = CountVehiclesInChain(v);
       
  1761 
       
  1762 	/* we have to make sure all wagons that leave a depot because of train reversing are moved coorectly
       
  1763 	 * they have already correct spacing, so we have to make sure they are moved how they should */
       
  1764 	bool nomove = (dep == NULL); // if there is no vehicle leaving a depot, limit the number of wagons moved immediatelly
       
  1765 
       
  1766 	while (length > 2) {
       
  1767 		/* we reached vehicle (originally) in front of a depot, stop now
       
  1768 		 * (we would move wagons that are alredy moved with new wagon length) */
       
  1769 		if (base == dep) break;
       
  1770 
       
  1771 		/* the last wagon was that one leaving a depot, so do not move it anymore */
       
  1772 		if (last == dep) nomove = true;
       
  1773 
       
  1774 		last = last->Previous();
       
  1775 		first = first->Next();
  1739 
  1776 
  1740 		int differential = last->u.rail.cached_veh_length - base->u.rail.cached_veh_length;
  1777 		int differential = last->u.rail.cached_veh_length - base->u.rail.cached_veh_length;
  1741 		if (before) differential *= -1;
  1778 
  1742 
  1779 		/* do not update images now */
  1743 		if (differential > 0) {
  1780 		for (int i = 0; i < differential; i++) TrainController(first, (nomove ? last->Next() : NULL), false);
  1744 			/* disconnect last car to make sure only this subset moves */
  1781 
  1745 			Vehicle *tempnext = last->Next();
  1782 		base = first; // == base->Next()
  1746 			last->SetNext(NULL);
       
  1747 
       
  1748 			/* do not update images now because the wagons are disconnected
       
  1749 			 * and that could cause problems with NewGRFs */
       
  1750 			for (int i = 0; i < differential; i++) TrainController(first, false);
       
  1751 
       
  1752 			last->SetNext(tempnext);
       
  1753 		}
       
  1754 
       
  1755 		base = first;
       
  1756 		first = first->Next();
       
  1757 		length -= 2;
  1783 		length -= 2;
  1758 	}
  1784 	}
  1759 }
  1785 }
  1760 
  1786 
  1761 
  1787 
  1767 
  1793 
  1768 	/* Check if we were approaching a rail/road-crossing */
  1794 	/* Check if we were approaching a rail/road-crossing */
  1769 	TileIndex crossing = TrainApproachingCrossingTile(v);
  1795 	TileIndex crossing = TrainApproachingCrossingTile(v);
  1770 
  1796 
  1771 	/* count number of vehicles */
  1797 	/* count number of vehicles */
  1772 	int r = 0;  ///< number of vehicles - 1
  1798 	int r = CountVehiclesInChain(v) - 1;  // number of vehicles - 1
  1773 	for (const Vehicle *u = v; (u = u->Next()) != NULL;) { r++; }
  1799 
  1774 
  1800 	AdvanceWagonsBeforeSwap(v);
  1775 	AdvanceWagons(v, true);
       
  1776 
  1801 
  1777 	/* swap start<>end, start+1<>end-1, ... */
  1802 	/* swap start<>end, start+1<>end-1, ... */
  1778 	int l = 0;
  1803 	int l = 0;
  1779 	do {
  1804 	do {
  1780 		ReverseTrainSwapVeh(v, l++, r--);
  1805 		ReverseTrainSwapVeh(v, l++, r--);
  1781 	} while (l <= r);
  1806 	} while (l <= r);
  1782 
  1807 
  1783 	AdvanceWagons(v, false);
  1808 	AdvanceWagonsAfterSwap(v);
  1784 
  1809 
  1785 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL)) {
  1810 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL)) {
  1786 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  1811 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  1787 	}
  1812 	}
  1788 
  1813 
  1817 
  1842 
  1818 	Vehicle *v = GetVehicle(p1);
  1843 	Vehicle *v = GetVehicle(p1);
  1819 
  1844 
  1820 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  1845 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  1821 
  1846 
  1822 	if (p2) {
  1847 	if (p2 != 0) {
  1823 		/* turn a single unit around */
  1848 		/* turn a single unit around */
  1824 
  1849 
  1825 		if (IsMultiheaded(v) || HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) {
  1850 		if (IsMultiheaded(v) || HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) {
  1826 			return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
  1851 			return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
  1827 		}
  1852 		}
  2022 			bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse);
  2047 			bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse);
  2023 			tfdd.best_length = found ? max_distance / 2 : UINT_MAX; // some fake distance or NOT_FOUND
  2048 			tfdd.best_length = found ? max_distance / 2 : UINT_MAX; // some fake distance or NOT_FOUND
  2024 		} break;
  2049 		} break;
  2025 
  2050 
  2026 		case VPF_NPF: { /* NPF */
  2051 		case VPF_NPF: { /* NPF */
  2027 			Vehicle* last = GetLastVehicleInChain(v);
  2052 			const Vehicle *last = GetLastVehicleInChain(v);
  2028 			Trackdir trackdir = GetVehicleTrackdir(v);
  2053 			Trackdir trackdir = GetVehicleTrackdir(v);
  2029 			Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
  2054 			Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
  2030 
  2055 
  2031 			assert(trackdir != INVALID_TRACKDIR);
  2056 			assert(trackdir != INVALID_TRACKDIR);
  2032 			NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY);
  2057 			NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY);
  2033 			if (ftd.best_bird_dist == 0) {
  2058 			if (ftd.best_bird_dist == 0) {
  2034 				/* Found target */
  2059 				/* Found target */
  2035 				tfdd.tile = ftd.node.tile;
  2060 				tfdd.tile = ftd.node.tile;
  2036 				/* Our caller expects a number of tiles, so we just approximate that
  2061 				/* Our caller expects a number of tiles, so we just approximate that
  2037 				* number by this. It might not be completely what we want, but it will
  2062 				 * number by this. It might not be completely what we want, but it will
  2038 				* work for now :-) We can possibly change this when the old pathfinder
  2063 				 * work for now :-) We can possibly change this when the old pathfinder
  2039 				* is removed. */
  2064 				 * is removed. */
  2040 				tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH;
  2065 				tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH;
  2041 				if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) tfdd.reverse = true;
  2066 				if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) tfdd.reverse = true;
  2042 			}
  2067 			}
  2043 		} break;
  2068 		} break;
  2044 
  2069 
  2081 
  2106 
  2082 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  2107 	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
  2083 
  2108 
  2084 	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
  2109 	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
  2085 
  2110 
  2086 	if (v->current_order.type == OT_GOTO_DEPOT) {
  2111 	if (v->current_order.IsType(OT_GOTO_DEPOT)) {
  2087 		if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) {
  2112 		bool halt_in_depot = v->current_order.GetDepotActionType() & ODATFB_HALT;
       
  2113 		if (!!(p2 & DEPOT_SERVICE) == halt_in_depot) {
  2088 			/* We called with a different DEPOT_SERVICE setting.
  2114 			/* We called with a different DEPOT_SERVICE setting.
  2089 			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
  2115 			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
  2090 			 * Note: the if is (true for requesting service == true for ordered to stop in depot)          */
  2116 			 * Note: the if is (true for requesting service == true for ordered to stop in depot)          */
  2091 			if (flags & DC_EXEC) {
  2117 			if (flags & DC_EXEC) {
  2092 				ClrBit(v->current_order.flags, OF_PART_OF_ORDERS);
  2118 				v->current_order.SetDepotOrderType(ODTF_MANUAL);
  2093 				ToggleBit(v->current_order.flags, OF_HALT_IN_DEPOT);
  2119 				v->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT);
  2094 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  2120 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  2095 			}
  2121 			}
  2096 			return CommandCost();
  2122 			return CommandCost();
  2097 		}
  2123 		}
  2098 
  2124 
  2099 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
  2125 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
  2100 		if (flags & DC_EXEC) {
  2126 		if (flags & DC_EXEC) {
  2101 			if (HasBit(v->current_order.flags, OF_PART_OF_ORDERS)) {
  2127 			/* If the orders to 'goto depot' are in the orders list (forced servicing),
  2102 				v->cur_order_index++;
  2128 			 * then skip to the next order; effectively cancelling this forced service */
  2103 			}
  2129 			if (v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) v->cur_order_index++;
  2104 
  2130 
  2105 			v->current_order.type = OT_DUMMY;
  2131 			v->current_order.MakeDummy();
  2106 			v->current_order.flags = 0;
       
  2107 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  2132 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  2108 		}
  2133 		}
  2109 		return CommandCost();
  2134 		return CommandCost();
  2110 	}
  2135 	}
  2111 
  2136 
  2115 
  2140 
  2116 	TrainFindDepotData tfdd = FindClosestTrainDepot(v, 0);
  2141 	TrainFindDepotData tfdd = FindClosestTrainDepot(v, 0);
  2117 	if (tfdd.best_length == (uint)-1) return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO);
  2142 	if (tfdd.best_length == (uint)-1) return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO);
  2118 
  2143 
  2119 	if (flags & DC_EXEC) {
  2144 	if (flags & DC_EXEC) {
  2120 		if (v->current_order.type == OT_LOADING) v->LeaveStation();
  2145 		if (v->current_order.IsType(OT_LOADING)) v->LeaveStation();
  2121 
  2146 
  2122 		v->dest_tile = tfdd.tile;
  2147 		v->dest_tile = tfdd.tile;
  2123 		v->current_order.type = OT_GOTO_DEPOT;
  2148 		v->current_order.MakeGoToDepot(GetDepotByTile(tfdd.tile)->index, ODTF_MANUAL);
  2124 		v->current_order.flags = OFB_NON_STOP;
  2149 		if (!(p2 & DEPOT_SERVICE)) v->current_order.SetDepotActionType(ODATFB_HALT);
  2125 		if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT);
       
  2126 		v->current_order.dest = GetDepotByTile(tfdd.tile)->index;
       
  2127 		v->current_order.refit_cargo = CT_INVALID;
       
  2128 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  2150 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  2129 		/* If there is no depot in front, reverse automatically */
  2151 		/* If there is no depot in front, reverse automatically */
  2130 		if (tfdd.reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
  2152 		if (tfdd.reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
  2131 	}
  2153 	}
  2132 
  2154 
  2141 
  2163 
  2142 static const int8 _vehicle_smoke_pos[8] = {
  2164 static const int8 _vehicle_smoke_pos[8] = {
  2143 	1, 1, 1, 0, -1, -1, -1, 0
  2165 	1, 1, 1, 0, -1, -1, -1, 0
  2144 };
  2166 };
  2145 
  2167 
  2146 static void HandleLocomotiveSmokeCloud(const Vehicle* v)
  2168 static void HandleLocomotiveSmokeCloud(const Vehicle *v)
  2147 {
  2169 {
  2148 	bool sound = false;
  2170 	bool sound = false;
  2149 
  2171 
  2150 	if (v->vehstatus & VS_TRAIN_SLOWING || v->load_unload_time_rem != 0 || v->cur_speed < 2)
  2172 	if (v->vehstatus & VS_TRAIN_SLOWING || v->load_unload_time_rem != 0 || v->cur_speed < 2) {
  2151 		return;
  2173 		return;
  2152 
  2174 	}
  2153 	const Vehicle* u = v;
  2175 
       
  2176 	const Vehicle *u = v;
  2154 
  2177 
  2155 	do {
  2178 	do {
  2156 		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
  2179 		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
  2157 		int effect_offset = GB(v->u.rail.cached_vis_effect, 0, 4) - 8;
  2180 		int effect_offset = GB(v->u.rail.cached_vis_effect, 0, 4) - 8;
  2158 		byte effect_type = GB(v->u.rail.cached_vis_effect, 4, 2);
  2181 		byte effect_type = GB(v->u.rail.cached_vis_effect, 4, 2);
  2185 			x = -x;
  2208 			x = -x;
  2186 			y = -y;
  2209 			y = -y;
  2187 		}
  2210 		}
  2188 
  2211 
  2189 		switch (effect_type) {
  2212 		switch (effect_type) {
  2190 		case 0:
  2213 			case 0:
  2191 			/* steam smoke. */
  2214 				/* steam smoke. */
  2192 			if (GB(v->tick_counter, 0, 4) == 0) {
  2215 				if (GB(v->tick_counter, 0, 4) == 0) {
  2193 				CreateEffectVehicleRel(v, x, y, 10, EV_STEAM_SMOKE);
  2216 					CreateEffectVehicleRel(v, x, y, 10, EV_STEAM_SMOKE);
  2194 				sound = true;
  2217 					sound = true;
  2195 			}
  2218 				}
  2196 			break;
  2219 				break;
  2197 
  2220 
  2198 		case 1:
  2221 			case 1:
  2199 			/* diesel smoke */
  2222 				/* diesel smoke */
  2200 			if (u->cur_speed <= 40 && Chance16(15, 128)) {
  2223 				if (u->cur_speed <= 40 && Chance16(15, 128)) {
  2201 				CreateEffectVehicleRel(v, 0, 0, 10, EV_DIESEL_SMOKE);
  2224 					CreateEffectVehicleRel(v, 0, 0, 10, EV_DIESEL_SMOKE);
  2202 				sound = true;
  2225 					sound = true;
  2203 			}
  2226 				}
  2204 			break;
  2227 				break;
  2205 
  2228 
  2206 		case 2:
  2229 			case 2:
  2207 			/* blue spark */
  2230 				/* blue spark */
  2208 			if (GB(v->tick_counter, 0, 2) == 0 && Chance16(1, 45)) {
  2231 				if (GB(v->tick_counter, 0, 2) == 0 && Chance16(1, 45)) {
  2209 				CreateEffectVehicleRel(v, 0, 0, 10, EV_ELECTRIC_SPARK);
  2232 					CreateEffectVehicleRel(v, 0, 0, 10, EV_ELECTRIC_SPARK);
  2210 				sound = true;
  2233 					sound = true;
  2211 			}
  2234 				}
  2212 			break;
  2235 				break;
       
  2236 
       
  2237 			default:
       
  2238 				break;
  2213 		}
  2239 		}
  2214 	} while ((v = v->Next()) != NULL);
  2240 	} while ((v = v->Next()) != NULL);
  2215 
  2241 
  2216 	if (sound) PlayVehicleSound(u, VSE_TRAIN_EFFECT);
  2242 	if (sound) PlayVehicleSound(u, VSE_TRAIN_EFFECT);
  2217 }
  2243 }
  2278 	InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  2304 	InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  2279 
  2305 
  2280 	return false;
  2306 	return false;
  2281 }
  2307 }
  2282 
  2308 
  2283 /* Check for station tiles */
  2309 /** Check for station tiles */
  2284 struct TrainTrackFollowerData {
  2310 struct TrainTrackFollowerData {
  2285 	TileIndex dest_coords;
  2311 	TileIndex dest_coords;
  2286 	StationID station_index; // station index we're heading for
  2312 	StationID station_index; ///< station index we're heading for
  2287 	uint best_bird_dist;
  2313 	uint best_bird_dist;
  2288 	uint best_track_dist;
  2314 	uint best_track_dist;
  2289 	TrackdirByte best_track;
  2315 	TrackdirByte best_track;
  2290 };
  2316 };
  2291 
  2317 
  2317 		}
  2343 		}
  2318 		return false;
  2344 		return false;
  2319 	}
  2345 	}
  2320 }
  2346 }
  2321 
  2347 
  2322 static void FillWithStationData(TrainTrackFollowerData* fd, const Vehicle* v)
  2348 static void FillWithStationData(TrainTrackFollowerData *fd, const Vehicle *v)
  2323 {
  2349 {
  2324 	fd->dest_coords = v->dest_tile;
  2350 	fd->dest_coords = v->dest_tile;
  2325 	if (v->current_order.type == OT_GOTO_STATION) {
  2351 	fd->station_index = v->current_order.IsType(OT_GOTO_STATION) ? v->current_order.GetDestination() : INVALID_STATION;
  2326 		fd->station_index = v->current_order.dest;
       
  2327 	} else {
       
  2328 		fd->station_index = INVALID_STATION;
       
  2329 	}
       
  2330 }
  2352 }
  2331 
  2353 
  2332 static const byte _initial_tile_subcoord[6][4][3] = {
  2354 static const byte _initial_tile_subcoord[6][4][3] = {
  2333 {{ 15, 8, 1 }, { 0, 0, 0 }, { 0, 8, 5 }, { 0,  0, 0 }},
  2355 {{ 15, 8, 1 }, { 0, 0, 0 }, { 0, 8, 5 }, { 0,  0, 0 }},
  2334 {{  0, 0, 0 }, { 8, 0, 3 }, { 0, 0, 0 }, { 8, 15, 7 }},
  2356 {{  0, 0, 0 }, { 8, 0, 3 }, { 0, 0, 0 }, { 8, 15, 7 }},
  2336 {{ 15, 8, 2 }, { 0, 0, 0 }, { 0, 0, 0 }, { 8, 15, 6 }},
  2358 {{ 15, 8, 2 }, { 0, 0, 0 }, { 0, 0, 0 }, { 8, 15, 6 }},
  2337 {{ 15, 7, 0 }, { 8, 0, 4 }, { 0, 0, 0 }, { 0,  0, 0 }},
  2359 {{ 15, 7, 0 }, { 8, 0, 4 }, { 0, 0, 0 }, { 0,  0, 0 }},
  2338 {{  0, 0, 0 }, { 0, 0, 0 }, { 0, 8, 4 }, { 7, 15, 0 }},
  2360 {{  0, 0, 0 }, { 0, 0, 0 }, { 0, 8, 4 }, { 7, 15, 0 }},
  2339 };
  2361 };
  2340 
  2362 
  2341 static const uint32 _reachable_tracks[4] = {
       
  2342 	0x10091009,
       
  2343 	0x00160016,
       
  2344 	0x05200520,
       
  2345 	0x2A002A00,
       
  2346 };
       
  2347 
       
  2348 static const byte _search_directions[6][4] = {
  2363 static const byte _search_directions[6][4] = {
  2349 	{ 0, 9, 2, 9 }, ///< track 1
  2364 	{ 0, 9, 2, 9 }, ///< track 1
  2350 	{ 9, 1, 9, 3 }, ///< track 2
  2365 	{ 9, 1, 9, 3 }, ///< track 2
  2351 	{ 9, 0, 3, 9 }, ///< track upper
  2366 	{ 9, 0, 3, 9 }, ///< track upper
  2352 	{ 1, 9, 9, 2 }, ///< track lower
  2367 	{ 1, 9, 9, 2 }, ///< track lower
  2355 };
  2370 };
  2356 
  2371 
  2357 static const byte _pick_track_table[6] = {1, 3, 2, 2, 0, 0};
  2372 static const byte _pick_track_table[6] = {1, 3, 2, 2, 0, 0};
  2358 
  2373 
  2359 /* choose a track */
  2374 /* choose a track */
  2360 static Track ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir, TrackBits tracks)
  2375 static Track ChooseTrainTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks)
  2361 {
  2376 {
  2362 	Track best_track;
  2377 	Track best_track;
  2363 	/* pathfinders are able to tell that route was only 'guessed' */
  2378 	/* pathfinders are able to tell that route was only 'guessed' */
  2364 	bool path_not_found = false;
  2379 	bool path_not_found = false;
  2365 
  2380 
  2451 			/* and notify user about the event */
  2466 			/* and notify user about the event */
  2452 			if (_patches.lost_train_warn && v->owner == _local_player) {
  2467 			if (_patches.lost_train_warn && v->owner == _local_player) {
  2453 				SetDParam(0, v->unitnumber);
  2468 				SetDParam(0, v->unitnumber);
  2454 				AddNewsItem(
  2469 				AddNewsItem(
  2455 					STR_TRAIN_IS_LOST,
  2470 					STR_TRAIN_IS_LOST,
  2456 					NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0),
  2471 					NM_SMALL, NF_VIEWPORT | NF_VEHICLE, NT_ADVICE, DNC_NONE,
  2457 					v->index,
  2472 					v->index,
  2458 					0);
  2473 					0);
  2459 			}
  2474 			}
  2460 		}
  2475 		}
  2461 	} else {
  2476 	} else {
  2477 
  2492 
  2478 static bool CheckReverseTrain(Vehicle *v)
  2493 static bool CheckReverseTrain(Vehicle *v)
  2479 {
  2494 {
  2480 	if (_opt.diff.line_reverse_mode != 0 ||
  2495 	if (_opt.diff.line_reverse_mode != 0 ||
  2481 			v->u.rail.track == TRACK_BIT_DEPOT || v->u.rail.track == TRACK_BIT_WORMHOLE ||
  2496 			v->u.rail.track == TRACK_BIT_DEPOT || v->u.rail.track == TRACK_BIT_WORMHOLE ||
  2482 			!(v->direction & 1))
  2497 			!(v->direction & 1)) {
  2483 		return false;
  2498 		return false;
       
  2499 	}
  2484 
  2500 
  2485 	TrainTrackFollowerData fd;
  2501 	TrainTrackFollowerData fd;
  2486 	FillWithStationData(&fd, v);
  2502 	FillWithStationData(&fd, v);
  2487 
  2503 
  2488 	uint reverse_best = 0;
  2504 	uint reverse_best = 0;
  2489 
  2505 
  2490 	assert(v->u.rail.track);
  2506 	assert(v->u.rail.track);
  2491 
  2507 
  2492 	int i = _search_directions[FIND_FIRST_BIT(v->u.rail.track)][DirToDiagDir(v->direction)];
       
  2493 
       
  2494 	switch (_patches.pathfinder_for_trains) {
  2508 	switch (_patches.pathfinder_for_trains) {
  2495 		case VPF_YAPF: { /* YAPF */
  2509 		case VPF_YAPF: /* YAPF */
  2496 			reverse_best = YapfCheckReverseTrain(v);
  2510 			reverse_best = YapfCheckReverseTrain(v);
  2497 		} break;
  2511 			break;
  2498 
  2512 
  2499 		case VPF_NPF: { /* NPF */
  2513 		case VPF_NPF: { /* NPF */
  2500 			NPFFindStationOrTileData fstd;
  2514 			NPFFindStationOrTileData fstd;
  2501 			NPFFoundTargetData ftd;
  2515 			NPFFoundTargetData ftd;
  2502 			Vehicle* last = GetLastVehicleInChain(v);
  2516 			Vehicle *last = GetLastVehicleInChain(v);
  2503 
  2517 
  2504 			NPFFillWithOrderData(&fstd, v);
  2518 			NPFFillWithOrderData(&fstd, v);
  2505 
  2519 
  2506 			Trackdir trackdir = GetVehicleTrackdir(v);
  2520 			Trackdir trackdir = GetVehicleTrackdir(v);
  2507 			Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
  2521 			Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
  2521 			}
  2535 			}
  2522 		} break;
  2536 		} break;
  2523 
  2537 
  2524 		default:
  2538 		default:
  2525 		case VPF_NTP: { /* NTP */
  2539 		case VPF_NTP: { /* NTP */
       
  2540 			int i = _search_directions[FindFirstTrack(v->u.rail.track)][DirToDiagDir(v->direction)];
       
  2541 
  2526 			int best_track = -1;
  2542 			int best_track = -1;
  2527 			uint reverse = 0;
  2543 			uint reverse = 0;
  2528 			uint best_bird_dist  = 0;
  2544 			uint best_bird_dist  = 0;
  2529 			uint best_track_dist = 0;
  2545 			uint best_track_dist = 0;
  2530 
  2546 
  2575 	}
  2591 	}
  2576 
  2592 
  2577 	return reverse_best != 0;
  2593 	return reverse_best != 0;
  2578 }
  2594 }
  2579 
  2595 
  2580 static bool ProcessTrainOrder(Vehicle *v)
  2596 TileIndex Train::GetOrderStationLocation(StationID station)
  2581 {
  2597 {
  2582 	switch (v->current_order.type) {
  2598 	if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION;
  2583 		case OT_GOTO_DEPOT:
  2599 
  2584 			if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return false;
  2600 	return GetStation(station)->xy;
  2585 			if ((v->current_order.flags & OFB_SERVICE_IF_NEEDED) &&
       
  2586 					!VehicleNeedsService(v)) {
       
  2587 				UpdateVehicleTimetable(v, true);
       
  2588 				v->cur_order_index++;
       
  2589 			}
       
  2590 			break;
       
  2591 
       
  2592 		case OT_LOADING:
       
  2593 		case OT_LEAVESTATION:
       
  2594 			return false;
       
  2595 
       
  2596 		default: break;
       
  2597 	}
       
  2598 
       
  2599 	/**
       
  2600 	 * Reversing because of order change is allowed only just after leaving a
       
  2601 	 * station (and the difficulty setting to allowed, of course)
       
  2602 	 * this can be detected because only after OT_LEAVESTATION, current_order
       
  2603 	 * will be reset to nothing. (That also happens if no order, but in that case
       
  2604 	 * it won't hit the point in code where may_reverse is checked)
       
  2605 	 */
       
  2606 	bool may_reverse = v->current_order.type == OT_NOTHING;
       
  2607 
       
  2608 	/* check if we've reached the waypoint? */
       
  2609 	if (v->current_order.type == OT_GOTO_WAYPOINT && v->tile == v->dest_tile) {
       
  2610 		UpdateVehicleTimetable(v, true);
       
  2611 		v->cur_order_index++;
       
  2612 	}
       
  2613 
       
  2614 	/* check if we've reached a non-stop station while TTDPatch nonstop is enabled.. */
       
  2615 	if (_patches.new_nonstop &&
       
  2616 			v->current_order.flags & OFB_NON_STOP &&
       
  2617 			IsTileType(v->tile, MP_STATION) &&
       
  2618 			v->current_order.dest == GetStationIndex(v->tile)) {
       
  2619 		UpdateVehicleTimetable(v, true);
       
  2620 		v->cur_order_index++;
       
  2621 	}
       
  2622 
       
  2623 	/* Get the current order */
       
  2624 	if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
       
  2625 
       
  2626 	const Order *order = GetVehicleOrder(v, v->cur_order_index);
       
  2627 
       
  2628 	/* If no order, do nothing. */
       
  2629 	if (order == NULL) {
       
  2630 		v->current_order.Free();
       
  2631 		v->dest_tile = 0;
       
  2632 		return false;
       
  2633 	}
       
  2634 
       
  2635 	/* If it is unchanged, keep it. */
       
  2636 	if (order->type  == v->current_order.type &&
       
  2637 			order->flags == v->current_order.flags &&
       
  2638 			order->dest  == v->current_order.dest)
       
  2639 		return false;
       
  2640 
       
  2641 	/* Otherwise set it, and determine the destination tile. */
       
  2642 	v->current_order = *order;
       
  2643 
       
  2644 	v->dest_tile = 0;
       
  2645 
       
  2646 	InvalidateVehicleOrder(v);
       
  2647 
       
  2648 	switch (order->type) {
       
  2649 		case OT_GOTO_STATION:
       
  2650 			if (order->dest == v->last_station_visited)
       
  2651 				v->last_station_visited = INVALID_STATION;
       
  2652 			v->dest_tile = GetStation(order->dest)->xy;
       
  2653 			break;
       
  2654 
       
  2655 		case OT_GOTO_DEPOT:
       
  2656 			v->dest_tile = GetDepot(order->dest)->xy;
       
  2657 			break;
       
  2658 
       
  2659 		case OT_GOTO_WAYPOINT:
       
  2660 			v->dest_tile = GetWaypoint(order->dest)->xy;
       
  2661 			break;
       
  2662 
       
  2663 		default:
       
  2664 			return false;
       
  2665 	}
       
  2666 
       
  2667 	return may_reverse && CheckReverseTrain(v);
       
  2668 }
  2601 }
  2669 
  2602 
  2670 void Train::MarkDirty()
  2603 void Train::MarkDirty()
  2671 {
  2604 {
  2672 	Vehicle *v = this;
  2605 	Vehicle *v = this;
  2721 	/* check if a train ever visited this station before */
  2654 	/* check if a train ever visited this station before */
  2722 	Station *st = GetStation(station);
  2655 	Station *st = GetStation(station);
  2723 	if (!(st->had_vehicle_of_type & HVOT_TRAIN)) {
  2656 	if (!(st->had_vehicle_of_type & HVOT_TRAIN)) {
  2724 		st->had_vehicle_of_type |= HVOT_TRAIN;
  2657 		st->had_vehicle_of_type |= HVOT_TRAIN;
  2725 		SetDParam(0, st->index);
  2658 		SetDParam(0, st->index);
  2726 		uint32 flags = v->owner == _local_player ?
       
  2727 			NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) :
       
  2728 			NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ARRIVAL_OTHER,  0);
       
  2729 		AddNewsItem(
  2659 		AddNewsItem(
  2730 			STR_8801_CITIZENS_CELEBRATE_FIRST,
  2660 			STR_8801_CITIZENS_CELEBRATE_FIRST,
  2731 			flags,
  2661 			NM_THIN, NF_VIEWPORT | NF_VEHICLE, v->owner == _local_player ? NT_ARRIVAL_PLAYER : NT_ARRIVAL_OTHER, DNC_NONE,
  2732 			v->index,
  2662 			v->index,
  2733 			0
  2663 			0
  2734 		);
  2664 		);
  2735 	}
  2665 	}
  2736 
  2666 
  2737 	v->BeginLoading();
  2667 	v->BeginLoading();
  2738 	v->current_order.dest = 0;
       
  2739 }
  2668 }
  2740 
  2669 
  2741 static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
  2670 static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
  2742 {
  2671 {
  2743 	byte old_z = v->z_pos;
  2672 	byte old_z = v->z_pos;
  2830 	{256 / 4, 256 / 2, 256 / 4, 2}, ///< monorail
  2759 	{256 / 4, 256 / 2, 256 / 4, 2}, ///< monorail
  2831 	{0,       256 / 2, 256 / 4, 2}, ///< maglev
  2760 	{0,       256 / 2, 256 / 4, 2}, ///< maglev
  2832 };
  2761 };
  2833 
  2762 
  2834 /** Modify the speed of the vehicle due to a turn */
  2763 /** Modify the speed of the vehicle due to a turn */
  2835 static inline void AffectSpeedByDirChange(Vehicle* v, Direction new_dir)
  2764 static inline void AffectSpeedByDirChange(Vehicle *v, Direction new_dir)
  2836 {
  2765 {
  2837 	if (_patches.realistic_acceleration) return;
  2766 	if (_patches.realistic_acceleration) return;
  2838 
  2767 
  2839 	DirDiff diff = DirDifference(v->direction, new_dir);
  2768 	DirDiff diff = DirDifference(v->direction, new_dir);
  2840 	if (diff == DIRDIFF_SAME) return;
  2769 	if (diff == DIRDIFF_SAME) return;
  2856 		uint16 spd = v->cur_speed + rsp->z_down;
  2785 		uint16 spd = v->cur_speed + rsp->z_down;
  2857 		if (spd <= v->max_speed) v->cur_speed = spd;
  2786 		if (spd <= v->max_speed) v->cur_speed = spd;
  2858 	}
  2787 	}
  2859 }
  2788 }
  2860 
  2789 
  2861 static const DiagDirection _otherside_signal_directions[] = {
       
  2862 	DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, INVALID_DIAGDIR, INVALID_DIAGDIR,
       
  2863 	DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
       
  2864 };
       
  2865 
       
  2866 static void TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
  2790 static void TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
  2867 {
  2791 {
  2868 	if (IsTileType(tile, MP_RAILWAY) &&
  2792 	if (IsTileType(tile, MP_RAILWAY) &&
  2869 			GetRailTileType(tile) == RAIL_TILE_SIGNALS) {
  2793 			GetRailTileType(tile) == RAIL_TILE_SIGNALS) {
  2870 		uint i = FindFirstBit2x64(GetTrackBits(tile) * 0x101 & _reachable_tracks[dir]);
  2794 		TrackdirBits tracks = TrackBitsToTrackdirBits(GetTrackBits(tile)) & DiagdirReachesTrackdirs(dir);
  2871 		UpdateSignalsOnSegment(tile, _otherside_signal_directions[i], GetTileOwner(tile));
  2795 		Trackdir trackdir = FindFirstTrackdir(tracks);
       
  2796 		UpdateSignalsOnSegment(tile, TrackdirToExitdir(trackdir), GetTileOwner(tile));
  2872 	}
  2797 	}
  2873 }
  2798 }
  2874 
  2799 
  2875 
  2800 
  2876 static void SetVehicleCrashed(Vehicle *v)
  2801 static void SetVehicleCrashed(Vehicle *v)
  2898 
  2823 
  2899 	/* must be updated after the train has been marked crashed */
  2824 	/* must be updated after the train has been marked crashed */
  2900 	if (crossing != INVALID_TILE) UpdateLevelCrossing(crossing);
  2825 	if (crossing != INVALID_TILE) UpdateLevelCrossing(crossing);
  2901 }
  2826 }
  2902 
  2827 
  2903 static uint CountPassengersInTrain(const Vehicle* v)
  2828 static uint CountPassengersInTrain(const Vehicle *v)
  2904 {
  2829 {
  2905 	uint num = 0;
  2830 	uint num = 0;
  2906 	BEGIN_ENUM_WAGONS(v)
  2831 	BEGIN_ENUM_WAGONS(v)
  2907 		if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) num += v->cargo.Count();
  2832 		if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) num += v->cargo.Count();
  2908 	END_ENUM_WAGONS(v)
  2833 	END_ENUM_WAGONS(v)
  2909 	return num;
  2834 	return num;
  2910 }
  2835 }
  2911 
  2836 
  2912 struct TrainCollideChecker {
  2837 struct TrainCollideChecker {
  2913 	Vehicle *v;
  2838 	Vehicle *v;  ///< vehicle we are testing for collision
  2914 	uint num;
  2839 	uint num;    ///< number of dead if train collided
  2915 };
  2840 };
  2916 
  2841 
  2917 static void *FindTrainCollideEnum(Vehicle *v, void *data)
  2842 static void *FindTrainCollideEnum(Vehicle *v, void *data)
  2918 {
  2843 {
  2919 	TrainCollideChecker* tcc = (TrainCollideChecker*)data;
  2844 	TrainCollideChecker *tcc = (TrainCollideChecker*)data;
  2920 
  2845 
  2921 	if (v->type != VEH_TRAIN) return NULL;
  2846 	if (v->type != VEH_TRAIN) return NULL;
  2922 
  2847 
  2923 	/* get first vehicle now to make most usual checks faster */
  2848 	/* get first vehicle now to make most usual checks faster */
  2924 	Vehicle *coll = v->First();
  2849 	Vehicle *coll = v->First();
  2975 	/* any dead -> no crash */
  2900 	/* any dead -> no crash */
  2976 	if (tcc.num == 0) return;
  2901 	if (tcc.num == 0) return;
  2977 
  2902 
  2978 	SetDParam(0, tcc.num);
  2903 	SetDParam(0, tcc.num);
  2979 	AddNewsItem(STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL,
  2904 	AddNewsItem(STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL,
  2980 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ACCIDENT, 0),
  2905 		NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ACCIDENT, DNC_NONE,
  2981 		v->index,
  2906 		v->index,
  2982 		0
  2907 		0
  2983 	);
  2908 	);
  2984 
  2909 
  2985 	ModifyStationRatingAround(v->tile, v->owner, -160, 30);
  2910 	ModifyStationRatingAround(v->tile, v->owner, -160, 30);
  2996 		if (diff == DIRDIFF_90RIGHT || (v->cur_speed <= 5 && diff <= DIRDIFF_REVERSE)) return v;
  2921 		if (diff == DIRDIFF_90RIGHT || (v->cur_speed <= 5 && diff <= DIRDIFF_REVERSE)) return v;
  2997 	}
  2922 	}
  2998 	return NULL;
  2923 	return NULL;
  2999 }
  2924 }
  3000 
  2925 
  3001 static void TrainController(Vehicle *v, bool update_image)
  2926 static void TrainController(Vehicle *v, Vehicle *nomove, bool update_image)
  3002 {
  2927 {
  3003 	Vehicle *prev;
  2928 	Vehicle *prev;
  3004 
  2929 
  3005 	/* For every vehicle after and including the given vehicle */
  2930 	/* For every vehicle after and including the given vehicle */
  3006 	for (prev = v->Previous(); v != NULL; prev = v, v = v->Next()) {
  2931 	for (prev = v->Previous(); v != nomove; prev = v, v = v->Next()) {
  3007 		DiagDirection enterdir = DIAGDIR_BEGIN;
  2932 		DiagDirection enterdir = DIAGDIR_BEGIN;
  3008 		bool update_signals_crossing = false; // will we update signals or crossing state?
  2933 		bool update_signals_crossing = false; // will we update signals or crossing state?
  3009 		BeginVehicleMove(v);
  2934 		BeginVehicleMove(v);
  3010 
  2935 
  3011 		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
  2936 		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
  3029 					if (HasBit(r, VETS_ENTERED_STATION)) {
  2954 					if (HasBit(r, VETS_ENTERED_STATION)) {
  3030 						TrainEnterStation(v, r >> VETS_STATION_ID_OFFSET);
  2955 						TrainEnterStation(v, r >> VETS_STATION_ID_OFFSET);
  3031 						return;
  2956 						return;
  3032 					}
  2957 					}
  3033 
  2958 
  3034 					if (v->current_order.type == OT_LEAVESTATION) {
  2959 					if (v->current_order.IsType(OT_LEAVESTATION)) {
  3035 						v->current_order.Free();
  2960 						v->current_order.Free();
  3036 						InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  2961 						InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  3037 					}
  2962 					}
  3038 				}
  2963 				}
  3039 			} else {
  2964 			} else {
  3044 				enterdir = DirToDiagDir(dir);
  2969 				enterdir = DirToDiagDir(dir);
  3045 				assert(IsValidDiagDirection(enterdir));
  2970 				assert(IsValidDiagDirection(enterdir));
  3046 
  2971 
  3047 				/* Get the status of the tracks in the new tile and mask
  2972 				/* Get the status of the tracks in the new tile and mask
  3048 				 * away the bits that aren't reachable. */
  2973 				 * away the bits that aren't reachable. */
  3049 				TrackStatus ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL, 0, ReverseDiagDir(enterdir)) & _reachable_tracks[enterdir];
  2974 				TrackStatus ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL, 0, ReverseDiagDir(enterdir));
  3050 				TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts);
  2975 				TrackdirBits reachable_trackdirs = DiagdirReachesTrackdirs(enterdir);
  3051 				TrackBits red_signals = TrackdirBitsToTrackBits(TrackStatusToRedSignals(ts));
  2976 
       
  2977 				TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts) & reachable_trackdirs;
       
  2978 				TrackBits red_signals = TrackdirBitsToTrackBits(TrackStatusToRedSignals(ts) & reachable_trackdirs);
  3052 
  2979 
  3053 				TrackBits bits = TrackdirBitsToTrackBits(trackdirbits);
  2980 				TrackBits bits = TrackdirBitsToTrackBits(trackdirbits);
  3054 				if (_patches.pathfinder_for_trains != VPF_NTP && _patches.forbid_90_deg && prev == NULL) {
  2981 				if (_patches.pathfinder_for_trains != VPF_NTP && _patches.forbid_90_deg && prev == NULL) {
  3055 					/* We allow wagons to make 90 deg turns, because forbid_90_deg
  2982 					/* We allow wagons to make 90 deg turns, because forbid_90_deg
  3056 					 * can be switched on halfway a turn */
  2983 					 * can be switched on halfway a turn */
  3225 		DeleteWindowById(WC_VEHICLE_VIEW, v->index);
  3152 		DeleteWindowById(WC_VEHICLE_VIEW, v->index);
  3226 		InvalidateWindow(WC_COMPANY, v->owner);
  3153 		InvalidateWindow(WC_COMPANY, v->owner);
  3227 	} else {
  3154 	} else {
  3228 		/* Recalculate cached train properties */
  3155 		/* Recalculate cached train properties */
  3229 		TrainConsistChanged(first);
  3156 		TrainConsistChanged(first);
  3230 		InvalidateWindow(WC_VEHICLE_DETAILS, first->index);
       
  3231 		/* Update the depot window if the first vehicle is in depot -
  3157 		/* Update the depot window if the first vehicle is in depot -
  3232 		 * if v == first, then it is updated in PreDestructor() */
  3158 		 * if v == first, then it is updated in PreDestructor() */
  3233 		if (first->u.rail.track == TRACK_BIT_DEPOT) {
  3159 		if (first->u.rail.track == TRACK_BIT_DEPOT) {
  3234 			InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
  3160 			InvalidateWindow(WC_VEHICLE_DEPOT, first->tile);
  3235 		}
  3161 		}
  3270 			v->direction = ChangeDir(v->direction, delta[GB(Random(), 0, 2)]);
  3196 			v->direction = ChangeDir(v->direction, delta[GB(Random(), 0, 2)]);
  3271 			BeginVehicleMove(v);
  3197 			BeginVehicleMove(v);
  3272 			v->UpdateDeltaXY(v->direction);
  3198 			v->UpdateDeltaXY(v->direction);
  3273 			v->cur_image = v->GetImage(v->direction);
  3199 			v->cur_image = v->GetImage(v->direction);
  3274 			/* Refrain from updating the z position of the vehicle when on
  3200 			/* Refrain from updating the z position of the vehicle when on
  3275 			   a bridge, because AfterSetTrainPos will put the vehicle under
  3201 			 * a bridge, because AfterSetTrainPos will put the vehicle under
  3276 			   the bridge in that case */
  3202 			 * the bridge in that case */
  3277 			if (v->u.rail.track != TRACK_BIT_WORMHOLE) AfterSetTrainPos(v, false);
  3203 			if (v->u.rail.track != TRACK_BIT_WORMHOLE) AfterSetTrainPos(v, false);
  3278 		}
  3204 		}
  3279 	} while ((v = v->Next()) != NULL);
  3205 	} while ((v = v->Next()) != NULL);
  3280 }
  3206 }
  3281 
  3207 
  3475 	DiagDirection dir = TrainExitDir(v->direction, v->u.rail.track);
  3401 	DiagDirection dir = TrainExitDir(v->direction, v->u.rail.track);
  3476 	/* Calculate next tile */
  3402 	/* Calculate next tile */
  3477 	TileIndex tile = v->tile + TileOffsByDiagDir(dir);
  3403 	TileIndex tile = v->tile + TileOffsByDiagDir(dir);
  3478 
  3404 
  3479 	/* Determine the track status on the next tile */
  3405 	/* Determine the track status on the next tile */
  3480 	TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0, ReverseDiagDir(dir)) & _reachable_tracks[dir];
  3406 	TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0, ReverseDiagDir(dir));
  3481 	TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts);
  3407 	TrackdirBits reachable_trackdirs = DiagdirReachesTrackdirs(dir);
  3482 	TrackdirBits red_signals = TrackStatusToRedSignals(ts);
  3408 
       
  3409 	TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts) & reachable_trackdirs;
       
  3410 	TrackdirBits red_signals = TrackStatusToRedSignals(ts) & reachable_trackdirs;
  3483 
  3411 
  3484 	/* We are sure the train is not entering a depot, it is detected above */
  3412 	/* We are sure the train is not entering a depot, it is detected above */
  3485 
  3413 
  3486 	/* mask unreachable track bits if we are forbidden to do 90deg turns */
  3414 	/* mask unreachable track bits if we are forbidden to do 90deg turns */
  3487 	TrackBits bits = TrackdirBitsToTrackBits(trackdirbits);
  3415 	TrackBits bits = TrackdirBitsToTrackBits(trackdirbits);
  3528 	}
  3456 	}
  3529 
  3457 
  3530 	/* exit if train is stopped */
  3458 	/* exit if train is stopped */
  3531 	if (v->vehstatus & VS_STOPPED && v->cur_speed == 0) return;
  3459 	if (v->vehstatus & VS_STOPPED && v->cur_speed == 0) return;
  3532 
  3460 
  3533 	if (ProcessTrainOrder(v)) {
  3461 	if (ProcessOrders(v) && CheckReverseTrain(v)) {
  3534 		v->load_unload_time_rem = 0;
  3462 		v->load_unload_time_rem = 0;
  3535 		v->cur_speed = 0;
  3463 		v->cur_speed = 0;
  3536 		v->subspeed = 0;
  3464 		v->subspeed = 0;
  3537 		ReverseTrainDirection(v);
  3465 		ReverseTrainDirection(v);
  3538 		return;
  3466 		return;
  3539 	}
  3467 	}
  3540 
  3468 
  3541 	v->HandleLoading(mode);
  3469 	v->HandleLoading(mode);
  3542 
  3470 
  3543 	if (v->current_order.type == OT_LOADING) return;
  3471 	if (v->current_order.IsType(OT_LOADING)) return;
  3544 
  3472 
  3545 	if (CheckTrainStayInDepot(v)) return;
  3473 	if (CheckTrainStayInDepot(v)) return;
  3546 
  3474 
  3547 	if (!mode) HandleLocomotiveSmokeCloud(v);
  3475 	if (!mode) HandleLocomotiveSmokeCloud(v);
  3548 
  3476 
  3558 		if (v->cur_speed != 0) return;
  3486 		if (v->cur_speed != 0) return;
  3559 	} else {
  3487 	} else {
  3560 		TrainCheckIfLineEnds(v);
  3488 		TrainCheckIfLineEnds(v);
  3561 
  3489 
  3562 		do {
  3490 		do {
  3563 			TrainController(v, true);
  3491 			TrainController(v, NULL, true);
  3564 			CheckTrainCollision(v);
  3492 			CheckTrainCollision(v);
  3565 			if (v->cur_speed <= 0x100)
  3493 			if (v->cur_speed <= 0x100)
  3566 				break;
  3494 				break;
  3567 		} while (--j != 0);
  3495 		} while (--j != 0);
  3568 	}
  3496 	}
  3609 		/* Delete flooded standalone wagon chain */
  3537 		/* Delete flooded standalone wagon chain */
  3610 		if (++this->u.rail.crash_anim_pos >= 4400) DeleteVehicleChain(this);
  3538 		if (++this->u.rail.crash_anim_pos >= 4400) DeleteVehicleChain(this);
  3611 	}
  3539 	}
  3612 }
  3540 }
  3613 
  3541 
  3614 #define MAX_ACCEPTABLE_DEPOT_DIST 16
       
  3615 
       
  3616 static void CheckIfTrainNeedsService(Vehicle *v)
  3542 static void CheckIfTrainNeedsService(Vehicle *v)
  3617 {
  3543 {
  3618 	if (_patches.servint_trains == 0 || !VehicleNeedsService(v)) return;
  3544 	static const uint MAX_ACCEPTABLE_DEPOT_DIST = 16;
       
  3545 
       
  3546 	if (_patches.servint_trains == 0 || !v->NeedsAutomaticServicing()) return;
  3619 	if (v->IsInDepot()) {
  3547 	if (v->IsInDepot()) {
  3620 		VehicleServiceInDepot(v);
  3548 		VehicleServiceInDepot(v);
  3621 		return;
  3549 		return;
  3622 	}
  3550 	}
  3623 
  3551 
  3624 	TrainFindDepotData tfdd = FindClosestTrainDepot(v, MAX_ACCEPTABLE_DEPOT_DIST);
  3552 	TrainFindDepotData tfdd = FindClosestTrainDepot(v, MAX_ACCEPTABLE_DEPOT_DIST);
  3625 	/* Only go to the depot if it is not too far out of our way. */
  3553 	/* Only go to the depot if it is not too far out of our way. */
  3626 	if (tfdd.best_length == (uint)-1 || tfdd.best_length > MAX_ACCEPTABLE_DEPOT_DIST) {
  3554 	if (tfdd.best_length == (uint)-1 || tfdd.best_length > MAX_ACCEPTABLE_DEPOT_DIST) {
  3627 		if (v->current_order.type == OT_GOTO_DEPOT) {
  3555 		if (v->current_order.IsType(OT_GOTO_DEPOT)) {
  3628 			/* If we were already heading for a depot but it has
  3556 			/* If we were already heading for a depot but it has
  3629 			 * suddenly moved farther away, we continue our normal
  3557 			 * suddenly moved farther away, we continue our normal
  3630 			 * schedule? */
  3558 			 * schedule? */
  3631 			v->current_order.type = OT_DUMMY;
  3559 			v->current_order.MakeDummy();
  3632 			v->current_order.flags = 0;
       
  3633 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  3560 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  3634 		}
  3561 		}
  3635 		return;
  3562 		return;
  3636 	}
  3563 	}
  3637 
  3564 
  3638 	const Depot* depot = GetDepotByTile(tfdd.tile);
  3565 	const Depot *depot = GetDepotByTile(tfdd.tile);
  3639 
  3566 
  3640 	if (v->current_order.type == OT_GOTO_DEPOT &&
  3567 	if (v->current_order.IsType(OT_GOTO_DEPOT) &&
  3641 			v->current_order.dest != depot->index &&
  3568 			v->current_order.GetDestination() != depot->index &&
  3642 			!Chance16(3, 16)) {
  3569 			!Chance16(3, 16)) {
  3643 		return;
  3570 		return;
  3644 	}
  3571 	}
  3645 
  3572 
  3646 	v->current_order.type = OT_GOTO_DEPOT;
  3573 	v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE);
  3647 	v->current_order.flags = OFB_NON_STOP;
       
  3648 	v->current_order.dest = depot->index;
       
  3649 	v->dest_tile = tfdd.tile;
  3574 	v->dest_tile = tfdd.tile;
  3650 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  3575 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  3651 }
  3576 }
  3652 
  3577 
  3653 void Train::OnNewDay()
  3578 void Train::OnNewDay()
  3661 		CheckIfTrainNeedsService(this);
  3586 		CheckIfTrainNeedsService(this);
  3662 
  3587 
  3663 		CheckOrders(this);
  3588 		CheckOrders(this);
  3664 
  3589 
  3665 		/* update destination */
  3590 		/* update destination */
  3666 		if (this->current_order.type == OT_GOTO_STATION) {
  3591 		if (this->current_order.IsType(OT_GOTO_STATION)) {
  3667 			TileIndex tile = GetStation(this->current_order.dest)->train_tile;
  3592 			TileIndex tile = GetStation(this->current_order.GetDestination())->train_tile;
  3668 			if (tile != 0) this->dest_tile = tile;
  3593 			if (tile != 0) this->dest_tile = tile;
  3669 		}
  3594 		}
  3670 
  3595 
  3671 		if (this->running_ticks != 0) {
  3596 		if (this->running_ticks != 0) {
  3672 			/* running costs */
  3597 			/* running costs */
  3696 			if (_patches.train_income_warn && v->owner == _local_player && v->age >= 730 && v->GetDisplayProfitThisYear() < 0) {
  3621 			if (_patches.train_income_warn && v->owner == _local_player && v->age >= 730 && v->GetDisplayProfitThisYear() < 0) {
  3697 				SetDParam(1, v->GetDisplayProfitThisYear());
  3622 				SetDParam(1, v->GetDisplayProfitThisYear());
  3698 				SetDParam(0, v->unitnumber);
  3623 				SetDParam(0, v->unitnumber);
  3699 				AddNewsItem(
  3624 				AddNewsItem(
  3700 					STR_TRAIN_IS_UNPROFITABLE,
  3625 					STR_TRAIN_IS_UNPROFITABLE,
  3701 					NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0),
  3626 					NM_SMALL, NF_VIEWPORT | NF_VEHICLE, NT_ADVICE, DNC_NONE,
  3702 					v->index,
  3627 					v->index,
  3703 					0);
  3628 					0);
  3704 			}
  3629 			}
  3705 
  3630 
  3706 			v->profit_last_year = v->profit_this_year;
  3631 			v->profit_last_year = v->profit_this_year;
  3743 						SetTrainEngine(u);
  3668 						SetTrainEngine(u);
  3744 						u->spritenum--;
  3669 						u->spritenum--;
  3745 					}
  3670 					}
  3746 
  3671 
  3747 					Vehicle *w;
  3672 					Vehicle *w;
  3748 					for (w = u->Next(); w != NULL && (w->engine_type != u->engine_type || w->u.rail.other_multiheaded_part != NULL); w = GetNextVehicle(w));
  3673 					for (w = u->Next(); w != NULL && (w->engine_type != u->engine_type || w->u.rail.other_multiheaded_part != NULL); w = GetNextVehicle(w)) {}
  3749 					if (w != NULL) {
  3674 					if (w != NULL) {
  3750 						/* we found a car to partner with this engine. Now we will make sure it face the right way */
  3675 						/* we found a car to partner with this engine. Now we will make sure it face the right way */
  3751 						if (IsTrainEngine(w)) {
  3676 						if (IsTrainEngine(w)) {
  3752 							ClearTrainEngine(w);
  3677 							ClearTrainEngine(w);
  3753 							w->spritenum++;
  3678 							w->spritenum++;