File diff r26193:4bc7915a2156 → r26194:f7347205838e
src/vehicle.cpp
Show inline comments
 
@@ -162,14 +162,29 @@ bool Vehicle::NeedsAutorenewing(const Co
 
void VehicleServiceInDepot(Vehicle *v)
 
{
 
	assert(v != nullptr);
 
	const Engine *e = Engine::Get(v->engine_type);
 
	if (v->type == VEH_TRAIN) {
 
		if (v->Next() != NULL) VehicleServiceInDepot(v->Next());
 
		if (!(Train::From(v)->IsEngine()) && !(Train::From(v)->IsRearDualheaded())) return;
 
		ClrBit(Train::From(v)->flags,VRF_NEED_REPAIR);
 
		const RailVehicleInfo *rvi = &e->u.rail;
 
		v->vcache.cached_max_speed = rvi->max_speed;
 
		if (Train::From(v)->IsFrontEngine()) {
 
			Train::From(v)->ConsistChanged(CCF_REFIT);
 
			CLRBITS(Train::From(v)->flags, (1 << VRF_BREAKDOWN_BRAKING) | VRF_IS_BROKEN );
 
		}
 
	}
 
	v->date_of_last_service = _date;
 
	v->breakdowns_since_last_service = 0;
 
	v->reliability = e->reliability;
 
	v->breakdown_ctr = 0;
 
	v->vehstatus &= ~VS_AIRCRAFT_BROKEN;
 
	SetWindowDirty(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated
 

	
 
	do {
 
		v->date_of_last_service = _date;
 
		v->breakdowns_since_last_service = 0;
 
		v->reliability = v->GetEngine()->reliability;
 
		/* Prevent vehicles from breaking down directly after exiting the depot. */
 
		v->breakdown_chance /= 4;
 
		if (_settings_game.difficulty.vehicle_breakdowns == 1) v->breakdown_chance = 0; // on reduced breakdown
 
		v = v->Next();
 
	} while (v != nullptr && v->HasEngineType());
 
@@ -189,9 +204,10 @@ bool Vehicle::NeedsServicing() const
 

	
 
	/* Are we ready for the next service cycle? */
 
	const Company *c = Company::Get(this->owner);
 
	if (this->ServiceIntervalIsPercent() ?
 
			(this->reliability >= this->GetEngine()->reliability * (100 - this->GetServiceInterval()) / 100) :
 
			(this->date_of_last_service + this->GetServiceInterval() >= _date)) {
 
	if ((this->ServiceIntervalIsPercent() ?
 
			(this->reliability >= this->GetEngine()->reliability * (100 - this->service_interval) / 100) :
 
			(this->date_of_last_service + this->service_interval >= _date))
 
			&& !(this->type == VEH_TRAIN && HasBit(Train::From(this)->flags ,VRF_NEED_REPAIR))) {
 
		return false;
 
	}
 

	
 
@@ -981,6 +997,16 @@ void CallVehicleTicks()
 
			default: break;
 

	
 
			case VEH_TRAIN:
 
				if (HasBit(Train::From(v)->flags, VRF_TO_HEAVY)) {
 
					_current_company = v->owner;
 
					if (IsLocalCompany()) {
 
						SetDParam(0, v->index);
 
						SetDParam(1, STR_ERROR_TRAIN_TOO_HEAVY);
 
						AddVehicleNewsItem(STR_ERROR_TRAIN_TOO_HEAVY, NT_ADVICE, v->index);
 
						ClrBit(Train::From(v)->flags,VRF_TO_HEAVY);
 
					}
 
					_current_company = OWNER_NONE;
 
				}
 
			case VEH_ROAD:
 
			case VEH_AIRCRAFT:
 
			case VEH_SHIP: {
 
@@ -1253,17 +1279,117 @@ void DecreaseVehicleValue(Vehicle *v)
 
	SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
}
 

	
 
static const byte _breakdown_chance[64] = {
 
	  3,   3,   3,   3,   3,   3,   3,   3,
 
	  4,   4,   5,   5,   6,   6,   7,   7,
 
	  8,   8,   9,   9,  10,  10,  11,  11,
 
	 12,  13,  13,  13,  13,  14,  15,  16,
 
	 17,  19,  21,  25,  28,  31,  34,  37,
 
	 40,  44,  48,  52,  56,  60,  64,  68,
 
	 72,  80,  90, 100, 110, 120, 130, 140,
 
	150, 170, 190, 210, 230, 250, 250, 250,
 
/** The chances for the different types of vehicles to suffer from different types of breakdowns
 
 * The chance for a given breakdown type n is _breakdown_chances[vehtype][n] - _breakdown_chances[vehtype][n-1] */
 
static const byte _breakdown_chances[4][4] = {
 
	{ //Trains:
 
		25,  ///< 10% chance for BREAKDOWN_CRITICAL.
 
		51,  ///< 10% chance for BREAKDOWN_EM_STOP.
 
		127, ///< 30% chance for BREAKDOWN_LOW_SPEED.
 
		255, ///< 50% chance for BREAKDOWN_LOW_POWER.
 
	},
 
	{ //Road Vehicles:
 
		51,  ///< 20% chance for BREAKDOWN_CRITICAL.
 
		76,  ///< 10% chance for BREAKDOWN_EM_STOP.
 
		153, ///< 30% chance for BREAKDOWN_LOW_SPEED.
 
		255, ///< 40% chance for BREAKDOWN_LOW_POWER.
 
	},
 
	{ //Ships:
 
		51,  ///< 20% chance for BREAKDOWN_CRITICAL.
 
		76,  ///< 10% chance for BREAKDOWN_EM_STOP.
 
		178, ///< 40% chance for BREAKDOWN_LOW_SPEED.
 
		255, ///< 30% chance for BREAKDOWN_LOW_POWER.
 
	},
 
	{ //Aircraft:
 
		178, ///< 70% chance for BREAKDOWN_AIRCRAFT_SPEED.
 
		229, ///< 20% chance for BREAKDOWN_AIRCRAFT_DEPOT.
 
		255, ///< 10% chance for BREAKDOWN_AIRCRAFT_EM_LANDING.
 
		255, ///< Aircraft have only 3 breakdown types, so anything above 0% here will cause a crash.
 
	},
 
};
 

	
 
/**
 
 * Determine the type of breakdown a vehicle will have.
 
 * Results are saved in breakdown_type and breakdown_severity.
 
 * @param v the vehicle in question.
 
 * @param r the random number to use. (Note that bits 0..6 are already used)
 
 */
 
void
 
DetermineBreakdownType( Vehicle *v, uint32 r ) {
 
	/* if 'improved breakdowns' is off, just do the classic breakdown */
 
	if ( !_settings_game.vehicle.improved_breakdowns ) {
 
		v->breakdown_type = BREAKDOWN_CRITICAL;
 
		v->breakdown_severity = 40; //only used by aircraft (321 km/h)
 
		return;
 
	}
 
	byte rand = GB( r, 8, 8 );
 
	const byte *breakdown_type_chance = _breakdown_chances[v->type];
 

	
 
	if ( v->type == VEH_AIRCRAFT ) {
 
		if ( rand <= breakdown_type_chance[BREAKDOWN_AIRCRAFT_SPEED] ) {
 
			v->breakdown_type = BREAKDOWN_AIRCRAFT_SPEED;
 
			// RJD: replaced the max and min speeds here with percentages because engine type max speed is 0 in some GRF files.
 
			// the severity is now used as a percentage of max speed rather than the actual allowed max speed
 
			// and is multipled by the current situational max speed in aircraft_cmd.cpp to get a real limit.
 
			// (this hopefully fixes the severity 0 bug)
 
			byte max_speed_percentage = 80;
 
			byte min_speed_percentage = 10;
 
			v->breakdown_severity = min_speed_percentage + ( ( ( v->reliability + GB( r, 16, 16 ) ) * ( max_speed_percentage - min_speed_percentage) ) >> 17 );
 
		} else if ( rand <= breakdown_type_chance[BREAKDOWN_AIRCRAFT_DEPOT] ) {
 
			v->breakdown_type = BREAKDOWN_AIRCRAFT_DEPOT;
 
		} else if ( rand <= breakdown_type_chance[BREAKDOWN_AIRCRAFT_EM_LANDING] ) {
 
			/* emergency landings only happen when reliability < 87% */
 
			if ( v->reliability < 0xDDDD ) {
 
				v->breakdown_type = BREAKDOWN_AIRCRAFT_EM_LANDING;
 
			} else {
 
				/* try again */
 
				DetermineBreakdownType( v, Random( ) );
 
			}
 
		} else {
 
			NOT_REACHED( );
 
		}
 
		return;
 
	}
 

	
 
	if ( rand <= breakdown_type_chance[BREAKDOWN_CRITICAL] ) {
 
		v->breakdown_type = BREAKDOWN_CRITICAL;
 
	} else if ( rand <= breakdown_type_chance[BREAKDOWN_EM_STOP] ) {
 
		/* Non-front engines cannot have emergency stops */
 
		if ( v->type == VEH_TRAIN && !( Train::From( v )->IsFrontEngine( ) ) ) {
 
			return DetermineBreakdownType( v, Random( ) );
 
		}
 
		v->breakdown_type = BREAKDOWN_EM_STOP;
 
		v->breakdown_delay >>= 2; //emergency stops don't last long (1/4 of normal)
 
	} else if ( rand <= breakdown_type_chance[BREAKDOWN_LOW_SPEED] ) {
 
		v->breakdown_type = BREAKDOWN_LOW_SPEED;
 
		/* average of random and reliability */
 
		uint16 rand2 = ( GB( r, 16, 16 ) + v->reliability ) >> 1;
 
		uint16 max_speed =
 
			( v->type == VEH_TRAIN ) ?
 
			GetVehicleProperty( v, PROP_TRAIN_SPEED, RailVehInfo( v->engine_type )->max_speed ) :
 
			( v->type == VEH_ROAD ) ?
 
			GetVehicleProperty( v, PROP_ROADVEH_SPEED, RoadVehInfo( v->engine_type )->max_speed ) :
 
			( v->type == VEH_SHIP ) ?
 
			GetVehicleProperty( v, PROP_SHIP_SPEED, ShipVehInfo( v->engine_type )->max_speed ) :
 
			GetVehicleProperty( v, PROP_AIRCRAFT_SPEED, AircraftVehInfo( v->engine_type )->max_speed );
 
		byte min_speed = std::min( 41, max_speed >> 2 );
 
		/* we use the min() function here because we want to use the real value of max_speed for the min_speed calculation */
 
		max_speed = std::min<uint16>( max_speed, 255 );
 
		v->breakdown_severity = Clamp( ( max_speed * rand2 ) >> 16, min_speed, max_speed );
 
	} else if ( rand <= breakdown_type_chance[BREAKDOWN_LOW_POWER] ) {
 
		v->breakdown_type = BREAKDOWN_LOW_POWER;
 
		/** within this type there are two possibilities: (50/50)
 
		 * power reduction (10-90%), or no power at all */
 
		if ( GB( r, 7, 1 ) ) {
 
			v->breakdown_severity = Clamp( ( GB( r, 16, 16 ) + v->reliability ) >> 9, 26, 231 );
 
		} else {
 
			v->breakdown_severity = 0;
 
		}
 
	} else {
 
		NOT_REACHED( );
 
	}
 
}
 

	
 
void CheckVehicleBreakdown(Vehicle *v)
 
{
 
	int rel, rel_old;
 
@@ -1272,34 +1398,42 @@ void CheckVehicleBreakdown(Vehicle *v)
 
	if (!_settings_game.order.no_servicing_if_no_breakdowns ||
 
			_settings_game.difficulty.vehicle_breakdowns != 0) {
 
		v->reliability = rel = std::max((rel_old = v->reliability) - v->reliability_spd_dec, 0);
 
		if ((rel_old >> 8) != (rel >> 8)) SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
 
		if ((rel_old >> 8) != (rel >> 8)) SetWindowDirty(WC_VEHICLE_DETAILS, v->First()->index);
 
	}
 

	
 
	if (v->breakdown_ctr != 0 || (v->vehstatus & VS_STOPPED) ||
 
	if (v->breakdown_ctr != 0 || (v->First()->vehstatus & VS_STOPPED) ||
 
			_settings_game.difficulty.vehicle_breakdowns < 1 ||
 
			v->cur_speed < 5 || _game_mode == GM_MENU) {
 
			v->First()->cur_speed < 5 || _game_mode == GM_MENU ||
 
			(v->type == VEH_AIRCRAFT && ((Aircraft*)v)->state != FLYING) ||
 
			(v->type == VEH_TRAIN && !(Train::From(v)->IsFrontEngine()) && !_settings_game.vehicle.improved_breakdowns)) {
 
		return;
 
	}
 

	
 
	uint32 r = Random();
 

	
 
	/* increase chance of failure */
 
	int chance = v->breakdown_chance + 1;
 
	if (Chance16I(1, 25, r)) chance += 25;
 
	v->breakdown_chance = std::min(255, chance);
 

	
 
	/* calculate reliability value to use in comparison */
 
	rel = v->reliability;
 
	if (v->type == VEH_SHIP) rel += 0x6666;
 

	
 
	/* reduced breakdowns? */
 
	if (_settings_game.difficulty.vehicle_breakdowns == 1) rel += 0x6666;
 

	
 
	/* check if to break down */
 
	if (_breakdown_chance[(uint)std::min(rel, 0xffff) >> 10] <= v->breakdown_chance) {
 
		v->breakdown_ctr    = GB(r, 16, 6) + 0x3F;
 
		v->breakdown_delay  = GB(r, 24, 7) + 0x80;
 
		v->breakdown_chance = 0;
 
	uint32 r1 = Random();
 
	uint32 r2 = Random();
 
	uint32 r3 = Random();
 

	
 
	byte chance = 128;
 
	if (_settings_game.vehicle.improved_breakdowns) {
 
		/* Dual engines have their breakdown chances reduced to 70% of the normal value */
 
		chance = (v->type == VEH_TRAIN && Train::From(v)->IsMultiheaded()) ? v->First()->breakdown_chance * 7 / 10 : v->First()->breakdown_chance;
 
	} else if(v->type == VEH_SHIP) {
 
		chance = 64;
 
	}
 
	/**
 
	 * Chance is (1 - reliability) * breakdown_setting * breakdown_chance / 10.
 
	 * At 90% reliabilty, normal setting (2) and average breakdown_chance (128),
 
	 * a vehicle will break down (on average) every 100 days.
 
	 * This *should* mean that vehicles break down about as often as (or a little less than) they used to.
 
	 * However, because breakdowns are no longer by definition a complete stop,
 
	 * their impact will be significantly less.
 
	 */
 
	if ( (uint32) ( 0xffff - v->reliability ) * _settings_game.difficulty.vehicle_breakdowns * chance > GB( r1, 0, 24 ) * 10 ) {
 
		if (GB(r3, 0, 24) <= _settings_game.difficulty.vehicle_breakdown_scaler) { // uint32
 
			v->breakdown_ctr = GB(r1, 24, 6) + 0xF;
 
			v->breakdown_delay = GB(r2, 0, 7) + 0x80;
 
			DetermineBreakdownType(v, r2);
 
		}
 
	}
 
}
 

	
 
@@ -1328,28 +1462,108 @@ bool Vehicle::HandleBreakdown()
 
			}
 

	
 
			if (this->type == VEH_AIRCRAFT) {
 
				this->MarkDirty();
 
				assert(this->breakdown_type <= BREAKDOWN_AIRCRAFT_EM_LANDING);
 
				/* Aircraft just need this flag, the rest is handled elsewhere */
 
				this->vehstatus |= VS_AIRCRAFT_BROKEN;
 
			} else {
 
				this->cur_speed = 0;
 

	
 
				if (!PlayVehicleSound(this, VSE_BREAKDOWN)) {
 
					bool train_or_ship = this->type == VEH_TRAIN || this->type == VEH_SHIP;
 
					SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
 
						(train_or_ship ? SND_10_BREAKDOWN_TRAIN_SHIP : SND_0F_BREAKDOWN_ROADVEHICLE) :
 
						(train_or_ship ? SND_3A_BREAKDOWN_TRAIN_SHIP_TOYLAND : SND_35_BREAKDOWN_ROADVEHICLE_TOYLAND), this);
 
				if(this->breakdown_type == BREAKDOWN_AIRCRAFT_SPEED ||
 
						(this->current_order.IsType(OT_GOTO_DEPOT) &&
 
						(this->current_order.GetDepotOrderType() & ODTFB_BREAKDOWN) &&
 
						GetTargetAirportIfValid(Aircraft::From(this)) != NULL)) return false;
 
				FindBreakdownDestination(Aircraft::From(this));
 
				
 
			} else if ( this->type == VEH_TRAIN ) {
 
				if ( this->breakdown_type == BREAKDOWN_LOW_POWER ||
 
					this->First( )->cur_speed <= ( ( this->breakdown_type == BREAKDOWN_LOW_SPEED ) ? this->breakdown_severity : 0 ) ) {
 
					switch ( this->breakdown_type ) {
 
						case BREAKDOWN_CRITICAL:
 
							if (!PlayVehicleSound(this, VSE_BREAKDOWN)) {
 
										bool train_or_ship = this->type == VEH_TRAIN || this->type == VEH_SHIP;
 
										SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
 
										(train_or_ship ? SND_10_BREAKDOWN_TRAIN_SHIP : SND_0F_BREAKDOWN_ROADVEHICLE) :
 
										(train_or_ship ? SND_3A_BREAKDOWN_TRAIN_SHIP_TOYLAND : SND_35_BREAKDOWN_ROADVEHICLE_TOYLAND), this);
 
							}
 
							if (!(this->vehstatus & VS_HIDDEN) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_NO_BREAKDOWN_SMOKE) && this->breakdown_delay > 0) {
 
								EffectVehicle *u = CreateEffectVehicleRel(this, 4, 4, 5, EV_BREAKDOWN_SMOKE);
 
								if (u != NULL) u->animation_state = this->breakdown_delay * 2;
 
							}
 
							/* Max Speed reduction*/
 
							if (_settings_game.vehicle.improved_breakdowns) {
 
								if (!HasBit(Train::From(this)->flags,VRF_NEED_REPAIR)) {
 
									const Engine *e = Engine::Get(this->engine_type);
 
									const RailVehicleInfo *rvi = &e->u.rail;
 
									if (rvi->max_speed > this->vcache.cached_max_speed)
 
										this->vcache.cached_max_speed = rvi->max_speed;
 
								}
 
								/* Setting max speed. The lowest max speed can go is 28 km/h */
 
								this->vcache.cached_max_speed =
 
									std::max<uint16>(std::min<uint16>(
 
										this->vcache.cached_max_speed - (this->vcache.cached_max_speed >> 1) / Train::From(this->First())->tcache.cached_num_engines + 1,
 
										this->vcache.cached_max_speed), 28);
 
								SetBit(Train::From(this)->flags, VRF_NEED_REPAIR);
 
								Train::From(this->First())->ConsistChanged(CCF_TRACK);
 
							}
 
						/* FALL THROUGH */
 
						case BREAKDOWN_EM_STOP:
 
							CheckBreakdownFlags(Train::From(this->First()));
 
							SetBit(Train::From(this->First())->flags, VRF_BREAKDOWN_STOPPED);
 
							break;
 
						case BREAKDOWN_LOW_SPEED:
 
							CheckBreakdownFlags(Train::From(this->First()));
 
							SetBit(Train::From(this->First())->flags, VRF_BREAKDOWN_SPEED);
 
							break;
 
						case BREAKDOWN_LOW_POWER:
 
							SetBit(Train::From(this->First())->flags, VRF_BREAKDOWN_POWER);
 
							break;
 
						default: NOT_REACHED();
 
					}
 

	
 
					this->First()->MarkDirty();
 
					SetWindowDirty(WC_VEHICLE_VIEW, this->index);
 
					SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
 
				} else {
 
					this->breakdown_ctr = 2; // wait until slowdown (handled by GetAccelerationStatus)
 
					this->breakdowns_since_last_service--;
 
					SetBit(Train::From(this)->flags, VRF_BREAKDOWN_BRAKING);
 
					return false;
 
				}
 

	
 
				if (!(this->vehstatus & VS_HIDDEN) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_NO_BREAKDOWN_SMOKE)) {
 
					EffectVehicle *u = CreateEffectVehicleRel(this, 4, 4, 5, EV_BREAKDOWN_SMOKE);
 
					if (u != nullptr) u->animation_state = this->breakdown_delay * 2;
 
				if ((!(this->vehstatus & VS_HIDDEN)) && (this->breakdown_type == BREAKDOWN_LOW_SPEED || this->breakdown_type == BREAKDOWN_LOW_POWER)
 
						&& !HasBit(EngInfo(this->engine_type)->misc_flags, EF_NO_BREAKDOWN_SMOKE)) {
 
					EffectVehicle *u = CreateEffectVehicleRel(this, 0, 0, 2, EV_BREAKDOWN_SMOKE); //some grey clouds to indicate a broken engine
 
					if (u != NULL) u->animation_state = 25;
 
				}
 
			} else {
 
				switch (this->breakdown_type) {
 
					case BREAKDOWN_CRITICAL:
 
						if (!PlayVehicleSound(this, VSE_BREAKDOWN)) {
 
							SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ? SND_0F_BREAKDOWN_ROADVEHICLE : SND_35_BREAKDOWN_ROADVEHICLE_TOYLAND, this);
 
						}
 
						if (!(this->vehstatus & VS_HIDDEN) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_NO_BREAKDOWN_SMOKE) && this->breakdown_delay > 0) {
 
							EffectVehicle *u = CreateEffectVehicleRel(this, 4, 4, 5, EV_BREAKDOWN_SMOKE);
 
							if (u != NULL) u->animation_state = this->breakdown_delay * 2;
 
						}
 
					/* FALL THROUGH */
 
					case BREAKDOWN_EM_STOP:
 
						this->cur_speed = 0;
 
						break;
 
					case BREAKDOWN_LOW_SPEED:
 
					case BREAKDOWN_LOW_POWER:
 
						/* do nothing */
 
						break;
 
					default: NOT_REACHED( );
 
				}
 
				if ( ( !( this->vehstatus & VS_HIDDEN ) ) && 
 
						( this->breakdown_type == BREAKDOWN_LOW_SPEED || this->breakdown_type == BREAKDOWN_LOW_POWER )) {
 
					/* Some gray clouds to indicate a broken RV */
 
					EffectVehicle *u = CreateEffectVehicleRel(this, 0, 0, 2, EV_BREAKDOWN_SMOKE);
 
					if (u != NULL) u->animation_state = 25;
 
 				}
 
				this->First()->MarkDirty();
 
				SetWindowDirty(WC_VEHICLE_VIEW, this->index);
 
				SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
 
				return (this->breakdown_type == BREAKDOWN_CRITICAL || this->breakdown_type == BREAKDOWN_EM_STOP );
 
			}
 

	
 
			this->MarkDirty(); // Update graphics after speed is zeroed
 
			SetWindowDirty(WC_VEHICLE_VIEW, this->index);
 
			SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
 

	
 
			FALLTHROUGH;
 
		case 1:
 
			/* Aircraft breakdowns end only when arriving at the airport */
 
@@ -1359,11 +1573,17 @@ bool Vehicle::HandleBreakdown()
 
			if ((this->tick_counter & (this->type == VEH_TRAIN ? 3 : 1)) == 0) {
 
				if (--this->breakdown_delay == 0) {
 
					this->breakdown_ctr = 0;
 
					this->MarkDirty();
 
					SetWindowDirty(WC_VEHICLE_VIEW, this->index);
 
					if( this->type == VEH_TRAIN ) {
 
						CheckBreakdownFlags(Train::From(this->First()));
 
						this->First()->MarkDirty();
 
						SetWindowDirty(WC_VEHICLE_VIEW, this->First()->index);
 
					} else {
 
						this->MarkDirty();
 
						SetWindowDirty(WC_VEHICLE_VIEW, this->index);
 
					}
 
				}
 
			}
 
			return true;
 
			return (this->breakdown_type == BREAKDOWN_CRITICAL || this->breakdown_type == BREAKDOWN_EM_STOP);
 

	
 
		default:
 
			if (!this->current_order.IsType(OT_LOADING)) this->breakdown_ctr--;
 
@@ -2398,7 +2618,7 @@ CommandCost Vehicle::SendToDepot(DoComma
 
			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
 
			 * Note: the if is (true for requesting service == true for ordered to stop in depot)          */
 
			if (flags & DC_EXEC) {
 
				this->current_order.SetDepotOrderType(ODTF_MANUAL);
 
				if (!(this->current_order.GetDepotOrderType() & ODTFB_BREAKDOWN)) this->current_order.SetDepotOrderType(ODTF_MANUAL);
 
				this->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT);
 
				SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
 
			}
 
@@ -2416,8 +2636,13 @@ CommandCost Vehicle::SendToDepot(DoComma
 
				SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
 
			}
 

	
 
			this->current_order.MakeDummy();
 
			SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
 
			/* We don't cancel a breakdown-related goto depot order, we only change whether to halt or not */
 
			if (this->current_order.GetDepotOrderType() & ODTFB_BREAKDOWN) {
 
				this->current_order.SetDepotActionType(this->current_order.GetDepotActionType() == ODATFB_HALT ? ODATF_SERVICE_ONLY : ODATFB_HALT);
 
			} else {
 
				this->current_order.MakeDummy();
 
				SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
 
			}
 
		}
 
		return CommandCost();
 
	}