mirror of https://github.com/OpenTTD/OpenTTD
Add: [NewGRF] All callbacks returning D0xx strings, have now the option to return any string id via register 0x100.
parent
84bc78fd8f
commit
c6fa5022cb
|
@ -801,6 +801,9 @@ static std::optional<std::string> GetNewGRFAdditionalText(EngineID engine)
|
|||
if (callback == CALLBACK_FAILED || callback == 0x400) return std::nullopt;
|
||||
const GRFFile *grffile = Engine::Get(engine)->GetGRF();
|
||||
assert(grffile != nullptr);
|
||||
if (callback == 0x40F) {
|
||||
return GetGRFStringWithTextStack(grffile, static_cast<GRFStringID>(regs100[0]), std::span{regs100}.subspan(1));
|
||||
}
|
||||
if (callback > 0x400) {
|
||||
ErrorUnknownCallbackResult(grffile->grfid, CBID_VEHICLE_ADDITIONAL_TEXT, callback);
|
||||
return std::nullopt;
|
||||
|
|
|
@ -116,10 +116,22 @@ static void GetCargoSuffix(uint cargo, CargoSuffixType cst, const Industry *ind,
|
|||
return;
|
||||
|
||||
} else { // GRF version 8 or higher.
|
||||
if (callback == 0x400) return;
|
||||
if (callback == 0x401) {
|
||||
suffix.display = CSD_CARGO;
|
||||
return;
|
||||
switch (callback) {
|
||||
case 0x400:
|
||||
return;
|
||||
case 0x401:
|
||||
suffix.display = CSD_CARGO;
|
||||
return;
|
||||
case 0x40E:
|
||||
suffix.display = CSD_CARGO_TEXT;
|
||||
suffix.text = GetGRFStringWithTextStack(indspec->grf_prop.grffile, static_cast<GRFStringID>(regs100[0]), std::span{regs100}.subspan(1));
|
||||
return;
|
||||
case 0x40F:
|
||||
suffix.display = CSD_CARGO_AMOUNT_TEXT;
|
||||
suffix.text = GetGRFStringWithTextStack(indspec->grf_prop.grffile, static_cast<GRFStringID>(regs100[0]), std::span{regs100}.subspan(1));
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (callback < 0x400) {
|
||||
suffix.text = GetGRFStringWithTextStack(indspec->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback, regs100);
|
||||
|
@ -594,13 +606,16 @@ public:
|
|||
std::array<int32_t, 6> regs100;
|
||||
uint16_t callback_res = GetIndustryCallback(CBID_INDUSTRY_FUND_MORE_TEXT, 0, 0, nullptr, this->selected_type, INVALID_TILE, regs100);
|
||||
if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
|
||||
if (callback_res > 0x400) {
|
||||
std::string str;
|
||||
if (callback_res == 0x40F) {
|
||||
str = GetGRFStringWithTextStack(indsp->grf_prop.grffile, static_cast<GRFStringID>(regs100[0]), std::span{regs100}.subspan(1));
|
||||
} else if (callback_res > 0x400) {
|
||||
ErrorUnknownCallbackResult(indsp->grf_prop.grfid, CBID_INDUSTRY_FUND_MORE_TEXT, callback_res);
|
||||
} else {
|
||||
std::string str = GetGRFStringWithTextStack(indsp->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback_res, regs100);
|
||||
if (!str.empty()) {
|
||||
DrawStringMultiLine(ir, str, TC_YELLOW);
|
||||
}
|
||||
str = GetGRFStringWithTextStack(indsp->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback_res, regs100);
|
||||
}
|
||||
if (!str.empty()) {
|
||||
DrawStringMultiLine(ir, str, TC_YELLOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -977,14 +992,17 @@ public:
|
|||
std::array<int32_t, 6> regs100;
|
||||
uint16_t callback_res = GetIndustryCallback(CBID_INDUSTRY_WINDOW_MORE_TEXT, 0, 0, i, i->type, i->location.tile, regs100);
|
||||
if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
|
||||
if (callback_res > 0x400) {
|
||||
std::string str;
|
||||
if (callback_res == 0x40F) {
|
||||
str = GetGRFStringWithTextStack(ind->grf_prop.grffile, static_cast<GRFStringID>(regs100[0]), std::span{regs100}.subspan(1));
|
||||
} else if (callback_res > 0x400) {
|
||||
ErrorUnknownCallbackResult(ind->grf_prop.grfid, CBID_INDUSTRY_WINDOW_MORE_TEXT, callback_res);
|
||||
} else {
|
||||
std::string str = GetGRFStringWithTextStack(ind->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback_res, regs100);
|
||||
if (!str.empty()) {
|
||||
ir.top += WidgetDimensions::scaled.vsep_wide;
|
||||
ir.top = DrawStringMultiLine(ir, str, TC_YELLOW);
|
||||
}
|
||||
str = GetGRFStringWithTextStack(ind->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback_res, regs100);
|
||||
}
|
||||
if (!str.empty()) {
|
||||
ir.top += WidgetDimensions::scaled.vsep_wide;
|
||||
ir.top = DrawStringMultiLine(ir, str, TC_YELLOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -280,8 +280,12 @@ uint16_t GetAirportCallback(CallbackID callback, uint32_t param1, uint32_t param
|
|||
StringID GetAirportTextCallback(const AirportSpec *as, uint8_t layout, uint16_t callback)
|
||||
{
|
||||
AirportResolverObject object(INVALID_TILE, nullptr, as, layout, (CallbackID)callback);
|
||||
uint16_t cb_res = object.ResolveCallback({});
|
||||
std::array<int32_t, 1> regs100;
|
||||
uint16_t cb_res = object.ResolveCallback(regs100);
|
||||
if (cb_res == CALLBACK_FAILED || cb_res == 0x400) return STR_UNDEFINED;
|
||||
if (cb_res == 0x40F) {
|
||||
return GetGRFStringID(as->grf_prop.grfid, static_cast<GRFStringID>(regs100[0]));
|
||||
}
|
||||
if (cb_res > 0x400) {
|
||||
ErrorUnknownCallbackResult(as->grf_prop.grfid, callback, cb_res);
|
||||
return STR_UNDEFINED;
|
||||
|
|
|
@ -470,17 +470,22 @@ uint32_t GetCompanyInfo(CompanyID owner, const Livery *l)
|
|||
*/
|
||||
CommandCost GetErrorMessageFromLocationCallbackResult(uint16_t cb_res, std::span<const int32_t> textstack, const GRFFile *grffile, StringID default_error)
|
||||
{
|
||||
CommandCost res;
|
||||
|
||||
if (cb_res < 0x400) {
|
||||
res = CommandCost(GetGRFStringID(grffile->grfid, GRFSTR_MISC_GRF_TEXT + cb_res));
|
||||
auto get_newgrf_text = [&grffile](GRFStringID text_id, std::span<const int32_t> textstack) {
|
||||
CommandCost res = CommandCost(GetGRFStringID(grffile->grfid, text_id));
|
||||
|
||||
/* If this error isn't for the local player then it won't be seen, so don't bother encoding anything. */
|
||||
if (!IsLocalCompany()) return res;
|
||||
if (IsLocalCompany()) {
|
||||
StringID stringid = GetGRFStringID(grffile->grfid, text_id);
|
||||
auto params = GetGRFSringTextStackParameters(grffile, stringid, textstack);
|
||||
res.SetEncodedMessage(GetEncodedStringWithArgs(stringid, params));
|
||||
}
|
||||
|
||||
StringID stringid = GetGRFStringID(grffile->grfid, GRFSTR_MISC_GRF_TEXT + cb_res);
|
||||
auto params = GetGRFSringTextStackParameters(grffile, stringid, textstack);
|
||||
res.SetEncodedMessage(GetEncodedStringWithArgs(stringid, params));
|
||||
return res;
|
||||
};
|
||||
|
||||
CommandCost res;
|
||||
if (cb_res < 0x400) {
|
||||
res = get_newgrf_text(GRFSTR_MISC_GRF_TEXT + cb_res, textstack);
|
||||
} else {
|
||||
switch (cb_res) {
|
||||
case 0x400: return res; // No error.
|
||||
|
@ -495,6 +500,7 @@ CommandCost GetErrorMessageFromLocationCallbackResult(uint16_t cb_res, std::span
|
|||
case 0x406: res = CommandCost(STR_ERROR_CAN_T_BUILD_ON_SEA); break;
|
||||
case 0x407: res = CommandCost(STR_ERROR_CAN_T_BUILD_ON_CANAL); break;
|
||||
case 0x408: res = CommandCost(STR_ERROR_CAN_T_BUILD_ON_RIVER); break;
|
||||
case 0x40F: res = get_newgrf_text(static_cast<GRFStringID>(textstack[0]), textstack.subspan(1)); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -240,13 +240,16 @@ public:
|
|||
std::array<int32_t, 6> regs100;
|
||||
uint16_t callback_res = GetObjectCallback(CBID_OBJECT_FUND_MORE_TEXT, 0, 0, spec, nullptr, INVALID_TILE, regs100, _object_gui.sel_view);
|
||||
if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
|
||||
if (callback_res > 0x400) {
|
||||
std::string str;
|
||||
if (callback_res == 0x40F) {
|
||||
str = GetGRFStringWithTextStack(spec->grf_prop.grffile, static_cast<GRFStringID>(regs100[0]), std::span{regs100}.subspan(1));
|
||||
} else if (callback_res > 0x400) {
|
||||
ErrorUnknownCallbackResult(spec->grf_prop.grfid, CBID_OBJECT_FUND_MORE_TEXT, callback_res);
|
||||
} else {
|
||||
std::string str = GetGRFStringWithTextStack(spec->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback_res, regs100);
|
||||
if (!str.empty()) {
|
||||
tr.top = DrawStringMultiLine(tr, str, TC_ORANGE);
|
||||
}
|
||||
str = GetGRFStringWithTextStack(spec->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback_res, regs100);
|
||||
}
|
||||
if (!str.empty()) {
|
||||
tr.top = DrawStringMultiLine(tr, str, TC_ORANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1613,7 +1613,13 @@ static void FormatString(StringBuilder &builder, std::string_view str_arg, Strin
|
|||
std::array<int32_t, 6> regs100;
|
||||
uint16_t callback = GetVehicleCallback(CBID_VEHICLE_NAME, static_cast<uint32_t>(arg >> 32), 0, e->index, nullptr, regs100);
|
||||
/* Not calling ErrorUnknownCallbackResult due to being inside string processing. */
|
||||
if (callback != CALLBACK_FAILED && callback < 0x400) {
|
||||
if (callback == 0x40F) {
|
||||
const GRFFile *grffile = e->GetGRF();
|
||||
assert(grffile != nullptr);
|
||||
|
||||
builder += GetGRFStringWithTextStack(grffile, static_cast<GRFStringID>(regs100[0]), std::span{regs100}.subspan(1));
|
||||
break;
|
||||
} else if (callback < 0x400) {
|
||||
const GRFFile *grffile = e->GetGRF();
|
||||
assert(grffile != nullptr);
|
||||
|
||||
|
|
|
@ -862,15 +862,19 @@ static void GetTileDesc_Town(TileIndex tile, TileDesc &td)
|
|||
td.str = hs->building_name;
|
||||
td.town_can_upgrade = !IsHouseProtected(tile);
|
||||
|
||||
uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile);
|
||||
std::array<int32_t, 1> regs100;
|
||||
uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile, regs100);
|
||||
if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
|
||||
if (callback_res > 0x400) {
|
||||
StringID new_name = STR_NULL;
|
||||
if (callback_res == 0x40F) {
|
||||
new_name = GetGRFStringID(hs->grf_prop.grfid, static_cast<GRFStringID>(regs100[0]));
|
||||
} else if (callback_res > 0x400) {
|
||||
ErrorUnknownCallbackResult(hs->grf_prop.grfid, CBID_HOUSE_CUSTOM_NAME, callback_res);
|
||||
} else {
|
||||
StringID new_name = GetGRFStringID(hs->grf_prop.grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
|
||||
if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
|
||||
td.str = new_name;
|
||||
}
|
||||
new_name = GetGRFStringID(hs->grf_prop.grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
|
||||
}
|
||||
if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
|
||||
td.str = new_name;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1410,15 +1410,19 @@ void DrawHouseInGUI(int x, int y, HouseID house_id, int view)
|
|||
*/
|
||||
static StringID GetHouseName(const HouseSpec *hs)
|
||||
{
|
||||
uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, 1, 0, hs->Index(), nullptr, INVALID_TILE, {}, true);
|
||||
std::array<int32_t, 1> regs100;
|
||||
uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, 1, 0, hs->Index(), nullptr, INVALID_TILE, regs100, true);
|
||||
if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
|
||||
if (callback_res > 0x400) {
|
||||
StringID new_name = STR_NULL;
|
||||
if (callback_res == 0x40F) {
|
||||
new_name = GetGRFStringID(hs->grf_prop.grffile->grfid, static_cast<GRFStringID>(regs100[0]));
|
||||
} else if (callback_res > 0x400) {
|
||||
ErrorUnknownCallbackResult(hs->grf_prop.grffile->grfid, CBID_HOUSE_CUSTOM_NAME, callback_res);
|
||||
} else {
|
||||
StringID new_name = GetGRFStringID(hs->grf_prop.grffile->grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
|
||||
if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
|
||||
return new_name;
|
||||
}
|
||||
new_name = GetGRFStringID(hs->grf_prop.grffile->grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
|
||||
}
|
||||
if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
|
||||
return new_name;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1041,7 +1041,8 @@ static CommandCost CheckTrainAttachment(Train *t)
|
|||
* the loop and after each callback does not need to be cleared here. */
|
||||
t->InvalidateNewGRFCache();
|
||||
|
||||
uint16_t callback = GetVehicleCallbackParent(CBID_TRAIN_ALLOW_WAGON_ATTACH, 0, 0, head->engine_type, t, head);
|
||||
std::array<int32_t, 1> regs100;
|
||||
uint16_t callback = GetVehicleCallbackParent(CBID_TRAIN_ALLOW_WAGON_ATTACH, 0, 0, head->engine_type, t, head, regs100);
|
||||
|
||||
/* Restore original first_engine data */
|
||||
t->gcache.first_engine = first_engine;
|
||||
|
@ -1067,6 +1068,10 @@ static CommandCost CheckTrainAttachment(Train *t)
|
|||
case 0x401: // allow
|
||||
break;
|
||||
|
||||
case 0x40F:
|
||||
error = GetGRFStringID(head->GetGRFID(), static_cast<GRFStringID>(regs100[0]));
|
||||
break;
|
||||
|
||||
default: // unknown reason -> disallow
|
||||
case 0x402: // disallow attaching
|
||||
error = STR_ERROR_INCOMPATIBLE_RAIL_TYPES;
|
||||
|
|
|
@ -617,7 +617,8 @@ CommandCost CmdStartStopVehicle(DoCommandFlags flags, VehicleID veh_id, bool eva
|
|||
|
||||
if (evaluate_startstop_cb) {
|
||||
/* Check if this vehicle can be started/stopped. Failure means 'allow'. */
|
||||
uint16_t callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
|
||||
std::array<int32_t, 1> regs100;
|
||||
uint16_t callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v, regs100);
|
||||
StringID error = STR_NULL;
|
||||
if (callback != CALLBACK_FAILED) {
|
||||
if (v->GetGRF()->grf_version < 8) {
|
||||
|
@ -631,6 +632,10 @@ CommandCost CmdStartStopVehicle(DoCommandFlags flags, VehicleID veh_id, bool eva
|
|||
case 0x400: // allow
|
||||
break;
|
||||
|
||||
case 0x40F:
|
||||
error = GetGRFStringID(v->GetGRFID(), static_cast<GRFStringID>(regs100[0]));
|
||||
break;
|
||||
|
||||
default: // unknown reason -> disallow
|
||||
error = STR_ERROR_INCOMPATIBLE_RAIL_TYPES;
|
||||
break;
|
||||
|
|
|
@ -1387,17 +1387,19 @@ uint ShowRefitOptionsList(int left, int right, int y, EngineID engine)
|
|||
/** Get the cargo subtype text from NewGRF for the vehicle details window. */
|
||||
StringID GetCargoSubtypeText(const Vehicle *v)
|
||||
{
|
||||
if (EngInfo(v->engine_type)->callback_mask.Test(VehicleCallbackMask::CargoSuffix)) {
|
||||
uint16_t cb = GetVehicleCallback(CBID_VEHICLE_CARGO_SUFFIX, 0, 0, v->engine_type, v);
|
||||
if (cb != CALLBACK_FAILED) {
|
||||
if (cb > 0x400) ErrorUnknownCallbackResult(v->GetGRFID(), CBID_VEHICLE_CARGO_SUFFIX, cb);
|
||||
if (cb >= 0x400 || (v->GetGRF()->grf_version < 8 && cb == 0xFF)) cb = CALLBACK_FAILED;
|
||||
}
|
||||
if (cb != CALLBACK_FAILED) {
|
||||
return GetGRFStringID(v->GetGRFID(), GRFSTR_MISC_GRF_TEXT + cb);
|
||||
}
|
||||
if (!EngInfo(v->engine_type)->callback_mask.Test(VehicleCallbackMask::CargoSuffix)) return STR_EMPTY;
|
||||
std::array<int32_t, 1> regs100;
|
||||
uint16_t cb = GetVehicleCallback(CBID_VEHICLE_CARGO_SUFFIX, 0, 0, v->engine_type, v, regs100);
|
||||
if (v->GetGRF()->grf_version < 8 && cb == 0xFF) return STR_EMPTY;
|
||||
if (cb == CALLBACK_FAILED || cb == 0x400) return STR_EMPTY;
|
||||
if (cb == 0x40F) {
|
||||
return GetGRFStringID(v->GetGRFID(), static_cast<GRFStringID>(regs100[0]));
|
||||
}
|
||||
return STR_EMPTY;
|
||||
if (cb > 0x400) {
|
||||
ErrorUnknownCallbackResult(v->GetGRFID(), CBID_VEHICLE_CARGO_SUFFIX, cb);
|
||||
return STR_EMPTY;
|
||||
}
|
||||
return GetGRFStringID(v->GetGRFID(), GRFSTR_MISC_GRF_TEXT + cb);
|
||||
}
|
||||
|
||||
/** Sort vehicle groups by the number of vehicles in the group */
|
||||
|
|
Loading…
Reference in New Issue