From eaa765d615e3c70f23ac9a4a22ad6f686d5751f1 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 7 Feb 2025 13:10:39 +0000 Subject: [PATCH] Codechange: Disentangle news window style from news flags. (#13482) This avoids NewsFlags being used as both bitmask and bitstuffed data. --- src/company_cmd.cpp | 2 +- src/currency.cpp | 2 +- src/economy.cpp | 4 ++-- src/engine.cpp | 2 +- src/news_func.h | 12 ++++++------ src/news_gui.cpp | 26 +++++++++++++------------- src/news_type.h | 20 +++++++++++--------- src/station_cmd.cpp | 2 +- src/subsidy.cpp | 8 ++++---- src/town_cmd.cpp | 4 ++-- 10 files changed, 42 insertions(+), 40 deletions(-) diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 49e1727750..a274ec0415 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -433,7 +433,7 @@ set_name:; 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, std::move(cni)); + AddNewsItem(STR_MESSAGE_NEWS_FORMAT, NT_COMPANY_INFO, NewsStyle::Company, {}, NR_TILE, c->last_build_coordinate.base(), NR_NONE, UINT32_MAX, std::move(cni)); } return; } diff --git a/src/currency.cpp b/src/currency.cpp index c683f8ebe1..a3d559e39a 100644 --- a/src/currency.cpp +++ b/src/currency.cpp @@ -148,7 +148,7 @@ static IntervalTimer _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, NT_ECONOMY, NewsStyle::Normal, {}); } }); diff --git a/src/economy.cpp b/src/economy.cpp index d1d9019d91..0dcdfb65ec 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -873,10 +873,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, NT_ECONOMY, NewsStyle::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, NT_ECONOMY, NewsStyle::Normal, {}); } } diff --git a/src/engine.cpp b/src/engine.cpp index 7d949b4304..2090d1faf2 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1131,7 +1131,7 @@ static void NewVehicleAvailable(Engine *e) if (!IsVehicleTypeDisabled(e->type, false) && !e->info.extra_flags.Test(ExtraEngineFlag::NoNews)) { 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, NT_NEW_VEHICLES, NewsStyle::Vehicle, {}, NR_ENGINE, index); } /* Update the toolbar. */ diff --git a/src/news_func.h b/src/news_func.h index c2ab08f876..02552af88f 100644 --- a/src/news_func.h +++ b/src/news_func.h @@ -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, std::unique_ptr &&data = nullptr, AdviceType advice_type = AdviceType::Invalid); +void AddNewsItem(StringID string, NewsType type, NewsStyle style, NewsFlag flags, NewsReferenceType reftype1 = NR_NONE, uint32_t ref1 = UINT32_MAX, NewsReferenceType reftype2 = NR_NONE, uint32_t ref2 = UINT32_MAX, std::unique_ptr &&data = nullptr, AdviceType advice_type = AdviceType::Invalid); inline void AddCompanyNewsItem(StringID string, std::unique_ptr cni) { - AddNewsItem(string, NT_COMPANY_INFO, NF_COMPANY, NR_NONE, UINT32_MAX, NR_NONE, UINT32_MAX, std::move(cni)); + AddNewsItem(string, NT_COMPANY_INFO, NewsStyle::Company, {}, NR_NONE, UINT32_MAX, NR_NONE, UINT32_MAX, std::move(cni)); } /** @@ -29,7 +29,7 @@ inline void AddCompanyNewsItem(StringID string, std::unique_ptr &&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, std::move(data)); + AddNewsItem(string, type, NewsStyle::Thin, NF_NO_TRANSPARENT | NF_SHADE, NR_TILE, tile.base(), station == INVALID_STATION ? NR_NONE : NR_STATION, station, std::move(data)); } inline void AddIndustryNewsItem(StringID string, NewsType type, IndustryID industry, std::unique_ptr &&data = nullptr) { - AddNewsItem(string, type, NF_NO_TRANSPARENT | NF_SHADE | NF_THIN, NR_INDUSTRY, industry, NR_NONE, UINT32_MAX, std::move(data)); + AddNewsItem(string, type, NewsStyle::Thin, NF_NO_TRANSPARENT | NF_SHADE, NR_INDUSTRY, industry, NR_NONE, UINT32_MAX, std::move(data)); } void NewsLoop(); diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 1c29471c77..ccad1f8c28 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -294,16 +294,16 @@ static WindowDesc _small_news_desc( * Window layouts for news items. */ static WindowDesc *_news_window_layout[] = { - &_thin_news_desc, ///< NF_THIN - &_small_news_desc, ///< NF_SMALL - &_normal_news_desc, ///< NF_NORMAL - &_vehicle_news_desc, ///< NF_VEHICLE - &_company_news_desc, ///< NF_COMPANY + &_thin_news_desc, // NewsStyle::Thin + &_small_news_desc, // NewsStyle::Small + &_normal_news_desc, // NewsStyle::Normal + &_vehicle_news_desc, // NewsStyle::Vehicle + &_company_news_desc, // NewsStyle::Company }; -WindowDesc &GetNewsWindowLayout(NewsFlag flags) +static WindowDesc &GetNewsWindowLayout(NewsStyle style) { - uint layout = GB(flags, NFB_WINDOW_LAYOUT, NFB_WINDOW_LAYOUT_COUNT); + uint layout = to_underlying(style); assert(layout < lengthof(_news_window_layout)); return *_news_window_layout[layout]; } @@ -703,7 +703,7 @@ static void ShowNewspaper(const NewsItem *ni) SoundFx sound = _news_type_data[ni->type].sound; if (sound != 0 && _settings_client.sound.news_full) SndPlayFx(sound); - new NewsWindow(GetNewsWindowLayout(ni->flags), ni); + new NewsWindow(GetNewsWindowLayout(ni->style), ni); } /** Show news item in the ticker */ @@ -874,8 +874,8 @@ static std::list::iterator DeleteNewsItem(std::list::iterato * * @see NewsSubtype */ -NewsItem::NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, std::unique_ptr &&data, AdviceType advice_type) : - string_id(string_id), date(TimerGameCalendar::date), economy_date(TimerGameEconomy::date), type(type), advice_type(advice_type), flags(flags), reftype1(reftype1), reftype2(reftype2), ref1(ref1), ref2(ref2), data(std::move(data)) +NewsItem::NewsItem(StringID string_id, NewsType type, NewsStyle style, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, std::unique_ptr &&data, AdviceType advice_type) : + string_id(string_id), date(TimerGameCalendar::date), economy_date(TimerGameEconomy::date), type(type), advice_type(advice_type), style(style), flags(flags), reftype1(reftype1), reftype2(reftype2), ref1(ref1), ref2(ref2), data(std::move(data)) { /* show this news message in colour? */ if (TimerGameCalendar::year >= _settings_client.gui.coloured_news_year) this->flags |= NF_INCOLOUR; @@ -896,12 +896,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, std::unique_ptr &&data, AdviceType advice_type) +void AddNewsItem(StringID string, NewsType type, NewsStyle style, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, std::unique_ptr &&data, AdviceType advice_type) { if (_game_mode == GM_MENU) return; /* Create new news item node */ - _news.emplace_front(string, type, flags, reftype1, ref1, reftype2, ref2, std::move(data), advice_type); + _news.emplace_front(string, type, style, flags, reftype1, ref1, reftype2, ref2, std::move(data), advice_type); /* Keep the number of stored news items to a managable number */ if (std::size(_news) > MAX_NEWS_AMOUNT) { @@ -962,7 +962,7 @@ CommandCost CmdCustomNewsItem(DoCommandFlag flags, NewsType type, NewsReferenceT if (flags & DC_EXEC) { SetDParamStr(0, text); - AddNewsItem(STR_NEWS_CUSTOM_ITEM, type, NF_NORMAL, reftype1, reference, NR_NONE, UINT32_MAX); + AddNewsItem(STR_NEWS_CUSTOM_ITEM, type, NewsStyle::Normal, {}, reftype1, reference, NR_NONE, UINT32_MAX); } return CommandCost(); diff --git a/src/news_type.h b/src/news_type.h index d094e016b4..15a194bc48 100644 --- a/src/news_type.h +++ b/src/news_type.h @@ -74,6 +74,15 @@ enum NewsReferenceType : uint8_t { NR_ENGINE, ///< Reference engine. }; +/** News Window Styles. */ +enum class NewsStyle : uint8_t { + Thin, ///< Thin news item. (Newspaper with headline and viewport) + Small, ///< Small news item. (Information window with text and viewport) + Normal, ///< Normal news item. (Newspaper with text only) + Vehicle, ///< Vehicle news item. (new engine available) + Company, ///< Company news item. (Newspaper with face) +}; + /** * Various OR-able news-item flags. * @note #NF_INCOLOUR is set automatically if needed. @@ -82,20 +91,12 @@ enum NewsFlag : uint8_t { NFB_INCOLOUR = 0, ///< News item is shown in colour (otherwise it is shown in black & white). NFB_NO_TRANSPARENT = 1, ///< News item disables transparency in the viewport. NFB_SHADE = 2, ///< News item uses shaded colours. - NFB_WINDOW_LAYOUT = 3, ///< First bit for window layout. - NFB_WINDOW_LAYOUT_COUNT = 3, ///< Number of bits for window layout. NFB_VEHICLE_PARAM0 = 6, ///< String param 0 contains a vehicle ID. (special autoreplace behaviour) NF_INCOLOUR = 1 << NFB_INCOLOUR, ///< Bit value for coloured news. NF_NO_TRANSPARENT = 1 << NFB_NO_TRANSPARENT, ///< Bit value for disabling transparency. NF_SHADE = 1 << NFB_SHADE, ///< Bit value for enabling shading. NF_VEHICLE_PARAM0 = 1 << NFB_VEHICLE_PARAM0, ///< Bit value for specifying that string param 0 contains a vehicle ID. (special autoreplace behaviour) - - NF_THIN = 0 << NFB_WINDOW_LAYOUT, ///< Thin news item. (Newspaper with headline and viewport) - NF_SMALL = 1 << NFB_WINDOW_LAYOUT, ///< Small news item. (Information window with text and viewport) - NF_NORMAL = 2 << NFB_WINDOW_LAYOUT, ///< Normal news item. (Newspaper with text only) - NF_VEHICLE = 3 << NFB_WINDOW_LAYOUT, ///< Vehicle news item. (new engine available) - NF_COMPANY = 4 << NFB_WINDOW_LAYOUT, ///< Company news item. (Newspaper with face) }; DECLARE_ENUM_AS_BIT_SET(NewsFlag) @@ -146,6 +147,7 @@ struct NewsItem { TimerGameEconomy::Date economy_date; ///< Economy date of the news item, never shown but used to calculate age NewsType type; ///< Type of the news AdviceType advice_type; ///< The type of advice, to be able to remove specific advices later on. + NewsStyle style; /// Window style for the news. NewsFlag flags; ///< NewsFlags bits @see NewsFlag NewsReferenceType reftype1; ///< Type of ref1 @@ -157,7 +159,7 @@ struct NewsItem { std::vector params; ///< Parameters for string resolving. - NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, std::unique_ptr &&data, AdviceType advice_type); + NewsItem(StringID string_id, NewsType type, NewsStyle style, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, std::unique_ptr &&data, AdviceType advice_type); }; /** diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 487cd119a5..d1f7b1b031 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -534,7 +534,7 @@ static void ShowRejectOrAcceptNews(const Station *st, CargoTypes cargoes, bool r 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, NT_ACCEPTANCE, NewsStyle::Small, NF_INCOLOUR, NR_STATION, st->index); } /** diff --git a/src/subsidy.cpp b/src/subsidy.cpp index 43a97f65ac..e04ddee70c 100644 --- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -56,7 +56,7 @@ void Subsidy::AwardTo(CompanyID company) SetDParamStr(0, company_name); AddNewsItem( STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF + _settings_game.difficulty.subsidy_multiplier, - NT_SUBSIDIES, NF_NORMAL, + NT_SUBSIDIES, NewsStyle::Normal, {}, reftype.first, this->src, reftype.second, this->dst ); AI::BroadcastNewEvent(new ScriptEventSubsidyAwarded(this->index)); @@ -222,7 +222,7 @@ void CreateSubsidy(CargoType cargo_type, SourceType src_type, SourceID src, Sour s->awarded = INVALID_COMPANY; std::pair reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsOffered); - AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, NT_SUBSIDIES, NF_NORMAL, reftype.first, s->src, reftype.second, s->dst); + AddNewsItem(STR_NEWS_SERVICE_SUBSIDY_OFFERED, NT_SUBSIDIES, NewsStyle::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)); @@ -488,13 +488,13 @@ static IntervalTimer _economy_subsidies_monthly({TimerGameEcon if (--s->remaining == 0) { if (!s->IsAwarded()) { std::pair reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsWithdrawn); - AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NT_SUBSIDIES, NF_NORMAL, reftype.first, s->src, reftype.second, s->dst); + AddNewsItem(STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED, NT_SUBSIDIES, NewsStyle::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 reftype = SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::NewsWithdrawn); - AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, NT_SUBSIDIES, NF_NORMAL, reftype.first, s->src, reftype.second, s->dst); + AddNewsItem(STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE, NT_SUBSIDIES, NewsStyle::Normal, {}, reftype.first, s->src, reftype.second, s->dst); } AI::BroadcastNewEvent(new ScriptEventSubsidyExpired(s->index)); Game::NewEvent(new ScriptEventSubsidyExpired(s->index)); diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index b02ae53c04..eba5392022 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -3389,7 +3389,7 @@ static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlag flags) AddNewsItem( TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_ROAD_REBUILDING_MINUTES : STR_NEWS_ROAD_REBUILDING_MONTHS, - NT_GENERAL, NF_NORMAL, NR_TOWN, t->index, NR_NONE, UINT32_MAX); + NT_GENERAL, NewsStyle::Normal, {}, NR_TOWN, t->index, NR_NONE, UINT32_MAX); AI::BroadcastNewEvent(new ScriptEventRoadReconstruction((ScriptCompany::CompanyID)(Owner)_current_company, t->index)); Game::NewEvent(new ScriptEventRoadReconstruction((ScriptCompany::CompanyID)(Owner)_current_company, t->index)); } @@ -3544,7 +3544,7 @@ static CommandCost TownActionBuyRights(Town *t, DoCommandFlag flags) 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, std::move(cni)); + AddNewsItem(STR_MESSAGE_NEWS_FORMAT, NT_GENERAL, NewsStyle::Company, {}, NR_TOWN, t->index, NR_NONE, UINT32_MAX, std::move(cni)); AI::BroadcastNewEvent(new ScriptEventExclusiveTransportRights((ScriptCompany::CompanyID)(Owner)_current_company, t->index)); Game::NewEvent(new ScriptEventExclusiveTransportRights((ScriptCompany::CompanyID)(Owner)_current_company, t->index)); }