From 4a9df576654afd22a6951e225a9f617c5148f091 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 30 Jan 2018 18:57:51 +0000 Subject: [PATCH] TBTR: Enable autorenew when template replacement active --- src/autoreplace_cmd.cpp | 42 ++++++++++++++++++++++++----------------- src/train_cmd.cpp | 4 ++++ src/vehicle.cpp | 10 ++++++++++ 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 06ef881b0b..4985fccf9f 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -238,10 +238,11 @@ static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, bool * @param v The vehicle to find a replacement for * @param c The vehicle's owner (it's faster to forward the pointer than refinding it) * @param always_replace Always replace, even if not old. + * @param same_type_only Only replace with same engine type. * @param [out] e the EngineID of the replacement. INVALID_ENGINE if no replacement is found * @return Error if the engine to build is not available */ -static CommandCost GetNewEngineType(const Vehicle *v, const Company *c, bool always_replace, EngineID &e) +static CommandCost GetNewEngineType(const Vehicle *v, const Company *c, bool always_replace, bool same_type_only, EngineID &e) { assert(v->type != VEH_TRAIN || !v->IsArticulatedPart()); @@ -252,9 +253,11 @@ static CommandCost GetNewEngineType(const Vehicle *v, const Company *c, bool alw return CommandCost(); } - bool replace_when_old; - e = EngineReplacementForCompany(c, v->engine_type, v->group_id, &replace_when_old); - if (!always_replace && replace_when_old && !v->NeedsAutorenewing(c, false)) e = INVALID_ENGINE; + if (!same_type_only) { + bool replace_when_old; + e = EngineReplacementForCompany(c, v->engine_type, v->group_id, &replace_when_old); + if (!always_replace && replace_when_old && !v->NeedsAutorenewing(c, false)) e = INVALID_ENGINE; + } /* Autoreplace, if engine is available */ if (e != INVALID_ENGINE && IsEngineBuildable(e, v->type, _current_company)) { @@ -277,16 +280,17 @@ static CommandCost GetNewEngineType(const Vehicle *v, const Company *c, bool alw * @param old_veh A single (articulated/multiheaded) vehicle that shall be replaced. * @param new_vehicle Returns the newly build and refitted vehicle * @param part_of_chain The vehicle is part of a train + * @param same_type_only Only replace with same engine type. * @return cost or error */ -static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehicle, bool part_of_chain) +static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehicle, bool part_of_chain, bool same_type_only) { *new_vehicle = NULL; /* Shall the vehicle be replaced? */ const Company *c = Company::Get(_current_company); EngineID e; - CommandCost cost = GetNewEngineType(old_veh, c, true, e); + CommandCost cost = GetNewEngineType(old_veh, c, true, same_type_only, e); if (cost.Failed()) return cost; if (e == INVALID_ENGINE) return CommandCost(); // neither autoreplace is set, nor autorenew is triggered @@ -386,9 +390,10 @@ CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, DoComma * @param single_unit vehicle to let autoreplace/renew operator on * @param flags command flags * @param nothing_to_do is set to 'false' when something was done (only valid when not failed) + * @param same_type_only Only replace with same engine type. * @return cost or error */ -static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, bool *nothing_to_do) +static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, bool *nothing_to_do, bool same_type_only) { Train *old_v = Train::From(*single_unit); assert(!old_v->IsArticulatedPart() && !old_v->IsRearDualheaded()); @@ -397,7 +402,7 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b /* Build and refit replacement vehicle */ Vehicle *new_v = NULL; - cost.AddCost(BuildReplacementVehicle(old_v, &new_v, false)); + cost.AddCost(BuildReplacementVehicle(old_v, &new_v, false, same_type_only)); /* Was a new vehicle constructed? */ if (cost.Succeeded() && new_v != NULL) { @@ -436,9 +441,10 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b * @param flags command flags * @param wagon_removal remove wagons when the resulting chain occupies more tiles than the old did * @param nothing_to_do is set to 'false' when something was done (only valid when not failed) + * @param same_type_only Only replace with same engine type. * @return cost or error */ -static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon_removal, bool *nothing_to_do) +static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon_removal, bool *nothing_to_do, bool same_type_only) { Vehicle *old_head = *chain; assert(old_head->IsPrimaryVehicle()); @@ -464,7 +470,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon assert(i < num_units); old_vehs[i] = w; - CommandCost ret = BuildReplacementVehicle(old_vehs[i], (Vehicle**)&new_vehs[i], true); + CommandCost ret = BuildReplacementVehicle(old_vehs[i], (Vehicle**)&new_vehs[i], true, same_type_only); cost.AddCost(ret); if (cost.Failed()) break; @@ -624,7 +630,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon } else { /* Build and refit replacement vehicle */ Vehicle *new_head = NULL; - cost.AddCost(BuildReplacementVehicle(old_head, &new_head, true)); + cost.AddCost(BuildReplacementVehicle(old_head, &new_head, true, same_type_only)); /* Was a new vehicle constructed? */ if (cost.Succeeded() && new_head != NULL) { @@ -660,7 +666,8 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon * @param tile not used * @param flags type of operation * @param p1 Index of vehicle - * @param p2 not used + * @param p2 packed data + * - bit 0 = Autoreplace with same type only * @param text unused * @return the cost of this operation or an error */ @@ -687,13 +694,14 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1 const Company *c = Company::Get(_current_company); bool wagon_removal = c->settings.renew_keep_length; + bool same_type_only = HasBit(p2, 0); /* Test whether any replacement is set, before issuing a whole lot of commands that would end in nothing changed */ Vehicle *w = v; bool any_replacements = false; while (w != NULL) { EngineID e; - CommandCost cost = GetNewEngineType(w, c, false, e); + CommandCost cost = GetNewEngineType(w, c, false, same_type_only, e); if (cost.Failed()) return cost; any_replacements |= (e != INVALID_ENGINE); w = (!free_wagon && w->type == VEH_TRAIN ? Train::From(w)->GetNextUnit() : NULL); @@ -717,18 +725,18 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1 SavedRandomSeeds saved_seeds; SaveRandomSeeds(&saved_seeds); if (free_wagon) { - cost.AddCost(ReplaceFreeUnit(&v, flags & ~DC_EXEC, ¬hing_to_do)); + cost.AddCost(ReplaceFreeUnit(&v, flags & ~DC_EXEC, ¬hing_to_do, same_type_only)); } else { - cost.AddCost(ReplaceChain(&v, flags & ~DC_EXEC, wagon_removal, ¬hing_to_do)); + cost.AddCost(ReplaceChain(&v, flags & ~DC_EXEC, wagon_removal, ¬hing_to_do, same_type_only)); } RestoreRandomSeeds(saved_seeds); if (cost.Succeeded() && (flags & DC_EXEC) != 0) { CommandCost ret; if (free_wagon) { - ret = ReplaceFreeUnit(&v, flags, ¬hing_to_do); + ret = ReplaceFreeUnit(&v, flags, ¬hing_to_do, same_type_only); } else { - ret = ReplaceChain(&v, flags, wagon_removal, ¬hing_to_do); + ret = ReplaceChain(&v, flags, wagon_removal, ¬hing_to_do, same_type_only); } assert(ret.Succeeded() && ret.GetCost() == cost.GetCost()); } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 4f92b0ad5d..774339ad06 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -4300,6 +4300,8 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3 } EngineID eid = tv->engine_type; + _new_vehicle_id = p1; + CommandCost buy(EXPENSES_NEW_VEHICLES); CommandCost move_cost(EXPENSES_NEW_VEHICLES); CommandCost tmp_result(EXPENSES_NEW_VEHICLES); @@ -4474,5 +4476,7 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3 /* Redraw main gui for changed statistics */ SetWindowClassesDirty(WC_TEMPLATEGUI_MAIN); + _new_vehicle_id = new_chain->index; + return buy; } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index e87661093c..21542febf1 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1053,6 +1053,16 @@ void CallVehicleTicks() it->first->vehstatus |= VS_STOPPED; CommandCost res = DoCommand(t->tile, t->index, stayInDepot ? 1 : 0, DC_EXEC, CMD_TEMPLATE_REPLACE_VEHICLE); + if (res.Succeeded()) { + VehicleID t_new = _new_vehicle_id; + t = Train::From(Vehicle::Get(t_new)); + const Company *c = Company::Get(_current_company); + SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, (Money)c->settings.engine_renew_money)); + CommandCost res2 = DoCommand(0, t_new, 1, DC_EXEC, CMD_AUTOREPLACE_VEHICLE); + SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, -(Money)c->settings.engine_renew_money)); + if (res2.Succeeded() || res.GetCost() == 0) res.AddCost(res2); + } + if (!IsLocalCompany()) continue; if (res.Succeeded()) {