1
0
Fork 0

Codechange: Use parameterised-GetString for vehicle related windows.

pull/13636/head
Peter Nelson 2025-02-21 23:38:34 +00:00 committed by Peter Nelson
parent 0428f8c667
commit 24d327a30b
10 changed files with 301 additions and 461 deletions

View File

@ -34,18 +34,14 @@ void DrawAircraftDetails(const Aircraft *v, const Rect &r)
int y = r.top;
for (const Aircraft *u = v; u != nullptr; u = u->Next()) {
if (u->IsNormalAircraft()) {
SetDParam(0, PackEngineNameDParam(u->engine_type, EngineNameContext::VehicleDetails));
SetDParam(1, u->build_year);
SetDParam(2, u->value);
DrawString(r.left, r.right, y, STR_VEHICLE_INFO_BUILT_VALUE);
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_INFO_BUILT_VALUE, PackEngineNameDParam(u->engine_type, EngineNameContext::VehicleDetails), u->build_year, u->value));
y += GetCharacterHeight(FS_NORMAL);
SetDParam(0, u->cargo_type);
SetDParam(1, u->cargo_cap);
SetDParam(2, u->Next()->cargo_type);
SetDParam(3, u->Next()->cargo_cap);
SetDParam(4, GetCargoSubtypeText(u));
DrawString(r.left, r.right, y, (u->Next()->cargo_cap != 0) ? STR_VEHICLE_INFO_CAPACITY_CAPACITY : STR_VEHICLE_INFO_CAPACITY);
if (u->Next()->cargo_cap != 0) {
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_INFO_CAPACITY_CAPACITY, u->cargo_type, u->cargo_cap, u->Next()->cargo_type, u->Next()->cargo_cap, GetCargoSubtypeText(u)));
} else {
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_INFO_CAPACITY, u->cargo_type, u->cargo_cap, GetCargoSubtypeText(u)));
}
y += GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal;
}
@ -54,10 +50,7 @@ void DrawAircraftDetails(const Aircraft *v, const Rect &r)
if (cargo_count != 0) {
/* Cargo names (fix pluralness) */
SetDParam(0, u->cargo_type);
SetDParam(1, cargo_count);
SetDParam(2, u->cargo.GetFirstStation());
DrawString(r.left, r.right, y, STR_VEHICLE_DETAILS_CARGO_FROM);
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_DETAILS_CARGO_FROM, u->cargo_type, cargo_count, u->cargo.GetFirstStation()));
y += GetCharacterHeight(FS_NORMAL);
feeder_share += u->cargo.GetFeederShare();
}
@ -65,8 +58,7 @@ void DrawAircraftDetails(const Aircraft *v, const Rect &r)
}
y += WidgetDimensions::scaled.vsep_normal;
SetDParam(0, feeder_share);
DrawString(r.left, r.right, y, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE);
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_INFO_FEEDER_CARGO_VALUE, feeder_share));
}

View File

@ -319,10 +319,9 @@ public:
case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: {
StringID str = this->GetWidget<NWidgetCore>(widget)->GetString();
SetDParam(0, STR_CONFIG_SETTING_ON);
Dimension d = GetStringBoundingBox(str);
SetDParam(0, STR_CONFIG_SETTING_OFF);
d = maxdim(d, GetStringBoundingBox(str));
StringID group_str = Group::IsValidID(this->sel_group) ? STR_GROUP_NAME : STR_GROUP_DEFAULT_TRAINS + this->window_number;
Dimension d = GetStringBoundingBox(GetString(str, group_str, this->sel_group, STR_CONFIG_SETTING_ON));
d = maxdim(d, GetStringBoundingBox(GetString(str, group_str, this->sel_group, STR_CONFIG_SETTING_OFF)));
d.width += padding.width;
d.height += padding.height;
size = maxdim(size, d);
@ -444,21 +443,20 @@ public:
case WID_RV_INFO_TAB: {
const Company *c = Company::Get(_local_company);
StringID str;
std::string str;
if (this->sel_engine[0] != EngineID::Invalid()) {
if (!EngineHasReplacementForCompany(c, this->sel_engine[0], this->sel_group)) {
str = STR_REPLACE_NOT_REPLACING;
str = GetString(STR_REPLACE_NOT_REPLACING);
} else {
bool when_old = false;
EngineID e = EngineReplacementForCompany(c, this->sel_engine[0], this->sel_group, &when_old);
str = when_old ? STR_REPLACE_REPLACING_WHEN_OLD : STR_ENGINE_NAME;
SetDParam(0, PackEngineNameDParam(e, EngineNameContext::PurchaseList));
str = GetString(when_old ? STR_REPLACE_REPLACING_WHEN_OLD : STR_ENGINE_NAME, PackEngineNameDParam(e, EngineNameContext::PurchaseList));
}
} else {
str = STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED;
str = GetString(STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED);
}
DrawString(r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect), str, TC_BLACK, SA_HOR_CENTER);
DrawString(r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect), std::move(str), TC_BLACK, SA_HOR_CENTER);
break;
}

View File

@ -570,10 +570,7 @@ static int DrawCargoCapacityInfo(int left, int right, int y, TestedEngineDetails
CargoType cargo_type = cs->Index();
if (te.all_capacities[cargo_type] == 0) continue;
SetDParam(0, cargo_type);
SetDParam(1, te.all_capacities[cargo_type]);
SetDParam(2, refittable ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY);
DrawString(left, right, y, STR_PURCHASE_INFO_CAPACITY);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_CAPACITY, cargo_type, te.all_capacities[cargo_type], refittable ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY));
y += GetCharacterHeight(FS_NORMAL);
}
@ -587,36 +584,30 @@ static int DrawRailWagonPurchaseInfo(int left, int right, int y, EngineID engine
/* Purchase cost */
if (te.cost != 0) {
SetDParam(0, e->GetCost() + te.cost);
SetDParam(1, te.cost);
DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST_REFIT, e->GetCost() + te.cost, te.cost));
} else {
SetDParam(0, e->GetCost());
DrawString(left, right, y, STR_PURCHASE_INFO_COST);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST, e->GetCost()));
}
y += GetCharacterHeight(FS_NORMAL);
/* Wagon weight - (including cargo) */
uint weight = e->GetDisplayWeight();
SetDParam(0, weight);
SetDParam(1, GetCargoWeight(te.all_capacities, VEH_TRAIN) + weight);
DrawString(left, right, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT);
DrawString(left, right, y,
GetString(STR_PURCHASE_INFO_WEIGHT_CWEIGHT, weight, GetCargoWeight(te.all_capacities, VEH_TRAIN) + weight));
y += GetCharacterHeight(FS_NORMAL);
/* Wagon speed limit, displayed if above zero */
if (_settings_game.vehicle.wagon_speed_limits) {
uint max_speed = e->GetDisplayMaxSpeed();
if (max_speed > 0) {
SetDParam(0, PackVelocity(max_speed, e->type));
DrawString(left, right, y, STR_PURCHASE_INFO_SPEED);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_SPEED, PackVelocity(max_speed, e->type)));
y += GetCharacterHeight(FS_NORMAL);
}
}
/* Running cost */
if (rvi->running_cost_class != INVALID_PRICE) {
SetDParam(0, e->GetRunningCost());
DrawString(left, right, y, TimerGameEconomy::UsingWallclockUnits() ? STR_PURCHASE_INFO_RUNNINGCOST_PERIOD : STR_PURCHASE_INFO_RUNNINGCOST_YEAR);
DrawString(left, right, y, GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_PURCHASE_INFO_RUNNINGCOST_PERIOD : STR_PURCHASE_INFO_RUNNINGCOST_YEAR, e->GetRunningCost()));
y += GetCharacterHeight(FS_NORMAL);
}
@ -630,42 +621,31 @@ static int DrawRailEnginePurchaseInfo(int left, int right, int y, EngineID engin
/* Purchase Cost - Engine weight */
if (te.cost != 0) {
SetDParam(0, e->GetCost() + te.cost);
SetDParam(1, te.cost);
SetDParam(2, e->GetDisplayWeight());
DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT_WEIGHT);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST_REFIT_WEIGHT, e->GetCost() + te.cost, te.cost, e->GetDisplayWeight()));
} else {
SetDParam(0, e->GetCost());
SetDParam(1, e->GetDisplayWeight());
DrawString(left, right, y, STR_PURCHASE_INFO_COST_WEIGHT);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST_WEIGHT, e->GetCost(), e->GetDisplayWeight()));
}
y += GetCharacterHeight(FS_NORMAL);
/* Max speed - Engine power */
SetDParam(0, PackVelocity(e->GetDisplayMaxSpeed(), e->type));
SetDParam(1, e->GetPower());
DrawString(left, right, y, STR_PURCHASE_INFO_SPEED_POWER);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_SPEED_POWER, PackVelocity(e->GetDisplayMaxSpeed(), e->type), e->GetPower()));
y += GetCharacterHeight(FS_NORMAL);
/* Max tractive effort - not applicable if old acceleration or maglev */
if (_settings_game.vehicle.train_acceleration_model != AM_ORIGINAL && GetRailTypeInfo(rvi->railtype)->acceleration_type != 2) {
SetDParam(0, e->GetDisplayMaxTractiveEffort());
DrawString(left, right, y, STR_PURCHASE_INFO_MAX_TE);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_MAX_TE, e->GetDisplayMaxTractiveEffort()));
y += GetCharacterHeight(FS_NORMAL);
}
/* Running cost */
if (rvi->running_cost_class != INVALID_PRICE) {
SetDParam(0, e->GetRunningCost());
DrawString(left, right, y, TimerGameEconomy::UsingWallclockUnits() ? STR_PURCHASE_INFO_RUNNINGCOST_PERIOD : STR_PURCHASE_INFO_RUNNINGCOST_YEAR);
DrawString(left, right, y, GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_PURCHASE_INFO_RUNNINGCOST_PERIOD : STR_PURCHASE_INFO_RUNNINGCOST_YEAR, e->GetRunningCost()));
y += GetCharacterHeight(FS_NORMAL);
}
/* Powered wagons power - Powered wagons extra weight */
if (rvi->pow_wag_power != 0) {
SetDParam(0, rvi->pow_wag_power);
SetDParam(1, rvi->pow_wag_weight);
DrawString(left, right, y, STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT, rvi->pow_wag_power, rvi->pow_wag_weight));
y += GetCharacterHeight(FS_NORMAL);
}
@ -680,50 +660,36 @@ static int DrawRoadVehPurchaseInfo(int left, int right, int y, EngineID engine_n
if (_settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL) {
/* Purchase Cost */
if (te.cost != 0) {
SetDParam(0, e->GetCost() + te.cost);
SetDParam(1, te.cost);
DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST_REFIT, e->GetCost() + te.cost, te.cost));
} else {
SetDParam(0, e->GetCost());
DrawString(left, right, y, STR_PURCHASE_INFO_COST);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST, e->GetCost()));
}
y += GetCharacterHeight(FS_NORMAL);
/* Road vehicle weight - (including cargo) */
int16_t weight = e->GetDisplayWeight();
SetDParam(0, weight);
SetDParam(1, GetCargoWeight(te.all_capacities, VEH_ROAD) + weight);
DrawString(left, right, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_WEIGHT_CWEIGHT, weight, GetCargoWeight(te.all_capacities, VEH_ROAD) + weight));
y += GetCharacterHeight(FS_NORMAL);
/* Max speed - Engine power */
SetDParam(0, PackVelocity(e->GetDisplayMaxSpeed(), e->type));
SetDParam(1, e->GetPower());
DrawString(left, right, y, STR_PURCHASE_INFO_SPEED_POWER);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_SPEED_POWER, PackVelocity(e->GetDisplayMaxSpeed(), e->type), e->GetPower()));
y += GetCharacterHeight(FS_NORMAL);
/* Max tractive effort */
SetDParam(0, e->GetDisplayMaxTractiveEffort());
DrawString(left, right, y, STR_PURCHASE_INFO_MAX_TE);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_MAX_TE, e->GetDisplayMaxTractiveEffort()));
y += GetCharacterHeight(FS_NORMAL);
} else {
/* Purchase cost - Max speed */
if (te.cost != 0) {
SetDParam(0, e->GetCost() + te.cost);
SetDParam(1, te.cost);
SetDParam(2, PackVelocity(e->GetDisplayMaxSpeed(), e->type));
DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT_SPEED);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST_REFIT_SPEED, e->GetCost() + te.cost, te.cost, PackVelocity(e->GetDisplayMaxSpeed(), e->type)));
} else {
SetDParam(0, e->GetCost());
SetDParam(1, PackVelocity(e->GetDisplayMaxSpeed(), e->type));
DrawString(left, right, y, STR_PURCHASE_INFO_COST_SPEED);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST_SPEED, e->GetCost(), PackVelocity(e->GetDisplayMaxSpeed(), e->type)));
}
y += GetCharacterHeight(FS_NORMAL);
}
/* Running cost */
SetDParam(0, e->GetRunningCost());
DrawString(left, right, y, TimerGameEconomy::UsingWallclockUnits() ? STR_PURCHASE_INFO_RUNNINGCOST_PERIOD : STR_PURCHASE_INFO_RUNNINGCOST_YEAR);
DrawString(left, right, y, GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_PURCHASE_INFO_RUNNINGCOST_PERIOD : STR_PURCHASE_INFO_RUNNINGCOST_YEAR, e->GetRunningCost()));
y += GetCharacterHeight(FS_NORMAL);
return y;
@ -741,46 +707,32 @@ static int DrawShipPurchaseInfo(int left, int right, int y, EngineID engine_numb
if (ocean_speed == canal_speed) {
if (te.cost != 0) {
SetDParam(0, e->GetCost() + te.cost);
SetDParam(1, te.cost);
SetDParam(2, PackVelocity(ocean_speed, e->type));
DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT_SPEED);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST_REFIT_SPEED, e->GetCost() + te.cost, te.cost, PackVelocity(ocean_speed, e->type)));
} else {
SetDParam(0, e->GetCost());
SetDParam(1, PackVelocity(ocean_speed, e->type));
DrawString(left, right, y, STR_PURCHASE_INFO_COST_SPEED);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST_SPEED, e->GetCost(), PackVelocity(ocean_speed, e->type)));
}
y += GetCharacterHeight(FS_NORMAL);
} else {
if (te.cost != 0) {
SetDParam(0, e->GetCost() + te.cost);
SetDParam(1, te.cost);
DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST_REFIT, e->GetCost() + te.cost, te.cost));
} else {
SetDParam(0, e->GetCost());
DrawString(left, right, y, STR_PURCHASE_INFO_COST);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST, e->GetCost()));
}
y += GetCharacterHeight(FS_NORMAL);
SetDParam(0, PackVelocity(ocean_speed, e->type));
DrawString(left, right, y, STR_PURCHASE_INFO_SPEED_OCEAN);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_SPEED_OCEAN, PackVelocity(ocean_speed, e->type)));
y += GetCharacterHeight(FS_NORMAL);
SetDParam(0, PackVelocity(canal_speed, e->type));
DrawString(left, right, y, STR_PURCHASE_INFO_SPEED_CANAL);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_SPEED_CANAL, PackVelocity(canal_speed, e->type)));
y += GetCharacterHeight(FS_NORMAL);
}
/* Cargo type + capacity */
SetDParam(0, te.cargo);
SetDParam(1, te.capacity);
SetDParam(2, refittable ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY);
DrawString(left, right, y, STR_PURCHASE_INFO_CAPACITY);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_CAPACITY, te.cargo, te.capacity, refittable ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY));
y += GetCharacterHeight(FS_NORMAL);
/* Running cost */
SetDParam(0, e->GetRunningCost());
DrawString(left, right, y, TimerGameEconomy::UsingWallclockUnits() ? STR_PURCHASE_INFO_RUNNINGCOST_PERIOD : STR_PURCHASE_INFO_RUNNINGCOST_YEAR);
DrawString(left, right, y, GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_PURCHASE_INFO_RUNNINGCOST_PERIOD : STR_PURCHASE_INFO_RUNNINGCOST_YEAR, e->GetRunningCost()));
y += GetCharacterHeight(FS_NORMAL);
return y;
@ -801,49 +753,34 @@ static int DrawAircraftPurchaseInfo(int left, int right, int y, EngineID engine_
/* Purchase cost - Max speed */
if (te.cost != 0) {
SetDParam(0, e->GetCost() + te.cost);
SetDParam(1, te.cost);
SetDParam(2, PackVelocity(e->GetDisplayMaxSpeed(), e->type));
DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT_SPEED);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST_REFIT_SPEED, e->GetCost() + te.cost, te.cost, PackVelocity(e->GetDisplayMaxSpeed(), e->type)));
} else {
SetDParam(0, e->GetCost());
SetDParam(1, PackVelocity(e->GetDisplayMaxSpeed(), e->type));
DrawString(left, right, y, STR_PURCHASE_INFO_COST_SPEED);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_COST_SPEED, e->GetCost(), PackVelocity(e->GetDisplayMaxSpeed(), e->type)));
}
y += GetCharacterHeight(FS_NORMAL);
/* Cargo capacity */
if (te.mail_capacity > 0) {
SetDParam(0, te.cargo);
SetDParam(1, te.capacity);
SetDParam(2, GetCargoTypeByLabel(CT_MAIL));
SetDParam(3, te.mail_capacity);
DrawString(left, right, y, STR_PURCHASE_INFO_AIRCRAFT_CAPACITY);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_AIRCRAFT_CAPACITY, te.cargo, te.capacity, GetCargoTypeByLabel(CT_MAIL), te.mail_capacity));
} else {
/* Note, if the default capacity is selected by the refit capacity
* callback, then the capacity shown is likely to be incorrect. */
SetDParam(0, te.cargo);
SetDParam(1, te.capacity);
SetDParam(2, refittable ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY);
DrawString(left, right, y, STR_PURCHASE_INFO_CAPACITY);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_CAPACITY, te.cargo, te.capacity, refittable ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY));
}
y += GetCharacterHeight(FS_NORMAL);
/* Running cost */
SetDParam(0, e->GetRunningCost());
DrawString(left, right, y, TimerGameEconomy::UsingWallclockUnits() ? STR_PURCHASE_INFO_RUNNINGCOST_PERIOD : STR_PURCHASE_INFO_RUNNINGCOST_YEAR);
DrawString(left, right, y, GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_PURCHASE_INFO_RUNNINGCOST_PERIOD : STR_PURCHASE_INFO_RUNNINGCOST_YEAR, e->GetRunningCost()));
y += GetCharacterHeight(FS_NORMAL);
/* Aircraft type */
SetDParam(0, e->GetAircraftTypeText());
DrawString(left, right, y, STR_PURCHASE_INFO_AIRCRAFT_TYPE);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_AIRCRAFT_TYPE, e->GetAircraftTypeText()));
y += GetCharacterHeight(FS_NORMAL);
/* Aircraft range, if available. */
uint16_t range = e->GetRange();
if (range != 0) {
SetDParam(0, range);
DrawString(left, right, y, STR_PURCHASE_INFO_AIRCRAFT_RANGE);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_AIRCRAFT_RANGE, range));
y += GetCharacterHeight(FS_NORMAL);
}
@ -950,9 +887,7 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number,
int new_y = DrawCargoCapacityInfo(left, right, y, te, refittable);
if (new_y == y) {
SetDParam(0, INVALID_CARGO);
SetDParam(2, STR_EMPTY);
DrawString(left, right, y, STR_PURCHASE_INFO_CAPACITY);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_CAPACITY, INVALID_CARGO, 0, STR_EMPTY));
y += GetCharacterHeight(FS_NORMAL);
} else {
y = new_y;
@ -962,14 +897,11 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number,
/* Draw details that apply to all types except rail wagons. */
if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
/* Design date - Life length */
SetDParam(0, ymd.year);
SetDParam(1, TimerGameCalendar::DateToYear(e->GetLifeLengthInDays()));
DrawString(left, right, y, STR_PURCHASE_INFO_DESIGNED_LIFE);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_DESIGNED_LIFE, ymd.year, TimerGameCalendar::DateToYear(e->GetLifeLengthInDays())));
y += GetCharacterHeight(FS_NORMAL);
/* Reliability */
SetDParam(0, ToPercent16(e->reliability));
DrawString(left, right, y, STR_PURCHASE_INFO_RELIABILITY);
DrawString(left, right, y, GetString(STR_PURCHASE_INFO_RELIABILITY, ToPercent16(e->reliability)));
y += GetCharacterHeight(FS_NORMAL);
}
@ -1036,8 +968,7 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li
biggest_num_engines = std::max(biggest_num_engines, num_engines);
}
SetDParam(0, biggest_num_engines);
count_width = GetStringBoundingBox(STR_JUST_COMMA, FS_SMALL).width;
count_width = GetStringBoundingBox(GetString(STR_JUST_COMMA, biggest_num_engines), FS_SMALL).width;
}
const int text_row_height = ir.Shrink(WidgetDimensions::scaled.matrix).Height();
@ -1108,8 +1039,7 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li
Rect cr = tr.WithWidth(count_width, !rtl);
tr = tr.Indent(count_width + WidgetDimensions::scaled.hsep_normal, !rtl);
SetDParam(0, num_engines);
DrawString(cr.left, cr.right, textr.top + small_text_y_offset, STR_JUST_COMMA, TC_BLACK, SA_RIGHT | SA_FORCE, false, FS_SMALL);
DrawString(cr.left, cr.right, textr.top + small_text_y_offset, GetString(STR_JUST_COMMA, num_engines), TC_BLACK, SA_RIGHT | SA_FORCE, false, FS_SMALL);
if (EngineHasReplacementForCompany(Company::Get(_local_company), item.engine_id, selected_group)) {
DrawSpriteIgnorePadding(SPR_GROUP_REPLACE_ACTIVE, num_engines == 0 ? PALETTE_CRASH : PAL_NONE, rr, SA_CENTER);
@ -1126,13 +1056,9 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li
StringID str = hidden ? STR_HIDDEN_ENGINE_NAME : STR_ENGINE_NAME;
TextColour tc = (item.engine_id == selected_id) ? TC_WHITE : ((hidden | shaded) ? (TC_GREY | TC_FORCED | TC_NO_SHADE) : TC_BLACK);
if (show_count) {
/* relies on show_count to find 'Vehicle in use' panel of autoreplace window */
SetDParam(0, PackEngineNameDParam(item.engine_id, EngineNameContext::AutoreplaceVehicleInUse, item.indent));
} else {
SetDParam(0, PackEngineNameDParam(item.engine_id, EngineNameContext::PurchaseList, item.indent));
}
DrawString(tr.left, tr.right, textr.top + normal_text_y_offset, str, tc);
/* If the count is visible then this is part of in-use autoreplace list. */
auto engine_name = PackEngineNameDParam(item.engine_id, show_count ? EngineNameContext::AutoreplaceVehicleInUse : EngineNameContext::PurchaseList, item.indent);
DrawString(tr.left, tr.right, textr.top + normal_text_y_offset,GetString(str, engine_name), tc);
ir = ir.Translate(0, step_size);
}

View File

@ -99,9 +99,7 @@ struct EnginePreviewWindow : Window {
this->vehicle_space = std::max<int>(ScaleSpriteTrad(40), y - y_offs);
size.width = std::max(size.width, x + std::abs(x_offs));
SetDParam(0, GetEngineCategoryName(engine));
size.height = GetStringHeight(STR_ENGINE_PREVIEW_MESSAGE, size.width) + WidgetDimensions::scaled.vsep_wide + GetCharacterHeight(FS_NORMAL) + this->vehicle_space;
SetDParam(0, engine);
size.height = GetStringHeight(GetString(STR_ENGINE_PREVIEW_MESSAGE, GetEngineCategoryName(engine)), size.width) + WidgetDimensions::scaled.vsep_wide + GetCharacterHeight(FS_NORMAL) + this->vehicle_space;
size.height += GetStringHeight(GetEngineInfoString(engine), size.width);
}
@ -110,11 +108,9 @@ struct EnginePreviewWindow : Window {
if (widget != WID_EP_QUESTION) return;
EngineID engine = static_cast<EngineID>(this->window_number);
SetDParam(0, GetEngineCategoryName(engine));
int y = DrawStringMultiLine(r, STR_ENGINE_PREVIEW_MESSAGE, TC_FROMSTRING, SA_HOR_CENTER | SA_TOP) + WidgetDimensions::scaled.vsep_wide;
int y = DrawStringMultiLine(r, GetString(STR_ENGINE_PREVIEW_MESSAGE, GetEngineCategoryName(engine)), TC_FROMSTRING, SA_HOR_CENTER | SA_TOP) + WidgetDimensions::scaled.vsep_wide;
SetDParam(0, PackEngineNameDParam(engine, EngineNameContext::PreviewNews));
DrawString(r.left, r.right, y, STR_ENGINE_NAME, TC_BLACK, SA_HOR_CENTER);
DrawString(r.left, r.right, y, GetString(STR_ENGINE_NAME, PackEngineNameDParam(engine, EngineNameContext::PreviewNews)), TC_BLACK, SA_HOR_CENTER);
y += GetCharacterHeight(FS_NORMAL);
DrawVehicleEngine(r.left, r.right, this->width >> 1, y + this->vehicle_space / 2, engine, GetEnginePalette(engine, _local_company), EIT_PREVIEW);

View File

@ -4156,7 +4156,7 @@ STR_PURCHASE_INFO_COST_SPEED :{BLACK}Cost: {G
STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} (Refit Cost: {GOLD}{CURRENCY_LONG}{BLACK}) Speed: {GOLD}{VELOCITY}
STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacity: {GOLD}{CARGO_LONG}, {CARGO_LONG}
STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Powered Wagons: {GOLD}+{POWER}{BLACK} Weight: {GOLD}+{WEIGHT_SHORT}
STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Refittable to: {GOLD}{STRING2}
STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Refittable to: {GOLD}{STRING1}
STR_PURCHASE_INFO_ALL_TYPES :All cargo types
STR_PURCHASE_INFO_NONE :None
STR_PURCHASE_INFO_ENGINES_ONLY :Engines only
@ -4505,8 +4505,8 @@ STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Reliabil
STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY_LONG}
STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacity: {LTBLUE}None{STRING}
STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacity: {LTBLUE}{0:CARGO_LONG}{3:STRING}
STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacity: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM})
STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}{STRING}
STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}{STRING} (x{NUM})
STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING}
STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transfer Credits: {LTBLUE}{CURRENCY_LONG}

View File

@ -29,13 +29,9 @@
void DrawRoadVehDetails(const Vehicle *v, const Rect &r)
{
int y = r.top + (v->HasArticulatedPart() ? ScaleSpriteTrad(15) : 0); // Draw the first line below the sprite of an articulated RV instead of after it.
StringID str;
Money feeder_share = 0;
SetDParam(0, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails));
SetDParam(1, v->build_year);
SetDParam(2, v->value);
DrawString(r.left, r.right, y, STR_VEHICLE_INFO_BUILT_VALUE);
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_INFO_BUILT_VALUE, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->build_year, v->value));
y += GetCharacterHeight(FS_NORMAL);
if (v->HasArticulatedPart()) {
@ -59,9 +55,8 @@ void DrawRoadVehDetails(const Vehicle *v, const Rect &r)
if (max_cargo[cargo_type] > 0) {
if (!first) capacity += list_separator;
SetDParam(0, cargo_type);
SetDParam(1, max_cargo[cargo_type]);
AppendStringInPlace(capacity, STR_JUST_CARGO);
auto params = MakeParameters(cargo_type, max_cargo[cargo_type]);
AppendStringWithArgsInPlace(capacity, STR_JUST_CARGO, params);
if (subtype_text[cargo_type] != STR_NULL) {
AppendStringInPlace(capacity, subtype_text[cargo_type]);
@ -77,40 +72,34 @@ void DrawRoadVehDetails(const Vehicle *v, const Rect &r)
for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
if (u->cargo_cap == 0) continue;
str = STR_VEHICLE_DETAILS_CARGO_EMPTY;
std::string str;
if (u->cargo.StoredCount() > 0) {
SetDParam(0, u->cargo_type);
SetDParam(1, u->cargo.StoredCount());
SetDParam(2, u->cargo.GetFirstStation());
str = STR_VEHICLE_DETAILS_CARGO_FROM;
str = GetString(STR_VEHICLE_DETAILS_CARGO_FROM, u->cargo_type, u->cargo.StoredCount(), u->cargo.GetFirstStation());
feeder_share += u->cargo.GetFeederShare();
} else {
str = GetString(STR_VEHICLE_DETAILS_CARGO_EMPTY);
}
DrawString(r.left, r.right, y, str);
y += GetCharacterHeight(FS_NORMAL);
}
y += WidgetDimensions::scaled.vsep_normal;
} else {
SetDParam(0, v->cargo_type);
SetDParam(1, v->cargo_cap);
SetDParam(4, GetCargoSubtypeText(v));
DrawString(r.left, r.right, y, STR_VEHICLE_INFO_CAPACITY);
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_INFO_CAPACITY, v->cargo_type, v->cargo_cap, GetCargoSubtypeText(v)));
y += GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal;
str = STR_VEHICLE_DETAILS_CARGO_EMPTY;
std::string str;
if (v->cargo.StoredCount() > 0) {
SetDParam(0, v->cargo_type);
SetDParam(1, v->cargo.StoredCount());
SetDParam(2, v->cargo.GetFirstStation());
str = STR_VEHICLE_DETAILS_CARGO_FROM;
str = GetString(STR_VEHICLE_DETAILS_CARGO_FROM, v->cargo_type, v->cargo.StoredCount(), v->cargo.GetFirstStation());
feeder_share += v->cargo.GetFeederShare();
} else {
str = GetString(STR_VEHICLE_DETAILS_CARGO_EMPTY);
}
DrawString(r.left, r.right, y, str);
y += GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal;
}
/* Draw Transfer credits text */
SetDParam(0, feeder_share);
DrawString(r.left, r.right, y, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE);
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_INFO_FEEDER_CARGO_VALUE, feeder_share));
}
/**

View File

@ -64,29 +64,19 @@ void DrawShipDetails(const Vehicle *v, const Rect &r)
{
int y = r.top;
SetDParam(0, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails));
SetDParam(1, v->build_year);
SetDParam(2, v->value);
DrawString(r.left, r.right, y, STR_VEHICLE_INFO_BUILT_VALUE);
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_INFO_BUILT_VALUE, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->build_year, v->value));
y += GetCharacterHeight(FS_NORMAL);
SetDParam(0, v->cargo_type);
SetDParam(1, v->cargo_cap);
SetDParam(4, GetCargoSubtypeText(v));
DrawString(r.left, r.right, y, STR_VEHICLE_INFO_CAPACITY);
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_INFO_CAPACITY, v->cargo_type, v->cargo_cap, GetCargoSubtypeText(v)));
y += GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal;
StringID str = STR_VEHICLE_DETAILS_CARGO_EMPTY;
if (v->cargo.StoredCount() > 0) {
SetDParam(0, v->cargo_type);
SetDParam(1, v->cargo.StoredCount());
SetDParam(2, v->cargo.GetFirstStation());
str = STR_VEHICLE_DETAILS_CARGO_FROM;
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_DETAILS_CARGO_FROM, v->cargo_type, v->cargo.StoredCount(), v->cargo.GetFirstStation()));
} else {
DrawString(r.left, r.right, y, STR_VEHICLE_DETAILS_CARGO_EMPTY);
}
DrawString(r.left, r.right, y, str);
y += GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal;
/* Draw Transfer credits text */
SetDParam(0, v->cargo.GetFeederShare());
DrawString(r.left, r.right, y, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE);
DrawString(r.left, r.right, y, GetString(STR_VEHICLE_INFO_FEEDER_CARGO_VALUE, v->cargo.GetFeederShare()));
}

View File

@ -59,6 +59,15 @@ inline StringID MakeStringID(StringTab tab, StringIndexInTab index)
return (tab << TAB_SIZE_BITS) + index.base();
}
/**
* Prepare the string parameters for the next formatting run, resetting the type information.
* This is only necessary if parameters are reused for multiple format runs.
*/
static inline void PrepareArgsForNextRun(std::span<StringParameter> args)
{
for (auto &param : args) param.type = 0;
}
std::string GetStringWithArgs(StringID string, std::span<StringParameter> args);
std::string GetString(StringID string);
const char *GetStringPtr(StringID string);

View File

@ -204,17 +204,16 @@ static CargoSummary _cargo_summary;
*/
static void TrainDetailsCargoTab(const CargoSummaryItem *item, int left, int right, int y)
{
StringID str;
if (item->amount > 0) {
SetDParam(0, item->cargo);
SetDParam(1, item->amount);
SetDParam(2, item->source);
SetDParam(3, _settings_game.vehicle.freight_trains);
str = FreightWagonMult(item->cargo) > 1 ? STR_VEHICLE_DETAILS_CARGO_FROM_MULT : STR_VEHICLE_DETAILS_CARGO_FROM;
std::string str;
if (!IsValidCargoType(item->cargo)) {
str = GetString(STR_QUANTITY_N_A);
} else if (item->amount == 0) {
str = GetString(STR_VEHICLE_DETAILS_CARGO_EMPTY);
} else if (FreightWagonMult(item->cargo) > 1) {
str = GetString(STR_VEHICLE_DETAILS_CARGO_FROM_MULT, item->cargo, item->amount, item->source, _settings_game.vehicle.freight_trains);
} else {
str = !IsValidCargoType(item->cargo) ? STR_QUANTITY_N_A : STR_VEHICLE_DETAILS_CARGO_EMPTY;
str = GetString(STR_VEHICLE_DETAILS_CARGO_FROM, item->cargo, item->amount, item->source);
}
DrawString(left, right, y, str, TC_LIGHT_BLUE);
}
@ -228,16 +227,13 @@ static void TrainDetailsCargoTab(const CargoSummaryItem *item, int left, int rig
*/
static void TrainDetailsInfoTab(const Vehicle *v, int left, int right, int y)
{
std::string str;
if (RailVehInfo(v->engine_type)->railveh_type == RAILVEH_WAGON) {
SetDParam(0, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails));
SetDParam(1, v->value);
DrawString(left, right, y, STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE);
str = GetString(STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->value);
} else {
SetDParam(0, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails));
SetDParam(1, v->build_year);
SetDParam(2, v->value);
DrawString(left, right, y, STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE);
str = GetString(STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->build_year, v->value);
}
DrawString(left, right, y, str);
}
/**
@ -250,17 +246,14 @@ static void TrainDetailsInfoTab(const Vehicle *v, int left, int right, int y)
*/
static void TrainDetailsCapacityTab(const CargoSummaryItem *item, int left, int right, int y)
{
StringID str;
if (IsValidCargoType(item->cargo)) {
SetDParam(0, item->cargo);
SetDParam(1, item->capacity);
SetDParam(4, item->subtype);
SetDParam(5, _settings_game.vehicle.freight_trains);
str = FreightWagonMult(item->cargo) > 1 ? STR_VEHICLE_INFO_CAPACITY_MULT : STR_VEHICLE_INFO_CAPACITY;
} else {
std::string str;
if (!IsValidCargoType(item->cargo)) {
/* Draw subtype only */
SetDParam(0, item->subtype);
str = STR_VEHICLE_INFO_NO_CAPACITY;
str = GetString(STR_VEHICLE_INFO_NO_CAPACITY, item->subtype);
} else if (FreightWagonMult(item->cargo) > 1) {
str = GetString(STR_VEHICLE_INFO_CAPACITY_MULT, item->cargo, item->capacity, item->subtype, _settings_game.vehicle.freight_trains);
} else {
str = GetString(STR_VEHICLE_INFO_CAPACITY, item->cargo, item->capacity, item->subtype);
}
DrawString(left, right, y, str);
}
@ -422,8 +415,7 @@ void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16_t v
if (i < _cargo_summary.size()) {
TrainDetailsCapacityTab(&_cargo_summary[i], dr.left, dr.right, py);
} else {
SetDParam(0, STR_EMPTY);
DrawString(dr.left, dr.right, py, STR_VEHICLE_INFO_NO_CAPACITY);
DrawString(dr.left, dr.right, py, GetString(STR_VEHICLE_INFO_NO_CAPACITY, STR_EMPTY));
}
break;
@ -454,16 +446,16 @@ void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16_t v
for (const CargoSpec *cs : _sorted_cargo_specs) {
CargoType cargo_type = cs->Index();
if (max_cargo[cargo_type] > 0 && --vscroll_pos < 0 && vscroll_pos > -vscroll_cap) {
SetDParam(0, cargo_type); // {CARGO} #1
SetDParam(1, act_cargo[cargo_type]); // {CARGO} #2
SetDParam(2, cargo_type); // {SHORTCARGO} #1
SetDParam(3, max_cargo[cargo_type]); // {SHORTCARGO} #2
SetDParam(4, _settings_game.vehicle.freight_trains);
DrawString(ir.left, ir.right, y + text_y_offset, FreightWagonMult(cargo_type) > 1 ? STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT : STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY);
std::string str;
if (FreightWagonMult(cargo_type) > 1) {
str = GetString(STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT, cargo_type, act_cargo[cargo_type], cargo_type, max_cargo[cargo_type], _settings_game.vehicle.freight_trains);
} else {
str = GetString(STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY, cargo_type, act_cargo[cargo_type], cargo_type, max_cargo[cargo_type]);
}
DrawString(ir.left, ir.right, y + text_y_offset, str);
y += line_height;
}
}
SetDParam(0, feeder_share);
DrawString(r.left, r.right, y + text_y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE);
DrawString(r.left, r.right, y + text_y_offset, GetString(STR_VEHICLE_INFO_FEEDER_CARGO_VALUE, feeder_share));
}
}

View File

@ -732,9 +732,7 @@ static void DrawVehicleRefitWindow(const RefitOptions &refits, const RefitOption
TextColour colour = (sel != nullptr && sel->cargo == refit.cargo && sel->subtype == refit.subtype) ? TC_WHITE : TC_BLACK;
/* Get the cargo name. */
SetDParam(0, CargoSpec::Get(refit.cargo)->name);
SetDParam(1, refit.string);
DrawString(tr, STR_JUST_STRING_STRING, colour);
DrawString(tr, GetString(STR_JUST_STRING_STRING, CargoSpec::Get(refit.cargo)->name, refit.string), colour);
tr.top += delta;
current++;
@ -1005,43 +1003,37 @@ struct RefitWindow : public Window {
* @return INVALID_STRING_ID if there is no capacity. StringID to use in any other case.
* @post String parameters have been set.
*/
StringID GetCapacityString(const RefitOption &option) const
std::string GetCapacityString(const RefitOption &option) const
{
assert(_current_company == _local_company);
auto [cost, refit_capacity, mail_capacity, cargo_capacities] = Command<CMD_REFIT_VEHICLE>::Do(DoCommandFlag::QueryCost, this->selected_vehicle, option.cargo, option.subtype, this->auto_refit, false, this->num_vehicles);
if (cost.Failed()) return INVALID_STRING_ID;
SetDParam(0, option.cargo);
SetDParam(1, refit_capacity);
if (cost.Failed()) return {};
Money money = cost.GetCost();
if (mail_capacity > 0) {
SetDParam(2, GetCargoTypeByLabel(CT_MAIL));
SetDParam(3, mail_capacity);
if (this->order != INVALID_VEH_ORDER_ID) {
/* No predictable cost */
return STR_PURCHASE_INFO_AIRCRAFT_CAPACITY;
} else if (money <= 0) {
SetDParam(4, -money);
return STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT;
} else {
SetDParam(4, money);
return STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT;
return GetString(STR_PURCHASE_INFO_AIRCRAFT_CAPACITY, option.cargo, refit_capacity, GetCargoTypeByLabel(CT_MAIL), mail_capacity);
}
} else {
if (this->order != INVALID_VEH_ORDER_ID) {
/* No predictable cost */
SetDParam(2, STR_EMPTY);
return STR_PURCHASE_INFO_CAPACITY;
} else if (money <= 0) {
SetDParam(2, -money);
return STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT;
} else {
SetDParam(2, money);
return STR_REFIT_NEW_CAPACITY_COST_OF_REFIT;
if (money <= 0) {
return GetString(STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT, option.cargo, refit_capacity, GetCargoTypeByLabel(CT_MAIL), mail_capacity, -money);
}
return GetString(STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT, option.cargo, refit_capacity, GetCargoTypeByLabel(CT_MAIL), mail_capacity, money);
}
if (this->order != INVALID_VEH_ORDER_ID) {
/* No predictable cost */
return GetString(STR_PURCHASE_INFO_CAPACITY, option.cargo, refit_capacity, STR_EMPTY);
}
if (money <= 0) {
return GetString(STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT, option.cargo, refit_capacity, -money);
}
return GetString(STR_REFIT_NEW_CAPACITY_COST_OF_REFIT, option.cargo, refit_capacity, money);
}
void DrawWidget(const Rect &r, WidgetID widget) const override
@ -1118,8 +1110,8 @@ struct RefitWindow : public Window {
case WID_VR_INFO:
if (this->selected_refit != nullptr) {
StringID string = this->GetCapacityString(*this->selected_refit);
if (string != INVALID_STRING_ID) {
std::string string = this->GetCapacityString(*this->selected_refit);
if (!string.empty()) {
DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect), string);
}
}
@ -1155,8 +1147,8 @@ struct RefitWindow : public Window {
/* Check the width of all cargo information strings. */
for (const auto &list : this->refit_list) {
for (const RefitOption &refit : list.second) {
StringID string = this->GetCapacityString(refit);
if (string != INVALID_STRING_ID) {
std::string string = this->GetCapacityString(refit);
if (!string.empty()) {
Dimension dim = GetStringBoundingBox(string);
max_width = std::max(dim.width, max_width);
}
@ -1373,22 +1365,22 @@ uint ShowRefitOptionsList(int left, int right, int y, EngineID engine)
/* Draw nothing if the engine is not refittable */
if (HasAtMostOneBit(cmask)) return y;
std::string str;
if (cmask == lmask) {
/* Engine can be refitted to all types in this climate */
SetDParam(0, STR_PURCHASE_INFO_ALL_TYPES);
str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_PURCHASE_INFO_ALL_TYPES, std::monostate{});
} else {
/* Check if we are able to refit to more cargo types and unable to. If
* so, invert the cargo types to list those that we can't refit to. */
if (CountBits(cmask ^ lmask) < CountBits(cmask) && CountBits(cmask ^ lmask) <= 7) {
cmask ^= lmask;
SetDParam(0, STR_PURCHASE_INFO_ALL_BUT);
str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_PURCHASE_INFO_ALL_BUT, cmask);
} else {
SetDParam(0, STR_JUST_CARGO_LIST);
str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_JUST_CARGO_LIST, cmask);
}
SetDParam(1, cmask);
}
return DrawStringMultiLine(left, right, y, INT32_MAX, STR_PURCHASE_INFO_REFITTABLE_TO);
return DrawStringMultiLine(left, right, y, INT32_MAX, str);
}
/** Get the cargo subtype text from NewGRF for the vehicle details window. */
@ -1676,8 +1668,7 @@ static void DrawSmallOrderList(const Vehicle *v, int left, int right, int y, uin
if (oid == v->cur_real_order_index) DrawString(left, right, y, STR_JUST_RIGHT_ARROW, TC_BLACK, SA_LEFT, false, FS_SMALL);
if (order->IsType(OT_GOTO_STATION)) {
SetDParam(0, order->GetDestination());
DrawString(left + l_offset, right - r_offset, y, STR_STATION_NAME, TC_BLACK, SA_LEFT, false, FS_SMALL);
DrawString(left + l_offset, right - r_offset, y, GetString(STR_STATION_NAME, order->GetDestination()), TC_BLACK, SA_LEFT, false, FS_SMALL);
y += GetCharacterHeight(FS_SMALL);
if (++i == 4) break;
@ -1701,8 +1692,7 @@ static void DrawSmallOrderList(const Order *order, int left, int right, int y, u
int i = 0;
while (order != nullptr) {
if (order->IsType(OT_GOTO_STATION)) {
SetDParam(0, order->GetDestination());
DrawString(left + l_offset, right - r_offset, y, STR_STATION_NAME, TC_BLACK, SA_LEFT, false, FS_SMALL);
DrawString(left + l_offset, right - r_offset, y, GetString(STR_STATION_NAME, order->GetDestination()), TC_BLACK, SA_LEFT, false, FS_SMALL);
y += GetCharacterHeight(FS_SMALL);
if (++i == 4) break;
@ -1756,8 +1746,7 @@ uint GetVehicleListHeight(VehicleType type, uint divisor)
*/
static int GetUnitNumberWidth(int digits)
{
SetDParamMaxDigits(0, digits);
return GetStringBoundingBox(STR_JUST_COMMA).width;
return GetStringBoundingBox(GetString(STR_JUST_COMMA, GetParamMaxDigits(digits))).width;
}
/**
@ -1787,10 +1776,10 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
for (auto it = first; it != last; ++it) {
const GUIVehicleGroup &vehgroup = *it;
SetDParam(0, vehgroup.GetDisplayProfitThisYear());
SetDParam(1, vehgroup.GetDisplayProfitLastYear());
DrawString(tr.left, tr.right, ir.bottom - GetCharacterHeight(FS_SMALL) - WidgetDimensions::scaled.framerect.bottom,
TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_LIST_PROFIT_THIS_PERIOD_LAST_PERIOD : STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR);
GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_LIST_PROFIT_THIS_PERIOD_LAST_PERIOD : STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR,
vehgroup.GetDisplayProfitThisYear(),
vehgroup.GetDisplayProfitLastYear()));
DrawVehicleProfitButton(vehgroup.GetOldestVehicleAge(), vehgroup.GetDisplayProfitLastYear(), vehgroup.NumVehicles(), vehicle_button_x, ir.top + GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal);
@ -1816,31 +1805,24 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
if (!v->name.empty()) {
/* The vehicle got a name so we will print it and the cargoes */
SetDParam(0, STR_VEHICLE_NAME);
SetDParam(1, v->index);
SetDParam(2, STR_VEHICLE_LIST_CARGO);
SetDParam(3, vehicle_cargoes);
DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_LIST_NAME_AND_CARGO, TC_BLACK, SA_LEFT, false, FS_SMALL);
DrawString(tr.left, tr.right, ir.top,
GetString(STR_VEHICLE_LIST_NAME_AND_CARGO, STR_VEHICLE_NAME, v->index, STR_VEHICLE_LIST_CARGO, vehicle_cargoes),
TC_BLACK, SA_LEFT, false, FS_SMALL);
} else if (v->group_id != DEFAULT_GROUP) {
/* The vehicle has no name, but is member of a group, so print group name and the cargoes */
SetDParam(0, STR_GROUP_NAME);
SetDParam(1, v->group_id);
SetDParam(2, STR_VEHICLE_LIST_CARGO);
SetDParam(3, vehicle_cargoes);
DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_LIST_NAME_AND_CARGO, TC_BLACK, SA_LEFT, false, FS_SMALL);
DrawString(tr.left, tr.right, ir.top,
GetString(STR_VEHICLE_LIST_NAME_AND_CARGO, STR_GROUP_NAME, v->group_id, STR_VEHICLE_LIST_CARGO, vehicle_cargoes),
TC_BLACK, SA_LEFT, false, FS_SMALL);
} else {
/* The vehicle has no name, and is not a member of a group, so just print the cargoes */
SetDParam(0, vehicle_cargoes);
DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_LIST_CARGO, TC_BLACK, SA_LEFT, false, FS_SMALL);
DrawString(tr.left, tr.right, ir.top, GetString(STR_VEHICLE_LIST_CARGO, vehicle_cargoes), TC_BLACK, SA_LEFT, false, FS_SMALL);
}
} else if (!v->name.empty()) {
/* The vehicle got a name so we will print it */
SetDParam(0, v->index);
DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_NAME, TC_BLACK, SA_LEFT, false, FS_SMALL);
DrawString(tr.left, tr.right, ir.top, GetString(STR_VEHICLE_NAME, v->index), TC_BLACK, SA_LEFT, false, FS_SMALL);
} else if (v->group_id != DEFAULT_GROUP) {
/* The vehicle has no name, but is member of a group, so print group name */
SetDParam(0, v->group_id);
DrawString(tr.left, tr.right, ir.top, STR_GROUP_NAME, TC_BLACK, SA_LEFT, false, FS_SMALL);
DrawString(tr.left, tr.right, ir.top, GetString(STR_GROUP_NAME, v->group_id), TC_BLACK, SA_LEFT, false, FS_SMALL);
}
if (show_orderlist) DrawSmallOrderList(v, olr.left, olr.right, ir.top + GetCharacterHeight(FS_SMALL), this->order_arrow_width, v->cur_real_order_index);
@ -1852,8 +1834,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
tc = (v->age > v->max_age - CalendarTime::DAYS_IN_LEAP_YEAR) ? TC_RED : TC_BLACK;
}
SetDParam(0, v->unitnumber);
DrawString(ir.left, ir.right, ir.top + WidgetDimensions::scaled.framerect.top, STR_JUST_COMMA, tc);
DrawString(ir.left, ir.right, ir.top + WidgetDimensions::scaled.framerect.top, GetString(STR_JUST_COMMA, v->unitnumber), tc);
break;
}
@ -1867,8 +1848,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int
if (show_orderlist) DrawSmallOrderList((vehgroup.vehicles_begin[0])->GetFirstOrder(), olr.left, olr.right, ir.top + GetCharacterHeight(FS_SMALL), this->order_arrow_width);
SetDParam(0, vehgroup.NumVehicles());
DrawString(ir.left, ir.right, ir.top + WidgetDimensions::scaled.framerect.top, STR_JUST_COMMA, TC_BLACK);
DrawString(ir.left, ir.right, ir.top + WidgetDimensions::scaled.framerect.top, GetString(STR_JUST_COMMA, vehgroup.NumVehicles()), TC_BLACK);
break;
default:
@ -2504,20 +2484,14 @@ struct VehicleDetailsWindow : Window {
Dimension dim = { 0, 0 };
size.height = 4 * GetCharacterHeight(FS_NORMAL) + padding.height;
for (uint i = 0; i < 4; i++) SetDParamMaxValue(i, INT16_MAX);
static const StringID info_strings[] = {
STR_VEHICLE_INFO_MAX_SPEED,
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED,
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE,
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE,
STR_VEHICLE_INFO_PROFIT_THIS_PERIOD_LAST_PERIOD_MIN_PERFORMANCE,
STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS
};
for (const auto &info_string : info_strings) {
dim = maxdim(dim, GetStringBoundingBox(info_string));
}
SetDParam(0, STR_VEHICLE_INFO_AGE);
dim = maxdim(dim, GetStringBoundingBox(TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_INFO_AGE_RUNNING_COST_PERIOD : STR_VEHICLE_INFO_AGE_RUNNING_COST_YR));
uint64_t max_value = GetParamMaxValue(INT16_MAX);
dim = maxdim(dim, GetStringBoundingBox(GetString(STR_VEHICLE_INFO_MAX_SPEED, max_value)));
dim = maxdim(dim, GetStringBoundingBox(GetString(STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, max_value, max_value, max_value)));
dim = maxdim(dim, GetStringBoundingBox(GetString(STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE, max_value, max_value, max_value, max_value)));
dim = maxdim(dim, GetStringBoundingBox(GetString(STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE, max_value, max_value, max_value)));
dim = maxdim(dim, GetStringBoundingBox(GetString(STR_VEHICLE_INFO_PROFIT_THIS_PERIOD_LAST_PERIOD_MIN_PERFORMANCE, max_value, max_value, max_value)));
dim = maxdim(dim, GetStringBoundingBox(GetString(STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS, max_value, max_value)));
dim = maxdim(dim, GetStringBoundingBox(GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_INFO_AGE_RUNNING_COST_PERIOD : STR_VEHICLE_INFO_AGE_RUNNING_COST_YR, STR_VEHICLE_INFO_AGE, max_value, max_value, max_value)));
size.width = dim.width + padding.width;
break;
}
@ -2557,22 +2531,16 @@ struct VehicleDetailsWindow : Window {
}
case WID_VD_SERVICING_INTERVAL:
SetDParamMaxValue(0, MAX_SERVINT_DAYS); // Roughly the maximum interval
/* Do we show the last serviced value as a date or minutes since service? */
if (TimerGameEconomy::UsingWallclockUnits()) {
SetDParam(1, STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO);
/*/ Vehicle was last serviced at year 0, and we're at max year */
SetDParamMaxValue(2, EconomyTime::MONTHS_IN_YEAR * EconomyTime::MAX_YEAR.base());
} else {
SetDParam(1, STR_VEHICLE_DETAILS_LAST_SERVICE_DATE);
/*/ Vehicle was last serviced at year 0, and we're at max year */
SetDParamMaxValue(2, TimerGameEconomy::DateAtStartOfYear(EconomyTime::MAX_YEAR));
}
size.width = std::max(
GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT).width,
GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS).width
) + padding.width;
auto params = TimerGameEconomy::UsingWallclockUnits()
? MakeParameters(GetParamMaxValue(MAX_SERVINT_DAYS), STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO, EconomyTime::MAX_DATE)
: MakeParameters(GetParamMaxValue(MAX_SERVINT_DAYS), STR_VEHICLE_DETAILS_LAST_SERVICE_DATE, TimerGameEconomy::DateAtStartOfYear(EconomyTime::MAX_YEAR));
size.width = std::max(size.width, GetStringBoundingBox(GetStringWithArgs(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT, params)).width);
PrepareArgsForNextRun(params);
size.width = std::max(size.width, GetStringBoundingBox(GetStringWithArgs(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS, params)).width);
size.width += padding.width;
size.height = GetCharacterHeight(FS_NORMAL) + padding.height;
break;
}
@ -2627,60 +2595,54 @@ struct VehicleDetailsWindow : Window {
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
/* Draw running cost */
SetDParam(1, TimerGameCalendar::DateToYear(v->age));
SetDParam(0, (v->age + CalendarTime::DAYS_IN_YEAR < v->max_age) ? STR_VEHICLE_INFO_AGE : STR_VEHICLE_INFO_AGE_RED);
SetDParam(2, TimerGameCalendar::DateToYear(v->max_age));
SetDParam(3, v->GetDisplayRunningCost());
DrawString(tr, TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_INFO_AGE_RUNNING_COST_PERIOD : STR_VEHICLE_INFO_AGE_RUNNING_COST_YR);
DrawString(tr,
GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_INFO_AGE_RUNNING_COST_PERIOD : STR_VEHICLE_INFO_AGE_RUNNING_COST_YR,
(v->age + CalendarTime::DAYS_IN_YEAR < v->max_age) ? STR_VEHICLE_INFO_AGE : STR_VEHICLE_INFO_AGE_RED,
TimerGameCalendar::DateToYear(v->age),
TimerGameCalendar::DateToYear(v->max_age),
v->GetDisplayRunningCost()));
tr.top += GetCharacterHeight(FS_NORMAL);
/* Draw max speed */
StringID string;
uint64_t max_speed = PackVelocity(v->GetDisplayMaxSpeed(), v->type);
if (v->type == VEH_TRAIN ||
(v->type == VEH_ROAD && _settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL)) {
const GroundVehicleCache *gcache = v->GetGroundVehicleCache();
SetDParam(2, PackVelocity(v->GetDisplayMaxSpeed(), v->type));
SetDParam(1, gcache->cached_power);
SetDParam(0, gcache->cached_weight);
SetDParam(3, gcache->cached_max_te);
if (v->type == VEH_TRAIN && (_settings_game.vehicle.train_acceleration_model == AM_ORIGINAL ||
GetRailTypeInfo(Train::From(v)->railtype)->acceleration_type == 2)) {
string = STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED;
DrawString(tr, GetString(STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, gcache->cached_weight, gcache->cached_power, max_speed));
} else {
string = STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE;
DrawString(tr, GetString(STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE, gcache->cached_weight, gcache->cached_power, max_speed, gcache->cached_max_te));
}
} else if (v->type == VEH_AIRCRAFT) {
StringID type = v->GetEngine()->GetAircraftTypeText();
if (Aircraft::From(v)->GetRange() > 0) {
DrawString(tr, GetString(STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE, max_speed, type, Aircraft::From(v)->GetRange()));
} else {
DrawString(tr, GetString(STR_VEHICLE_INFO_MAX_SPEED_TYPE, max_speed, type));
}
} else {
SetDParam(0, PackVelocity(v->GetDisplayMaxSpeed(), v->type));
if (v->type == VEH_AIRCRAFT) {
SetDParam(1, v->GetEngine()->GetAircraftTypeText());
if (Aircraft::From(v)->GetRange() > 0) {
SetDParam(2, Aircraft::From(v)->GetRange());
string = STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE;
} else {
string = STR_VEHICLE_INFO_MAX_SPEED_TYPE;
}
} else {
string = STR_VEHICLE_INFO_MAX_SPEED;
}
DrawString(tr, GetString(STR_VEHICLE_INFO_MAX_SPEED, max_speed));
}
DrawString(tr, string);
tr.top += GetCharacterHeight(FS_NORMAL);
/* Draw profit */
SetDParam(0, v->GetDisplayProfitThisYear());
SetDParam(1, v->GetDisplayProfitLastYear());
if (v->IsGroundVehicle()) {
SetDParam(2, v->GetDisplayMinPowerToWeight());
DrawString(tr, TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_INFO_PROFIT_THIS_PERIOD_LAST_PERIOD_MIN_PERFORMANCE : STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE);
DrawString(tr,
GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_INFO_PROFIT_THIS_PERIOD_LAST_PERIOD_MIN_PERFORMANCE : STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE,
v->GetDisplayProfitThisYear(),
v->GetDisplayProfitLastYear(),
v->GetDisplayMinPowerToWeight()));
} else {
DrawString(tr, TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_INFO_PROFIT_THIS_PERIOD_LAST_PERIOD : STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR);
DrawString(tr,
GetString(TimerGameEconomy::UsingWallclockUnits() ? STR_VEHICLE_INFO_PROFIT_THIS_PERIOD_LAST_PERIOD : STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR,
v->GetDisplayProfitThisYear(),
v->GetDisplayProfitLastYear()));
}
tr.top += GetCharacterHeight(FS_NORMAL);
/* Draw breakdown & reliability */
SetDParam(0, ToPercent16(v->reliability));
SetDParam(1, v->breakdowns_since_last_service);
DrawString(tr, STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS);
DrawString(tr, GetString(STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS, ToPercent16(v->reliability), v->breakdowns_since_last_service));
break;
}
@ -2712,23 +2674,19 @@ struct VehicleDetailsWindow : Window {
/* Draw service interval text */
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
SetDParam(0, v->GetServiceInterval());
/* We're using wallclock units. Show minutes since last serviced. */
if (TimerGameEconomy::UsingWallclockUnits()) {
int minutes_since_serviced = (TimerGameEconomy::date - v->date_of_last_service).base() / EconomyTime::DAYS_IN_ECONOMY_MONTH;
SetDParam(1, STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO);
SetDParam(2, minutes_since_serviced);
DrawString(tr.left, tr.right, CenterBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL)),
v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_MINUTES);
GetString(v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_MINUTES,
v->GetServiceInterval(), STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO, minutes_since_serviced));
break;
}
/* We're using calendar dates. Show the date of last service. */
SetDParam(1, STR_VEHICLE_DETAILS_LAST_SERVICE_DATE);
SetDParam(2, v->date_of_last_service);
DrawString(tr.left, tr.right, CenterBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL)),
v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS);
GetString(v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS,
v->GetServiceInterval(), STR_VEHICLE_DETAILS_LAST_SERVICE_DATE, v->date_of_last_service));
break;
}
}
@ -3168,112 +3126,102 @@ public:
SetDParam(0, v->index);
}
std::string GetVehicleStatusString(const Vehicle *v, TextColour &text_colour) const
{
text_colour = TC_BLACK;
if (v->vehstatus & VS_CRASHED) return GetString(STR_VEHICLE_STATUS_CRASHED);
if (v->type != VEH_AIRCRAFT && v->breakdown_ctr == 1) return GetString(STR_VEHICLE_STATUS_BROKEN_DOWN);
if (v->vehstatus & VS_STOPPED && (!mouse_over_start_stop || v->IsStoppedInDepot())) {
if (v->type != VEH_TRAIN) return GetString(STR_VEHICLE_STATUS_STOPPED);
if (v->cur_speed != 0) return GetString(STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL, PackVelocity(v->GetDisplaySpeed(), v->type));
if (Train::From(v)->gcache.cached_power == 0) return GetString(STR_VEHICLE_STATUS_TRAIN_NO_POWER);
return GetString(STR_VEHICLE_STATUS_STOPPED);
}
if (v->IsInDepot() && v->IsWaitingForUnbunching()) return GetString(STR_VEHICLE_STATUS_WAITING_UNBUNCHING);
if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_TRAIN_STUCK) && !v->current_order.IsType(OT_LOADING)) return GetString(STR_VEHICLE_STATUS_TRAIN_STUCK);
if (v->type == VEH_AIRCRAFT && HasBit(Aircraft::From(v)->flags, VAF_DEST_TOO_FAR) && !v->current_order.IsType(OT_LOADING)) return GetString(STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR);
/* Vehicle is in a "normal" state, show current order. */
if (mouse_over_start_stop) {
if (v->vehstatus & VS_STOPPED) {
text_colour = TC_RED | TC_FORCED;
} else if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_TRAIN_STUCK) && !v->current_order.IsType(OT_LOADING)) {
text_colour = TC_ORANGE | TC_FORCED;
}
}
switch (v->current_order.GetType()) {
case OT_GOTO_STATION:
return GetString(HasBit(v->vehicle_flags, VF_PATHFINDER_LOST) ? STR_VEHICLE_STATUS_CANNOT_REACH_STATION_VEL : STR_VEHICLE_STATUS_HEADING_FOR_STATION_VEL,
v->current_order.GetDestination(), PackVelocity(v->GetDisplaySpeed(), v->type));
case OT_GOTO_DEPOT: {
/* This case *only* happens when multiple nearest depot orders
* follow each other (including an order list only one order: a
* nearest depot order) and there are no reachable depots.
* It is primarily to guard for the case that there is no
* depot with index 0, which would be used as fallback for
* evaluating the string in the status bar. */
if (v->current_order.GetDestination() == DepotID::Invalid()) return {};
auto params = MakeParameters(v->type, v->current_order.GetDestination(), PackVelocity(v->GetDisplaySpeed(), v->type));
if (v->current_order.GetDepotActionType() & ODATFB_HALT) {
return GetStringWithArgs(HasBit(v->vehicle_flags, VF_PATHFINDER_LOST) ? STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_VEL : STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_VEL, params);
}
if (v->current_order.GetDepotActionType() & ODATFB_UNBUNCH) {
return GetStringWithArgs(HasBit(v->vehicle_flags, VF_PATHFINDER_LOST) ? STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_SERVICE_VEL : STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_UNBUNCH_VEL, params);
}
return GetStringWithArgs(HasBit(v->vehicle_flags, VF_PATHFINDER_LOST) ? STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_SERVICE_VEL : STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_SERVICE_VEL, params);
}
case OT_LOADING:
return GetString(STR_VEHICLE_STATUS_LOADING_UNLOADING);
case OT_GOTO_WAYPOINT:
assert(v->type == VEH_TRAIN || v->type == VEH_ROAD || v->type == VEH_SHIP);
return GetString(HasBit(v->vehicle_flags, VF_PATHFINDER_LOST) ? STR_VEHICLE_STATUS_CANNOT_REACH_WAYPOINT_VEL : STR_VEHICLE_STATUS_HEADING_FOR_WAYPOINT_VEL,
v->current_order.GetDestination(),PackVelocity(v->GetDisplaySpeed(), v->type));
case OT_LEAVESTATION:
if (v->type != VEH_AIRCRAFT) {
return GetString(STR_VEHICLE_STATUS_LEAVING);
}
[[fallthrough]];
default:
if (v->GetNumManualOrders() == 0) {
return GetString(STR_VEHICLE_STATUS_NO_ORDERS_VEL, PackVelocity(v->GetDisplaySpeed(), v->type));
}
return {};
}
}
void DrawWidget(const Rect &r, WidgetID widget) const override
{
if (widget != WID_VV_START_STOP) return;
Vehicle *v = Vehicle::Get(this->window_number);
StringID str;
TextColour text_colour = TC_FROMSTRING;
if (v->vehstatus & VS_CRASHED) {
str = STR_VEHICLE_STATUS_CRASHED;
} else if (v->type != VEH_AIRCRAFT && v->breakdown_ctr == 1) { // check for aircraft necessary?
str = STR_VEHICLE_STATUS_BROKEN_DOWN;
} else if (v->vehstatus & VS_STOPPED && (!mouse_over_start_stop || v->IsStoppedInDepot())) {
if (v->type == VEH_TRAIN) {
if (v->cur_speed == 0) {
if (Train::From(v)->gcache.cached_power == 0) {
str = STR_VEHICLE_STATUS_TRAIN_NO_POWER;
} else {
str = STR_VEHICLE_STATUS_STOPPED;
}
} else {
SetDParam(0, PackVelocity(v->GetDisplaySpeed(), v->type));
str = STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL;
}
} else { // no train
str = STR_VEHICLE_STATUS_STOPPED;
}
} else if (v->IsInDepot() && v->IsWaitingForUnbunching()) {
str = STR_VEHICLE_STATUS_WAITING_UNBUNCHING;
} else if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_TRAIN_STUCK) && !v->current_order.IsType(OT_LOADING)) {
str = STR_VEHICLE_STATUS_TRAIN_STUCK;
} else if (v->type == VEH_AIRCRAFT && HasBit(Aircraft::From(v)->flags, VAF_DEST_TOO_FAR) && !v->current_order.IsType(OT_LOADING)) {
str = STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR;
} else { // vehicle is in a "normal" state, show current order
if (mouse_over_start_stop) {
if (v->vehstatus & VS_STOPPED) {
text_colour = TC_RED | TC_FORCED;
} else if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_TRAIN_STUCK) && !v->current_order.IsType(OT_LOADING)) {
text_colour = TC_ORANGE | TC_FORCED;
}
}
switch (v->current_order.GetType()) {
case OT_GOTO_STATION: {
SetDParam(0, v->current_order.GetDestination());
SetDParam(1, PackVelocity(v->GetDisplaySpeed(), v->type));
str = HasBit(v->vehicle_flags, VF_PATHFINDER_LOST) ? STR_VEHICLE_STATUS_CANNOT_REACH_STATION_VEL : STR_VEHICLE_STATUS_HEADING_FOR_STATION_VEL;
break;
}
case OT_GOTO_DEPOT: {
SetDParam(0, v->type);
SetDParam(1, v->current_order.GetDestination());
SetDParam(2, PackVelocity(v->GetDisplaySpeed(), v->type));
if (v->current_order.GetDestination() == DepotID::Invalid()) {
/* This case *only* happens when multiple nearest depot orders
* follow each other (including an order list only one order: a
* nearest depot order) and there are no reachable depots.
* It is primarily to guard for the case that there is no
* depot with index 0, which would be used as fallback for
* evaluating the string in the status bar. */
str = STR_EMPTY;
} else if (v->current_order.GetDepotActionType() & ODATFB_HALT) {
str = HasBit(v->vehicle_flags, VF_PATHFINDER_LOST) ? STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_VEL : STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_VEL;
} else if (v->current_order.GetDepotActionType() & ODATFB_UNBUNCH) {
str = HasBit(v->vehicle_flags, VF_PATHFINDER_LOST) ? STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_SERVICE_VEL : STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_UNBUNCH_VEL;
} else {
str = HasBit(v->vehicle_flags, VF_PATHFINDER_LOST) ? STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_SERVICE_VEL : STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_SERVICE_VEL;
}
break;
}
case OT_LOADING:
str = STR_VEHICLE_STATUS_LOADING_UNLOADING;
break;
case OT_GOTO_WAYPOINT: {
assert(v->type == VEH_TRAIN || v->type == VEH_ROAD || v->type == VEH_SHIP);
SetDParam(0, v->current_order.GetDestination());
str = HasBit(v->vehicle_flags, VF_PATHFINDER_LOST) ? STR_VEHICLE_STATUS_CANNOT_REACH_WAYPOINT_VEL : STR_VEHICLE_STATUS_HEADING_FOR_WAYPOINT_VEL;
SetDParam(1, PackVelocity(v->GetDisplaySpeed(), v->type));
break;
}
case OT_LEAVESTATION:
if (v->type != VEH_AIRCRAFT) {
str = STR_VEHICLE_STATUS_LEAVING;
break;
}
[[fallthrough]];
default:
if (v->GetNumManualOrders() == 0) {
str = STR_VEHICLE_STATUS_NO_ORDERS_VEL;
SetDParam(0, PackVelocity(v->GetDisplaySpeed(), v->type));
} else {
str = STR_EMPTY;
}
break;
}
}
/* Draw the flag plus orders. */
bool rtl = (_current_text_dir == TD_RTL);
uint icon_width = std::max({GetScaledSpriteSize(SPR_WARNING_SIGN).width, GetScaledSpriteSize(SPR_FLAG_VEH_STOPPED).width, GetScaledSpriteSize(SPR_FLAG_VEH_RUNNING).width});
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
const Vehicle *v = Vehicle::Get(this->window_number);
SpriteID image = ((v->vehstatus & VS_STOPPED) != 0) ? SPR_FLAG_VEH_STOPPED : (HasBit(v->vehicle_flags, VF_PATHFINDER_LOST)) ? SPR_WARNING_SIGN : SPR_FLAG_VEH_RUNNING;
DrawSpriteIgnorePadding(image, PAL_NONE, tr.WithWidth(icon_width, rtl), SA_CENTER);
tr = tr.Indent(icon_width + WidgetDimensions::scaled.imgbtn.Horizontal(), rtl);
TextColour text_colour = TC_FROMSTRING;
std::string str = GetVehicleStatusString(v, text_colour);
DrawString(tr.left, tr.right, CenterBounds(tr.top, tr.bottom, GetCharacterHeight(FS_NORMAL)), str, text_colour, SA_HOR_CENTER);
}