Fix #10032: Capacities of articulated vehicles in build window

See also: #9954
This commit is contained in:
Jonathan G Rennison
2023-01-06 20:21:27 +00:00
committed by rubidium42
parent 07fba75238
commit 10e76b2788
13 changed files with 115 additions and 94 deletions

View File

@@ -553,18 +553,29 @@ static GUIEngineList::FilterFunction * const _filter_funcs[] = {
&CargoAndEngineFilter,
};
static int DrawCargoCapacityInfo(int left, int right, int y, EngineID engine, TestedEngineDetails &te)
static uint GetCargoWeight(const CargoArray &cap, VehicleType vtype)
{
CargoArray cap;
CargoTypes refits;
GetArticulatedVehicleCargoesAndRefits(engine, &cap, &refits, te.cargo, te.capacity);
uint weight = 0;
for (CargoID c = 0; c < NUM_CARGO; c++) {
if (cap[c] == 0) continue;
if (cap[c] != 0) {
if (vtype == VEH_TRAIN) {
weight += CargoSpec::Get(c)->WeightOfNUnitsInTrain(cap[c]);
} else {
weight += CargoSpec::Get(c)->WeightOfNUnits(cap[c]);
}
}
}
return weight;
}
static int DrawCargoCapacityInfo(int left, int right, int y, TestedEngineDetails &te, bool refittable)
{
for (CargoID c = 0; c < NUM_CARGO; c++) {
if (te.all_capacities[c] == 0) continue;
SetDParam(0, c);
SetDParam(1, cap[c]);
SetDParam(2, HasBit(refits, c) ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY);
SetDParam(1, te.all_capacities[c]);
SetDParam(2, refittable ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY);
DrawString(left, right, y, STR_PURCHASE_INFO_CAPACITY);
y += FONT_HEIGHT_NORMAL;
}
@@ -591,8 +602,7 @@ static int DrawRailWagonPurchaseInfo(int left, int right, int y, EngineID engine
/* Wagon weight - (including cargo) */
uint weight = e->GetDisplayWeight();
SetDParam(0, weight);
uint cargo_weight = (e->CanCarryCargo() ? CargoSpec::Get(te.cargo)->WeightOfNUnitsInTrain(te.capacity) : 0);
SetDParam(1, cargo_weight + weight);
SetDParam(1, GetCargoWeight(te.all_capacities, VEH_TRAIN) + weight);
DrawString(left, right, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT);
y += FONT_HEIGHT_NORMAL;
@@ -685,8 +695,7 @@ static int DrawRoadVehPurchaseInfo(int left, int right, int y, EngineID engine_n
/* Road vehicle weight - (including cargo) */
int16 weight = e->GetDisplayWeight();
SetDParam(0, weight);
uint cargo_weight = (e->CanCarryCargo() ? CargoSpec::Get(te.cargo)->WeightOfNUnits(te.capacity) : 0);
SetDParam(1, cargo_weight + weight);
SetDParam(1, GetCargoWeight(te.all_capacities, VEH_ROAD) + weight);
DrawString(left, right, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT);
y += FONT_HEIGHT_NORMAL;
@@ -868,6 +877,21 @@ static uint ShowAdditionalText(int left, int right, int y, EngineID engine)
return result;
}
void TestedEngineDetails::FillDefaultCapacities(const Engine *e)
{
this->cargo = e->GetDefaultCargoType();
if (e->type == VEH_TRAIN || e->type == VEH_ROAD) {
this->all_capacities = GetCapacityOfArticulatedParts(e->index);
this->capacity = this->all_capacities[this->cargo];
this->mail_capacity = 0;
} else {
this->capacity = e->GetDisplayDefaultCapacity(&this->mail_capacity);
this->all_capacities[this->cargo] = this->capacity;
this->all_capacities[CT_MAIL] = this->mail_capacity;
}
if (this->all_capacities.GetCount() == 0) this->cargo = CT_INVALID;
}
/**
* Draw the purchase info details of a vehicle at a given location.
* @param left,right,y location where to draw the info
@@ -909,7 +933,7 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number,
if (articulated_cargo) {
/* Cargo type + capacity, or N/A */
int new_y = DrawCargoCapacityInfo(left, right, y, engine_number, te);
int new_y = DrawCargoCapacityInfo(left, right, y, te, refittable);
if (new_y == y) {
SetDParam(0, CT_INVALID);
@@ -1261,28 +1285,23 @@ struct BuildVehicleWindow : Window {
if (this->sel_engine == INVALID_ENGINE) return;
const Engine *e = Engine::Get(this->sel_engine);
if (!e->CanCarryCargo()) {
this->te.cost = 0;
this->te.cargo = CT_INVALID;
return;
}
if (!this->listview_mode) {
/* Query for cost and refitted capacity */
auto [ret, veh_id, refit_capacity, refit_mail] = Command<CMD_BUILD_VEHICLE>::Do(DC_QUERY_COST, this->window_number, this->sel_engine, true, cargo, INVALID_CLIENT_ID);
auto [ret, veh_id, refit_capacity, refit_mail, cargo_capacities] = Command<CMD_BUILD_VEHICLE>::Do(DC_QUERY_COST, this->window_number, this->sel_engine, true, cargo, INVALID_CLIENT_ID);
if (ret.Succeeded()) {
this->te.cost = ret.GetCost() - e->GetCost();
this->te.capacity = refit_capacity;
this->te.mail_capacity = refit_mail;
this->te.cargo = (cargo == CT_INVALID) ? e->GetDefaultCargoType() : cargo;
this->te.all_capacities = cargo_capacities;
return;
}
}
/* Purchase test was not possible or failed, fill in the defaults instead. */
this->te.cost = 0;
this->te.capacity = e->GetDisplayDefaultCapacity(&this->te.mail_capacity);
this->te.cargo = e->GetDefaultCargoType();
this->te.FillDefaultCapacities(e);
}
void OnInit() override