From 01549e1574b8c4deeb28bf5127bc5027d58841d1 Mon Sep 17 00:00:00 2001 From: bjarni Date: Sat, 19 Apr 2008 17:47:56 +0000 Subject: [PATCH] (svn r12792) -Codechange: [autoreplace] added a function to figure out if a replacement is needed and if so, to which EngineID It's designed to save a bit of CPU time, specially if the replacement isn't buildable (think autorenew of old vehicle) --- src/autoreplace_cmd.cpp | 53 +++++++++++++++++++++++++---------------- src/vehicle.cpp | 1 + 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 2b848ea3cf..4c7249ea53 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -117,31 +117,26 @@ static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type) return CT_NO_REFIT; // We failed to find a cargo type on the old vehicle and we will not refit the new one } -/* Replaces a vehicle (used to be called autorenew) +/** Replaces a vehicle (used to be called autorenew) * This function is only called from MaybeReplaceVehicle() * Must be called with _current_player set to the owner of the vehicle * @param w Vehicle to replace * @param flags is the flags to use when calling DoCommand(). Mainly DC_EXEC counts + * @param p The vehicle owner (faster than refinding the pointer) + * @param new_engine_type The EngineID to replace to * @return value is cost of the replacement or CMD_ERROR */ -static CommandCost ReplaceVehicle(Vehicle **w, byte flags, Money total_cost) +static CommandCost ReplaceVehicle(Vehicle **w, byte flags, Money total_cost, const Player *p, EngineID new_engine_type) { CommandCost cost; CommandCost sell_value; Vehicle *old_v = *w; - const Player *p = GetPlayer(old_v->owner); - EngineID new_engine_type; const UnitID cached_unitnumber = old_v->unitnumber; bool new_front = false; Vehicle *new_v = NULL; char *vehicle_name = NULL; CargoID replacement_cargo_type; - /* Check if there is a autoreplacement set for the vehicle */ - new_engine_type = EngineReplacementForPlayer(p, old_v->engine_type, old_v->group_id); - /* if not, just renew to the same type */ - if (new_engine_type == INVALID_ENGINE) new_engine_type = old_v->engine_type; - replacement_cargo_type = GetNewCargoTypeForReplace(old_v, new_engine_type); /* check if we can't refit to the needed type, so no replace takes place to prevent the vehicle from altering cargo type */ @@ -292,6 +287,32 @@ static CommandCost ReplaceVehicle(Vehicle **w, byte flags, Money total_cost) return cost; } +/** Get the EngineID of the replacement for a vehicle + * @param v The vehicle to find a replacement for + * @param p The vehicle's owner (it's faster to forward the pointer than refinding it) + * @return the EngineID of the replacement. INVALID_ENGINE if no buildable replacement is found + */ +static EngineID GetNewEngineType(const Vehicle *v, const Player *p) +{ + if (v->type == VEH_TRAIN && IsRearDualheaded(v)) { + /* we build the rear ends of multiheaded trains with the front ones */ + return INVALID_ENGINE; + } + + EngineID e = EngineReplacementForPlayer(p, v->engine_type, v->group_id); + + if (e != INVALID_ENGINE && IsEngineBuildable(e, v->type, _current_player)) { + return e; + } + + if (v->NeedsAutorenewing(p) && // replace if engine is too old + IsEngineBuildable(v->engine_type, v->type, _current_player)) { // engine can still be build + return v->engine_type; + } + + return INVALID_ENGINE; +} + /** replaces a vehicle if it's set for autoreplace or is too old * (used to be called autorenew) * @param v The vehicle to replace @@ -348,19 +369,11 @@ CommandCost MaybeReplaceVehicle(Vehicle *v, uint32 flags, bool display_costs) cost = CommandCost(EXPENSES_NEW_VEHICLES); w = v; do { - if (w->type == VEH_TRAIN && IsRearDualheaded(w)) { - /* we build the rear ends of multiheaded trains with the front ones */ - continue; - } - - // check if the vehicle should be replaced - if (!w->NeedsAutorenewing(p) || // replace if engine is too old - w->max_age == 0) { // rail cars got a max age of 0 - if (!EngineHasReplacementForPlayer(p, w->engine_type, w->group_id)) continue; - } + EngineID new_engine = GetNewEngineType(w, p); + if (new_engine == INVALID_ENGINE) continue; /* Now replace the vehicle */ - cost.AddCost(ReplaceVehicle(&w, flags, cost.GetCost())); + cost.AddCost(ReplaceVehicle(&w, flags, cost.GetCost(), p, new_engine)); if (flags & DC_EXEC && (w->type != VEH_TRAIN || w->u.rail.first_engine == INVALID_ENGINE)) { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 028ae53516..a4515f923a 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -106,6 +106,7 @@ bool Vehicle::NeedsAutorenewing(const Player *p) const if (!p->engine_renew) return false; if (this->age - this->max_age < (p->engine_renew_months * 30)) return false; + if (this->age == 0) return false; // rail cars don't age and lacks a max age return true; }