1
0
Fork 0

Codechange: use StringParameters to pass parameters for News strings

pull/11956/head
Patric Stout 2024-02-02 18:54:15 +01:00
parent bd80ff4d57
commit 5a7a1f9543
22 changed files with 136 additions and 149 deletions

View File

@ -1350,7 +1350,7 @@ static void CrashAirplane(Aircraft *v)
newstype = NT_ACCIDENT_OTHER; newstype = NT_ACCIDENT_OTHER;
} }
AddTileNewsItem(newsitem, newstype, vt, nullptr, st != nullptr ? st->index : INVALID_STATION); AddTileNewsItem(newsitem, MakeParameters(), newstype, vt, nullptr, st != nullptr ? st->index : INVALID_STATION);
ModifyStationRatingAround(vt, v->owner, -160, 30); ModifyStationRatingAround(vt, v->owner, -160, 30);
if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v); if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v);
@ -1401,10 +1401,10 @@ static void AircraftEntersTerminal(Aircraft *v)
/* Check if station was ever visited before */ /* Check if station was ever visited before */
if (!(st->had_vehicle_of_type & HVOT_AIRCRAFT)) { if (!(st->had_vehicle_of_type & HVOT_AIRCRAFT)) {
st->had_vehicle_of_type |= HVOT_AIRCRAFT; st->had_vehicle_of_type |= HVOT_AIRCRAFT;
SetDParam(0, st->index);
/* show newsitem of celebrating citizens */ /* show newsitem of celebrating citizens */
AddVehicleNewsItem( AddVehicleNewsItem(
STR_NEWS_FIRST_AIRCRAFT_ARRIVAL, STR_NEWS_FIRST_AIRCRAFT_ARRIVAL,
MakeParameters(st->index),
(v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER, (v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER,
v->index, v->index,
st->index st->index
@ -2052,8 +2052,7 @@ static void AircraftHandleDestTooFar(Aircraft *v, bool too_far)
AI::NewEvent(v->owner, new ScriptEventAircraftDestTooFar(v->index)); AI::NewEvent(v->owner, new ScriptEventAircraftDestTooFar(v->index));
if (v->owner == _local_company) { if (v->owner == _local_company) {
/* Post a news message. */ /* Post a news message. */
SetDParam(0, v->index); AddVehicleAdviceNewsItem(STR_NEWS_AIRCRAFT_DEST_TOO_FAR, MakeParameters(v->index), v->index);
AddVehicleAdviceNewsItem(STR_NEWS_AIRCRAFT_DEST_TOO_FAR, v->index);
} }
} }
return; return;

View File

@ -333,20 +333,22 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
if (!IsValidCargoID(refit_cargo)) { if (!IsValidCargoID(refit_cargo)) {
if (!IsLocalCompany()) return CommandCost(); if (!IsLocalCompany()) return CommandCost();
SetDParam(0, old_veh->index); ArrayStringParameters<3> params;
params.SetParam(0, old_veh->index);
int order_id = GetIncompatibleRefitOrderIdForAutoreplace(old_veh, e); int order_id = GetIncompatibleRefitOrderIdForAutoreplace(old_veh, e);
if (order_id != -1) { if (order_id != -1) {
/* Orders contained a refit order that is incompatible with the new vehicle. */ /* Orders contained a refit order that is incompatible with the new vehicle. */
SetDParam(1, STR_ERROR_AUTOREPLACE_INCOMPATIBLE_REFIT); params.SetParam(1, STR_ERROR_AUTOREPLACE_INCOMPATIBLE_REFIT);
SetDParam(2, order_id + 1); // 1-based indexing for display params.SetParam(2, order_id + 1); // 1-based indexing for display
} else { } else {
/* Current cargo is incompatible with the new vehicle. */ /* Current cargo is incompatible with the new vehicle. */
SetDParam(1, STR_ERROR_AUTOREPLACE_INCOMPATIBLE_CARGO); params.SetParam(1, STR_ERROR_AUTOREPLACE_INCOMPATIBLE_CARGO);
SetDParam(2, CargoSpec::Get(old_veh->cargo_type)->name); params.SetParam(2, CargoSpec::Get(old_veh->cargo_type)->name);
} }
AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_AUTORENEW_FAILED, old_veh->index); AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_AUTORENEW_FAILED, std::move(params), old_veh->index);
return CommandCost(); return CommandCost();
} }

View File

@ -424,11 +424,13 @@ set_name:;
if (c->is_ai) { if (c->is_ai) {
CompanyNewsInformation *cni = new CompanyNewsInformation(c); CompanyNewsInformation *cni = new CompanyNewsInformation(c);
SetDParam(0, STR_NEWS_COMPANY_LAUNCH_TITLE); auto params = MakeParameters(
SetDParam(1, STR_NEWS_COMPANY_LAUNCH_DESCRIPTION); STR_NEWS_COMPANY_LAUNCH_TITLE,
SetDParamStr(2, cni->company_name); STR_NEWS_COMPANY_LAUNCH_DESCRIPTION,
SetDParam(3, t->index); cni->company_name,
AddNewsItem(STR_MESSAGE_NEWS_FORMAT, NT_COMPANY_INFO, NF_COMPANY, NR_TILE, c->last_build_coordinate.base(), NR_NONE, UINT32_MAX, cni); t->index
);
AddNewsItem(STR_MESSAGE_NEWS_FORMAT, std::move(params), NT_COMPANY_INFO, NF_COMPANY, NR_TILE, c->last_build_coordinate.base(), NR_NONE, UINT32_MAX, cni);
} }
return; return;
} }
@ -940,10 +942,7 @@ CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID
CompanyNewsInformation *cni = new CompanyNewsInformation(c); CompanyNewsInformation *cni = new CompanyNewsInformation(c);
/* Show the bankrupt news */ /* Show the bankrupt news */
SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE); AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, MakeParameters(STR_NEWS_COMPANY_BANKRUPT_TITLE, STR_NEWS_COMPANY_BANKRUPT_DESCRIPTION, cni->company_name), cni);
SetDParam(1, STR_NEWS_COMPANY_BANKRUPT_DESCRIPTION);
SetDParamStr(2, cni->company_name);
AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, cni);
/* Remove the company */ /* Remove the company */
ChangeOwnershipOfCompanyItems(c->index, INVALID_OWNER); ChangeOwnershipOfCompanyItems(c->index, INVALID_OWNER);

View File

@ -146,7 +146,7 @@ static IntervalTimer<TimerGameCalendar> _check_switch_to_euro({TimerGameCalendar
_currency_specs[_settings_game.locale.currency].to_euro != CF_ISEURO && _currency_specs[_settings_game.locale.currency].to_euro != CF_ISEURO &&
TimerGameCalendar::year >= _currency_specs[_settings_game.locale.currency].to_euro) { TimerGameCalendar::year >= _currency_specs[_settings_game.locale.currency].to_euro) {
_settings_game.locale.currency = 2; // this is the index of euro above. _settings_game.locale.currency = 2; // this is the index of euro above.
AddNewsItem(STR_NEWS_EURO_INTRODUCTION, NT_ECONOMY, NF_NORMAL); AddNewsItem(STR_NEWS_EURO_INTRODUCTION, MakeParameters(), NT_ECONOMY, NF_NORMAL);
} }
}); });

View File

@ -245,8 +245,7 @@ static bool DisasterTick_Zeppeliner(DisasterVehicle *v)
v->state = 1; v->state = 1;
v->age = 0; v->age = 0;
SetDParam(0, GetStationIndex(v->tile)); AddTileNewsItem(STR_NEWS_DISASTER_ZEPPELIN, MakeParameters(GetStationIndex(v->tile)), NT_ACCIDENT, v->tile);
AddTileNewsItem(STR_NEWS_DISASTER_ZEPPELIN, NT_ACCIDENT, v->tile);
AI::NewEvent(GetTileOwner(v->tile), new ScriptEventDisasterZeppelinerCrashed(GetStationIndex(v->tile))); AI::NewEvent(GetTileOwner(v->tile), new ScriptEventDisasterZeppelinerCrashed(GetStationIndex(v->tile)));
} }
} }
@ -380,7 +379,7 @@ static bool DisasterTick_Ufo(DisasterVehicle *v)
if (u->crashed_ctr == 0) { if (u->crashed_ctr == 0) {
u->Crash(); u->Crash();
AddTileNewsItem(STR_NEWS_DISASTER_SMALL_UFO, NT_ACCIDENT, u->tile); AddTileNewsItem(STR_NEWS_DISASTER_SMALL_UFO, MakeParameters(), NT_ACCIDENT, u->tile);
AI::NewEvent(u->owner, new ScriptEventVehicleCrashed(u->index, u->tile, ScriptEventVehicleCrashed::CRASH_RV_UFO)); AI::NewEvent(u->owner, new ScriptEventVehicleCrashed(u->index, u->tile, ScriptEventVehicleCrashed::CRASH_RV_UFO));
Game::NewEvent(new ScriptEventVehicleCrashed(u->index, u->tile, ScriptEventVehicleCrashed::CRASH_RV_UFO)); Game::NewEvent(new ScriptEventVehicleCrashed(u->index, u->tile, ScriptEventVehicleCrashed::CRASH_RV_UFO));
@ -458,8 +457,7 @@ static bool DisasterTick_Aircraft(DisasterVehicle *v, uint16_t image_override, b
Industry *i = Industry::Get(v->dest_tile.base()); // Industry destructor calls ReleaseDisastersTargetingIndustry, so this is valid Industry *i = Industry::Get(v->dest_tile.base()); // Industry destructor calls ReleaseDisastersTargetingIndustry, so this is valid
DestructIndustry(i); DestructIndustry(i);
SetDParam(0, i->town->index); AddIndustryNewsItem(news_message, MakeParameters(i->town->index), NT_ACCIDENT, i->index);
AddIndustryNewsItem(news_message, NT_ACCIDENT, i->index);
if (_settings_client.sound.disaster) SndPlayTileFx(SND_12_EXPLOSION, i->location.tile); if (_settings_client.sound.disaster) SndPlayTileFx(SND_12_EXPLOSION, i->location.tile);
} }
} else if (v->state == 0) { } else if (v->state == 0) {
@ -554,8 +552,7 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v)
} }
Town *t = ClosestTownFromTile(v->dest_tile, UINT_MAX); Town *t = ClosestTownFromTile(v->dest_tile, UINT_MAX);
SetDParam(0, t->index); AddTileNewsItem(STR_NEWS_DISASTER_BIG_UFO, MakeParameters(t->index), NT_ACCIDENT, v->tile);
AddTileNewsItem(STR_NEWS_DISASTER_BIG_UFO, NT_ACCIDENT, v->tile);
if (!Vehicle::CanAllocateItem(2)) { if (!Vehicle::CanAllocateItem(2)) {
delete v; delete v;
@ -880,8 +877,7 @@ static void Disaster_CoalMine_Init()
for (m = 0; m < 15; m++) { for (m = 0; m < 15; m++) {
for (const Industry *i : Industry::Iterate()) { for (const Industry *i : Industry::Iterate()) {
if ((GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_CAN_SUBSIDENCE) && --index < 0) { if ((GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_CAN_SUBSIDENCE) && --index < 0) {
SetDParam(0, i->town->index); AddTileNewsItem(STR_NEWS_DISASTER_COAL_MINE_SUBSIDENCE, MakeParameters(i->town->index), NT_ACCIDENT, i->location.tile + TileDiffXY(1, 1)); // keep the news, even when the mine closes
AddTileNewsItem(STR_NEWS_DISASTER_COAL_MINE_SUBSIDENCE, NT_ACCIDENT, i->location.tile + TileDiffXY(1, 1)); // keep the news, even when the mine closes
{ {
TileIndex tile = i->location.tile; TileIndex tile = i->location.tile;

View File

@ -599,10 +599,7 @@ static void CompanyCheckBankrupt(Company *c)
/* Warn about bankruptcy after 3 months */ /* Warn about bankruptcy after 3 months */
case 4: { case 4: {
CompanyNewsInformation *cni = new CompanyNewsInformation(c); CompanyNewsInformation *cni = new CompanyNewsInformation(c);
SetDParam(0, STR_NEWS_COMPANY_IN_TROUBLE_TITLE); AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, MakeParameters(STR_NEWS_COMPANY_IN_TROUBLE_TITLE, STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION, cni->company_name), cni);
SetDParam(1, STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION);
SetDParamStr(2, cni->company_name);
AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, cni);
AI::BroadcastNewEvent(new ScriptEventCompanyInTrouble(c->index)); AI::BroadcastNewEvent(new ScriptEventCompanyInTrouble(c->index));
Game::NewEvent(new ScriptEventCompanyInTrouble(c->index)); Game::NewEvent(new ScriptEventCompanyInTrouble(c->index));
break; break;
@ -877,10 +874,10 @@ static void HandleEconomyFluctuations()
if (_economy.fluct == 0) { if (_economy.fluct == 0) {
_economy.fluct = -(int)GB(Random(), 0, 2); _economy.fluct = -(int)GB(Random(), 0, 2);
AddNewsItem(STR_NEWS_BEGIN_OF_RECESSION, NT_ECONOMY, NF_NORMAL); AddNewsItem(STR_NEWS_BEGIN_OF_RECESSION, MakeParameters(), NT_ECONOMY, NF_NORMAL);
} else if (_economy.fluct == -12) { } else if (_economy.fluct == -12) {
_economy.fluct = GB(Random(), 0, 8) + 312; _economy.fluct = GB(Random(), 0, 8) + 312;
AddNewsItem(STR_NEWS_END_OF_RECESSION, NT_ECONOMY, NF_NORMAL); AddNewsItem(STR_NEWS_END_OF_RECESSION, MakeParameters(), NT_ECONOMY, NF_NORMAL);
} }
} }
@ -2014,12 +2011,14 @@ static void DoAcquireCompany(Company *c, bool hostile_takeover)
CompanyNewsInformation *cni = new CompanyNewsInformation(c, Company::Get(_current_company)); CompanyNewsInformation *cni = new CompanyNewsInformation(c, Company::Get(_current_company));
SetDParam(0, STR_NEWS_COMPANY_MERGER_TITLE); auto params = MakeParameters(
SetDParam(1, hostile_takeover ? STR_NEWS_MERGER_TAKEOVER_TITLE : STR_NEWS_COMPANY_MERGER_DESCRIPTION); STR_NEWS_COMPANY_MERGER_TITLE,
SetDParamStr(2, cni->company_name); hostile_takeover ? STR_NEWS_MERGER_TAKEOVER_TITLE : STR_NEWS_COMPANY_MERGER_DESCRIPTION,
SetDParamStr(3, cni->other_company_name); cni->company_name,
SetDParam(4, c->bankrupt_value); cni->other_company_name,
AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, cni); c->bankrupt_value
);
AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, std::move(params), cni);
AI::BroadcastNewEvent(new ScriptEventCompanyMerger(ci, _current_company)); AI::BroadcastNewEvent(new ScriptEventCompanyMerger(ci, _current_company));
Game::NewEvent(new ScriptEventCompanyMerger(ci, _current_company)); Game::NewEvent(new ScriptEventCompanyMerger(ci, _current_company));

View File

@ -1091,9 +1091,7 @@ static void NewVehicleAvailable(Engine *e)
/* Only provide the "New Vehicle available" news paper entry, if engine can be built. */ /* 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) { if (!IsVehicleTypeDisabled(e->type, false) && (e->info.extra_flags & ExtraEngineFlags::NoNews) == ExtraEngineFlags::None) {
SetDParam(0, GetEngineCategoryName(index)); AddNewsItem(STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE, MakeParameters(GetEngineCategoryName(index), PackEngineNameDParam(index, EngineNameContext::PreviewNews)), NT_NEW_VEHICLES, NF_VEHICLE, NR_ENGINE, index);
SetDParam(1, PackEngineNameDParam(index, EngineNameContext::PreviewNews));
AddNewsItem(STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE, NT_NEW_VEHICLES, NF_VEHICLE, NR_ENGINE, index);
} }
/* Update the toolbar. */ /* Update the toolbar. */

View File

@ -1728,14 +1728,15 @@ static CommandCost CheckIfFarEnoughFromConflictingIndustry(TileIndex tile, int t
static void AdvertiseIndustryOpening(const Industry *ind) static void AdvertiseIndustryOpening(const Industry *ind)
{ {
const IndustrySpec *ind_spc = GetIndustrySpec(ind->type); const IndustrySpec *ind_spc = GetIndustrySpec(ind->type);
SetDParam(0, ind_spc->name); ArrayStringParameters<3> params;
params.SetParam(0, ind_spc->name);
if (ind_spc->new_industry_text > STR_LAST_STRINGID) { if (ind_spc->new_industry_text > STR_LAST_STRINGID) {
SetDParam(1, STR_TOWN_NAME); params.SetParam(1, STR_TOWN_NAME);
SetDParam(2, ind->town->index); params.SetParam(2, ind->town->index);
} else { } else {
SetDParam(1, ind->town->index); params.SetParam(1, ind->town->index);
} }
AddIndustryNewsItem(ind_spc->new_industry_text, NT_INDUSTRY_OPEN, ind->index); AddIndustryNewsItem(ind_spc->new_industry_text, std::move(params), NT_INDUSTRY_OPEN, ind->index);
AI::BroadcastNewEvent(new ScriptEventIndustryOpen(ind->index)); AI::BroadcastNewEvent(new ScriptEventIndustryOpen(ind->index));
Game::NewEvent(new ScriptEventIndustryOpen(ind->index)); Game::NewEvent(new ScriptEventIndustryOpen(ind->index));
} }
@ -2185,17 +2186,18 @@ CommandCost CmdIndustrySetProduction(DoCommandFlag flags, IndustryID ind_id, byt
/* Set parameters of news string */ /* Set parameters of news string */
NewsAllocatedData *data = nullptr; NewsAllocatedData *data = nullptr;
ArrayStringParameters<3> params;
if (str == STR_NEWS_CUSTOM_ITEM) { if (str == STR_NEWS_CUSTOM_ITEM) {
NewsStringData *news = new NewsStringData(custom_news); NewsStringData *news = new NewsStringData(custom_news);
SetDParamStr(0, news->string); params.SetParam(0, news->string);
} else if (str > STR_LAST_STRINGID) { } else if (str > STR_LAST_STRINGID) {
SetDParam(0, STR_TOWN_NAME); params.SetParam(0, STR_TOWN_NAME);
SetDParam(1, ind->town->index); params.SetParam(1, ind->town->index);
SetDParam(2, GetIndustrySpec(ind->type)->name); params.SetParam(2, GetIndustrySpec(ind->type)->name);
} else { } else {
SetDParam(0, ind->index); params.SetParam(0, ind->index);
} }
AddIndustryNewsItem(str, nt, ind->index, data); AddIndustryNewsItem(str, std::move(params), nt, ind->index, data);
} }
} }
@ -2768,11 +2770,9 @@ static void ReportNewsProductionChangeIndustry(Industry *ind, CargoID type, int
case 2: nt = NT_INDUSTRY_COMPANY; break; case 2: nt = NT_INDUSTRY_COMPANY; break;
default: NOT_REACHED(); default: NOT_REACHED();
} }
SetDParam(2, abs(percent));
SetDParam(0, CargoSpec::Get(type)->name);
SetDParam(1, ind->index);
AddIndustryNewsItem( AddIndustryNewsItem(
percent >= 0 ? STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH : STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH, percent >= 0 ? STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH : STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH,
MakeParameters(CargoSpec::Get(type)->name, ind->index, abs(percent)),
nt, nt,
ind->index ind->index
); );
@ -2974,23 +2974,24 @@ static void ChangeIndustryProduction(Industry *i, bool monthly)
default: NOT_REACHED(); default: NOT_REACHED();
} }
} }
ArrayStringParameters<3> params;
/* Set parameters of news string */ /* Set parameters of news string */
if (str > STR_LAST_STRINGID) { if (str > STR_LAST_STRINGID) {
SetDParam(0, STR_TOWN_NAME); params.SetParam(0, STR_TOWN_NAME);
SetDParam(1, i->town->index); params.SetParam(1, i->town->index);
SetDParam(2, indspec->name); params.SetParam(2, indspec->name);
} else if (closeit) { } else if (closeit) {
SetDParam(0, STR_FORMAT_INDUSTRY_NAME); params.SetParam(0, STR_FORMAT_INDUSTRY_NAME);
SetDParam(1, i->town->index); params.SetParam(1, i->town->index);
SetDParam(2, indspec->name); params.SetParam(2, indspec->name);
} else { } else {
SetDParam(0, i->index); params.SetParam(0, i->index);
} }
/* and report the news to the user */ /* and report the news to the user */
if (closeit) { if (closeit) {
AddTileNewsItem(str, nt, i->location.tile + TileDiffXY(1, 1)); AddTileNewsItem(str, std::move(params), nt, i->location.tile + TileDiffXY(1, 1));
} else { } else {
AddIndustryNewsItem(str, nt, i->index); AddIndustryNewsItem(str, std::move(params), nt, i->index);
} }
} }
} }

View File

@ -15,11 +15,11 @@
#include "station_type.h" #include "station_type.h"
#include "industry_type.h" #include "industry_type.h"
void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1 = NR_NONE, uint32_t ref1 = UINT32_MAX, NewsReferenceType reftype2 = NR_NONE, uint32_t ref2 = UINT32_MAX, const NewsAllocatedData *data = nullptr); void AddNewsItem(StringID string, class StringParameters &&params, NewsType type, NewsFlag flags, NewsReferenceType reftype1 = NR_NONE, uint32_t ref1 = UINT32_MAX, NewsReferenceType reftype2 = NR_NONE, uint32_t ref2 = UINT32_MAX, const NewsAllocatedData *data = nullptr);
inline void AddCompanyNewsItem(StringID string, CompanyNewsInformation *cni) inline void AddCompanyNewsItem(StringID string, class StringParameters &&params, CompanyNewsInformation *cni)
{ {
AddNewsItem(string, NT_COMPANY_INFO, NF_COMPANY, NR_NONE, UINT32_MAX, NR_NONE, UINT32_MAX, cni); AddNewsItem(string, std::move(params), NT_COMPANY_INFO, NF_COMPANY, NR_NONE, UINT32_MAX, NR_NONE, UINT32_MAX, cni);
} }
/** /**
@ -27,9 +27,9 @@ inline void AddCompanyNewsItem(StringID string, CompanyNewsInformation *cni)
* *
* @warning The DParams may not reference the vehicle due to autoreplace stuff. See AddVehicleAdviceNewsItem for how that can be done. * @warning The DParams may not reference the vehicle due to autoreplace stuff. See AddVehicleAdviceNewsItem for how that can be done.
*/ */
inline void AddVehicleNewsItem(StringID string, NewsType type, VehicleID vehicle, StationID station = INVALID_STATION) inline void AddVehicleNewsItem(StringID string, class StringParameters &&params, NewsType type, VehicleID vehicle, StationID station = INVALID_STATION)
{ {
AddNewsItem(string, type, NF_NO_TRANSPARENT | NF_SHADE | NF_THIN, NR_VEHICLE, vehicle, station == INVALID_STATION ? NR_NONE : NR_STATION, station); AddNewsItem(string, std::move(params), type, NF_NO_TRANSPARENT | NF_SHADE | NF_THIN, NR_VEHICLE, vehicle, station == INVALID_STATION ? NR_NONE : NR_STATION, station);
} }
/** /**
@ -37,19 +37,19 @@ inline void AddVehicleNewsItem(StringID string, NewsType type, VehicleID vehicle
* *
* @warning DParam 0 must reference the vehicle! * @warning DParam 0 must reference the vehicle!
*/ */
inline void AddVehicleAdviceNewsItem(StringID string, VehicleID vehicle) inline void AddVehicleAdviceNewsItem(StringID string, class StringParameters &&params, VehicleID vehicle)
{ {
AddNewsItem(string, NT_ADVICE, NF_INCOLOUR | NF_SMALL | NF_VEHICLE_PARAM0, NR_VEHICLE, vehicle); AddNewsItem(string, std::move(params), NT_ADVICE, NF_INCOLOUR | NF_SMALL | NF_VEHICLE_PARAM0, NR_VEHICLE, vehicle);
} }
inline void AddTileNewsItem(StringID string, NewsType type, TileIndex tile, const NewsAllocatedData *data = nullptr, StationID station = INVALID_STATION) inline void AddTileNewsItem(StringID string, class StringParameters &&params, NewsType type, TileIndex tile, const NewsAllocatedData *data = nullptr, StationID station = INVALID_STATION)
{ {
AddNewsItem(string, type, NF_NO_TRANSPARENT | NF_SHADE | NF_THIN, NR_TILE, tile.base(), station == INVALID_STATION ? NR_NONE : NR_STATION, station, data); AddNewsItem(string, std::move(params), type, NF_NO_TRANSPARENT | NF_SHADE | NF_THIN, NR_TILE, tile.base(), station == INVALID_STATION ? NR_NONE : NR_STATION, station, data);
} }
inline void AddIndustryNewsItem(StringID string, NewsType type, IndustryID industry, const NewsAllocatedData *data = nullptr) inline void AddIndustryNewsItem(StringID string, class StringParameters &&params, NewsType type, IndustryID industry, const NewsAllocatedData *data = nullptr)
{ {
AddNewsItem(string, type, NF_NO_TRANSPARENT | NF_SHADE | NF_THIN, NR_INDUSTRY, industry, NR_NONE, UINT32_MAX, data); AddNewsItem(string, std::move(params), type, NF_NO_TRANSPARENT | NF_SHADE | NF_THIN, NR_INDUSTRY, industry, NR_NONE, UINT32_MAX, data);
} }
void NewsLoop(); void NewsLoop();

View File

@ -793,6 +793,7 @@ static void DeleteNewsItem(NewsItem *ni)
/** /**
* Create a new newsitem to be shown. * Create a new newsitem to be shown.
* @param string_id String to display. * @param string_id String to display.
* @param params Parameters for the string.
* @param type The type of news. * @param type The type of news.
* @param flags Flags related to how to display the news. * @param flags Flags related to how to display the news.
* @param reftype1 Type of ref1. * @param reftype1 Type of ref1.
@ -803,17 +804,18 @@ static void DeleteNewsItem(NewsItem *ni)
* *
* @see NewsSubtype * @see NewsSubtype
*/ */
NewsItem::NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, const NewsAllocatedData *data) : NewsItem::NewsItem(StringID string_id, StringParameters &&params, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, const NewsAllocatedData *data) :
string_id(string_id), date(TimerGameCalendar::date), economy_date(TimerGameEconomy::date), type(type), flags(flags), reftype1(reftype1), reftype2(reftype2), ref1(ref1), ref2(ref2), data(data) string_id(string_id), date(TimerGameCalendar::date), economy_date(TimerGameEconomy::date), type(type), flags(flags), reftype1(reftype1), reftype2(reftype2), ref1(ref1), ref2(ref2), data(data)
{ {
/* show this news message in colour? */ /* show this news message in colour? */
if (TimerGameCalendar::year >= _settings_client.gui.coloured_news_year) this->flags |= NF_INCOLOUR; if (TimerGameCalendar::year >= _settings_client.gui.coloured_news_year) this->flags |= NF_INCOLOUR;
CopyOutDParam(this->params, 10); CopyOutDParam(this->params, std::move(params));
} }
/** /**
* Add a new newsitem to be shown. * Add a new newsitem to be shown.
* @param string String to display * @param string String to display
* @param params Parameters for the string.
* @param type news category * @param type news category
* @param flags display flags for the news * @param flags display flags for the news
* @param reftype1 Type of ref1 * @param reftype1 Type of ref1
@ -824,12 +826,12 @@ NewsItem::NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsRefere
* *
* @see NewsSubtype * @see NewsSubtype
*/ */
void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, const NewsAllocatedData *data) void AddNewsItem(StringID string, StringParameters &&params, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, const NewsAllocatedData *data)
{ {
if (_game_mode == GM_MENU) return; if (_game_mode == GM_MENU) return;
/* Create new news item node */ /* Create new news item node */
NewsItem *ni = new NewsItem(string, type, flags, reftype1, ref1, reftype2, ref2, data); NewsItem *ni = new NewsItem(string, std::move(params), type, flags, reftype1, ref1, reftype2, ref2, data);
if (_total_news++ == 0) { if (_total_news++ == 0) {
assert(_oldest_news == nullptr); assert(_oldest_news == nullptr);
@ -903,8 +905,7 @@ CommandCost CmdCustomNewsItem(DoCommandFlag flags, NewsType type, NewsReferenceT
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
NewsStringData *news = new NewsStringData(text); NewsStringData *news = new NewsStringData(text);
SetDParamStr(0, news->string); AddNewsItem(STR_NEWS_CUSTOM_ITEM, MakeParameters(news->string), type, NF_NORMAL, reftype1, reference, NR_NONE, UINT32_MAX, news);
AddNewsItem(STR_NEWS_CUSTOM_ITEM, type, NF_NORMAL, reftype1, reference, NR_NONE, UINT32_MAX, news);
} }
return CommandCost(); return CommandCost();

View File

@ -143,7 +143,7 @@ struct NewsItem {
std::vector<StringParameterBackup> params; ///< Parameters for string resolving. std::vector<StringParameterBackup> params; ///< Parameters for string resolving.
NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, const NewsAllocatedData *data); NewsItem(StringID string_id, class StringParameters &&, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, const NewsAllocatedData *data);
}; };
/** Container for a single string to be passed as NewsAllocatedData. */ /** Container for a single string to be passed as NewsAllocatedData. */

View File

@ -1726,8 +1726,7 @@ void CheckOrders(const Vehicle *v)
/* We don't have a problem */ /* We don't have a problem */
if (message == INVALID_STRING_ID) return; if (message == INVALID_STRING_ID) return;
SetDParam(0, v->index); AddVehicleAdviceNewsItem(message, MakeParameters(v->index), v->index);
AddVehicleAdviceNewsItem(message, v->index);
} }
} }

View File

@ -548,7 +548,6 @@ static void RoadVehCrash(RoadVehicle *v)
AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING)); AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING));
Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING)); Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING));
SetDParam(0, pass);
StringID newsitem = (pass == 1) ? STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER : STR_NEWS_ROAD_VEHICLE_CRASH; StringID newsitem = (pass == 1) ? STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER : STR_NEWS_ROAD_VEHICLE_CRASH;
NewsType newstype = NT_ACCIDENT; NewsType newstype = NT_ACCIDENT;
@ -556,7 +555,7 @@ static void RoadVehCrash(RoadVehicle *v)
newstype = NT_ACCIDENT_OTHER; newstype = NT_ACCIDENT_OTHER;
} }
AddTileNewsItem(newsitem, newstype, v->tile); AddTileNewsItem(newsitem, MakeParameters(pass), newstype, v->tile);
ModifyStationRatingAround(v->tile, v->owner, -160, 22); ModifyStationRatingAround(v->tile, v->owner, -160, 22);
if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v); if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v);
@ -689,9 +688,9 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st)
/* Check if station was ever visited before */ /* Check if station was ever visited before */
if (!(st->had_vehicle_of_type & HVOT_BUS)) { if (!(st->had_vehicle_of_type & HVOT_BUS)) {
st->had_vehicle_of_type |= HVOT_BUS; st->had_vehicle_of_type |= HVOT_BUS;
SetDParam(0, st->index);
AddVehicleNewsItem( AddVehicleNewsItem(
RoadTypeIsRoad(v->roadtype) ? STR_NEWS_FIRST_BUS_ARRIVAL : STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL, RoadTypeIsRoad(v->roadtype) ? STR_NEWS_FIRST_BUS_ARRIVAL : STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL,
MakeParameters(st->index),
(v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER, (v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER,
v->index, v->index,
st->index st->index
@ -703,9 +702,9 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st)
/* Check if station was ever visited before */ /* Check if station was ever visited before */
if (!(st->had_vehicle_of_type & HVOT_TRUCK)) { if (!(st->had_vehicle_of_type & HVOT_TRUCK)) {
st->had_vehicle_of_type |= HVOT_TRUCK; st->had_vehicle_of_type |= HVOT_TRUCK;
SetDParam(0, st->index);
AddVehicleNewsItem( AddVehicleNewsItem(
RoadTypeIsRoad(v->roadtype) ? STR_NEWS_FIRST_TRUCK_ARRIVAL : STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL, RoadTypeIsRoad(v->roadtype) ? STR_NEWS_FIRST_TRUCK_ARRIVAL : STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL,
MakeParameters(st->index),
(v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER, (v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER,
v->index, v->index,
st->index st->index

View File

@ -477,9 +477,9 @@ static void ShipArrivesAt(const Vehicle *v, Station *st)
if (!(st->had_vehicle_of_type & HVOT_SHIP)) { if (!(st->had_vehicle_of_type & HVOT_SHIP)) {
st->had_vehicle_of_type |= HVOT_SHIP; st->had_vehicle_of_type |= HVOT_SHIP;
SetDParam(0, st->index);
AddVehicleNewsItem( AddVehicleNewsItem(
STR_NEWS_FIRST_SHIP_ARRIVAL, STR_NEWS_FIRST_SHIP_ARRIVAL,
MakeParameters(st->index),
(v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER, (v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER,
v->index, v->index,
st->index st->index

View File

@ -527,10 +527,8 @@ CargoTypes GetEmptyMask(const Station *st)
*/ */
static void ShowRejectOrAcceptNews(const Station *st, CargoTypes cargoes, bool reject) static void ShowRejectOrAcceptNews(const Station *st, CargoTypes cargoes, bool reject)
{ {
SetDParam(0, st->index);
SetDParam(1, cargoes);
StringID msg = reject ? STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_LIST : STR_NEWS_STATION_NOW_ACCEPTS_CARGO_LIST; StringID msg = reject ? STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_LIST : STR_NEWS_STATION_NOW_ACCEPTS_CARGO_LIST;
AddNewsItem(msg, NT_ACCEPTANCE, NF_INCOLOUR | NF_SMALL, NR_STATION, st->index); AddNewsItem(msg, MakeParameters(st->index, cargoes), NT_ACCEPTANCE, NF_INCOLOUR | NF_SMALL, NR_STATION, st->index);
} }
/** /**

View File

@ -51,11 +51,13 @@ void Subsidy::AwardTo(CompanyID company)
NewsStringData *company_name = new NewsStringData(GetString(STR_COMPANY_NAME)); NewsStringData *company_name = new NewsStringData(GetString(STR_COMPANY_NAME));
/* Add a news item */ /* Add a news item */
std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(this, SubsidyDecodeParamType::NewsAwarded, 1); ArrayStringParameters<8> params;
std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(this, SubsidyDecodeParamType::NewsAwarded, params, 1);
params.SetParam(0, company_name->string);
SetDParamStr(0, company_name->string);
AddNewsItem( AddNewsItem(
STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF + _settings_game.difficulty.subsidy_multiplier, STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF + _settings_game.difficulty.subsidy_multiplier,
std::move(params),
NT_SUBSIDIES, NF_NORMAL, NT_SUBSIDIES, NF_NORMAL,
reftype.first, this->src, reftype.second, this->dst, reftype.first, this->src, reftype.second, this->dst,
company_name company_name
@ -70,47 +72,48 @@ void Subsidy::AwardTo(CompanyID company)
* Setup the string parameters for printing the subsidy at the screen, and compute the news reference for the subsidy. * Setup the string parameters for printing the subsidy at the screen, and compute the news reference for the subsidy.
* @param s %Subsidy being printed. * @param s %Subsidy being printed.
* @param mode Type of subsidy news message to decide on parameter format. * @param mode Type of subsidy news message to decide on parameter format.
* @param params String parameters to be filled. Needs to be able to contain at least 8 + parameter_offset entries.
* @param parameter_offset The location/index in the String DParams to start decoding the subsidy's parameters. Defaults to 0. * @param parameter_offset The location/index in the String DParams to start decoding the subsidy's parameters. Defaults to 0.
* @return Reference of the subsidy in the news system. * @return Reference of the subsidy in the news system.
*/ */
std::pair<NewsReferenceType, NewsReferenceType> SetupSubsidyDecodeParam(const Subsidy *s, SubsidyDecodeParamType mode, uint parameter_offset) std::pair<NewsReferenceType, NewsReferenceType> SetupSubsidyDecodeParam(const Subsidy *s, SubsidyDecodeParamType mode, StringParameters &params, uint parameter_offset)
{ {
NewsReferenceType reftype1 = NR_NONE; NewsReferenceType reftype1 = NR_NONE;
NewsReferenceType reftype2 = NR_NONE; NewsReferenceType reftype2 = NR_NONE;
/* Always use the plural form of the cargo name - trying to decide between plural or singular causes issues for translations */ /* Always use the plural form of the cargo name - trying to decide between plural or singular causes issues for translations */
const CargoSpec *cs = CargoSpec::Get(s->cargo_type); const CargoSpec *cs = CargoSpec::Get(s->cargo_type);
SetDParam(parameter_offset, cs->name); params.SetParam(parameter_offset, cs->name);
switch (s->src_type) { switch (s->src_type) {
case SourceType::Industry: case SourceType::Industry:
reftype1 = NR_INDUSTRY; reftype1 = NR_INDUSTRY;
SetDParam(parameter_offset + 1, STR_INDUSTRY_NAME); params.SetParam(parameter_offset + 1, STR_INDUSTRY_NAME);
break; break;
case SourceType::Town: case SourceType::Town:
reftype1 = NR_TOWN; reftype1 = NR_TOWN;
SetDParam(parameter_offset + 1, STR_TOWN_NAME); params.SetParam(parameter_offset + 1, STR_TOWN_NAME);
break; break;
default: NOT_REACHED(); default: NOT_REACHED();
} }
SetDParam(parameter_offset + 2, s->src); params.SetParam(parameter_offset + 2, s->src);
switch (s->dst_type) { switch (s->dst_type) {
case SourceType::Industry: case SourceType::Industry:
reftype2 = NR_INDUSTRY; reftype2 = NR_INDUSTRY;
SetDParam(parameter_offset + 4, STR_INDUSTRY_NAME); params.SetParam(parameter_offset + 4, STR_INDUSTRY_NAME);
break; break;
case SourceType::Town: case SourceType::Town:
reftype2 = NR_TOWN; reftype2 = NR_TOWN;
SetDParam(parameter_offset + 4, STR_TOWN_NAME); params.SetParam(parameter_offset + 4, STR_TOWN_NAME);
break; break;
default: NOT_REACHED(); default: NOT_REACHED();
} }
SetDParam(parameter_offset + 5, s->dst); params.SetParam(parameter_offset + 5, s->dst);
/* If the subsidy is being offered or awarded, the news item mentions the subsidy duration. */ /* If the subsidy is being offered or awarded, the news item mentions the subsidy duration. */
if (mode == SubsidyDecodeParamType::NewsOffered || mode == SubsidyDecodeParamType::NewsAwarded) { if (mode == SubsidyDecodeParamType::NewsOffered || mode == SubsidyDecodeParamType::NewsAwarded) {
SetDParam(parameter_offset + 7, _settings_game.difficulty.subsidy_duration); params.SetParam(parameter_offset + 7, _settings_game.difficulty.subsidy_duration);
} }
return std::pair<NewsReferenceType, NewsReferenceType>(reftype1, reftype2); return std::pair<NewsReferenceType, NewsReferenceType>(reftype1, reftype2);
@ -222,8 +225,9 @@ void CreateSubsidy(CargoID cid, SourceType src_type, SourceID src, SourceType ds
s->remaining = SUBSIDY_OFFER_MONTHS; s->remaining = SUBSIDY_OFFER_MONTHS;
s->awarded = INVALID_COMPANY; s->awarded = INVALID_COMPANY;
std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsOffered); ArrayStringParameters<8> params;
AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, NT_SUBSIDIES, NF_NORMAL, reftype.first, s->src, reftype.second, s->dst); std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsOffered, params);
AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, std::move(params), NT_SUBSIDIES, NF_NORMAL, reftype.first, s->src, reftype.second, s->dst);
SetPartOfSubsidyFlag(s->src_type, s->src, POS_SRC); SetPartOfSubsidyFlag(s->src_type, s->src, POS_SRC);
SetPartOfSubsidyFlag(s->dst_type, s->dst, POS_DST); SetPartOfSubsidyFlag(s->dst_type, s->dst, POS_DST);
AI::BroadcastNewEvent(new ScriptEventSubsidyOffer(s->index)); AI::BroadcastNewEvent(new ScriptEventSubsidyOffer(s->index));
@ -482,14 +486,16 @@ static IntervalTimer<TimerGameEconomy> _economy_subsidies_monthly({TimerGameEcon
for (Subsidy *s : Subsidy::Iterate()) { for (Subsidy *s : Subsidy::Iterate()) {
if (--s->remaining == 0) { if (--s->remaining == 0) {
if (!s->IsAwarded()) { if (!s->IsAwarded()) {
std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsWithdrawn); ArrayStringParameters<8> params;
AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NT_SUBSIDIES, NF_NORMAL, reftype.first, s->src, reftype.second, s->dst); std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsWithdrawn, params);
AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, std::move(params), NT_SUBSIDIES, NF_NORMAL, reftype.first, s->src, reftype.second, s->dst);
AI::BroadcastNewEvent(new ScriptEventSubsidyOfferExpired(s->index)); AI::BroadcastNewEvent(new ScriptEventSubsidyOfferExpired(s->index));
Game::NewEvent(new ScriptEventSubsidyOfferExpired(s->index)); Game::NewEvent(new ScriptEventSubsidyOfferExpired(s->index));
} else { } else {
if (s->awarded == _local_company) { if (s->awarded == _local_company) {
std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsWithdrawn); ArrayStringParameters<8> params;
AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, NT_SUBSIDIES, NF_NORMAL, reftype.first, s->src, reftype.second, s->dst); std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsWithdrawn, params);
AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, std::move(params), NT_SUBSIDIES, NF_NORMAL, reftype.first, s->src, reftype.second, s->dst);
} }
AI::BroadcastNewEvent(new ScriptEventSubsidyExpired(s->index)); AI::BroadcastNewEvent(new ScriptEventSubsidyExpired(s->index));
Game::NewEvent(new ScriptEventSubsidyExpired(s->index)); Game::NewEvent(new ScriptEventSubsidyExpired(s->index));

View File

@ -17,7 +17,7 @@
#include "news_type.h" #include "news_type.h"
#include "subsidy_base.h" #include "subsidy_base.h"
std::pair<NewsReferenceType, NewsReferenceType> SetupSubsidyDecodeParam(const struct Subsidy *s, SubsidyDecodeParamType mode, uint parameter_offset = 0); std::pair<NewsReferenceType, NewsReferenceType> SetupSubsidyDecodeParam(const struct Subsidy *s, SubsidyDecodeParamType mode, StringParameters &params, uint parameter_offset = 0);
void DeleteSubsidyWith(SourceType type, SourceID index); void DeleteSubsidyWith(SourceType type, SourceID index);
bool CheckSubsidised(CargoID cargo_type, CompanyID company, SourceType src_type, SourceID src, const Station *st); bool CheckSubsidised(CargoID cargo_type, CompanyID company, SourceType src_type, SourceID src, const Station *st);
void RebuildSubsidisedSourceAndDestinationCache(); void RebuildSubsidisedSourceAndDestinationCache();

View File

@ -158,7 +158,9 @@ struct SubsidyListWindow : Window {
if (!s->IsAwarded()) { if (!s->IsAwarded()) {
if (IsInsideMM(pos, 0, cap)) { if (IsInsideMM(pos, 0, cap)) {
/* Displays the two offered towns */ /* Displays the two offered towns */
SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::Gui); extern ArrayStringParameters<20> _global_string_params;
SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::Gui, _global_string_params);
/* If using wallclock units, show minutes remaining. Otherwise show the date when the subsidy ends. */ /* If using wallclock units, show minutes remaining. Otherwise show the date when the subsidy ends. */
if (TimerGameEconomy::UsingWallclockUnits()) { if (TimerGameEconomy::UsingWallclockUnits()) {
SetDParam(7, STR_SUBSIDIES_OFFERED_EXPIRY_TIME); SetDParam(7, STR_SUBSIDIES_OFFERED_EXPIRY_TIME);
@ -189,7 +191,9 @@ struct SubsidyListWindow : Window {
for (const Subsidy *s : Subsidy::Iterate()) { for (const Subsidy *s : Subsidy::Iterate()) {
if (s->IsAwarded()) { if (s->IsAwarded()) {
if (IsInsideMM(pos, 0, cap)) { if (IsInsideMM(pos, 0, cap)) {
SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::Gui); extern ArrayStringParameters<20> _global_string_params;
SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::Gui, _global_string_params);
SetDParam(7, s->awarded); SetDParam(7, s->awarded);
/* If using wallclock units, show minutes remaining. Otherwise show the date when the subsidy ends. */ /* If using wallclock units, show minutes remaining. Otherwise show the date when the subsidy ends. */
if (TimerGameEconomy::UsingWallclockUnits()) { if (TimerGameEconomy::UsingWallclockUnits()) {

View File

@ -2103,16 +2103,12 @@ std::tuple<CommandCost, Money, TownID> CmdFoundTown(DoCommandFlag flags, TileInd
assert(!random_location); assert(!random_location);
if (_current_company == OWNER_DEITY) { if (_current_company == OWNER_DEITY) {
SetDParam(0, t->index); AddTileNewsItem(STR_NEWS_NEW_TOWN_UNSPONSORED, MakeParameters(t->index), NT_INDUSTRY_OPEN, tile);
AddTileNewsItem(STR_NEWS_NEW_TOWN_UNSPONSORED, NT_INDUSTRY_OPEN, tile);
} else { } else {
SetDParam(0, _current_company); SetDParam(0, _current_company);
NewsStringData *company_name = new NewsStringData(GetString(STR_COMPANY_NAME)); NewsStringData *company_name = new NewsStringData(GetString(STR_COMPANY_NAME));
SetDParamStr(0, company_name->string); AddTileNewsItem(STR_NEWS_NEW_TOWN, MakeParameters(company_name->string, t->index), NT_INDUSTRY_OPEN, tile, company_name);
SetDParam(1, t->index);
AddTileNewsItem(STR_NEWS_NEW_TOWN, NT_INDUSTRY_OPEN, tile, company_name);
} }
AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index)); AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index));
Game::NewEvent(new ScriptEventTownFounded(t->index)); Game::NewEvent(new ScriptEventTownFounded(t->index));
@ -3199,11 +3195,9 @@ static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlag flags)
SetDParam(0, _current_company); SetDParam(0, _current_company);
NewsStringData *company_name = new NewsStringData(GetString(STR_COMPANY_NAME)); NewsStringData *company_name = new NewsStringData(GetString(STR_COMPANY_NAME));
SetDParam(0, t->index);
SetDParamStr(1, company_name->string);
AddNewsItem( AddNewsItem(
TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_ROAD_REBUILDING_MINUTES : STR_NEWS_ROAD_REBUILDING_MONTHS, TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_ROAD_REBUILDING_MINUTES : STR_NEWS_ROAD_REBUILDING_MONTHS,
MakeParameters(t->index, company_name->string),
NT_GENERAL, NF_NORMAL, NR_TOWN, t->index, NR_NONE, UINT32_MAX, company_name); NT_GENERAL, NF_NORMAL, NR_TOWN, t->index, NR_NONE, UINT32_MAX, company_name);
AI::BroadcastNewEvent(new ScriptEventRoadReconstruction((ScriptCompany::CompanyID)(Owner)_current_company, t->index)); AI::BroadcastNewEvent(new ScriptEventRoadReconstruction((ScriptCompany::CompanyID)(Owner)_current_company, t->index));
Game::NewEvent(new ScriptEventRoadReconstruction((ScriptCompany::CompanyID)(Owner)_current_company, t->index)); Game::NewEvent(new ScriptEventRoadReconstruction((ScriptCompany::CompanyID)(Owner)_current_company, t->index));
@ -3355,11 +3349,13 @@ static CommandCost TownActionBuyRights(Town *t, DoCommandFlag flags)
/* Spawn news message */ /* Spawn news message */
CompanyNewsInformation *cni = new CompanyNewsInformation(Company::Get(_current_company)); CompanyNewsInformation *cni = new CompanyNewsInformation(Company::Get(_current_company));
SetDParam(0, STR_NEWS_EXCLUSIVE_RIGHTS_TITLE); auto params = MakeParameters(
SetDParam(1, TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS); STR_NEWS_EXCLUSIVE_RIGHTS_TITLE,
SetDParam(2, t->index); TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS,
SetDParamStr(3, cni->company_name); t->index,
AddNewsItem(STR_MESSAGE_NEWS_FORMAT, NT_GENERAL, NF_COMPANY, NR_TOWN, t->index, NR_NONE, UINT32_MAX, cni); cni->company_name
);
AddNewsItem(STR_MESSAGE_NEWS_FORMAT, std::move(params), NT_GENERAL, NF_COMPANY, NR_TOWN, t->index, NR_NONE, UINT32_MAX, cni);
AI::BroadcastNewEvent(new ScriptEventExclusiveTransportRights((ScriptCompany::CompanyID)(Owner)_current_company, t->index)); AI::BroadcastNewEvent(new ScriptEventExclusiveTransportRights((ScriptCompany::CompanyID)(Owner)_current_company, t->index));
Game::NewEvent(new ScriptEventExclusiveTransportRights((ScriptCompany::CompanyID)(Owner)_current_company, t->index)); Game::NewEvent(new ScriptEventExclusiveTransportRights((ScriptCompany::CompanyID)(Owner)_current_company, t->index));
} }

View File

@ -2993,9 +2993,9 @@ static void TrainEnterStation(Train *v, StationID station)
Station *st = Station::Get(station); Station *st = Station::Get(station);
if (!(st->had_vehicle_of_type & HVOT_TRAIN)) { if (!(st->had_vehicle_of_type & HVOT_TRAIN)) {
st->had_vehicle_of_type |= HVOT_TRAIN; st->had_vehicle_of_type |= HVOT_TRAIN;
SetDParam(0, st->index);
AddVehicleNewsItem( AddVehicleNewsItem(
STR_NEWS_FIRST_TRAIN_ARRIVAL, STR_NEWS_FIRST_TRAIN_ARRIVAL,
MakeParameters(st->index),
v->owner == _local_company ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER, v->owner == _local_company ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER,
v->index, v->index,
st->index st->index
@ -3230,8 +3230,7 @@ static bool CheckTrainCollision(Train *v)
/* any dead -> no crash */ /* any dead -> no crash */
if (tcc.num == 0) return false; if (tcc.num == 0) return false;
SetDParam(0, tcc.num); AddTileNewsItem(STR_NEWS_TRAIN_CRASH, MakeParameters(tcc.num), NT_ACCIDENT, v->tile);
AddTileNewsItem(STR_NEWS_TRAIN_CRASH, NT_ACCIDENT, v->tile);
ModifyStationRatingAround(v->tile, v->owner, -160, 30); ModifyStationRatingAround(v->tile, v->owner, -160, 30);
if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_13_TRAIN_COLLISION, v); if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_13_TRAIN_COLLISION, v);
@ -3993,8 +3992,7 @@ static bool TrainLocoHandler(Train *v, bool mode)
if (HasBit(v->flags, VRF_TRAIN_STUCK) && v->wait_counter > 2 * _settings_game.pf.wait_for_pbs_path * Ticks::DAY_TICKS) { if (HasBit(v->flags, VRF_TRAIN_STUCK) && v->wait_counter > 2 * _settings_game.pf.wait_for_pbs_path * Ticks::DAY_TICKS) {
/* Show message to player. */ /* Show message to player. */
if (_settings_client.gui.lost_vehicle_warn && v->owner == _local_company) { if (_settings_client.gui.lost_vehicle_warn && v->owner == _local_company) {
SetDParam(0, v->index); AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_STUCK, MakeParameters(v->index), v->index);
AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_STUCK, v->index);
} }
v->wait_counter = 0; v->wait_counter = 0;
} }

View File

@ -811,8 +811,7 @@ void Vehicle::HandlePathfindingResult(bool path_found)
/* Notify user about the event. */ /* Notify user about the event. */
AI::NewEvent(this->owner, new ScriptEventVehicleLost(this->index)); AI::NewEvent(this->owner, new ScriptEventVehicleLost(this->index));
if (_settings_client.gui.lost_vehicle_warn && this->owner == _local_company) { if (_settings_client.gui.lost_vehicle_warn && this->owner == _local_company) {
SetDParam(0, this->index); AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_IS_LOST, MakeParameters(this->index), this->index);
AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_IS_LOST, this->index);
} }
} }
@ -1097,9 +1096,7 @@ void CallVehicleTicks()
message = STR_NEWS_VEHICLE_AUTORENEW_FAILED; message = STR_NEWS_VEHICLE_AUTORENEW_FAILED;
} }
SetDParam(0, v->index); AddVehicleAdviceNewsItem(message, MakeParameters(v->index, error_message), v->index);
SetDParam(1, error_message);
AddVehicleAdviceNewsItem(message, v->index);
} }
cur_company.Restore(); cur_company.Restore();
@ -1453,8 +1450,7 @@ void AgeVehicle(Vehicle *v)
return; return;
} }
SetDParam(0, v->index); AddVehicleAdviceNewsItem(str, MakeParameters(v->index), v->index);
AddVehicleAdviceNewsItem(str, v->index);
} }
/** /**
@ -1609,8 +1605,7 @@ void VehicleEnterDepot(Vehicle *v)
_vehicles_to_autoreplace[v] = false; _vehicles_to_autoreplace[v] = false;
if (v->owner == _local_company) { if (v->owner == _local_company) {
/* Notify the user that we stopped the vehicle */ /* Notify the user that we stopped the vehicle */
SetDParam(0, v->index); AddVehicleAdviceNewsItem(STR_NEWS_ORDER_REFIT_FAILED, MakeParameters(v->index), v->index);
AddVehicleAdviceNewsItem(STR_NEWS_ORDER_REFIT_FAILED, v->index);
} }
} else if (cost.GetCost() != 0) { } else if (cost.GetCost() != 0) {
v->profit_this_year -= cost.GetCost() << 8; v->profit_this_year -= cost.GetCost() << 8;
@ -1634,8 +1629,7 @@ void VehicleEnterDepot(Vehicle *v)
* we shouldn't construct it when the vehicle visits the next stop. */ * we shouldn't construct it when the vehicle visits the next stop. */
v->last_loading_station = INVALID_STATION; v->last_loading_station = INVALID_STATION;
if (v->owner == _local_company) { if (v->owner == _local_company) {
SetDParam(0, v->index); AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_WAITING + v->type, MakeParameters(v->index), v->index);
AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_WAITING + v->type, v->index);
} }
AI::NewEvent(v->owner, new ScriptEventVehicleWaitingInDepot(v->index)); AI::NewEvent(v->owner, new ScriptEventVehicleWaitingInDepot(v->index));
} }
@ -2848,10 +2842,9 @@ static IntervalTimer<TimerGameEconomy> _economy_vehicles_yearly({TimerGameEconom
Money profit = v->GetDisplayProfitThisYear(); Money profit = v->GetDisplayProfitThisYear();
if (v->age >= 730 && profit < 0) { if (v->age >= 730 && profit < 0) {
if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company) { if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company) {
SetDParam(0, v->index);
SetDParam(1, profit);
AddVehicleAdviceNewsItem( AddVehicleAdviceNewsItem(
TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_VEHICLE_UNPROFITABLE_PERIOD : STR_NEWS_VEHICLE_UNPROFITABLE_YEAR, TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_VEHICLE_UNPROFITABLE_PERIOD : STR_NEWS_VEHICLE_UNPROFITABLE_YEAR,
MakeParameters(v->index, profit),
v->index); v->index);
} }
AI::NewEvent(v->owner, new ScriptEventVehicleUnprofitable(v->index)); AI::NewEvent(v->owner, new ScriptEventVehicleUnprofitable(v->index));

View File

@ -993,8 +993,7 @@ static void FloodVehicle(Vehicle *v)
AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_FLOODED)); AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_FLOODED));
Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_FLOODED)); Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_FLOODED));
SetDParam(0, pass); AddTileNewsItem(STR_NEWS_DISASTER_FLOOD_VEHICLE, MakeParameters(pass), NT_ACCIDENT, v->tile);
AddTileNewsItem(STR_NEWS_DISASTER_FLOOD_VEHICLE, NT_ACCIDENT, v->tile);
CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v); if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v);
} }