Skip to content

Commit

Permalink
TBTR: Implement cost estimation for template replacement
Browse files Browse the repository at this point in the history
Simplified operation, CMD_NO_TEST is still in use
  • Loading branch information
JGRennison committed Sep 23, 2023
1 parent 1e7f31b commit 90192f9
Showing 1 changed file with 54 additions and 6 deletions.
60 changes: 54 additions & 6 deletions src/train_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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
Expand Down

0 comments on commit 90192f9

Please sign in to comment.