diff --git a/src/aircraft_gui.cpp b/src/aircraft_gui.cpp index ea04ffe4e8..991186b7ca 100644 --- a/src/aircraft_gui.cpp +++ b/src/aircraft_gui.cpp @@ -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)); } diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 3d0e15c821..b92216acde 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -319,10 +319,9 @@ public: case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: { StringID str = this->GetWidget(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; } diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 4783bbe5aa..b1a6c9ca46 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -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); } diff --git a/src/engine_gui.cpp b/src/engine_gui.cpp index aa3dd13e28..61a207cfea 100644 --- a/src/engine_gui.cpp +++ b/src/engine_gui.cpp @@ -99,9 +99,7 @@ struct EnginePreviewWindow : Window { this->vehicle_space = std::max(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(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); diff --git a/src/lang/english.txt b/src/lang/english.txt index 452046cd57..d4f74c1caa 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -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} diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp index f3deefbede..c462a44e04 100644 --- a/src/roadveh_gui.cpp +++ b/src/roadveh_gui.cpp @@ -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)); } /** diff --git a/src/ship_gui.cpp b/src/ship_gui.cpp index 4580cd6746..7edccb0be6 100644 --- a/src/ship_gui.cpp +++ b/src/ship_gui.cpp @@ -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())); } diff --git a/src/strings_func.h b/src/strings_func.h index 5b8a306f19..25db9feed2 100644 --- a/src/strings_func.h +++ b/src/strings_func.h @@ -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 args) +{ + for (auto ¶m : args) param.type = 0; +} + std::string GetStringWithArgs(StringID string, std::span args); std::string GetString(StringID string); const char *GetStringPtr(StringID string); diff --git a/src/train_gui.cpp b/src/train_gui.cpp index daf28ff239..205bff2039 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -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)); } } diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 74ef78faab..ac89884dd2 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -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::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); }