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;
}
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);
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 */
if (!(st->had_vehicle_of_type & HVOT_AIRCRAFT)) {
st->had_vehicle_of_type |= HVOT_AIRCRAFT;
SetDParam(0, st->index);
/* show newsitem of celebrating citizens */
AddVehicleNewsItem(
STR_NEWS_FIRST_AIRCRAFT_ARRIVAL,
MakeParameters(st->index),
(v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER,
v->index,
st->index
@ -2052,8 +2052,7 @@ static void AircraftHandleDestTooFar(Aircraft *v, bool too_far)
AI::NewEvent(v->owner, new ScriptEventAircraftDestTooFar(v->index));
if (v->owner == _local_company) {
/* Post a news message. */
SetDParam(0, v->index);
AddVehicleAdviceNewsItem(STR_NEWS_AIRCRAFT_DEST_TOO_FAR, v->index);
AddVehicleAdviceNewsItem(STR_NEWS_AIRCRAFT_DEST_TOO_FAR, MakeParameters(v->index), v->index);
}
}
return;

View File

@ -333,20 +333,22 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
if (!IsValidCargoID(refit_cargo)) {
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);
if (order_id != -1) {
/* Orders contained a refit order that is incompatible with the new vehicle. */
SetDParam(1, STR_ERROR_AUTOREPLACE_INCOMPATIBLE_REFIT);
SetDParam(2, order_id + 1); // 1-based indexing for display
params.SetParam(1, STR_ERROR_AUTOREPLACE_INCOMPATIBLE_REFIT);
params.SetParam(2, order_id + 1); // 1-based indexing for display
} else {
/* Current cargo is incompatible with the new vehicle. */
SetDParam(1, STR_ERROR_AUTOREPLACE_INCOMPATIBLE_CARGO);
SetDParam(2, CargoSpec::Get(old_veh->cargo_type)->name);
params.SetParam(1, STR_ERROR_AUTOREPLACE_INCOMPATIBLE_CARGO);
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();
}

View File

@ -424,11 +424,13 @@ set_name:;
if (c->is_ai) {
CompanyNewsInformation *cni = new CompanyNewsInformation(c);
SetDParam(0, STR_NEWS_COMPANY_LAUNCH_TITLE);
SetDParam(1, STR_NEWS_COMPANY_LAUNCH_DESCRIPTION);
SetDParamStr(2, cni->company_name);
SetDParam(3, t->index);
AddNewsItem(STR_MESSAGE_NEWS_FORMAT, NT_COMPANY_INFO, NF_COMPANY, NR_TILE, c->last_build_coordinate.base(), NR_NONE, UINT32_MAX, cni);
auto params = MakeParameters(
STR_NEWS_COMPANY_LAUNCH_TITLE,
STR_NEWS_COMPANY_LAUNCH_DESCRIPTION,
cni->company_name,
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;
}
@ -940,10 +942,7 @@ CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID
CompanyNewsInformation *cni = new CompanyNewsInformation(c);
/* Show the bankrupt news */
SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE);
SetDParam(1, STR_NEWS_COMPANY_BANKRUPT_DESCRIPTION);
SetDParamStr(2, cni->company_name);
AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, cni);
AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, MakeParameters(STR_NEWS_COMPANY_BANKRUPT_TITLE, STR_NEWS_COMPANY_BANKRUPT_DESCRIPTION, cni->company_name), cni);
/* Remove the company */
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 &&
TimerGameCalendar::year >= _currency_specs[_settings_game.locale.currency].to_euro) {
_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->age = 0;
SetDParam(0, GetStationIndex(v->tile));
AddTileNewsItem(STR_NEWS_DISASTER_ZEPPELIN, NT_ACCIDENT, v->tile);
AddTileNewsItem(STR_NEWS_DISASTER_ZEPPELIN, MakeParameters(GetStationIndex(v->tile)), NT_ACCIDENT, 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) {
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));
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
DestructIndustry(i);
SetDParam(0, i->town->index);
AddIndustryNewsItem(news_message, NT_ACCIDENT, i->index);
AddIndustryNewsItem(news_message, MakeParameters(i->town->index), NT_ACCIDENT, i->index);
if (_settings_client.sound.disaster) SndPlayTileFx(SND_12_EXPLOSION, i->location.tile);
}
} else if (v->state == 0) {
@ -554,8 +552,7 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v)
}
Town *t = ClosestTownFromTile(v->dest_tile, UINT_MAX);
SetDParam(0, t->index);
AddTileNewsItem(STR_NEWS_DISASTER_BIG_UFO, NT_ACCIDENT, v->tile);
AddTileNewsItem(STR_NEWS_DISASTER_BIG_UFO, MakeParameters(t->index), NT_ACCIDENT, v->tile);
if (!Vehicle::CanAllocateItem(2)) {
delete v;
@ -880,8 +877,7 @@ static void Disaster_CoalMine_Init()
for (m = 0; m < 15; m++) {
for (const Industry *i : Industry::Iterate()) {
if ((GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_CAN_SUBSIDENCE) && --index < 0) {
SetDParam(0, i->town->index);
AddTileNewsItem(STR_NEWS_DISASTER_COAL_MINE_SUBSIDENCE, NT_ACCIDENT, i->location.tile + TileDiffXY(1, 1)); // keep the news, even when the mine closes
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
{
TileIndex tile = i->location.tile;

View File

@ -599,10 +599,7 @@ static void CompanyCheckBankrupt(Company *c)
/* Warn about bankruptcy after 3 months */
case 4: {
CompanyNewsInformation *cni = new CompanyNewsInformation(c);
SetDParam(0, STR_NEWS_COMPANY_IN_TROUBLE_TITLE);
SetDParam(1, STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION);
SetDParamStr(2, cni->company_name);
AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, cni);
AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, MakeParameters(STR_NEWS_COMPANY_IN_TROUBLE_TITLE, STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION, cni->company_name), cni);
AI::BroadcastNewEvent(new ScriptEventCompanyInTrouble(c->index));
Game::NewEvent(new ScriptEventCompanyInTrouble(c->index));
break;
@ -877,10 +874,10 @@ static void HandleEconomyFluctuations()
if (_economy.fluct == 0) {
_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) {
_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));
SetDParam(0, STR_NEWS_COMPANY_MERGER_TITLE);
SetDParam(1, hostile_takeover ? STR_NEWS_MERGER_TAKEOVER_TITLE : STR_NEWS_COMPANY_MERGER_DESCRIPTION);
SetDParamStr(2, cni->company_name);
SetDParamStr(3, cni->other_company_name);
SetDParam(4, c->bankrupt_value);
AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, cni);
auto params = MakeParameters(
STR_NEWS_COMPANY_MERGER_TITLE,
hostile_takeover ? STR_NEWS_MERGER_TAKEOVER_TITLE : STR_NEWS_COMPANY_MERGER_DESCRIPTION,
cni->company_name,
cni->other_company_name,
c->bankrupt_value
);
AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, std::move(params), cni);
AI::BroadcastNewEvent(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. */
if (!IsVehicleTypeDisabled(e->type, false) && (e->info.extra_flags & ExtraEngineFlags::NoNews) == ExtraEngineFlags::None) {
SetDParam(0, GetEngineCategoryName(index));
SetDParam(1, PackEngineNameDParam(index, EngineNameContext::PreviewNews));
AddNewsItem(STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE, NT_NEW_VEHICLES, NF_VEHICLE, NR_ENGINE, 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);
}
/* Update the toolbar. */

View File

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

View File

@ -793,6 +793,7 @@ static void DeleteNewsItem(NewsItem *ni)
/**
* Create a new newsitem to be shown.
* @param string_id String to display.
* @param params Parameters for the string.
* @param type The type of news.
* @param flags Flags related to how to display the news.
* @param reftype1 Type of ref1.
@ -803,17 +804,18 @@ static void DeleteNewsItem(NewsItem *ni)
*
* @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)
{
/* show this news message in colour? */
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.
* @param string String to display
* @param params Parameters for the string.
* @param type news category
* @param flags display flags for the news
* @param reftype1 Type of ref1
@ -824,12 +826,12 @@ NewsItem::NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsRefere
*
* @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;
/* 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) {
assert(_oldest_news == nullptr);
@ -903,8 +905,7 @@ CommandCost CmdCustomNewsItem(DoCommandFlag flags, NewsType type, NewsReferenceT
if (flags & DC_EXEC) {
NewsStringData *news = new NewsStringData(text);
SetDParamStr(0, news->string);
AddNewsItem(STR_NEWS_CUSTOM_ITEM, type, NF_NORMAL, reftype1, reference, NR_NONE, UINT32_MAX, news);
AddNewsItem(STR_NEWS_CUSTOM_ITEM, MakeParameters(news->string), type, NF_NORMAL, reftype1, reference, NR_NONE, UINT32_MAX, news);
}
return CommandCost();

View File

@ -143,7 +143,7 @@ struct NewsItem {
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. */

View File

@ -1726,8 +1726,7 @@ void CheckOrders(const Vehicle *v)
/* We don't have a problem */
if (message == INVALID_STRING_ID) return;
SetDParam(0, v->index);
AddVehicleAdviceNewsItem(message, v->index);
AddVehicleAdviceNewsItem(message, MakeParameters(v->index), 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));
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;
NewsType newstype = NT_ACCIDENT;
@ -556,7 +555,7 @@ static void RoadVehCrash(RoadVehicle *v)
newstype = NT_ACCIDENT_OTHER;
}
AddTileNewsItem(newsitem, newstype, v->tile);
AddTileNewsItem(newsitem, MakeParameters(pass), newstype, v->tile);
ModifyStationRatingAround(v->tile, v->owner, -160, 22);
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 */
if (!(st->had_vehicle_of_type & HVOT_BUS)) {
st->had_vehicle_of_type |= HVOT_BUS;
SetDParam(0, st->index);
AddVehicleNewsItem(
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->index,
st->index
@ -703,9 +702,9 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st)
/* Check if station was ever visited before */
if (!(st->had_vehicle_of_type & HVOT_TRUCK)) {
st->had_vehicle_of_type |= HVOT_TRUCK;
SetDParam(0, st->index);
AddVehicleNewsItem(
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->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)) {
st->had_vehicle_of_type |= HVOT_SHIP;
SetDParam(0, st->index);
AddVehicleNewsItem(
STR_NEWS_FIRST_SHIP_ARRIVAL,
MakeParameters(st->index),
(v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER,
v->index,
st->index

View File

@ -527,10 +527,8 @@ CargoTypes GetEmptyMask(const Station *st)
*/
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;
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));
/* 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(
STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF + _settings_game.difficulty.subsidy_multiplier,
std::move(params),
NT_SUBSIDIES, NF_NORMAL,
reftype.first, this->src, reftype.second, this->dst,
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.
* @param s %Subsidy being printed.
* @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.
* @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 reftype2 = NR_NONE;
/* 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);
SetDParam(parameter_offset, cs->name);
params.SetParam(parameter_offset, cs->name);
switch (s->src_type) {
case SourceType::Industry:
reftype1 = NR_INDUSTRY;
SetDParam(parameter_offset + 1, STR_INDUSTRY_NAME);
params.SetParam(parameter_offset + 1, STR_INDUSTRY_NAME);
break;
case SourceType::Town:
reftype1 = NR_TOWN;
SetDParam(parameter_offset + 1, STR_TOWN_NAME);
params.SetParam(parameter_offset + 1, STR_TOWN_NAME);
break;
default: NOT_REACHED();
}
SetDParam(parameter_offset + 2, s->src);
params.SetParam(parameter_offset + 2, s->src);
switch (s->dst_type) {
case SourceType::Industry:
reftype2 = NR_INDUSTRY;
SetDParam(parameter_offset + 4, STR_INDUSTRY_NAME);
params.SetParam(parameter_offset + 4, STR_INDUSTRY_NAME);
break;
case SourceType::Town:
reftype2 = NR_TOWN;
SetDParam(parameter_offset + 4, STR_TOWN_NAME);
params.SetParam(parameter_offset + 4, STR_TOWN_NAME);
break;
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 (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);
@ -222,8 +225,9 @@ void CreateSubsidy(CargoID cid, SourceType src_type, SourceID src, SourceType ds
s->remaining = SUBSIDY_OFFER_MONTHS;
s->awarded = INVALID_COMPANY;
std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsOffered);
AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, NT_SUBSIDIES, NF_NORMAL, reftype.first, s->src, reftype.second, s->dst);
ArrayStringParameters<8> params;
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->dst_type, s->dst, POS_DST);
AI::BroadcastNewEvent(new ScriptEventSubsidyOffer(s->index));
@ -482,14 +486,16 @@ static IntervalTimer<TimerGameEconomy> _economy_subsidies_monthly({TimerGameEcon
for (Subsidy *s : Subsidy::Iterate()) {
if (--s->remaining == 0) {
if (!s->IsAwarded()) {
std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsWithdrawn);
AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NT_SUBSIDIES, NF_NORMAL, reftype.first, s->src, reftype.second, s->dst);
ArrayStringParameters<8> params;
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));
Game::NewEvent(new ScriptEventSubsidyOfferExpired(s->index));
} else {
if (s->awarded == _local_company) {
std::pair<NewsReferenceType, NewsReferenceType> reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsWithdrawn);
AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, NT_SUBSIDIES, NF_NORMAL, reftype.first, s->src, reftype.second, s->dst);
ArrayStringParameters<8> params;
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));
Game::NewEvent(new ScriptEventSubsidyExpired(s->index));

View File

@ -17,7 +17,7 @@
#include "news_type.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);
bool CheckSubsidised(CargoID cargo_type, CompanyID company, SourceType src_type, SourceID src, const Station *st);
void RebuildSubsidisedSourceAndDestinationCache();

View File

@ -158,7 +158,9 @@ struct SubsidyListWindow : Window {
if (!s->IsAwarded()) {
if (IsInsideMM(pos, 0, cap)) {
/* 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 (TimerGameEconomy::UsingWallclockUnits()) {
SetDParam(7, STR_SUBSIDIES_OFFERED_EXPIRY_TIME);
@ -189,7 +191,9 @@ struct SubsidyListWindow : Window {
for (const Subsidy *s : Subsidy::Iterate()) {
if (s->IsAwarded()) {
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);
/* If using wallclock units, show minutes remaining. Otherwise show the date when the subsidy ends. */
if (TimerGameEconomy::UsingWallclockUnits()) {

View File

@ -2103,16 +2103,12 @@ std::tuple<CommandCost, Money, TownID> CmdFoundTown(DoCommandFlag flags, TileInd
assert(!random_location);
if (_current_company == OWNER_DEITY) {
SetDParam(0, t->index);
AddTileNewsItem(STR_NEWS_NEW_TOWN_UNSPONSORED, NT_INDUSTRY_OPEN, tile);
AddTileNewsItem(STR_NEWS_NEW_TOWN_UNSPONSORED, MakeParameters(t->index), NT_INDUSTRY_OPEN, tile);
} else {
SetDParam(0, _current_company);
NewsStringData *company_name = new NewsStringData(GetString(STR_COMPANY_NAME));
SetDParamStr(0, company_name->string);
SetDParam(1, t->index);
AddTileNewsItem(STR_NEWS_NEW_TOWN, NT_INDUSTRY_OPEN, tile, company_name);
AddTileNewsItem(STR_NEWS_NEW_TOWN, MakeParameters(company_name->string, t->index), NT_INDUSTRY_OPEN, tile, company_name);
}
AI::BroadcastNewEvent(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);
NewsStringData *company_name = new NewsStringData(GetString(STR_COMPANY_NAME));
SetDParam(0, t->index);
SetDParamStr(1, company_name->string);
AddNewsItem(
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);
AI::BroadcastNewEvent(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 */
CompanyNewsInformation *cni = new CompanyNewsInformation(Company::Get(_current_company));
SetDParam(0, STR_NEWS_EXCLUSIVE_RIGHTS_TITLE);
SetDParam(1, TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS);
SetDParam(2, t->index);
SetDParamStr(3, cni->company_name);
AddNewsItem(STR_MESSAGE_NEWS_FORMAT, NT_GENERAL, NF_COMPANY, NR_TOWN, t->index, NR_NONE, UINT32_MAX, cni);
auto params = MakeParameters(
STR_NEWS_EXCLUSIVE_RIGHTS_TITLE,
TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS,
t->index,
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));
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);
if (!(st->had_vehicle_of_type & HVOT_TRAIN)) {
st->had_vehicle_of_type |= HVOT_TRAIN;
SetDParam(0, st->index);
AddVehicleNewsItem(
STR_NEWS_FIRST_TRAIN_ARRIVAL,
MakeParameters(st->index),
v->owner == _local_company ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER,
v->index,
st->index
@ -3230,8 +3230,7 @@ static bool CheckTrainCollision(Train *v)
/* any dead -> no crash */
if (tcc.num == 0) return false;
SetDParam(0, tcc.num);
AddTileNewsItem(STR_NEWS_TRAIN_CRASH, NT_ACCIDENT, v->tile);
AddTileNewsItem(STR_NEWS_TRAIN_CRASH, MakeParameters(tcc.num), NT_ACCIDENT, v->tile);
ModifyStationRatingAround(v->tile, v->owner, -160, 30);
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) {
/* Show message to player. */
if (_settings_client.gui.lost_vehicle_warn && v->owner == _local_company) {
SetDParam(0, v->index);
AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_STUCK, v->index);
AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_STUCK, MakeParameters(v->index), v->index);
}
v->wait_counter = 0;
}

View File

@ -811,8 +811,7 @@ void Vehicle::HandlePathfindingResult(bool path_found)
/* Notify user about the event. */
AI::NewEvent(this->owner, new ScriptEventVehicleLost(this->index));
if (_settings_client.gui.lost_vehicle_warn && this->owner == _local_company) {
SetDParam(0, this->index);
AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_IS_LOST, this->index);
AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_IS_LOST, MakeParameters(this->index), this->index);
}
}
@ -1097,9 +1096,7 @@ void CallVehicleTicks()
message = STR_NEWS_VEHICLE_AUTORENEW_FAILED;
}
SetDParam(0, v->index);
SetDParam(1, error_message);
AddVehicleAdviceNewsItem(message, v->index);
AddVehicleAdviceNewsItem(message, MakeParameters(v->index, error_message), v->index);
}
cur_company.Restore();
@ -1453,8 +1450,7 @@ void AgeVehicle(Vehicle *v)
return;
}
SetDParam(0, v->index);
AddVehicleAdviceNewsItem(str, v->index);
AddVehicleAdviceNewsItem(str, MakeParameters(v->index), v->index);
}
/**
@ -1609,8 +1605,7 @@ void VehicleEnterDepot(Vehicle *v)
_vehicles_to_autoreplace[v] = false;
if (v->owner == _local_company) {
/* Notify the user that we stopped the vehicle */
SetDParam(0, v->index);
AddVehicleAdviceNewsItem(STR_NEWS_ORDER_REFIT_FAILED, v->index);
AddVehicleAdviceNewsItem(STR_NEWS_ORDER_REFIT_FAILED, MakeParameters(v->index), v->index);
}
} else if (cost.GetCost() != 0) {
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. */
v->last_loading_station = INVALID_STATION;
if (v->owner == _local_company) {
SetDParam(0, v->index);
AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_WAITING + v->type, v->index);
AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_WAITING + v->type, MakeParameters(v->index), 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();
if (v->age >= 730 && profit < 0) {
if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company) {
SetDParam(0, v->index);
SetDParam(1, profit);
AddVehicleAdviceNewsItem(
TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_VEHICLE_UNPROFITABLE_PERIOD : STR_NEWS_VEHICLE_UNPROFITABLE_YEAR,
MakeParameters(v->index, profit),
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));
Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_FLOODED));
SetDParam(0, pass);
AddTileNewsItem(STR_NEWS_DISASTER_FLOOD_VEHICLE, NT_ACCIDENT, v->tile);
AddTileNewsItem(STR_NEWS_DISASTER_FLOOD_VEHICLE, MakeParameters(pass), NT_ACCIDENT, v->tile);
CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v);
}