Mercurial > hg > openttd
changeset 12010:d0bf08a7c260 draft
(svn r16416) -Fix [FS#2912]: Rework deleting of news when referenced vehicles/stations/industries are deleted.
author | frosch <frosch@openttd.org> |
---|---|
date | Sun, 24 May 2009 16:52:42 +0000 |
parents | 5ac019d48a1b |
children | 69744e567407 |
files | src/aircraft_cmd.cpp src/company_cmd.cpp src/currency.cpp src/disaster_cmd.cpp src/economy.cpp src/engine.cpp src/engine_gui.cpp src/industry_cmd.cpp src/news_func.h src/news_gui.cpp src/news_type.h src/order_cmd.cpp src/roadveh_cmd.cpp src/ship_cmd.cpp src/station_cmd.cpp src/subsidy.cpp src/town_cmd.cpp src/train_cmd.cpp src/vehicle.cpp src/water_cmd.cpp |
diffstat | 20 files changed, 216 insertions(+), 162 deletions(-) [+] |
line wrap: on
line diff
--- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1320,10 +1320,10 @@ AI::NewEvent(v->owner, new AIEventVehicleCrashed(v->index, v->tile, crash_reason)); - AddNewsItem(newsitem, - NS_ACCIDENT_VEHICLE, + AddVehicleNewsItem(newsitem, + NS_ACCIDENT, v->index, - 0); + st != NULL ? st->index : INVALID_STATION); SndPlayVehicleFx(SND_12_EXPLOSION, v); } @@ -1364,7 +1364,7 @@ st->had_vehicle_of_type |= HVOT_AIRCRAFT; SetDParam(0, st->index); /* show newsitem of celebrating citizens */ - AddNewsItem( + AddVehicleNewsItem( STR_NEWS_FIRST_AIRCRAFT_ARRIVAL, (v->owner == _local_company) ? NS_ARRIVAL_COMPANY : NS_ARRIVAL_OTHER, v->index,
--- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -289,7 +289,7 @@ SetDParam(1, STR_NEWS_COMPANY_LAUNCH_DESCRIPTION); SetDParamStr(2, cni->company_name); SetDParam(3, t->index); - AddNewsItem(STR_NEWS_MESSAGE, NS_COMPANY_NEW, c->last_build_coordinate, 0, cni); + AddNewsItem(STR_NEWS_MESSAGE, NS_COMPANY_NEW, NR_TILE, c->last_build_coordinate, NR_NONE, UINT32_MAX, cni); } AI::BroadcastNewEvent(new AIEventCompanyNew(c->index), c->index); return; @@ -827,7 +827,7 @@ SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE); SetDParam(1, STR_NEWS_COMPANY_BANKRUPT_DESCRIPTION); SetDParamStr(2, cni->company_name); - AddNewsItem(STR_NEWS_MESSAGE, NS_COMPANY_BANKRUPT, 0, 0, cni); + AddCompanyNewsItem(STR_NEWS_MESSAGE, NS_COMPANY_BANKRUPT, cni); /* Remove the company */ ChangeOwnershipOfCompanyItems(c->index, INVALID_OWNER);
--- a/src/currency.cpp +++ b/src/currency.cpp @@ -157,7 +157,7 @@ _currency_specs[_settings_game.locale.currency].to_euro != CF_ISEURO && _cur_year >= _currency_specs[_settings_game.locale.currency].to_euro) { _settings_game.locale.currency = 2; // this is the index of euro above. - AddNewsItem(STR_EURO_INTRODUCE, NS_ECONOMY, 0, 0); + AddNewsItem(STR_EURO_INTRODUCE, NS_ECONOMY); } }
--- a/src/disaster_cmd.cpp +++ b/src/disaster_cmd.cpp @@ -207,10 +207,9 @@ v->age = 0; SetDParam(0, GetStationIndex(v->tile)); - AddNewsItem(STR_NEWS_DISASTER_ZEPPELIN, - NS_ACCIDENT_VEHICLE, - v->index, - 0); + AddVehicleNewsItem(STR_NEWS_DISASTER_ZEPPELIN, + NS_ACCIDENT, + v->index); // Delete the news, when the zeppelin is gone AI::NewEvent(GetTileOwner(v->tile), new AIEventDisasterZeppelinerCrashed(GetStationIndex(v->tile))); } } @@ -340,10 +339,9 @@ if (u->crashed_ctr == 0) { u->crashed_ctr++; - AddNewsItem(STR_NEWS_DISASTER_SMALL_UFO, - NS_ACCIDENT_VEHICLE, - u->index, - 0); + AddVehicleNewsItem(STR_NEWS_DISASTER_SMALL_UFO, + NS_ACCIDENT, + u->index); // delete the news, when the roadvehicle is gone AI::NewEvent(u->owner, new AIEventVehicleCrashed(u->index, u->tile, AIEventVehicleCrashed::CRASH_RV_UFO)); @@ -426,7 +424,7 @@ DestructIndustry(i); SetDParam(0, i->town->index); - AddNewsItem(news_message, NS_ACCIDENT_TILE, i->xy, 0); + AddIndustryNewsItem(news_message, NS_ACCIDENT, i->index); // delete the news, when the industry closes SndPlayTileFx(SND_12_EXPLOSION, i->xy); } } else if (v->current_order.GetDestination() == 0) { @@ -523,9 +521,9 @@ Town *t = ClosestTownFromTile(v->dest_tile, UINT_MAX); SetDParam(0, t->index); AddNewsItem(STR_NEWS_DISASTER_BIG_UFO, - NS_ACCIDENT_TILE, - v->tile, - 0); + NS_ACCIDENT, + NR_TILE, + v->tile); if (!Vehicle::CanAllocateItem(2)) { delete v; @@ -865,7 +863,7 @@ if ((GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_CAN_SUBSIDENCE) && --index < 0) { SetDParam(0, i->town->index); AddNewsItem(STR_NEWS_DISASTER_COAL_MINE_SUBSIDENCE, - NS_ACCIDENT_TILE, i->xy + TileDiffXY(1, 1), 0); + NS_ACCIDENT, NR_TILE, i->xy + TileDiffXY(1, 1)); // keep the news, even when the mine closes { TileIndex tile = i->xy;
--- a/src/economy.cpp +++ b/src/economy.cpp @@ -481,7 +481,7 @@ SetDParam(0, STR_NEWS_COMPANY_IN_TROUBLE_TITLE); SetDParam(1, STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION); SetDParamStr(2, cni->company_name); - AddNewsItem(STR_NEWS_MESSAGE, NS_COMPANY_TROUBLE, 0, 0, cni); + AddCompanyNewsItem(STR_NEWS_MESSAGE, NS_COMPANY_TROUBLE, cni); AI::BroadcastNewEvent(new AIEventCompanyInTrouble(c->index)); break; case 3: { @@ -491,7 +491,7 @@ SetDParam(0, STR_NEWS_COMPANY_IN_TROUBLE_TITLE); SetDParam(1, STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION); SetDParamStr(2, cni->company_name); - AddNewsItem(STR_NEWS_MESSAGE, NS_COMPANY_TROUBLE, 0, 0, cni); + AddCompanyNewsItem(STR_NEWS_MESSAGE, NS_COMPANY_TROUBLE, cni); break; } @@ -526,7 +526,7 @@ SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE); SetDParam(1, STR_NEWS_COMPANY_BANKRUPT_DESCRIPTION); SetDParamStr(2, cni->company_name); - AddNewsItem(STR_NEWS_MESSAGE, NS_COMPANY_BANKRUPT, 0, 0, cni); + AddCompanyNewsItem(STR_NEWS_MESSAGE, NS_COMPANY_BANKRUPT, cni); /* Remove the company */ ChangeNetworkOwner(c->index, COMPANY_SPECTATOR); @@ -668,10 +668,10 @@ if (--_economy.fluct == 0) { _economy.fluct = -(int)GB(Random(), 0, 2); - AddNewsItem(STR_NEWS_BEGIN_OF_RECESSION, NS_ECONOMY, 0, 0); + AddNewsItem(STR_NEWS_BEGIN_OF_RECESSION, NS_ECONOMY); } else if (_economy.fluct == -12) { _economy.fluct = GB(Random(), 0, 8) + 312; - AddNewsItem(STR_NEWS_END_OF_RECESSION, NS_ECONOMY, 0, 0); + AddNewsItem(STR_NEWS_END_OF_RECESSION, NS_ECONOMY); } } @@ -1507,7 +1507,7 @@ SetDParamStr(2, cni->company_name); SetDParamStr(3, cni->other_company_name); SetDParam(4, c->bankrupt_value); - AddNewsItem(STR_NEWS_MESSAGE, NS_COMPANY_MERGER, 0, 0, cni); + AddCompanyNewsItem(STR_NEWS_MESSAGE, NS_COMPANY_MERGER, cni); AI::BroadcastNewEvent(new AIEventCompanyMerger(ci, _current_company)); /* original code does this a little bit differently */
--- a/src/engine.cpp +++ b/src/engine.cpp @@ -683,7 +683,7 @@ SetDParam(0, GetEngineCategoryName(index)); SetDParam(1, index); - AddNewsItem(STR_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE, NS_NEW_VEHICLES, index, 0); + AddNewsItem(STR_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE, NS_NEW_VEHICLES, NR_ENGINE, index); } void EnginesMonthlyLoop()
--- a/src/engine_gui.cpp +++ b/src/engine_gui.cpp @@ -224,7 +224,8 @@ void DrawNewsNewVehicleAvail(Window *w, const NewsItem *ni) { - EngineID engine = ni->data_a; + assert(ni->reftype1 == NR_ENGINE); + EngineID engine = ni->ref1; const DrawEngineInfo *dei = &_draw_engine_list[Engine::Get(engine)->type]; SetDParam(0, GetEngineCategoryName(engine));
--- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -164,6 +164,7 @@ DecIndustryTypeCount(this->type); DeleteSubsidyWithIndustry(this->index); + DeleteIndustryNews(this->index); DeleteWindowById(WC_INDUSTRY_VIEW, this->index); InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 0); } @@ -1693,7 +1694,7 @@ } else { SetDParam(1, ind->town->index); } - AddNewsItem(indspec->new_industry_text, NS_INDUSTRY_OPEN, ind->xy, 0); + AddIndustryNewsItem(indspec->new_industry_text, NS_INDUSTRY_OPEN, ind->index); AI::BroadcastNewEvent(new AIEventIndustryOpen(ind->index)); } @@ -1898,7 +1899,7 @@ } else { SetDParam(1, ind->town->index); } - AddNewsItem(ind_spc->new_industry_text, NS_INDUSTRY_OPEN, ind->xy, 0); + AddIndustryNewsItem(ind_spc->new_industry_text, NS_INDUSTRY_OPEN, ind->index); AI::BroadcastNewEvent(new AIEventIndustryOpen(ind->index)); } @@ -2042,10 +2043,10 @@ SetDParam(2, abs(percent)); SetDParam(0, GetCargo(type)->name); SetDParam(1, ind->index); - AddNewsItem( + AddIndustryNewsItem( percent >= 0 ? STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH : STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH, ns, - ind->xy + TileDiffXY(1, 1), 0 + ind->index ); } @@ -2250,7 +2251,8 @@ /* and report the news to the user */ AddNewsItem(str, ns, - i->xy + TileDiffXY(1, 1), 0); + closeit ? NR_TILE : NR_INDUSTRY, + closeit ? i->xy + TileDiffXY(1, 1) : i->index); } }
--- a/src/news_func.h +++ b/src/news_func.h @@ -8,8 +8,25 @@ #include "news_type.h" #include "vehicle_type.h" #include "station_type.h" +#include "industry_type.h" -void AddNewsItem(StringID string, NewsSubtype subtype, uint data_a, uint data_b, void *free_data = NULL); +void AddNewsItem(StringID string, NewsSubtype subtype, NewsReferenceType reftype1 = NR_NONE, uint32 ref1 = UINT32_MAX, NewsReferenceType reftype2 = NR_NONE, uint32 ref2 = UINT32_MAX, void *free_data = NULL); + +static inline void AddCompanyNewsItem(StringID string, NewsSubtype subtype, CompanyNewsInformation *cni) +{ + AddNewsItem(string, subtype, NR_NONE, UINT32_MAX, NR_NONE, UINT32_MAX, cni); +} + +static inline void AddVehicleNewsItem(StringID string, NewsSubtype subtype, VehicleID vehicle, StationID station = INVALID_STATION) +{ + AddNewsItem(string, subtype, NR_VEHICLE, vehicle, station == INVALID_STATION ? NR_NONE : NR_STATION, station); +} + +static inline void AddIndustryNewsItem(StringID string, NewsSubtype subtype, IndustryID industry) +{ + AddNewsItem(string, subtype, NR_INDUSTRY, industry); +} + void NewsLoop(); void InitNewsItemStructs(); @@ -23,9 +40,12 @@ * if the news item type is INVALID_STRING_ID all news about the vehicle get * deleted */ -void DeleteVehicleNews(VehicleID, StringID news); +void DeleteVehicleNews(VehicleID vid, StringID news); /** Delete news associated with given station */ -void DeleteStationNews(StationID); +void DeleteStationNews(StationID sid); + +/** Delete news associated with given station */ +void DeleteIndustryNews(IndustryID iid); #endif /* NEWS_FUNC_H */
--- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -14,11 +14,15 @@ #include "window_func.h" #include "date_func.h" #include "vehicle_base.h" +#include "station_base.h" +#include "industry.h" +#include "town.h" #include "sound_func.h" #include "string_func.h" #include "widgets/dropdown_func.h" #include "statusbar_gui.h" #include "company_manager_face.h" +#include "map_func.h" #include "table/strings.h" @@ -90,6 +94,22 @@ } } +/** + * Get the position a news-reference is referencing. + * @param reftype The type of reference. + * @param ref The reference. + * @return A tile for the referenced object, or INVALID_TILE if none. + */ +static TileIndex GetReferenceTile(NewsReferenceType reftype, uint32 ref) +{ + switch (reftype) { + case NR_TILE: return (TileIndex)ref; + case NR_STATION: return Station::Get((StationID)ref)->xy; + case NR_INDUSTRY: return Industry::Get((IndustryID)ref)->xy + TileDiffXY(1, 1); + case NR_TOWN: return Town::Get((TownID)ref)->xy; + default: return INVALID_TILE; + } +} /** * Data common to all news items of a given subtype (structure) @@ -106,25 +126,24 @@ */ static const NewsSubtypeData _news_subtype_data[] = { /* type, display_mode, flags, callback */ - { NT_ARRIVAL_COMPANY, NM_THIN, NF_VIEWPORT|NF_VEHICLE, NULL }, ///< NS_ARRIVAL_COMPANY - { NT_ARRIVAL_OTHER, NM_THIN, NF_VIEWPORT|NF_VEHICLE, NULL }, ///< NS_ARRIVAL_OTHER - { NT_ACCIDENT, NM_THIN, NF_VIEWPORT|NF_TILE, NULL }, ///< NS_ACCIDENT_TILE - { NT_ACCIDENT, NM_THIN, NF_VIEWPORT|NF_VEHICLE, NULL }, ///< NS_ACCIDENT_VEHICLE - { NT_COMPANY_INFO, NM_NORMAL, NF_NONE, DrawNewsBankrupcy }, ///< NS_COMPANY_TROUBLE - { NT_COMPANY_INFO, NM_NORMAL, NF_NONE, DrawNewsBankrupcy }, ///< NS_COMPANY_MERGER - { NT_COMPANY_INFO, NM_NORMAL, NF_NONE, DrawNewsBankrupcy }, ///< NS_COMPANY_BANKRUPT - { NT_COMPANY_INFO, NM_NORMAL, NF_TILE, DrawNewsBankrupcy }, ///< NS_COMPANY_NEW - { NT_INDUSTRY_OPEN, NM_THIN, NF_VIEWPORT|NF_TILE, NULL }, ///< NS_INDUSTRY_OPEN - { NT_INDUSTRY_CLOSE, NM_THIN, NF_VIEWPORT|NF_TILE, NULL }, ///< NS_INDUSTRY_CLOSE - { NT_ECONOMY, NM_NORMAL, NF_NONE, NULL }, ///< NS_ECONOMY - { NT_INDUSTRY_COMPANY, NM_THIN, NF_VIEWPORT|NF_TILE, NULL }, ///< NS_INDUSTRY_COMPANY - { NT_INDUSTRY_OTHER, NM_THIN, NF_VIEWPORT|NF_TILE, NULL }, ///< NS_INDUSTRY_OTHER - { NT_INDUSTRY_NOBODY, NM_THIN, NF_VIEWPORT|NF_TILE, NULL }, ///< NS_INDUSTRY_NOBODY - { NT_ADVICE, NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NULL }, ///< NS_ADVICE - { NT_NEW_VEHICLES, NM_NORMAL, NF_NONE, DrawNewsNewVehicleAvail }, ///< NS_NEW_VEHICLES - { NT_ACCEPTANCE, NM_SMALL, NF_VIEWPORT|NF_TILE, NULL }, ///< NS_ACCEPTANCE - { NT_SUBSIDIES, NM_NORMAL, NF_TILE|NF_TILE2, NULL }, ///< NS_SUBSIDIES - { NT_GENERAL, NM_NORMAL, NF_TILE, NULL }, ///< NS_GENERAL + { NT_ARRIVAL_COMPANY, NM_THIN, NF_VIEWPORT, NULL }, ///< NS_ARRIVAL_COMPANY + { NT_ARRIVAL_OTHER, NM_THIN, NF_VIEWPORT, NULL }, ///< NS_ARRIVAL_OTHER + { NT_ACCIDENT, NM_THIN, NF_VIEWPORT, NULL }, ///< NS_ACCIDENT + { NT_COMPANY_INFO, NM_NORMAL, NF_NONE, DrawNewsBankrupcy }, ///< NS_COMPANY_TROUBLE + { NT_COMPANY_INFO, NM_NORMAL, NF_NONE, DrawNewsBankrupcy }, ///< NS_COMPANY_MERGER + { NT_COMPANY_INFO, NM_NORMAL, NF_NONE, DrawNewsBankrupcy }, ///< NS_COMPANY_BANKRUPT + { NT_COMPANY_INFO, NM_NORMAL, NF_NONE, DrawNewsBankrupcy }, ///< NS_COMPANY_NEW + { NT_INDUSTRY_OPEN, NM_THIN, NF_VIEWPORT, NULL }, ///< NS_INDUSTRY_OPEN + { NT_INDUSTRY_CLOSE, NM_THIN, NF_VIEWPORT, NULL }, ///< NS_INDUSTRY_CLOSE + { NT_ECONOMY, NM_NORMAL, NF_NONE, NULL }, ///< NS_ECONOMY + { NT_INDUSTRY_COMPANY, NM_THIN, NF_VIEWPORT, NULL }, ///< NS_INDUSTRY_COMPANY + { NT_INDUSTRY_OTHER, NM_THIN, NF_VIEWPORT, NULL }, ///< NS_INDUSTRY_OTHER + { NT_INDUSTRY_NOBODY, NM_THIN, NF_VIEWPORT, NULL }, ///< NS_INDUSTRY_NOBODY + { NT_ADVICE, NM_SMALL, NF_VIEWPORT, NULL }, ///< NS_ADVICE + { NT_NEW_VEHICLES, NM_NORMAL, NF_NONE, DrawNewsNewVehicleAvail }, ///< NS_NEW_VEHICLES + { NT_ACCEPTANCE, NM_SMALL, NF_VIEWPORT, NULL }, ///< NS_ACCEPTANCE + { NT_SUBSIDIES, NM_NORMAL, NF_NONE, NULL }, ///< NS_SUBSIDIES + { NT_GENERAL, NM_NORMAL, NF_NONE, NULL }, ///< NS_GENERAL }; assert_compile(lengthof(_news_subtype_data) == NS_END); @@ -253,18 +272,18 @@ break; case 0: - if (this->ni->flags & NF_VEHICLE) { - const Vehicle *v = Vehicle::Get(this->ni->data_a); + if (this->ni->reftype1 == NR_VEHICLE) { + const Vehicle *v = Vehicle::Get(this->ni->ref1); ScrollMainWindowTo(v->x_pos, v->y_pos, v->z_pos); - } else if (this->ni->flags & NF_TILE) { + } else { + TileIndex tile1 = GetReferenceTile(this->ni->reftype1, this->ni->ref1); + TileIndex tile2 = GetReferenceTile(this->ni->reftype2, this->ni->ref2); if (_ctrl_pressed) { - ShowExtraViewPortWindow(this->ni->data_a); - if (this->ni->flags & NF_TILE2) { - ShowExtraViewPortWindow(this->ni->data_b); - } + if (tile1 != INVALID_TILE) ShowExtraViewPortWindow(tile1); + if (tile2 != INVALID_TILE) ShowExtraViewPortWindow(tile2); } else { - if (!ScrollMainWindowToTile(this->ni->data_a) && this->ni->flags & NF_TILE2) { - ScrollMainWindowToTile(this->ni->data_b); + if (((tile1 == INVALID_TILE) || !ScrollMainWindowToTile(tile1)) && (tile2 != INVALID_TILE)) { + ScrollMainWindowToTile(tile2); } } } @@ -405,7 +424,7 @@ w = new NewsWindow(&_news_type13_desc, ni); if (ni->flags & NF_VIEWPORT) { InitializeWindowViewport(w, 2, 58, 426, 110, - ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), ZOOM_LVL_NEWS); + ni->reftype1 == NR_VEHICLE ? 0x80000000 | ni->ref1 : GetReferenceTile(ni->reftype1, ni->ref1), ZOOM_LVL_NEWS); } break; @@ -414,7 +433,7 @@ w = new NewsWindow(&_news_type2_desc, ni); if (ni->flags & NF_VIEWPORT) { InitializeWindowViewport(w, 2, 58, 426, 70, - ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), ZOOM_LVL_NEWS); + ni->reftype1 == NR_VEHICLE ? 0x80000000 | ni->ref1 : GetReferenceTile(ni->reftype1, ni->ref1), ZOOM_LVL_NEWS); } break; @@ -423,7 +442,7 @@ w = new NewsWindow(&_news_type0_desc, ni); if (ni->flags & NF_VIEWPORT) { InitializeWindowViewport(w, 3, 17, 274, 47, - ni->data_a | (ni->flags & NF_VEHICLE ? 0x80000000 : 0), ZOOM_LVL_NEWS); + ni->reftype1 == NR_VEHICLE ? 0x80000000 | ni->ref1 : GetReferenceTile(ni->reftype1, ni->ref1), ZOOM_LVL_NEWS); } break; } @@ -511,12 +530,14 @@ * Add a new newsitem to be shown. * @param string String to display * @param subtype news category, any of the NewsSubtype enums (NS_) - * @param data_a news-specific value based on news type - * @param data_b news-specific value based on news type + * @param reftype1 Type of ref1 + * @param ref1 Reference 1 to some object: Used for a possible viewport, scrolling after clicking on the news, and for deleteing the news when the object is deleted. + * @param reftype2 Type of ref2 + * @param ref2 Reference 2 to some object: Used for scrolling after clicking on the news, and for deleteing the news when the object is deleted. * * @see NewsSubype */ -void AddNewsItem(StringID string, NewsSubtype subtype, uint data_a, uint data_b, void *free_data) +void AddNewsItem(StringID string, NewsSubtype subtype, NewsReferenceType reftype1, uint32 ref1, NewsReferenceType reftype2, uint32 ref2, void *free_data) { if (_game_mode == GM_MENU) return; @@ -530,8 +551,10 @@ /* show this news message in colour? */ if (_cur_year >= _settings_client.gui.coloured_news_year) ni->flags |= NF_INCOLOUR; - ni->data_a = data_a; - ni->data_b = data_b; + ni->reftype1 = reftype1; + ni->reftype2 = reftype2; + ni->ref1 = ref1; + ni->ref2 = ref2; ni->free_data = free_data; ni->date = _date; CopyOutDParam(ni->params, 0, lengthof(ni->params)); @@ -591,16 +614,12 @@ NewsItem *ni = _oldest_news; while (ni != NULL) { - if (ni->flags & NF_VEHICLE && - ni->data_a == vid && + NewsItem *next = ni->next; + if (((ni->reftype1 == NR_VEHICLE && ni->ref1 == vid) || (ni->reftype2 == NR_VEHICLE && ni->ref2 == vid)) && (news == INVALID_STRING_ID || ni->string_id == news)) { - /* grab a pointer to the next item before ni is freed */ - NewsItem *p = ni->next; DeleteNewsItem(ni); - ni = p; - } else { - ni = ni->next; } + ni = next; } } @@ -614,14 +633,24 @@ while (ni != NULL) { NewsItem *next = ni->next; - switch (ni->subtype) { - case NS_ARRIVAL_COMPANY: - case NS_ARRIVAL_OTHER: - case NS_ACCEPTANCE: - if (ni->data_b == sid) DeleteNewsItem(ni); - break; - default: - break; + if ((ni->reftype1 == NR_STATION && ni->ref1 == sid) || (ni->reftype2 == NR_STATION && ni->ref2 == sid)) { + DeleteNewsItem(ni); + } + ni = next; + } +} + +/** Remove news regarding given industry + * @param iid industry to remove news about + */ +void DeleteIndustryNews(IndustryID iid) +{ + NewsItem *ni = _oldest_news; + + while (ni != NULL) { + NewsItem *next = ni->next; + if ((ni->reftype1 == NR_INDUSTRY && ni->ref1 == iid) || (ni->reftype2 == NR_INDUSTRY && ni->ref2 == iid)) { + DeleteNewsItem(ni); } ni = next; }
--- a/src/news_type.h +++ b/src/news_type.h @@ -38,8 +38,7 @@ enum NewsSubtype { NS_ARRIVAL_COMPANY, ///< NT_ARRIVAL_COMPANY NS_ARRIVAL_OTHER, ///< NT_ARRIVAL_OTHER - NS_ACCIDENT_TILE, ///< NT_ACCIDENT (tile) - NS_ACCIDENT_VEHICLE, ///< NT_ACCIDENT (vehicle) + NS_ACCIDENT, ///< NT_ACCIDENT NS_COMPANY_TROUBLE, ///< NT_COMPANY_INFO (trouble) NS_COMPANY_MERGER, ///< NT_COMPANY_INFO (merger) NS_COMPANY_BANKRUPT, ///< NT_COMPANY_INFO (bankrupt) @@ -68,16 +67,26 @@ }; /** + * References to objects in news. + */ +enum NewsReferenceType { + NR_NONE, ///< Empty reference + NR_TILE, ///< Reference tile. Scroll to tile when clicking on the news. + NR_VEHICLE, ///< Reference vehicle. Scroll to vehicle when clicking on the news. Delete news when vehicle is deleted. + NR_STATION, ///< Reference station. Scroll to station when clicking on the news. Delete news when station is deleted. + NR_INDUSTRY, ///< Reference industry. Scroll to industry when clicking on the news. Delete news when industry is deleted. + NR_TOWN, ///< Reference town. Scroll to town when clicking on the news. + NR_ENGINE ///< Reference engine. +}; + +/** * Various OR-able news-item flags. * note: NF_INCOLOUR is set automatically if needed */ enum NewsFlag { - NF_NONE = 0, ///< No flag is set. - NF_VIEWPORT = (1 << 1), ///< Does the news message have a viewport? (ingame picture of happening) - NF_TILE = (1 << 2), ///< When clicked on the news message scroll to a given tile? Tile is in data_a - NF_VEHICLE = (1 << 3), ///< When clicked on the message scroll to the vehicle? VehicleID is in data_a - NF_INCOLOUR = (1 << 5), ///< Show the newsmessage in colour, otherwise it defaults to black & white - NF_TILE2 = (1 << 6), ///< There is a second tile to scroll to; tile is in data_b + NF_NONE = 0, ///< No flag is set. + NF_VIEWPORT = 1 << 1, ///< Does the news message have a viewport? (ingame picture of happening) + NF_INCOLOUR = 1 << 2, ///< Show the newsmessage in colour, otherwise it defaults to black & white }; DECLARE_ENUM_AS_BIT_SET(NewsFlag); @@ -112,17 +121,19 @@ }; struct NewsItem { - NewsItem *prev; ///< Previous news item - NewsItem *next; ///< Next news item - StringID string_id; ///< Message text - Date date; ///< Date of the news - NewsSubtype subtype; ///< News subtype @see NewsSubtype - NewsFlag flags; ///< NewsFlags bits @see NewsFlag + NewsItem *prev; ///< Previous news item + NewsItem *next; ///< Next news item + StringID string_id; ///< Message text + Date date; ///< Date of the news + NewsSubtype subtype; ///< News subtype @see NewsSubtype + NewsFlag flags; ///< NewsFlags bits @see NewsFlag - uint data_a; ///< Custom data 1 (usually tile or vehicle) - uint data_b; ///< Custom data 2 + NewsReferenceType reftype1; ///< Type of ref1 + NewsReferenceType reftype2; ///< Type of ref2 + uint32 ref1; ///< Reference 1 to some object: Used for a possible viewport, scrolling after clicking on the news, and for deleteing the news when the object is deleted. + uint32 ref2; ///< Reference 2 to some object: Used for scrolling after clicking on the news, and for deleteing the news when the object is deleted. - void *free_data; ///< Data to be freed when the news item has reached its end. + void *free_data; ///< Data to be freed when the news item has reached its end. uint64 params[10]; };
--- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1433,11 +1433,10 @@ //DEBUG(misc, 3, "Triggered News Item for vehicle %d", v->index); SetDParam(0, v->index); - AddNewsItem( + AddVehicleNewsItem( message, NS_ADVICE, - v->index, - 0 + v->index ); } }
--- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -591,12 +591,11 @@ AI::NewEvent(v->owner, new AIEventVehicleCrashed(v->index, v->tile, AIEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING)); SetDParam(0, pass); - AddNewsItem( + AddVehicleNewsItem( (pass == 1) ? STR_NEWS_ROAD_CRASH_DRIVER : STR_NEWS_ROAD_CRASH, - NS_ACCIDENT_VEHICLE, - v->index, - 0 + NS_ACCIDENT, + v->index ); ModifyStationRatingAround(v->tile, v->owner, -160, 22); @@ -770,7 +769,7 @@ if (!(st->had_vehicle_of_type & HVOT_BUS)) { st->had_vehicle_of_type |= HVOT_BUS; SetDParam(0, st->index); - AddNewsItem( + AddVehicleNewsItem( v->roadtype == ROADTYPE_ROAD ? STR_NEWS_FIRST_ROAD_BUS_ARRIVAL : STR_NEWS_FIRST_ROAD_PASSENGER_TRAM_ARRIVAL, (v->owner == _local_company) ? NS_ARRIVAL_COMPANY : NS_ARRIVAL_OTHER, v->index, @@ -783,7 +782,7 @@ if (!(st->had_vehicle_of_type & HVOT_TRUCK)) { st->had_vehicle_of_type |= HVOT_TRUCK; SetDParam(0, st->index); - AddNewsItem( + AddVehicleNewsItem( v->roadtype == ROADTYPE_ROAD ? STR_NEWS_FIRST_ROAD_TRUCK_ARRIVAL : STR_NEWS_FIRST_ROAD_CARGO_TRAM_ARRIVAL, (v->owner == _local_company) ? NS_ARRIVAL_COMPANY : NS_ARRIVAL_OTHER, v->index,
--- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -354,7 +354,7 @@ st->had_vehicle_of_type |= HVOT_SHIP; SetDParam(0, st->index); - AddNewsItem( + AddVehicleNewsItem( STR_NEWS_FIRST_SHIP_ARRIVAL, (v->owner == _local_company) ? NS_ARRIVAL_COMPANY : NS_ARRIVAL_OTHER, v->index,
--- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -439,7 +439,7 @@ } SetDParam(0, st->index); - AddNewsItem(msg, NS_ACCEPTANCE, st->xy, st->index); + AddNewsItem(msg, NS_ACCEPTANCE, NR_STATION, st->index); } /**
--- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -21,9 +21,8 @@ Pair SetupSubsidyDecodeParam(const Subsidy *s, bool mode) { - TileIndex tile; - TileIndex tile2; - Pair tp; + NewsReferenceType reftype1 = NR_NONE; + NewsReferenceType reftype2 = NR_NONE; /* if mode is false, use the singular form */ const CargoSpec *cs = GetCargo(s->cargo_type); @@ -33,38 +32,38 @@ if (cs->town_effect != TE_PASSENGERS && cs->town_effect != TE_MAIL) { SetDParam(1, STR_INDUSTRY); SetDParam(2, s->from); - tile = Industry::Get(s->from)->xy; + reftype1 = NR_INDUSTRY; if (cs->town_effect != TE_GOODS && cs->town_effect != TE_FOOD) { SetDParam(4, STR_INDUSTRY); SetDParam(5, s->to); - tile2 = Industry::Get(s->to)->xy; + reftype2 = NR_INDUSTRY; } else { SetDParam(4, STR_TOWN); SetDParam(5, s->to); - tile2 = Town::Get(s->to)->xy; + reftype2 = NR_TOWN; } } else { SetDParam(1, STR_TOWN); SetDParam(2, s->from); - tile = Town::Get(s->from)->xy; + reftype1 = NR_TOWN; SetDParam(4, STR_TOWN); SetDParam(5, s->to); - tile2 = Town::Get(s->to)->xy; + reftype2 = NR_TOWN; } } else { SetDParam(1, s->from); - tile = Station::Get(s->from)->xy; + reftype1 = NR_STATION; SetDParam(2, s->to); - tile2 = Station::Get(s->to)->xy; + reftype2 = NR_STATION; } - tp.a = tile; - tp.b = tile2; - - return tp; + Pair p; + p.a = reftype1; + p.b = reftype2; + return p; } void DeleteSubsidyWithTown(TownID index) @@ -214,7 +213,6 @@ void SubsidyMonthlyLoop() { Subsidy *s; - Pair pair; Station *st; uint n; FoundRoute fr; @@ -224,16 +222,16 @@ if (s->cargo_type == CT_INVALID) continue; if (s->age == 12 - 1) { - pair = SetupSubsidyDecodeParam(s, 1); - AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NS_SUBSIDIES, pair.a, pair.b); + Pair reftype = SetupSubsidyDecodeParam(s, 1); + AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->from, (NewsReferenceType)reftype.b, s->to); s->cargo_type = CT_INVALID; modified = true; AI::BroadcastNewEvent(new AIEventSubsidyOfferExpired(s - _subsidies)); } else if (s->age == 2 * 12 - 1) { st = Station::Get(s->to); if (st->owner == _local_company) { - pair = SetupSubsidyDecodeParam(s, 1); - AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, NS_SUBSIDIES, pair.a, pair.b); + Pair reftype = SetupSubsidyDecodeParam(s, 1); + AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->from, (NewsReferenceType)reftype.b, s->to); } s->cargo_type = CT_INVALID; modified = true; @@ -272,8 +270,8 @@ add_subsidy: if (!CheckSubsidyDuplicate(s)) { s->age = 0; - pair = SetupSubsidyDecodeParam(s, 0); - AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, NS_SUBSIDIES, pair.a, pair.b); + Pair reftype = SetupSubsidyDecodeParam(s, 0); + AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, NS_SUBSIDIES, (NewsReferenceType)reftype.a, s->from, (NewsReferenceType)reftype.b, s->to); AI::BroadcastNewEvent(new AIEventSubsidyOffer(s - _subsidies)); modified = true; break; @@ -290,7 +288,6 @@ { Subsidy *s; TileIndex xy; - Pair pair; /* check if there is an already existing subsidy that applies to us */ for (s = _subsidies; s != endof(_subsidies); s++) { @@ -335,14 +332,14 @@ s->to = to->index; /* Add a news item */ - pair = SetupSubsidyDecodeParam(s, 0); + Pair reftype = SetupSubsidyDecodeParam(s, 0); InjectDParam(1); SetDParam(0, _current_company); AddNewsItem( STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF + _settings_game.difficulty.subsidy_multiplier, NS_SUBSIDIES, - pair.a, pair.b + (NewsReferenceType)reftype.a, s->from, (NewsReferenceType)reftype.b, s->to ); AI::BroadcastNewEvent(new AIEventSubsidyAwarded(s - _subsidies));
--- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -2344,7 +2344,7 @@ SetDParam(0, t->index); SetDParamStr(1, cn); - AddNewsItem(STR_NEWS_ROAD_REBUILDING, NS_GENERAL, t->xy, 0, cn); + AddNewsItem(STR_NEWS_ROAD_REBUILDING, NS_GENERAL, NR_TOWN, t->index, NR_NONE, UINT32_MAX, cn); } static bool DoBuildStatueOfCompany(TileIndex tile, TownID town_id)
--- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -2987,11 +2987,11 @@ AI::NewEvent(v->owner, new AIEventVehicleLost(v->index)); if (_settings_client.gui.lost_train_warn && v->owner == _local_company) { SetDParam(0, v->index); - AddNewsItem( + AddVehicleNewsItem( STR_TRAIN_IS_LOST, NS_ADVICE, - v->index, - 0); + v->index + ); } } } else { @@ -3357,7 +3357,7 @@ if (!(st->had_vehicle_of_type & HVOT_TRAIN)) { st->had_vehicle_of_type |= HVOT_TRAIN; SetDParam(0, st->index); - AddNewsItem( + AddVehicleNewsItem( STR_NEWS_FIRST_TRAIN_ARRIVAL, v->owner == _local_company ? NS_ARRIVAL_COMPANY : NS_ARRIVAL_OTHER, v->index, @@ -3615,10 +3615,9 @@ if (tcc.num == 0) return false; SetDParam(0, tcc.num); - AddNewsItem(STR_NEWS_TRAIN_CRASH, - NS_ACCIDENT_VEHICLE, - v->index, - 0 + AddVehicleNewsItem(STR_NEWS_TRAIN_CRASH, + NS_ACCIDENT, + v->index ); ModifyStationRatingAround(v->tile, v->owner, -160, 30); @@ -4328,11 +4327,11 @@ /* Show message to player. */ if (_settings_client.gui.lost_train_warn && v->owner == _local_company) { SetDParam(0, v->index); - AddNewsItem( + AddVehicleNewsItem( STR_TRAIN_IS_STUCK, NS_ADVICE, - v->index, - 0); + v->index + ); } v->load_unload_time_rem = 0; }
--- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -669,7 +669,7 @@ SetDParam(0, v->index); SetDParam(1, error_message); - AddNewsItem(message, NS_ADVICE, v->index, 0); + AddVehicleNewsItem(message, NS_ADVICE, v->index); } _current_company = OWNER_NONE; @@ -922,7 +922,7 @@ } SetDParam(0, v->index); - AddNewsItem(str, NS_ADVICE, v->index, 0); + AddVehicleNewsItem(str, NS_ADVICE, v->index); } /** @@ -1043,7 +1043,7 @@ if (v->owner == _local_company) { /* Notify the user that we stopped the vehicle */ SetDParam(0, v->index); - AddNewsItem(STR_ORDER_REFIT_FAILED, NS_ADVICE, v->index, 0); + AddVehicleNewsItem(STR_ORDER_REFIT_FAILED, NS_ADVICE, v->index); } } else if (v->owner == _local_company && cost.GetCost() != 0) { ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost()); @@ -1070,7 +1070,7 @@ } SetDParam(0, v->index); - AddNewsItem(string, NS_ADVICE, v->index, 0); + AddVehicleNewsItem(string, NS_ADVICE, v->index); } AI::NewEvent(v->owner, new AIEventVehicleWaitingInDepot(v->index)); } @@ -1681,11 +1681,11 @@ if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company) { SetDParam(0, v->index); SetDParam(1, profit); - AddNewsItem( + AddVehicleNewsItem( STR_VEHICLE_IS_UNPROFITABLE, NS_ADVICE, - v->index, - 0); + v->index + ); } AI::NewEvent(v->owner, new AIEventVehicleUnprofitable(v->index)); }
--- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -841,10 +841,9 @@ AI::NewEvent(v->owner, new AIEventVehicleCrashed(v->index, v->tile, AIEventVehicleCrashed::CRASH_FLOODED)); SetDParam(0, pass); - AddNewsItem(STR_NEWS_DISASTER_FLOOD_VEHICLE, - NS_ACCIDENT_VEHICLE, - v->index, - 0); + AddVehicleNewsItem(STR_NEWS_DISASTER_FLOOD_VEHICLE, + NS_ACCIDENT, + v->index); CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); SndPlayVehicleFx(SND_12_EXPLOSION, v); }