src/train_cmd.cpp
branchnoai
changeset 9620 31e38d28a0af
parent 9601 b499fdd106d5
child 9624 b71483f2330f
equal deleted inserted replaced
9619:6e81cec30a2b 9620:31e38d28a0af
   112 		uint32 vweight = GetCargo(u->cargo_type)->weight * u->cargo_count * FreightWagonMult(u->cargo_type) / 16;
   112 		uint32 vweight = GetCargo(u->cargo_type)->weight * u->cargo_count * FreightWagonMult(u->cargo_type) / 16;
   113 
   113 
   114 		/* Vehicle weight is not added for articulated parts. */
   114 		/* Vehicle weight is not added for articulated parts. */
   115 		if (!IsArticulatedPart(u)) {
   115 		if (!IsArticulatedPart(u)) {
   116 			/* vehicle weight is the sum of the weight of the vehicle and the weight of its cargo */
   116 			/* vehicle weight is the sum of the weight of the vehicle and the weight of its cargo */
   117 			vweight += RailVehInfo(u->engine_type)->weight;
   117 			vweight += GetVehicleProperty(u, 0x16, RailVehInfo(u->engine_type)->weight);
   118 
   118 
   119 			/* powered wagons have extra weight added */
   119 			/* powered wagons have extra weight added */
   120 			if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON))
   120 			if (HASBIT(u->u.rail.flags, VRF_POWEREDWAGON))
   121 				vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight;
   121 				vweight += RailVehInfo(u->u.rail.first_engine)->pow_wag_weight;
   122 		}
   122 		}
   188 
   188 
   189 				if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback;
   189 				if (callback != CALLBACK_FAILED) u->u.rail.cached_vis_effect = callback;
   190 			}
   190 			}
   191 
   191 
   192 			if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON &&
   192 			if (rvi_v->pow_wag_power != 0 && rvi_u->railveh_type == RAILVEH_WAGON &&
   193 				UsesWagonOverride(u) && (u->u.rail.cached_vis_effect < 0x40)) {
   193 				UsesWagonOverride(u) && !HASBIT(u->u.rail.cached_vis_effect, 7)) {
   194 				/* wagon is powered */
   194 				/* wagon is powered */
   195 				SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status
   195 				SETBIT(u->u.rail.flags, VRF_POWEREDWAGON); // cache 'powered' status
   196 			} else {
   196 			} else {
   197 				CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON);
   197 				CLRBIT(u->u.rail.flags, VRF_POWEREDWAGON);
   198 			}
   198 			}
   533 		u->owner = v->owner;
   533 		u->owner = v->owner;
   534 		u->tile = v->tile;
   534 		u->tile = v->tile;
   535 		u->x_pos = v->x_pos;
   535 		u->x_pos = v->x_pos;
   536 		u->y_pos = v->y_pos;
   536 		u->y_pos = v->y_pos;
   537 		u->z_pos = v->z_pos;
   537 		u->z_pos = v->z_pos;
   538 		u->z_height = v->z_height;
       
   539 		u->u.rail.track = v->u.rail.track;
   538 		u->u.rail.track = v->u.rail.track;
   540 		u->u.rail.railtype = v->u.rail.railtype;
   539 		u->u.rail.railtype = v->u.rail.railtype;
   541 		u->build_year = v->build_year;
   540 		u->build_year = v->build_year;
   542 		u->vehstatus = v->vehstatus & ~VS_STOPPED;
   541 		u->vehstatus = v->vehstatus & ~VS_STOPPED;
   543 		u->u.rail.first_engine = v->engine_type;
   542 		u->u.rail.first_engine = v->engine_type;
   550 		u->cargo_cap = rvi_artic->capacity;
   549 		u->cargo_cap = rvi_artic->capacity;
   551 		u->max_speed = 0;
   550 		u->max_speed = 0;
   552 		u->max_age = 0;
   551 		u->max_age = 0;
   553 		u->engine_type = engine_type;
   552 		u->engine_type = engine_type;
   554 		u->value = 0;
   553 		u->value = 0;
   555 		u->type = VEH_TRAIN;
   554 		u = new (u) Train();
   556 		u->subtype = 0;
   555 		u->subtype = 0;
   557 		SetArticulatedPart(u);
   556 		SetArticulatedPart(u);
   558 		u->cur_image = 0xAC2;
   557 		u->cur_image = 0xAC2;
   559 		u->random_bits = VehicleRandomBits();
   558 		u->random_bits = VehicleRandomBits();
   560 
   559 
   565 static int32 CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags)
   564 static int32 CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags)
   566 {
   565 {
   567 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   566 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   568 
   567 
   569 	const RailVehicleInfo *rvi = RailVehInfo(engine);
   568 	const RailVehicleInfo *rvi = RailVehInfo(engine);
   570 	int32 value = (rvi->base_cost * _price.build_railwagon) >> 8;
   569 	int32 value = (GetEngineProperty(engine, 0x17, rvi->base_cost) * _price.build_railwagon) >> 8;
   571 
   570 
   572 	uint num_vehicles = 1 + CountArticulatedParts(engine);
   571 	uint num_vehicles = 1 + CountArticulatedParts(engine);
   573 
   572 
   574 	if (!(flags & DC_QUERY_COST)) {
   573 	if (!(flags & DC_QUERY_COST)) {
   575 		Vehicle *vl[11]; // Allow for wagon and upto 10 artic parts.
   574 		Vehicle *vl[11]; // Allow for wagon and upto 10 artic parts.
   606 
   605 
   607 			v->x_pos = x;
   606 			v->x_pos = x;
   608 			v->y_pos = y;
   607 			v->y_pos = y;
   609 			v->z_pos = GetSlopeZ(x, y);
   608 			v->z_pos = GetSlopeZ(x, y);
   610 			v->owner = _current_player;
   609 			v->owner = _current_player;
   611 			v->z_height = 6;
       
   612 			v->u.rail.track = TRACK_BIT_DEPOT;
   610 			v->u.rail.track = TRACK_BIT_DEPOT;
   613 			v->vehstatus = VS_HIDDEN | VS_DEFPAL;
   611 			v->vehstatus = VS_HIDDEN | VS_DEFPAL;
   614 
   612 
   615 			v->subtype = 0;
   613 			v->subtype = 0;
   616 			SetTrainWagon(v);
   614 			SetTrainWagon(v);
   628 //			v->day_counter = 0;
   626 //			v->day_counter = 0;
   629 
   627 
   630 			v->u.rail.railtype = rvi->railtype;
   628 			v->u.rail.railtype = rvi->railtype;
   631 
   629 
   632 			v->build_year = _cur_year;
   630 			v->build_year = _cur_year;
   633 			v->type = VEH_TRAIN;
   631 			v = new (v) Train();
   634 			v->cur_image = 0xAC2;
   632 			v->cur_image = 0xAC2;
   635 			v->random_bits = VehicleRandomBits();
   633 			v->random_bits = VehicleRandomBits();
   636 
   634 
   637 			AddArticulatedParts(vl);
   635 			AddArticulatedParts(vl);
   638 
   636 
   666 				break;
   664 				break;
   667 		}
   665 		}
   668 	}
   666 	}
   669 }
   667 }
   670 
   668 
   671 static int32 EstimateTrainCost(const RailVehicleInfo* rvi)
   669 static int32 EstimateTrainCost(EngineID engine, const RailVehicleInfo* rvi)
   672 {
   670 {
   673 	return rvi->base_cost * (_price.build_railvehicle >> 3) >> 5;
   671 	return GetEngineProperty(engine, 0x17, rvi->base_cost) * (_price.build_railvehicle >> 3) >> 5;
   674 }
   672 }
   675 
   673 
   676 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
   674 static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool building)
   677 {
   675 {
   678 	u->direction = v->direction;
   676 	u->direction = v->direction;
   679 	u->owner = v->owner;
   677 	u->owner = v->owner;
   680 	u->tile = v->tile;
   678 	u->tile = v->tile;
   681 	u->x_pos = v->x_pos;
   679 	u->x_pos = v->x_pos;
   682 	u->y_pos = v->y_pos;
   680 	u->y_pos = v->y_pos;
   683 	u->z_pos = v->z_pos;
   681 	u->z_pos = v->z_pos;
   684 	u->z_height = 6;
       
   685 	u->u.rail.track = TRACK_BIT_DEPOT;
   682 	u->u.rail.track = TRACK_BIT_DEPOT;
   686 	u->vehstatus = v->vehstatus & ~VS_STOPPED;
   683 	u->vehstatus = v->vehstatus & ~VS_STOPPED;
   687 	u->subtype = 0;
   684 	u->subtype = 0;
   688 	SetMultiheaded(u);
   685 	SetMultiheaded(u);
   689 	u->spritenum = v->spritenum + 1;
   686 	u->spritenum = v->spritenum + 1;
   694 	if (building) v->next = u;
   691 	if (building) v->next = u;
   695 	u->engine_type = v->engine_type;
   692 	u->engine_type = v->engine_type;
   696 	u->build_year = v->build_year;
   693 	u->build_year = v->build_year;
   697 	if (building) v->value >>= 1;
   694 	if (building) v->value >>= 1;
   698 	u->value = v->value;
   695 	u->value = v->value;
   699 	u->type = VEH_TRAIN;
   696 	u = new (u) Train();
   700 	u->cur_image = 0xAC2;
   697 	u->cur_image = 0xAC2;
   701 	u->random_bits = VehicleRandomBits();
   698 	u->random_bits = VehicleRandomBits();
   702 	VehiclePositionChanged(u);
   699 	VehiclePositionChanged(u);
   703 }
   700 }
   704 
   701 
   729 	/* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
   726 	/* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
   730 	if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
   727 	if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
   731 
   728 
   732 	if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(p1, tile, flags);
   729 	if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(p1, tile, flags);
   733 
   730 
   734 	int32 value = EstimateTrainCost(rvi);
   731 	int32 value = EstimateTrainCost(p1, rvi);
   735 
   732 
   736 	uint num_vehicles =
   733 	uint num_vehicles =
   737 		(rvi->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) +
   734 		(rvi->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) +
   738 		CountArticulatedParts(p1);
   735 		CountArticulatedParts(p1);
   739 
   736 
   761 			v->tile = tile;
   758 			v->tile = tile;
   762 			v->owner = _current_player;
   759 			v->owner = _current_player;
   763 			v->x_pos = x;
   760 			v->x_pos = x;
   764 			v->y_pos = y;
   761 			v->y_pos = y;
   765 			v->z_pos = GetSlopeZ(x, y);
   762 			v->z_pos = GetSlopeZ(x, y);
   766 			v->z_height = 6;
       
   767 			v->u.rail.track = TRACK_BIT_DEPOT;
   763 			v->u.rail.track = TRACK_BIT_DEPOT;
   768 			v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
   764 			v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
   769 			v->spritenum = rvi->image_index;
   765 			v->spritenum = rvi->image_index;
   770 			v->cargo_type = rvi->cargo_type;
   766 			v->cargo_type = rvi->cargo_type;
   771 			v->cargo_subtype = 0;
   767 			v->cargo_subtype = 0;
   787 			_new_vehicle_id = v->index;
   783 			_new_vehicle_id = v->index;
   788 
   784 
   789 			v->service_interval = _patches.servint_trains;
   785 			v->service_interval = _patches.servint_trains;
   790 			v->date_of_last_service = _date;
   786 			v->date_of_last_service = _date;
   791 			v->build_year = _cur_year;
   787 			v->build_year = _cur_year;
   792 			v->type = VEH_TRAIN;
   788 			v = new (v) Train();
   793 			v->cur_image = 0xAC2;
   789 			v->cur_image = 0xAC2;
   794 			v->random_bits = VehicleRandomBits();
   790 			v->random_bits = VehicleRandomBits();
   795 
   791 
   796 			v->vehicle_flags = 0;
   792 			v->vehicle_flags = 0;
   797 			if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
   793 			if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
  1267 	if (flags & DC_EXEC) {
  1263 	if (flags & DC_EXEC) {
  1268 		if (v->vehstatus & VS_STOPPED && v->u.rail.track == TRACK_BIT_DEPOT) {
  1264 		if (v->vehstatus & VS_STOPPED && v->u.rail.track == TRACK_BIT_DEPOT) {
  1269 			DeleteVehicleNews(p1, STR_8814_TRAIN_IS_WAITING_IN_DEPOT);
  1265 			DeleteVehicleNews(p1, STR_8814_TRAIN_IS_WAITING_IN_DEPOT);
  1270 		}
  1266 		}
  1271 
  1267 
  1272 		v->u.rail.days_since_order_progr = 0;
       
  1273 		v->vehstatus ^= VS_STOPPED;
  1268 		v->vehstatus ^= VS_STOPPED;
  1274 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  1269 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  1275 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1270 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1276 	}
  1271 	}
  1277 	return 0;
  1272 	return 0;
  1461 		} break;
  1456 		} break;
  1462 	}
  1457 	}
  1463 	return cost;
  1458 	return cost;
  1464 }
  1459 }
  1465 
  1460 
  1466 static void UpdateTrainDeltaXY(Vehicle *v, Direction direction)
  1461 void Train::UpdateDeltaXY(Direction direction)
  1467 {
  1462 {
  1468 #define MKIT(a,b,c,d) ((a&0xFF)<<24) | ((b&0xFF)<<16) | ((c&0xFF)<<8) | ((d&0xFF)<<0)
  1463 #define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0)
  1469 	static const uint32 _delta_xy_table[8] = {
  1464 	static const uint32 _delta_xy_table[8] = {
  1470 		MKIT(3, 3, -1, -1),
  1465 		MKIT(3, 3, -1, -1),
  1471 		MKIT(3, 7, -1, -3),
  1466 		MKIT(3, 7, -1, -3),
  1472 		MKIT(3, 3, -1, -1),
  1467 		MKIT(3, 3, -1, -1),
  1473 		MKIT(7, 3, -3, -1),
  1468 		MKIT(7, 3, -3, -1),
  1477 		MKIT(7, 3, -3, -1),
  1472 		MKIT(7, 3, -3, -1),
  1478 	};
  1473 	};
  1479 #undef MKIT
  1474 #undef MKIT
  1480 
  1475 
  1481 	uint32 x = _delta_xy_table[direction];
  1476 	uint32 x = _delta_xy_table[direction];
  1482 
  1477 	this->x_offs        = GB(x,  0, 8);
  1483 	v->x_offs        = GB(x,  0, 8);
  1478 	this->y_offs        = GB(x,  8, 8);
  1484 	v->y_offs        = GB(x,  8, 8);
  1479 	this->sprite_width  = GB(x, 16, 8);
  1485 	v->sprite_width  = GB(x, 16, 8);
  1480 	this->sprite_height = GB(x, 24, 8);
  1486 	v->sprite_height = GB(x, 24, 8);
  1481 	this->z_height      = 6;
  1487 }
  1482 }
  1488 
  1483 
  1489 static void UpdateVarsAfterSwap(Vehicle *v)
  1484 static void UpdateVarsAfterSwap(Vehicle *v)
  1490 {
  1485 {
  1491 	UpdateTrainDeltaXY(v, v->direction);
  1486 	v->UpdateDeltaXY(v->direction);
  1492 	v->cur_image = GetTrainImage(v, v->direction);
  1487 	v->cur_image = GetTrainImage(v, v->direction);
  1493 	BeginVehicleMove(v);
  1488 	BeginVehicleMove(v);
  1494 	VehiclePositionChanged(v);
  1489 	VehiclePositionChanged(v);
  1495 	EndVehicleMove(v);
  1490 	EndVehicleMove(v);
  1496 }
  1491 }
  1749  * @param flags type of operation
  1744  * @param flags type of operation
  1750  * @param p1 vehicle ID of the train to refit
  1745  * @param p1 vehicle ID of the train to refit
  1751  * param p2 various bitstuffed elements
  1746  * param p2 various bitstuffed elements
  1752  * - p2 = (bit 0-7) - the new cargo type to refit to
  1747  * - p2 = (bit 0-7) - the new cargo type to refit to
  1753  * - p2 = (bit 8-15) - the new cargo subtype to refit to
  1748  * - p2 = (bit 8-15) - the new cargo subtype to refit to
       
  1749  * - p2 = (bit 16) - refit only this vehicle
       
  1750  * @return cost of refit or error
  1754  */
  1751  */
  1755 int32 CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1752 int32 CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1756 {
  1753 {
  1757 	CargoID new_cid = GB(p2, 0, 8);
  1754 	CargoID new_cid = GB(p2, 0, 8);
  1758 	byte new_subtype = GB(p2, 8, 8);
  1755 	byte new_subtype = GB(p2, 8, 8);
       
  1756 	bool only_this = HASBIT(p2, 16);
  1759 
  1757 
  1760 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1758 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1761 
  1759 
  1762 	Vehicle *v = GetVehicle(p1);
  1760 	Vehicle *v = GetVehicle(p1);
  1763 
  1761 
  1831 					InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1829 					InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1832 					RebuildVehicleLists();
  1830 					RebuildVehicleLists();
  1833 				}
  1831 				}
  1834 			}
  1832 			}
  1835 		}
  1833 		}
  1836 	} while ((v = v->next) != NULL);
  1834 	} while ((v = v->next) != NULL && !only_this);
  1837 
  1835 
  1838 	_returned_refit_capacity = num;
  1836 	_returned_refit_capacity = num;
  1839 
  1837 
  1840 	/* Update the train's cached variables */
  1838 	/* Update the train's cached variables */
  1841 	if (flags & DC_EXEC) TrainConsistChanged(GetFirstVehicleInChain(GetVehicle(p1)));
  1839 	if (flags & DC_EXEC) TrainConsistChanged(GetFirstVehicleInChain(GetVehicle(p1)));
  1964 		}
  1962 		}
  1965 
  1963 
  1966 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
  1964 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
  1967 		if (flags & DC_EXEC) {
  1965 		if (flags & DC_EXEC) {
  1968 			if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
  1966 			if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
  1969 				v->u.rail.days_since_order_progr = 0;
       
  1970 				v->cur_order_index++;
  1967 				v->cur_order_index++;
  1971 			}
  1968 			}
  1972 
  1969 
  1973 			v->current_order.type = OT_DUMMY;
  1970 			v->current_order.type = OT_DUMMY;
  1974 			v->current_order.flags = 0;
  1971 			v->current_order.flags = 0;
  2027 		bool disable_effect = HASBIT(v->u.rail.cached_vis_effect, 6);
  2024 		bool disable_effect = HASBIT(v->u.rail.cached_vis_effect, 6);
  2028 
  2025 
  2029 		/* no smoke? */
  2026 		/* no smoke? */
  2030 		if ((rvi->railveh_type == RAILVEH_WAGON && effect_type == 0) ||
  2027 		if ((rvi->railveh_type == RAILVEH_WAGON && effect_type == 0) ||
  2031 				disable_effect ||
  2028 				disable_effect ||
  2032 				rvi->railtype > RAILTYPE_ELECTRIC ||
       
  2033 				v->vehstatus & VS_HIDDEN) {
  2029 				v->vehstatus & VS_HIDDEN) {
  2034 			continue;
  2030 			continue;
  2035 		}
  2031 		}
  2036 
  2032 
  2037 		/* No smoke in depots or tunnels */
  2033 		/* No smoke in depots or tunnels */
  2088 static void TrainPlayLeaveStationSound(const Vehicle* v)
  2084 static void TrainPlayLeaveStationSound(const Vehicle* v)
  2089 {
  2085 {
  2090 	static const SoundFx sfx[] = {
  2086 	static const SoundFx sfx[] = {
  2091 		SND_04_TRAIN,
  2087 		SND_04_TRAIN,
  2092 		SND_0A_TRAIN_HORN,
  2088 		SND_0A_TRAIN_HORN,
  2093 		SND_0A_TRAIN_HORN
  2089 		SND_0A_TRAIN_HORN,
       
  2090 		SND_47_MAGLEV_2,
       
  2091 		SND_41_MAGLEV
  2094 	};
  2092 	};
  2095 
  2093 
  2096 	if (PlayVehicleSound(v, VSE_START)) return;
  2094 	if (PlayVehicleSound(v, VSE_START)) return;
  2097 
  2095 
  2098 	EngineID engtype = v->engine_type;
  2096 	EngineID engtype = v->engine_type;
  2099 	switch (RailVehInfo(engtype)->railtype) {
  2097 	SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], v);
  2100 		case RAILTYPE_RAIL:
  2098 }
  2101 		case RAILTYPE_ELECTRIC:
  2099 
  2102 			SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], v);
  2100 void Train::PlayLeaveStationSound() const
  2103 			break;
  2101 {
  2104 
  2102 	TrainPlayLeaveStationSound(this);
  2105 		case RAILTYPE_MONO: SndPlayVehicleFx(SND_47_MAGLEV_2, v); break;
       
  2106 		case RAILTYPE_MAGLEV: SndPlayVehicleFx(SND_41_MAGLEV, v); break;
       
  2107 		default: NOT_REACHED();
       
  2108 	}
       
  2109 }
  2103 }
  2110 
  2104 
  2111 static bool CheckTrainStayInDepot(Vehicle *v)
  2105 static bool CheckTrainStayInDepot(Vehicle *v)
  2112 {
  2106 {
  2113 	/* bail out if not all wagons are in the same depot or not in a depot at all */
  2107 	/* bail out if not all wagons are in the same depot or not in a depot at all */
  2144 	if (v->direction & 2) v->u.rail.track = TRACK_BIT_Y;
  2138 	if (v->direction & 2) v->u.rail.track = TRACK_BIT_Y;
  2145 
  2139 
  2146 	v->vehstatus &= ~VS_HIDDEN;
  2140 	v->vehstatus &= ~VS_HIDDEN;
  2147 	v->cur_speed = 0;
  2141 	v->cur_speed = 0;
  2148 
  2142 
  2149 	UpdateTrainDeltaXY(v, v->direction);
  2143 	v->UpdateDeltaXY(v->direction);
  2150 	v->cur_image = GetTrainImage(v, v->direction);
  2144 	v->cur_image = GetTrainImage(v, v->direction);
  2151 	VehiclePositionChanged(v);
  2145 	VehiclePositionChanged(v);
  2152 	UpdateSignalsOnSegment(v->tile, DirToDiagDir(v->direction));
  2146 	UpdateSignalsOnSegment(v->tile, DirToDiagDir(v->direction));
  2153 	UpdateTrainAcceleration(v);
  2147 	UpdateTrainAcceleration(v);
  2154 	InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  2148 	InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
  2517 	}
  2511 	}
  2518 
  2512 
  2519 	return !at_waypoint && CheckReverseTrain(v);
  2513 	return !at_waypoint && CheckReverseTrain(v);
  2520 }
  2514 }
  2521 
  2515 
  2522 static void MarkTrainDirty(Vehicle *v)
  2516 void Train::MarkDirty()
  2523 {
  2517 {
       
  2518 	Vehicle *v = this;
  2524 	do {
  2519 	do {
  2525 		v->cur_image = GetTrainImage(v, v->direction);
  2520 		v->cur_image = GetTrainImage(v, v->direction);
  2526 		MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
  2521 		MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
  2527 	} while ((v = v->next) != NULL);
  2522 	} while ((v = v->next) != NULL);
  2528 }
  2523 
  2529 
  2524 	/* need to update acceleration and cached values since the goods on the train changed. */
  2530 static void HandleTrainLoading(Vehicle *v, bool mode)
  2525 	TrainCargoChanged(this);
  2531 {
  2526 	UpdateTrainAcceleration(this);
  2532 	switch (v->current_order.type) {
       
  2533 		case OT_LOADING: {
       
  2534 			if (mode) return;
       
  2535 
       
  2536 			/* don't mark the train as lost if we're loading on the final station. */
       
  2537 			if (v->current_order.flags & OF_NON_STOP) {
       
  2538 				v->u.rail.days_since_order_progr = 0;
       
  2539 			}
       
  2540 
       
  2541 			if (--v->load_unload_time_rem) return;
       
  2542 
       
  2543 			if (CanFillVehicle(v) && (
       
  2544 						v->current_order.flags & OF_FULL_LOAD ||
       
  2545 						(_patches.gradual_loading && !HASBIT(v->vehicle_flags, VF_LOADING_FINISHED))
       
  2546 					)) {
       
  2547 				v->u.rail.days_since_order_progr = 0; // Prevent a train lost message for full loading trains
       
  2548 				SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC);
       
  2549 				if (LoadUnloadVehicle(v, false)) {
       
  2550 					InvalidateWindow(WC_TRAINS_LIST, v->owner);
       
  2551 					MarkTrainDirty(v);
       
  2552 
       
  2553 					/* need to update acceleration and cached values since the goods on the train changed. */
       
  2554 					TrainCargoChanged(v);
       
  2555 					UpdateTrainAcceleration(v);
       
  2556 				}
       
  2557 				return;
       
  2558 			}
       
  2559 
       
  2560 			TrainPlayLeaveStationSound(v);
       
  2561 
       
  2562 			Order b = v->current_order;
       
  2563 			v->LeaveStation();
       
  2564 
       
  2565 			/* If this was not the final order, don't remove it from the list. */
       
  2566 			if (!(b.flags & OF_NON_STOP)) return;
       
  2567 			break;
       
  2568 		}
       
  2569 
       
  2570 		case OT_DUMMY: break;
       
  2571 
       
  2572 		default: return;
       
  2573 	}
       
  2574 
       
  2575 	v->u.rail.days_since_order_progr = 0;
       
  2576 	v->cur_order_index++;
       
  2577 	InvalidateVehicleOrder(v);
       
  2578 }
  2527 }
  2579 
  2528 
  2580 static int UpdateTrainSpeed(Vehicle *v)
  2529 static int UpdateTrainSpeed(Vehicle *v)
  2581 {
  2530 {
  2582 	uint accel;
  2531 	uint accel;
  2629 			v->index,
  2578 			v->index,
  2630 			0
  2579 			0
  2631 		);
  2580 		);
  2632 	}
  2581 	}
  2633 
  2582 
  2634 	/* Did we reach the final destination? */
  2583 	v->BeginLoading();
  2635 	if (v->current_order.type == OT_GOTO_STATION &&
       
  2636 			v->current_order.dest == station) {
       
  2637 		/* Yeah, keep the load/unload flags
       
  2638 		 * Non Stop now means if the order should be increased. */
       
  2639 		v->BeginLoading();
       
  2640 		v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER;
       
  2641 		v->current_order.flags |= OF_NON_STOP;
       
  2642 	} else {
       
  2643 		/* No, just do a simple load */
       
  2644 		v->BeginLoading();
       
  2645 		v->current_order.flags = 0;
       
  2646 	}
       
  2647 	v->current_order.dest = 0;
  2584 	v->current_order.dest = 0;
  2648 
       
  2649 	SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC);
       
  2650 	if (LoadUnloadVehicle(v, true) != 0) {
       
  2651 		InvalidateWindow(WC_TRAINS_LIST, v->owner);
       
  2652 		TrainCargoChanged(v);
       
  2653 		UpdateTrainAcceleration(v);
       
  2654 	}
       
  2655 	MarkTrainDirty(v);
       
  2656 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
       
  2657 }
  2585 }
  2658 
  2586 
  2659 static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
  2587 static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
  2660 {
  2588 {
  2661 	/* need this hint so it returns the right z coordinate on bridges. */
  2589 	/* need this hint so it returns the right z coordinate on bridges. */
  3076 			}
  3004 			}
  3077 		}
  3005 		}
  3078 
  3006 
  3079 		/* update image of train, as well as delta XY */
  3007 		/* update image of train, as well as delta XY */
  3080 		Direction newdir = GetNewVehicleDirection(v, gp.x, gp.y);
  3008 		Direction newdir = GetNewVehicleDirection(v, gp.x, gp.y);
  3081 		UpdateTrainDeltaXY(v, newdir);
  3009 		v->UpdateDeltaXY(newdir);
  3082 		if (update_image) v->cur_image = GetTrainImage(v, newdir);
  3010 		if (update_image) v->cur_image = GetTrainImage(v, newdir);
  3083 
  3011 
  3084 		v->x_pos = gp.x;
  3012 		v->x_pos = gp.x;
  3085 		v->y_pos = gp.y;
  3013 		v->y_pos = gp.y;
  3086 
  3014 
  3172 	do {
  3100 	do {
  3173 		/* We don't need to twist around vehicles if they're not visible */
  3101 		/* We don't need to twist around vehicles if they're not visible */
  3174 		if (!(v->vehstatus & VS_HIDDEN)) {
  3102 		if (!(v->vehstatus & VS_HIDDEN)) {
  3175 			v->direction = ChangeDir(v->direction, delta[GB(Random(), 0, 2)]);
  3103 			v->direction = ChangeDir(v->direction, delta[GB(Random(), 0, 2)]);
  3176 			BeginVehicleMove(v);
  3104 			BeginVehicleMove(v);
  3177 			UpdateTrainDeltaXY(v, v->direction);
  3105 			v->UpdateDeltaXY(v->direction);
  3178 			v->cur_image = GetTrainImage(v, v->direction);
  3106 			v->cur_image = GetTrainImage(v, v->direction);
  3179 			/* Refrain from updating the z position of the vehicle when on
  3107 			/* Refrain from updating the z position of the vehicle when on
  3180 			   a bridge, because AfterSetTrainPos will put the vehicle under
  3108 			   a bridge, because AfterSetTrainPos will put the vehicle under
  3181 			   the bridge in that case */
  3109 			   the bridge in that case */
  3182 			if (v->u.rail.track != TRACK_BIT_WORMHOLE) AfterSetTrainPos(v, false);
  3110 			if (v->u.rail.track != TRACK_BIT_WORMHOLE) AfterSetTrainPos(v, false);
  3374 		v->subspeed = 0;
  3302 		v->subspeed = 0;
  3375 		ReverseTrainDirection(v);
  3303 		ReverseTrainDirection(v);
  3376 		return;
  3304 		return;
  3377 	}
  3305 	}
  3378 
  3306 
  3379 	HandleTrainLoading(v, mode);
  3307 	v->HandleLoading(mode);
  3380 
  3308 
  3381 	if (v->current_order.type == OT_LOADING) return;
  3309 	if (v->current_order.type == OT_LOADING) return;
  3382 
  3310 
  3383 	if (CheckTrainStayInDepot(v)) return;
  3311 	if (CheckTrainStayInDepot(v)) return;
  3384 
  3312 
  3462 	if (v->current_order.type == OT_GOTO_DEPOT &&
  3390 	if (v->current_order.type == OT_GOTO_DEPOT &&
  3463 			v->current_order.dest != depot->index &&
  3391 			v->current_order.dest != depot->index &&
  3464 			!CHANCE16(3, 16)) {
  3392 			!CHANCE16(3, 16)) {
  3465 		return;
  3393 		return;
  3466 	}
  3394 	}
       
  3395 
       
  3396 	if (v->current_order.type == OT_LOADING) v->LeaveStation();
  3467 
  3397 
  3468 	v->current_order.type = OT_GOTO_DEPOT;
  3398 	v->current_order.type = OT_GOTO_DEPOT;
  3469 	v->current_order.flags = OF_NON_STOP;
  3399 	v->current_order.flags = OF_NON_STOP;
  3470 	v->current_order.dest = depot->index;
  3400 	v->current_order.dest = depot->index;
  3471 	v->dest_tile = tfdd.tile;
  3401 	v->dest_tile = tfdd.tile;