Mercurial > hg > openttd
changeset 14009:809a3be57aef draft
(svn r18551) -Fix [FS#1762]: When autoreplace is the only allowed reason to send vehicles to depot, first check some minimal requirements (engine availability, refittability) and a heuristic for the needed money.
author | frosch <frosch@openttd.org> |
---|---|
date | Sat, 19 Dec 2009 21:54:34 +0000 |
parents | 6eca3533ed1d |
children | 122bec54f0ad |
files | src/vehicle.cpp |
diffstat | 1 files changed, 30 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -45,6 +45,7 @@ #include "network/network.h" #include "core/pool_func.hpp" #include "economy_base.h" +#include "articulated_vehicles.h" #include "table/sprites.h" #include "table/strings.h" @@ -96,7 +97,8 @@ if (this->vehstatus & (VS_STOPPED | VS_CRASHED)) return false; /* Are we ready for the next service cycle? */ - if (Company::Get(this->owner)->settings.vehicle.servint_ispercent ? + const Company *c = Company::Get(this->owner); + if (c->settings.vehicle.servint_ispercent ? (this->reliability >= Engine::Get(this->engine_type)->reliability * (100 - this->service_interval) / 100) : (this->date_of_last_service + this->service_interval >= _date)) { return false; @@ -109,9 +111,33 @@ return true; } - /* Vehicles set for autoreplacing needs to go to a depot even if breakdowns are turned off. - * Note: If servicing is enabled, we postpone replacement till next service. */ - return EngineHasReplacementForCompany(Company::Get(this->owner), this->engine_type, this->group_id); + /* Test whether there is some pending autoreplace. + * Note: We do this after the service-interval test. + * There are a lot more reasons for autoreplace to fail than we can test here reasonably. */ + bool pending_replace = false; + Money needed_money = c->settings.engine_renew_money; + if (needed_money > c->money) return false; + + const Vehicle *v = this; + do { + EngineID new_engine = EngineReplacementForCompany(c, v->engine_type, v->group_id); + /* Check engine availability */ + if (new_engine != INVALID_ENGINE && HasBit(Engine::Get(new_engine)->company_avail, v->owner)) { + /* Check refittability */ + CargoID cargo_type = CT_INVALID; + if (!IsArticulatedVehicleCarryingDifferentCargos(v, &cargo_type) && cargo_type != CT_INVALID && + HasBit(GetIntersectionOfArticulatedRefitMasks(new_engine, true), cargo_type)) { + /* Check money. + * We want 2*(the price of the new vehicle) without looking at the value of the vehicle we are going to sell. */ + pending_replace = true; + needed_money += 2 * Engine::Get(new_engine)->GetCost(); + if (needed_money > c->money) break; + } + } + v = (v->type == VEH_TRAIN) ? Train::From(v)->GetNextUnit() : NULL; + } while (v != NULL); + + return pending_replace && needed_money <= c->money; } bool Vehicle::NeedsAutomaticServicing() const