TBTR: Enable autorenew when template replacement active

pull/73/head
Jonathan G Rennison 6 years ago
parent 64d9f88802
commit 4a9df57665

@ -238,10 +238,11 @@ static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, bool
* @param v The vehicle to find a replacement for * @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 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 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 * @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 * @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()); assert(v->type != VEH_TRAIN || !v->IsArticulatedPart());
@ -252,9 +253,11 @@ static CommandCost GetNewEngineType(const Vehicle *v, const Company *c, bool alw
return CommandCost(); return CommandCost();
} }
bool replace_when_old; if (!same_type_only) {
e = EngineReplacementForCompany(c, v->engine_type, v->group_id, &replace_when_old); bool replace_when_old;
if (!always_replace && replace_when_old && !v->NeedsAutorenewing(c, false)) e = INVALID_ENGINE; 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 */ /* Autoreplace, if engine is available */
if (e != INVALID_ENGINE && IsEngineBuildable(e, v->type, _current_company)) { 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 old_veh A single (articulated/multiheaded) vehicle that shall be replaced.
* @param new_vehicle Returns the newly build and refitted vehicle * @param new_vehicle Returns the newly build and refitted vehicle
* @param part_of_chain The vehicle is part of a train * @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 * @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; *new_vehicle = NULL;
/* Shall the vehicle be replaced? */ /* Shall the vehicle be replaced? */
const Company *c = Company::Get(_current_company); const Company *c = Company::Get(_current_company);
EngineID e; 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 (cost.Failed()) return cost;
if (e == INVALID_ENGINE) return CommandCost(); // neither autoreplace is set, nor autorenew is triggered 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 single_unit vehicle to let autoreplace/renew operator on
* @param flags command flags * @param flags command flags
* @param nothing_to_do is set to 'false' when something was done (only valid when not failed) * @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 * @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); Train *old_v = Train::From(*single_unit);
assert(!old_v->IsArticulatedPart() && !old_v->IsRearDualheaded()); 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 */ /* Build and refit replacement vehicle */
Vehicle *new_v = NULL; 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? */ /* Was a new vehicle constructed? */
if (cost.Succeeded() && new_v != NULL) { if (cost.Succeeded() && new_v != NULL) {
@ -436,9 +441,10 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b
* @param flags command flags * @param flags command flags
* @param wagon_removal remove wagons when the resulting chain occupies more tiles than the old did * @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 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 * @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; Vehicle *old_head = *chain;
assert(old_head->IsPrimaryVehicle()); assert(old_head->IsPrimaryVehicle());
@ -464,7 +470,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
assert(i < num_units); assert(i < num_units);
old_vehs[i] = w; 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); cost.AddCost(ret);
if (cost.Failed()) break; if (cost.Failed()) break;
@ -624,7 +630,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
} else { } else {
/* Build and refit replacement vehicle */ /* Build and refit replacement vehicle */
Vehicle *new_head = NULL; 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? */ /* Was a new vehicle constructed? */
if (cost.Succeeded() && new_head != NULL) { if (cost.Succeeded() && new_head != NULL) {
@ -660,7 +666,8 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
* @param tile not used * @param tile not used
* @param flags type of operation * @param flags type of operation
* @param p1 Index of vehicle * @param p1 Index of vehicle
* @param p2 not used * @param p2 packed data
* - bit 0 = Autoreplace with same type only
* @param text unused * @param text unused
* @return the cost of this operation or an error * @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); const Company *c = Company::Get(_current_company);
bool wagon_removal = c->settings.renew_keep_length; 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 */ /* Test whether any replacement is set, before issuing a whole lot of commands that would end in nothing changed */
Vehicle *w = v; Vehicle *w = v;
bool any_replacements = false; bool any_replacements = false;
while (w != NULL) { while (w != NULL) {
EngineID e; EngineID e;
CommandCost cost = GetNewEngineType(w, c, false, e); CommandCost cost = GetNewEngineType(w, c, false, same_type_only, e);
if (cost.Failed()) return cost; if (cost.Failed()) return cost;
any_replacements |= (e != INVALID_ENGINE); any_replacements |= (e != INVALID_ENGINE);
w = (!free_wagon && w->type == VEH_TRAIN ? Train::From(w)->GetNextUnit() : NULL); 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; SavedRandomSeeds saved_seeds;
SaveRandomSeeds(&saved_seeds); SaveRandomSeeds(&saved_seeds);
if (free_wagon) { if (free_wagon) {
cost.AddCost(ReplaceFreeUnit(&v, flags & ~DC_EXEC, &nothing_to_do)); cost.AddCost(ReplaceFreeUnit(&v, flags & ~DC_EXEC, &nothing_to_do, same_type_only));
} else { } else {
cost.AddCost(ReplaceChain(&v, flags & ~DC_EXEC, wagon_removal, &nothing_to_do)); cost.AddCost(ReplaceChain(&v, flags & ~DC_EXEC, wagon_removal, &nothing_to_do, same_type_only));
} }
RestoreRandomSeeds(saved_seeds); RestoreRandomSeeds(saved_seeds);
if (cost.Succeeded() && (flags & DC_EXEC) != 0) { if (cost.Succeeded() && (flags & DC_EXEC) != 0) {
CommandCost ret; CommandCost ret;
if (free_wagon) { if (free_wagon) {
ret = ReplaceFreeUnit(&v, flags, &nothing_to_do); ret = ReplaceFreeUnit(&v, flags, &nothing_to_do, same_type_only);
} else { } else {
ret = ReplaceChain(&v, flags, wagon_removal, &nothing_to_do); ret = ReplaceChain(&v, flags, wagon_removal, &nothing_to_do, same_type_only);
} }
assert(ret.Succeeded() && ret.GetCost() == cost.GetCost()); assert(ret.Succeeded() && ret.GetCost() == cost.GetCost());
} }

@ -4300,6 +4300,8 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3
} }
EngineID eid = tv->engine_type; EngineID eid = tv->engine_type;
_new_vehicle_id = p1;
CommandCost buy(EXPENSES_NEW_VEHICLES); CommandCost buy(EXPENSES_NEW_VEHICLES);
CommandCost move_cost(EXPENSES_NEW_VEHICLES); CommandCost move_cost(EXPENSES_NEW_VEHICLES);
CommandCost tmp_result(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 */ /* Redraw main gui for changed statistics */
SetWindowClassesDirty(WC_TEMPLATEGUI_MAIN); SetWindowClassesDirty(WC_TEMPLATEGUI_MAIN);
_new_vehicle_id = new_chain->index;
return buy; return buy;
} }

@ -1053,6 +1053,16 @@ void CallVehicleTicks()
it->first->vehstatus |= VS_STOPPED; it->first->vehstatus |= VS_STOPPED;
CommandCost res = DoCommand(t->tile, t->index, stayInDepot ? 1 : 0, DC_EXEC, CMD_TEMPLATE_REPLACE_VEHICLE); 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 (!IsLocalCompany()) continue;
if (res.Succeeded()) { if (res.Succeeded()) {

Loading…
Cancel
Save