TBTR: Implement cost estimation for template replacement

Simplified operation, CMD_NO_TEST is still in use
This commit is contained in:
Jonathan G Rennison 2023-09-23 18:56:05 +01:00
parent 1e7f31b807
commit 90192f9537

View File

@ -7175,10 +7175,6 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3
return CMD_ERROR;
}
if (!(flags & DC_EXEC)) {
return CommandCost();
}
CommandCost buy(EXPENSES_NEW_VEHICLES);
const bool was_stopped = (incoming->vehstatus & VS_STOPPED) != 0;
@ -7235,8 +7231,6 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3
}
}
RegisterGameEvents(GEF_TBTR_REPLACEMENT);
TemplateDepotVehicles depot_vehicles;
if (tv->IsSetReuseDepotVehicles()) depot_vehicles.Init(tile);
@ -7245,6 +7239,60 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3
if (refit_cost.Succeeded()) buy.AddCost(refit_cost);
};
if (!(flags & DC_EXEC)) {
/* Simplified operation for cost estimation, this doesn't have to exactly match the actual cost due to CMD_NO_TEST */
if (need_replacement || need_refit) {
std::vector<const Train *> in;
for (const Train *u = incoming; u != nullptr; u = u->GetNextUnit()) {
in.push_back(u);
}
auto process_unit = [&](const TemplateVehicle *cur_tmpl) {
for (auto iter = in.begin(); iter != in.end(); ++iter) {
const Train *u = *iter;
if (u->engine_type == cur_tmpl->engine_type) {
/* use existing engine */
in.erase(iter);
if (refit_to_template) {
buy.AddCost(DoCommand(u->tile, u->index, cur_tmpl->cargo_type | cur_tmpl->cargo_subtype << 8 | (1 << 16) | (1 << 31), flags, GetCmdRefitVeh(u)));
} else {
refit_unit(u, store_refit_ct, store_refit_csubt);
}
return;
}
}
if (tv->IsSetReuseDepotVehicles()) {
const Train *depot_eng = depot_vehicles.ContainsEngine(cur_tmpl->engine_type, incoming);
if (depot_eng != nullptr) {
depot_vehicles.RemoveVehicle(depot_eng->index);
if (refit_to_template) {
buy.AddCost(DoCommand(depot_eng->tile, depot_eng->index, cur_tmpl->cargo_type | cur_tmpl->cargo_subtype << 8 | (1 << 16) | (1 << 31), flags, GetCmdRefitVeh(depot_eng)));
} else {
refit_unit(depot_eng, store_refit_ct, store_refit_csubt);
}
return;
}
}
CargoID refit_cargo = refit_to_template ? cur_tmpl->cargo_type : store_refit_ct;
uint32 refit_cmd = (refit_cargo != CT_INVALID) ? (refit_cargo << 24) : 0;
buy.AddCost(DoCommand(tile, cur_tmpl->engine_type | (1 << 16) | refit_cmd, 0, flags, CMD_BUILD_VEHICLE));
};
for (const TemplateVehicle *cur_tmpl = tv; cur_tmpl != nullptr; cur_tmpl = cur_tmpl->GetNextUnit()) {
process_unit(cur_tmpl);
}
if (!tv->IsSetKeepRemainingVehicles()) {
/* Sell leftovers */
for (const Train *u : in) {
buy.AddCost(DoCommand(u->tile, u->index, 0, flags, CMD_SELL_VEHICLE));
}
}
}
return buy;
}
RegisterGameEvents(GEF_TBTR_REPLACEMENT);
if (need_replacement) {
// step 1: generate primary for newchain and generate remainder_chain
// 1. primary of incoming might already fit the template