Feature: [NewGRF] Engine name callback.

This commit is contained in:
Michael Lutz 2023-01-22 22:06:48 +01:00
parent 2d73076056
commit 05ed9f56fd
12 changed files with 60 additions and 17 deletions

View File

@ -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);

View File

@ -458,7 +458,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;

View File

@ -145,13 +145,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]));
}
@ -1037,7 +1038,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;
@ -1599,7 +1600,7 @@ struct BuildVehicleWindow : Window {
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;

View File

@ -1049,7 +1049,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);
}

View File

@ -112,7 +112,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;

View File

@ -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<uint64>(context) << 32) | (static_cast<uint64>(extra_data) << 40);
}
static const uint MAX_LENGTH_ENGINE_NAME_CHARS = 32; ///< The maximum length of an engine name in characters including '\0'
static const EngineID INVALID_ENGINE = 0xFFFF; ///< Constant denoting an invalid engine.

View File

@ -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
};
/**

View File

@ -601,7 +601,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:

View File

@ -32,7 +32,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);

View File

@ -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);

View File

@ -34,6 +34,7 @@
#include "debug.h"
#include "game/game_text.hpp"
#include "network/network_content_gui.h"
#include "newgrf_engine.h"
#include <stack>
#include "table/strings.h"
@ -1371,17 +1372,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<EngineID>(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<uint32>(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;
}

View File

@ -227,11 +227,11 @@ static void TrainDetailsCargoTab(const CargoSummaryItem *item, int left, int rig
static void TrainDetailsInfoTab(const Vehicle *v, int left, int right, int y)
{
if (RailVehInfo(v->engine_type)->railveh_type == RAILVEH_WAGON) {
SetDParam(0, v->engine_type);
SetDParam(0, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails));
SetDParam(1, v->value);
DrawString(left, right, y, STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE);
} else {
SetDParam(0, v->engine_type);
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);