diff --git a/src/aircraft_gui.cpp b/src/aircraft_gui.cpp index babf1cc970..efe29292fe 100644 --- a/src/aircraft_gui.cpp +++ b/src/aircraft_gui.cpp @@ -34,7 +34,7 @@ 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, u->engine_type); + 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); diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 90a7c71dc8..716768db2d 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -456,7 +456,7 @@ public: 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, e); + SetDParam(0, PackEngineNameDParam(e, EngineNameContext::PurchaseList)); } } else { str = STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED; diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index bc5d5da345..66349dca7e 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -271,13 +271,14 @@ static bool EngineNameSorter(const GUIEngineListItem &a, const GUIEngineListItem if (a.engine_id != _last_engine[0]) { _last_engine[0] = a.engine_id; - SetDParam(0, a.engine_id); + SetDParam(0, PackEngineNameDParam(a.engine_id, EngineNameContext::PurchaseList)); + GetString(last_name[0], STR_ENGINE_NAME, lastof(last_name[0])); } if (b.engine_id != _last_engine[1]) { _last_engine[1] = b.engine_id; - SetDParam(0, b.engine_id); + SetDParam(0, PackEngineNameDParam(b.engine_id, EngineNameContext::PurchaseList)); GetString(last_name[1], STR_ENGINE_NAME, lastof(last_name[1])); } @@ -1243,7 +1244,7 @@ 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 : (TC_NO_SHADE | ((hidden | shaded) ? TC_GREY : TC_BLACK)); - SetDParam(0, item.engine_id); + SetDParam(0, PackEngineNameDParam(item.engine_id, EngineNameContext::PurchaseList, item.indent)); Rect itr = tr.Indent(indent, rtl); DrawString(itr.left, itr.right, y + normal_text_y_offset, str, tc); int sprite_x = ir.Indent(indent + circle_width + WidgetDimensions::scaled.hsep_normal, rtl).WithWidth(sprite_width, rtl).left + sprite_left; @@ -1874,7 +1875,7 @@ struct BuildVehicleWindow : BuildVehicleWindowBase { EngineID sel_eng = this->sel_engine; if (sel_eng != INVALID_ENGINE) { this->rename_engine = sel_eng; - SetDParam(0, sel_eng); + SetDParam(0, PackEngineNameDParam(sel_eng, EngineNameContext::Generic)); ShowQueryString(STR_ENGINE_NAME, STR_QUERY_RENAME_TRAIN_TYPE_CAPTION + this->vehicle_type, MAX_LENGTH_ENGINE_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS); } break; @@ -2663,7 +2664,7 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { if (selected_loco != INVALID_ENGINE) { this->loco.rename_engine = selected_loco; this->wagon.rename_engine = INVALID_ENGINE; - SetDParam(0, selected_loco); + SetDParam(0, PackEngineNameDParam(selected_loco, EngineNameContext::Generic)); ShowQueryString(STR_ENGINE_NAME, STR_QUERY_RENAME_TRAIN_TYPE_LOCOMOTIVE_CAPTION + this->vehicle_type, MAX_LENGTH_ENGINE_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS); } break; @@ -2727,7 +2728,7 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { if (selected_wagon != INVALID_ENGINE) { this->loco.rename_engine = INVALID_ENGINE; this->wagon.rename_engine = selected_wagon; - SetDParam(0, selected_wagon); + SetDParam(0, PackEngineNameDParam(selected_wagon, EngineNameContext::Generic)); ShowQueryString(STR_ENGINE_NAME, STR_QUERY_RENAME_TRAIN_TYPE_WAGON_CAPTION + this->vehicle_type, MAX_LENGTH_ENGINE_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS); } break; diff --git a/src/engine.cpp b/src/engine.cpp index 8b5902ae08..5ac84021c3 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1135,7 +1135,7 @@ static void NewVehicleAvailable(Engine *e) /* Only provide the "New Vehicle available" news paper entry, if engine can be built. */ if (!IsVehicleTypeDisabled(e->type, false) && (e->info.extra_flags & ExtraEngineFlags::NoNews) == ExtraEngineFlags::None) { SetDParam(0, GetEngineCategoryName(index)); - SetDParam(1, index); + SetDParam(1, PackEngineNameDParam(index, EngineNameContext::PreviewNews)); AddNewsItem(STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE, NT_NEW_VEHICLES, NF_VEHICLE, NR_ENGINE, index); } diff --git a/src/engine_gui.cpp b/src/engine_gui.cpp index ca93526ae4..fba19a2ac4 100644 --- a/src/engine_gui.cpp +++ b/src/engine_gui.cpp @@ -111,7 +111,7 @@ struct EnginePreviewWindow : Window { SetDParam(0, GetEngineCategoryName(engine)); int y = DrawStringMultiLine(r, STR_ENGINE_PREVIEW_MESSAGE, TC_FROMSTRING, SA_HOR_CENTER | SA_TOP) + WidgetDimensions::scaled.vsep_wide; - SetDParam(0, engine); + SetDParam(0, PackEngineNameDParam(engine, EngineNameContext::PreviewNews)); DrawString(r.left, r.right, y, STR_ENGINE_NAME, TC_BLACK, SA_HOR_CENTER); y += FONT_HEIGHT_NORMAL; diff --git a/src/engine_type.h b/src/engine_type.h index 34a498e2c6..ce102b44b3 100644 --- a/src/engine_type.h +++ b/src/engine_type.h @@ -182,6 +182,22 @@ enum EngineFlags { ENGINE_EXCLUSIVE_PREVIEW = 2, ///< This vehicle is in the exclusive preview stage, either being used or being offered to a company. }; +/** + * Contexts an engine name can be shown in. + */ +enum EngineNameContext : uint8 { + Generic = 0x00, ///< No specific context available. + VehicleDetails = 0x11, ///< Name is shown in the vehicle details GUI. + PurchaseList = 0x20, ///< Name is shown in the purchase list (including autoreplace window). + PreviewNews = 0x21, ///< Name is shown in exclusive preview or newspaper. +}; + +/** Combine an engine ID and a name context to an engine name dparam. */ +inline uint64 PackEngineNameDParam(EngineID engine_id, EngineNameContext context, uint32 extra_data = 0) +{ + return engine_id | (static_cast(context) << 32) | (static_cast(extra_data) << 40); +} + static const uint MAX_LENGTH_ENGINE_NAME_CHARS = 64; ///< The maximum length of an engine name in characters including '\0' static const EngineID INVALID_ENGINE = 0xFFFF; ///< Constant denoting an invalid engine. diff --git a/src/newgrf_callbacks.h b/src/newgrf_callbacks.h index 8bcb218a81..08fd8604c0 100644 --- a/src/newgrf_callbacks.h +++ b/src/newgrf_callbacks.h @@ -279,6 +279,9 @@ enum CallbackID { /** Called to spawn visual effects for vehicles. */ CBID_VEHICLE_SPAWN_VISUAL_EFFECT = 0x160, // 15 bit callback + + /** Called to determine the engine name to show. */ + CBID_VEHICLE_NAME = 0x161, // 15 bit callback }; /** @@ -294,6 +297,7 @@ enum VehicleCallbackMask { CBM_VEHICLE_CARGO_SUFFIX = 5, ///< Show suffix after cargo name CBM_VEHICLE_COLOUR_REMAP = 6, ///< Change colour mapping of vehicle CBM_VEHICLE_SOUND_EFFECT = 7, ///< Vehicle uses custom sound effects + CBM_VEHICLE_NAME = 8, ///< Engine name }; /** diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 58b482e347..865a831c8e 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -603,7 +603,7 @@ private: return STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE; case WID_N_VEH_NAME: - SetDParam(0, engine); + SetDParam(0, PackEngineNameDParam(engine, EngineNameContext::PreviewNews)); return STR_NEWS_NEW_VEHICLE_TYPE; default: diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp index 916a22cf58..0f076228cc 100644 --- a/src/roadveh_gui.cpp +++ b/src/roadveh_gui.cpp @@ -31,7 +31,7 @@ void DrawRoadVehDetails(const Vehicle *v, const Rect &r) StringID str; Money feeder_share = 0; - SetDParam(0, v->engine_type); + 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); diff --git a/src/ship_gui.cpp b/src/ship_gui.cpp index bd079fb9fa..492ba87436 100644 --- a/src/ship_gui.cpp +++ b/src/ship_gui.cpp @@ -63,7 +63,7 @@ void DrawShipDetails(const Vehicle *v, const Rect &r) { int y = r.top; - SetDParam(0, v->engine_type); + 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); diff --git a/src/strings.cpp b/src/strings.cpp index 575e0ade42..aa5c774e70 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -36,6 +36,7 @@ #include "tracerestrict.h" #include "game/game_text.hpp" #include "network/network_content_gui.h" +#include "newgrf_engine.h" #include "core/y_combinator.hpp" #include @@ -1717,17 +1718,38 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg } case SCC_ENGINE_NAME: { // {ENGINE} - const Engine *e = Engine::GetIfValid(args->GetInt32(SCC_ENGINE_NAME)); + int64 arg = args->GetInt64(SCC_ENGINE_NAME); + const Engine *e = Engine::GetIfValid(static_cast(arg)); if (e == nullptr) break; if (!e->name.empty() && e->IsEnabled()) { int64 args_array[] = {(int64)(size_t)e->name.c_str()}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); - } else { - StringParameters tmp_params(nullptr, 0, nullptr); - buff = GetStringWithArgs(buff, e->info.string_id, &tmp_params, last); + + break; } + + if (HasBit(e->info.callback_mask, CBM_VEHICLE_NAME)) { + uint16 callback = GetVehicleCallback(CBID_VEHICLE_NAME, static_cast(arg >> 32), 0, e->index, nullptr); + /* Not calling ErrorUnknownCallbackResult due to being inside string processing. */ + if (callback != CALLBACK_FAILED && callback < 0x400) { + const GRFFile *grffile = e->GetGRF(); + assert(grffile != nullptr); + + StartTextRefStackUsage(grffile, 6); + uint64 tmp_dparam[6] = { 0 }; + WChar tmp_type[6] = { 0 }; + StringParameters tmp_params(tmp_dparam, 6, tmp_type); + buff = GetStringWithArgs(buff, GetGRFStringID(grffile->grfid, 0xD000 + callback), &tmp_params, last); + StopTextRefStackUsage(); + + break; + } + } + + StringParameters tmp_params(nullptr, 0, nullptr); + buff = GetStringWithArgs(buff, e->info.string_id, &tmp_params, last); break; } diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 12852ff8c2..d8b3d4cfcc 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -236,7 +236,7 @@ static void TrainDetailsInfoTab(const Train *v, int left, int right, int y, byte uint16 speed; if (rvi->railveh_type == RAILVEH_WAGON) { - SetDParam(0, v->engine_type); + SetDParam(0, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails)); SetDParam(1, v->value); if (show_speed && (speed = GetVehicleProperty(v, PROP_TRAIN_SPEED, rvi->max_speed))) { @@ -248,7 +248,7 @@ static void TrainDetailsInfoTab(const Train *v, int left, int right, int y, byte } else { switch (line_number) { case 0: - SetDParam(0, v->engine_type); + SetDParam(0, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails)); SetDParam(1, v->build_year); SetDParam(2, v->value);