src/train_cmd.cpp
changeset 10775 7061477bfbcf
parent 10707 81a4013a7680
child 10839 a62547c31fdb
equal deleted inserted replaced
10773:88125a991761 10775:7061477bfbcf
    90  * @return Cargo weight multiplier
    90  * @return Cargo weight multiplier
    91  */
    91  */
    92 byte FreightWagonMult(CargoID cargo)
    92 byte FreightWagonMult(CargoID cargo)
    93 {
    93 {
    94 	if (!GetCargo(cargo)->is_freight) return 1;
    94 	if (!GetCargo(cargo)->is_freight) return 1;
    95 	return _settings.vehicle.freight_trains;
    95 	return _settings_game.vehicle.freight_trains;
    96 }
    96 }
    97 
    97 
    98 
    98 
    99 /**
    99 /**
   100  * Recalculates the cached total power of a train. Should be called when the consist is changed
   100  * Recalculates the cached total power of a train. Should be called when the consist is changed
   276 				u->u.rail.railtype = RAILTYPE_RAIL;
   276 				u->u.rail.railtype = RAILTYPE_RAIL;
   277 				u->u.rail.compatible_railtypes |= RAILTYPES_RAIL;
   277 				u->u.rail.compatible_railtypes |= RAILTYPES_RAIL;
   278 			}
   278 			}
   279 
   279 
   280 			/* max speed is the minimum of the speed limits of all vehicles in the consist */
   280 			/* max speed is the minimum of the speed limits of all vehicles in the consist */
   281 			if ((rvi_u->railveh_type != RAILVEH_WAGON || _settings.vehicle.wagon_speed_limits) && !UsesWagonOverride(u)) {
   281 			if ((rvi_u->railveh_type != RAILVEH_WAGON || _settings_game.vehicle.wagon_speed_limits) && !UsesWagonOverride(u)) {
   282 				uint16 speed = GetVehicleProperty(u, 0x09, rvi_u->max_speed);
   282 				uint16 speed = GetVehicleProperty(u, 0x09, rvi_u->max_speed);
   283 				if (speed != 0) max_speed = min(speed, max_speed);
   283 				if (speed != 0) max_speed = min(speed, max_speed);
   284 			}
   284 			}
   285 		}
   285 		}
   286 
   286 
   724 		}
   724 		}
   725 
   725 
   726 		Vehicle *v = vl[0];
   726 		Vehicle *v = vl[0];
   727 
   727 
   728 		UnitID unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_TRAIN);
   728 		UnitID unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_TRAIN);
   729 		if (unit_num > _settings.vehicle.max_trains)
   729 		if (unit_num > _settings_game.vehicle.max_trains)
   730 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   730 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   731 
   731 
   732 		if (flags & DC_EXEC) {
   732 		if (flags & DC_EXEC) {
   733 			DiagDirection dir = GetRailDepotDirection(tile);
   733 			DiagDirection dir = GetRailDepotDirection(tile);
   734 			int x = TileX(tile) * TILE_SIZE + _vehicle_initial_x_fract[dir];
   734 			int x = TileX(tile) * TILE_SIZE + _vehicle_initial_x_fract[dir];
   763 
   763 
   764 			v->name = NULL;
   764 			v->name = NULL;
   765 			v->u.rail.railtype = rvi->railtype;
   765 			v->u.rail.railtype = rvi->railtype;
   766 			_new_vehicle_id = v->index;
   766 			_new_vehicle_id = v->index;
   767 
   767 
   768 			v->service_interval = _settings.vehicle.servint_trains;
   768 			v->service_interval = _settings_game.vehicle.servint_trains;
   769 			v->date_of_last_service = _date;
   769 			v->date_of_last_service = _date;
   770 			v->build_year = _cur_year;
   770 			v->build_year = _cur_year;
   771 			v->cur_image = 0xAC2;
   771 			v->cur_image = 0xAC2;
   772 			v->random_bits = VehicleRandomBits();
   772 			v->random_bits = VehicleRandomBits();
   773 
   773 
   999 
   999 
  1000 	/* when moving all wagons, we can't have the same src_head and dst_head */
  1000 	/* when moving all wagons, we can't have the same src_head and dst_head */
  1001 	if (HasBit(p2, 0) && src_head == dst_head) return CommandCost();
  1001 	if (HasBit(p2, 0) && src_head == dst_head) return CommandCost();
  1002 
  1002 
  1003 	{
  1003 	{
  1004 		int max_len = _settings.vehicle.mammoth_trains ? 100 : 10;
  1004 		int max_len = _settings_game.vehicle.mammoth_trains ? 100 : 10;
  1005 
  1005 
  1006 		/* check if all vehicles in the source train are stopped inside a depot. */
  1006 		/* check if all vehicles in the source train are stopped inside a depot. */
  1007 		int src_len = CheckTrainStoppedInDepot(src_head);
  1007 		int src_len = CheckTrainStoppedInDepot(src_head);
  1008 		if (src_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
  1008 		if (src_len < 0) return_cmd_error(STR_881A_TRAINS_CAN_ONLY_BE_ALTERED);
  1009 
  1009 
  1042 	}
  1042 	}
  1043 
  1043 
  1044 	/* moving a loco to a new line?, then we need to assign a unitnumber. */
  1044 	/* moving a loco to a new line?, then we need to assign a unitnumber. */
  1045 	if (dst == NULL && !IsFrontEngine(src) && IsTrainEngine(src)) {
  1045 	if (dst == NULL && !IsFrontEngine(src) && IsTrainEngine(src)) {
  1046 		UnitID unit_num = GetFreeUnitNumber(VEH_TRAIN);
  1046 		UnitID unit_num = GetFreeUnitNumber(VEH_TRAIN);
  1047 		if (unit_num > _settings.vehicle.max_trains)
  1047 		if (unit_num > _settings_game.vehicle.max_trains)
  1048 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
  1048 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
  1049 
  1049 
  1050 		if (flags & DC_EXEC) src->unitnumber = unit_num;
  1050 		if (flags & DC_EXEC) src->unitnumber = unit_num;
  1051 	}
  1051 	}
  1052 
  1052 
  1542 static inline void SetLastSpeed(Vehicle *v, int spd)
  1542 static inline void SetLastSpeed(Vehicle *v, int spd)
  1543 {
  1543 {
  1544 	int old = v->u.rail.last_speed;
  1544 	int old = v->u.rail.last_speed;
  1545 	if (spd != old) {
  1545 	if (spd != old) {
  1546 		v->u.rail.last_speed = spd;
  1546 		v->u.rail.last_speed = spd;
  1547 		if (_settings.gui.vehicle_speed || (old == 0) != (spd == 0)) {
  1547 		if (_settings_client.gui.vehicle_speed || (old == 0) != (spd == 0)) {
  1548 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  1548 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  1549 		}
  1549 		}
  1550 	}
  1550 	}
  1551 }
  1551 }
  1552 
  1552 
  1881 	} else {
  1881 	} else {
  1882 		/* turn the whole train around */
  1882 		/* turn the whole train around */
  1883 		if (v->vehstatus & VS_CRASHED || v->breakdown_ctr != 0) return CMD_ERROR;
  1883 		if (v->vehstatus & VS_CRASHED || v->breakdown_ctr != 0) return CMD_ERROR;
  1884 
  1884 
  1885 		if (flags & DC_EXEC) {
  1885 		if (flags & DC_EXEC) {
  1886 			if (_settings.vehicle.realistic_acceleration && v->cur_speed != 0) {
  1886 			if (_settings_game.vehicle.realistic_acceleration && v->cur_speed != 0) {
  1887 				ToggleBit(v->u.rail.flags, VRF_REVERSING);
  1887 				ToggleBit(v->u.rail.flags, VRF_REVERSING);
  1888 			} else {
  1888 			} else {
  1889 				v->cur_speed = 0;
  1889 				v->cur_speed = 0;
  1890 				SetLastSpeed(v, 0);
  1890 				SetLastSpeed(v, 0);
  1891 				ReverseTrainDirection(v);
  1891 				ReverseTrainDirection(v);
  2056 		tfdd.tile = tile;
  2056 		tfdd.tile = tile;
  2057 		tfdd.best_length = 0;
  2057 		tfdd.best_length = 0;
  2058 		return tfdd;
  2058 		return tfdd;
  2059 	}
  2059 	}
  2060 
  2060 
  2061 	switch (_settings.pf.pathfinder_for_trains) {
  2061 	switch (_settings_game.pf.pathfinder_for_trains) {
  2062 		case VPF_YAPF: { /* YAPF */
  2062 		case VPF_YAPF: { /* YAPF */
  2063 			bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse);
  2063 			bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse);
  2064 			tfdd.best_length = found ? max_distance / 2 : UINT_MAX; // some fake distance or NOT_FOUND
  2064 			tfdd.best_length = found ? max_distance / 2 : UINT_MAX; // some fake distance or NOT_FOUND
  2065 		} break;
  2065 		} break;
  2066 
  2066 
  2367 	assert((tracks & ~TRACK_BIT_MASK) == 0);
  2367 	assert((tracks & ~TRACK_BIT_MASK) == 0);
  2368 
  2368 
  2369 	/* quick return in case only one possible track is available */
  2369 	/* quick return in case only one possible track is available */
  2370 	if (KillFirstBit(tracks) == TRACK_BIT_NONE) return FindFirstTrack(tracks);
  2370 	if (KillFirstBit(tracks) == TRACK_BIT_NONE) return FindFirstTrack(tracks);
  2371 
  2371 
  2372 	switch (_settings.pf.pathfinder_for_trains) {
  2372 	switch (_settings_game.pf.pathfinder_for_trains) {
  2373 		case VPF_YAPF: { /* YAPF */
  2373 		case VPF_YAPF: { /* YAPF */
  2374 			Trackdir trackdir = YapfChooseRailTrack(v, tile, enterdir, tracks, &path_not_found);
  2374 			Trackdir trackdir = YapfChooseRailTrack(v, tile, enterdir, tracks, &path_not_found);
  2375 			if (trackdir != INVALID_TRACKDIR) {
  2375 			if (trackdir != INVALID_TRACKDIR) {
  2376 				best_track = TrackdirToTrack(trackdir);
  2376 				best_track = TrackdirToTrack(trackdir);
  2377 			} else {
  2377 			} else {
  2444 		/* PF didn't find the route */
  2444 		/* PF didn't find the route */
  2445 		if (!HasBit(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
  2445 		if (!HasBit(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION)) {
  2446 			/* it is first time the problem occurred, set the "path not found" flag */
  2446 			/* it is first time the problem occurred, set the "path not found" flag */
  2447 			SetBit(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
  2447 			SetBit(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
  2448 			/* and notify user about the event */
  2448 			/* and notify user about the event */
  2449 			if (_settings.gui.lost_train_warn && v->owner == _local_player) {
  2449 			if (_settings_client.gui.lost_train_warn && v->owner == _local_player) {
  2450 				SetDParam(0, v->unitnumber);
  2450 				SetDParam(0, v->unitnumber);
  2451 				AddNewsItem(
  2451 				AddNewsItem(
  2452 					STR_TRAIN_IS_LOST,
  2452 					STR_TRAIN_IS_LOST,
  2453 					NS_ADVICE,
  2453 					NS_ADVICE,
  2454 					v->index,
  2454 					v->index,
  2472 }
  2472 }
  2473 
  2473 
  2474 
  2474 
  2475 static bool CheckReverseTrain(Vehicle *v)
  2475 static bool CheckReverseTrain(Vehicle *v)
  2476 {
  2476 {
  2477 	if (_settings.difficulty.line_reverse_mode != 0 ||
  2477 	if (_settings_game.difficulty.line_reverse_mode != 0 ||
  2478 			v->u.rail.track == TRACK_BIT_DEPOT || v->u.rail.track == TRACK_BIT_WORMHOLE ||
  2478 			v->u.rail.track == TRACK_BIT_DEPOT || v->u.rail.track == TRACK_BIT_WORMHOLE ||
  2479 			!(v->direction & 1)) {
  2479 			!(v->direction & 1)) {
  2480 		return false;
  2480 		return false;
  2481 	}
  2481 	}
  2482 
  2482 
  2485 
  2485 
  2486 	uint reverse_best = 0;
  2486 	uint reverse_best = 0;
  2487 
  2487 
  2488 	assert(v->u.rail.track);
  2488 	assert(v->u.rail.track);
  2489 
  2489 
  2490 	switch (_settings.pf.pathfinder_for_trains) {
  2490 	switch (_settings_game.pf.pathfinder_for_trains) {
  2491 		case VPF_YAPF: /* YAPF */
  2491 		case VPF_YAPF: /* YAPF */
  2492 			reverse_best = YapfCheckReverseTrain(v);
  2492 			reverse_best = YapfCheckReverseTrain(v);
  2493 			break;
  2493 			break;
  2494 
  2494 
  2495 		case VPF_NPF: { /* NPF */
  2495 		case VPF_NPF: { /* NPF */
  2605 static int UpdateTrainSpeed(Vehicle *v)
  2605 static int UpdateTrainSpeed(Vehicle *v)
  2606 {
  2606 {
  2607 	uint accel;
  2607 	uint accel;
  2608 
  2608 
  2609 	if (v->vehstatus & VS_STOPPED || HasBit(v->u.rail.flags, VRF_REVERSING)) {
  2609 	if (v->vehstatus & VS_STOPPED || HasBit(v->u.rail.flags, VRF_REVERSING)) {
  2610 		if (_settings.vehicle.realistic_acceleration) {
  2610 		if (_settings_game.vehicle.realistic_acceleration) {
  2611 			accel = GetTrainAcceleration(v, AM_BRAKE) * 2;
  2611 			accel = GetTrainAcceleration(v, AM_BRAKE) * 2;
  2612 		} else {
  2612 		} else {
  2613 			accel = v->acceleration * -2;
  2613 			accel = v->acceleration * -2;
  2614 		}
  2614 		}
  2615 	} else {
  2615 	} else {
  2616 		if (_settings.vehicle.realistic_acceleration) {
  2616 		if (_settings_game.vehicle.realistic_acceleration) {
  2617 			accel = GetTrainAcceleration(v, AM_ACCEL);
  2617 			accel = GetTrainAcceleration(v, AM_ACCEL);
  2618 		} else {
  2618 		} else {
  2619 			accel = v->acceleration;
  2619 			accel = v->acceleration;
  2620 		}
  2620 		}
  2621 	}
  2621 	}
  2752 };
  2752 };
  2753 
  2753 
  2754 /** Modify the speed of the vehicle due to a turn */
  2754 /** Modify the speed of the vehicle due to a turn */
  2755 static inline void AffectSpeedByDirChange(Vehicle *v, Direction new_dir)
  2755 static inline void AffectSpeedByDirChange(Vehicle *v, Direction new_dir)
  2756 {
  2756 {
  2757 	if (_settings.vehicle.realistic_acceleration) return;
  2757 	if (_settings_game.vehicle.realistic_acceleration) return;
  2758 
  2758 
  2759 	DirDiff diff = DirDifference(v->direction, new_dir);
  2759 	DirDiff diff = DirDifference(v->direction, new_dir);
  2760 	if (diff == DIRDIFF_SAME) return;
  2760 	if (diff == DIRDIFF_SAME) return;
  2761 
  2761 
  2762 	const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->u.rail.railtype];
  2762 	const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->u.rail.railtype];
  2764 }
  2764 }
  2765 
  2765 
  2766 /** Modify the speed of the vehicle due to a change in altitude */
  2766 /** Modify the speed of the vehicle due to a change in altitude */
  2767 static inline void AffectSpeedByZChange(Vehicle *v, byte old_z)
  2767 static inline void AffectSpeedByZChange(Vehicle *v, byte old_z)
  2768 {
  2768 {
  2769 	if (old_z == v->z_pos || _settings.vehicle.realistic_acceleration) return;
  2769 	if (old_z == v->z_pos || _settings_game.vehicle.realistic_acceleration) return;
  2770 
  2770 
  2771 	const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->u.rail.railtype];
  2771 	const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->u.rail.railtype];
  2772 
  2772 
  2773 	if (old_z < v->z_pos) {
  2773 	if (old_z < v->z_pos) {
  2774 		v->cur_speed -= (v->cur_speed * rsp->z_up >> 8);
  2774 		v->cur_speed -= (v->cur_speed * rsp->z_up >> 8);
  2969 
  2969 
  2970 				TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts) & reachable_trackdirs;
  2970 				TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts) & reachable_trackdirs;
  2971 				TrackBits red_signals = TrackdirBitsToTrackBits(TrackStatusToRedSignals(ts) & reachable_trackdirs);
  2971 				TrackBits red_signals = TrackdirBitsToTrackBits(TrackStatusToRedSignals(ts) & reachable_trackdirs);
  2972 
  2972 
  2973 				TrackBits bits = TrackdirBitsToTrackBits(trackdirbits);
  2973 				TrackBits bits = TrackdirBitsToTrackBits(trackdirbits);
  2974 				if (_settings.pf.pathfinder_for_trains != VPF_NTP && _settings.pf.forbid_90_deg && prev == NULL) {
  2974 				if (_settings_game.pf.pathfinder_for_trains != VPF_NTP && _settings_game.pf.forbid_90_deg && prev == NULL) {
  2975 					/* We allow wagons to make 90 deg turns, because forbid_90_deg
  2975 					/* We allow wagons to make 90 deg turns, because forbid_90_deg
  2976 					 * can be switched on halfway a turn */
  2976 					 * can be switched on halfway a turn */
  2977 					bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
  2977 					bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
  2978 				}
  2978 				}
  2979 
  2979 
  2997 
  2997 
  2998 						if (!HasSignalOnTrackdir(gp.new_tile, ReverseTrackdir(i))) {
  2998 						if (!HasSignalOnTrackdir(gp.new_tile, ReverseTrackdir(i))) {
  2999 							v->cur_speed = 0;
  2999 							v->cur_speed = 0;
  3000 							v->subspeed = 0;
  3000 							v->subspeed = 0;
  3001 							v->progress = 255 - 100;
  3001 							v->progress = 255 - 100;
  3002 							if (++v->load_unload_time_rem < _settings.pf.wait_oneway_signal * 20) return;
  3002 							if (++v->load_unload_time_rem < _settings_game.pf.wait_oneway_signal * 20) return;
  3003 						} else if (HasSignalOnTrackdir(gp.new_tile, i)) {
  3003 						} else if (HasSignalOnTrackdir(gp.new_tile, i)) {
  3004 							v->cur_speed = 0;
  3004 							v->cur_speed = 0;
  3005 							v->subspeed = 0;
  3005 							v->subspeed = 0;
  3006 							v->progress = 255 - 10;
  3006 							v->progress = 255 - 10;
  3007 							if (++v->load_unload_time_rem < _settings.pf.wait_twoway_signal * 73) {
  3007 							if (++v->load_unload_time_rem < _settings_game.pf.wait_twoway_signal * 73) {
  3008 								TileIndex o_tile = gp.new_tile + TileOffsByDiagDir(enterdir);
  3008 								TileIndex o_tile = gp.new_tile + TileOffsByDiagDir(enterdir);
  3009 								Direction rdir = ReverseDir(dir);
  3009 								Direction rdir = ReverseDir(dir);
  3010 
  3010 
  3011 								/* check if a train is waiting on the other side */
  3011 								/* check if a train is waiting on the other side */
  3012 								if (VehicleFromPos(o_tile, &rdir, &CheckVehicleAtSignal) == NULL) return;
  3012 								if (VehicleFromPos(o_tile, &rdir, &CheckVehicleAtSignal) == NULL) return;
  3244 
  3244 
  3245 		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
  3245 		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
  3246 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  3246 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  3247 
  3247 
  3248 		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
  3248 		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
  3249 			SndPlayVehicleFx((_settings.game_creation.landscape != LT_TOYLAND) ?
  3249 			SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
  3250 				SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
  3250 				SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
  3251 		}
  3251 		}
  3252 
  3252 
  3253 		if (!(v->vehstatus & VS_HIDDEN)) {
  3253 		if (!(v->vehstatus & VS_HIDDEN)) {
  3254 			Vehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
  3254 			Vehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
  3404 
  3404 
  3405 	/* We are sure the train is not entering a depot, it is detected above */
  3405 	/* We are sure the train is not entering a depot, it is detected above */
  3406 
  3406 
  3407 	/* mask unreachable track bits if we are forbidden to do 90deg turns */
  3407 	/* mask unreachable track bits if we are forbidden to do 90deg turns */
  3408 	TrackBits bits = TrackdirBitsToTrackBits(trackdirbits);
  3408 	TrackBits bits = TrackdirBitsToTrackBits(trackdirbits);
  3409 	if (_settings.pf.pathfinder_for_trains != VPF_NTP && _settings.pf.forbid_90_deg) {
  3409 	if (_settings_game.pf.pathfinder_for_trains != VPF_NTP && _settings_game.pf.forbid_90_deg) {
  3410 		bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
  3410 		bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
  3411 	}
  3411 	}
  3412 
  3412 
  3413 	/* no suitable trackbits at all || unusable rail (wrong type or owner) */
  3413 	/* no suitable trackbits at all || unusable rail (wrong type or owner) */
  3414 	if (bits == TRACK_BIT_NONE || !CheckCompatibleRail(v, tile)) {
  3414 	if (bits == TRACK_BIT_NONE || !CheckCompatibleRail(v, tile)) {
  3537 
  3537 
  3538 static void CheckIfTrainNeedsService(Vehicle *v)
  3538 static void CheckIfTrainNeedsService(Vehicle *v)
  3539 {
  3539 {
  3540 	static const uint MAX_ACCEPTABLE_DEPOT_DIST = 16;
  3540 	static const uint MAX_ACCEPTABLE_DEPOT_DIST = 16;
  3541 
  3541 
  3542 	if (_settings.vehicle.servint_trains == 0 || !v->NeedsAutomaticServicing()) return;
  3542 	if (_settings_game.vehicle.servint_trains == 0 || !v->NeedsAutomaticServicing()) return;
  3543 	if (v->IsInDepot()) {
  3543 	if (v->IsInDepot()) {
  3544 		VehicleServiceInDepot(v);
  3544 		VehicleServiceInDepot(v);
  3545 		return;
  3545 		return;
  3546 	}
  3546 	}
  3547 
  3547 
  3612 	Vehicle *v;
  3612 	Vehicle *v;
  3613 
  3613 
  3614 	FOR_ALL_VEHICLES(v) {
  3614 	FOR_ALL_VEHICLES(v) {
  3615 		if (v->type == VEH_TRAIN && IsFrontEngine(v)) {
  3615 		if (v->type == VEH_TRAIN && IsFrontEngine(v)) {
  3616 			/* show warning if train is not generating enough income last 2 years (corresponds to a red icon in the vehicle list) */
  3616 			/* show warning if train is not generating enough income last 2 years (corresponds to a red icon in the vehicle list) */
  3617 			if (_settings.gui.train_income_warn && v->owner == _local_player && v->age >= 730 && v->GetDisplayProfitThisYear() < 0) {
  3617 			if (_settings_client.gui.train_income_warn && v->owner == _local_player && v->age >= 730 && v->GetDisplayProfitThisYear() < 0) {
  3618 				SetDParam(1, v->GetDisplayProfitThisYear());
  3618 				SetDParam(1, v->GetDisplayProfitThisYear());
  3619 				SetDParam(0, v->unitnumber);
  3619 				SetDParam(0, v->unitnumber);
  3620 				AddNewsItem(
  3620 				AddNewsItem(
  3621 					STR_TRAIN_IS_UNPROFITABLE,
  3621 					STR_TRAIN_IS_UNPROFITABLE,
  3622 					NS_ADVICE,
  3622 					NS_ADVICE,