From 08d84b2f4a342d03df4846ea1e84c504011e6d15 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Tue, 7 Jan 2025 21:34:19 +0100 Subject: [PATCH] Codechange: use AdviceType over StringID to remove vehicle advice news --- src/aircraft_cmd.cpp | 4 ++-- src/autoreplace_cmd.cpp | 2 +- src/news_func.h | 8 ++++---- src/news_gui.cpp | 20 +++++++++++--------- src/news_type.h | 20 ++++++++++++++++++-- src/order_cmd.cpp | 8 ++------ src/train_cmd.cpp | 2 +- src/vehicle.cpp | 16 ++++++++-------- src/vehicle_cmd.cpp | 2 +- 9 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index a3e9a3c776..bb6d344fec 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -2064,7 +2064,7 @@ static void AircraftHandleDestTooFar(Aircraft *v, bool too_far) if (v->owner == _local_company) { /* Post a news message. */ SetDParam(0, v->index); - AddVehicleAdviceNewsItem(STR_NEWS_AIRCRAFT_DEST_TOO_FAR, v->index); + AddVehicleAdviceNewsItem(AdviceType::AircraftDestinationTooFar, STR_NEWS_AIRCRAFT_DEST_TOO_FAR, v->index); } } return; @@ -2074,7 +2074,7 @@ static void AircraftHandleDestTooFar(Aircraft *v, bool too_far) /* Not too far anymore, clear flag and message. */ ClrBit(v->flags, VAF_DEST_TOO_FAR); SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); - DeleteVehicleNews(v->index, STR_NEWS_AIRCRAFT_DEST_TOO_FAR); + DeleteVehicleNews(v->index, AdviceType::AircraftDestinationTooFar); } } diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 757f18d371..31a131d487 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -348,7 +348,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic SetDParam(2, CargoSpec::Get(old_veh->cargo_type)->name); } - AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_AUTORENEW_FAILED, old_veh_id); + AddVehicleAdviceNewsItem(AdviceType::AutorenewFailed, STR_NEWS_VEHICLE_AUTORENEW_FAILED, old_veh_id); return CommandCost(); } diff --git a/src/news_func.h b/src/news_func.h index 8e4ca6a591..c2ab08f876 100644 --- a/src/news_func.h +++ b/src/news_func.h @@ -15,7 +15,7 @@ #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); +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); inline void AddCompanyNewsItem(StringID string, std::unique_ptr cni) { @@ -37,9 +37,9 @@ 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(AdviceType advice_type, StringID string, VehicleID vehicle) { - AddNewsItem(string, NT_ADVICE, NF_INCOLOUR | NF_SMALL | NF_VEHICLE_PARAM0, NR_VEHICLE, vehicle); + AddNewsItem(string, NT_ADVICE, NF_INCOLOUR | NF_SMALL | NF_VEHICLE_PARAM0, NR_VEHICLE, vehicle, NR_NONE, {}, nullptr, advice_type); } inline void AddTileNewsItem(StringID string, NewsType type, TileIndex tile, std::unique_ptr &&data = nullptr, StationID station = INVALID_STATION) @@ -58,7 +58,7 @@ void InitNewsItemStructs(); const NewsItem *GetStatusbarNews(); void DeleteInvalidEngineNews(); -void DeleteVehicleNews(VehicleID vid, StringID news); +void DeleteVehicleNews(VehicleID vid, AdviceType advice_type = AdviceType::Invalid); void DeleteStationNews(StationID sid); void DeleteIndustryNews(IndustryID iid); diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 54993fb1f9..1342d99d6d 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -870,11 +870,12 @@ static std::list::iterator DeleteNewsItem(std::list::iterato * @param reftype2 Type of ref2. * @param ref2 Reference 2 to some object: Used for scrolling after clicking on the news, and for deleting the news when the object is deleted. * @param data Pointer to data that must be released once the news message is cleared. + * @param advice_type Sub-type in case the news type is #NT_ADVICE. * * @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) : - string_id(string_id), date(TimerGameCalendar::date), economy_date(TimerGameEconomy::date), type(type), flags(flags), reftype1(reftype1), reftype2(reftype2), ref1(ref1), ref2(ref2), data(std::move(data)) +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)) { /* show this news message in colour? */ if (TimerGameCalendar::year >= _settings_client.gui.coloured_news_year) this->flags |= NF_INCOLOUR; @@ -891,15 +892,16 @@ NewsItem::NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsRefere * @param reftype2 Type of ref2 * @param ref2 Reference 2 to some object: Used for scrolling after clicking on the news, and for deleting the news when the object is deleted. * @param data Pointer to data that must be released once the news message is cleared. + * @param advice_type Sub-type in case the news type is #NT_ADVICE. * * @see NewsSubtype */ -void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, std::unique_ptr &&data) +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) { if (_game_mode == GM_MENU) return; /* Create new news item node */ - _news.emplace_front(string, type, flags, reftype1, ref1, reftype2, ref2, std::move(data)); + _news.emplace_front(string, type, 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) { @@ -990,15 +992,15 @@ void DeleteNews(Tpredicate predicate) } /** - * Delete a news item type about a vehicle. - * When the news item type is INVALID_STRING_ID all news about the vehicle gets deleted. + * Delete news with a given advice type about a vehicle. + * When the advice_type is #AdviceType::Invalid all news about the vehicle gets deleted. * @param vid The vehicle to remove the news for. - * @param news The news type to remove. + * @param advice_type The advice type to remove for. */ -void DeleteVehicleNews(VehicleID vid, StringID news) +void DeleteVehicleNews(VehicleID vid, AdviceType advice_type) { DeleteNews([&](const auto &ni) { - return ((ni.reftype1 == NR_VEHICLE && ni.ref1 == vid) || (ni.reftype2 == NR_VEHICLE && ni.ref2 == vid)) && (news == INVALID_STRING_ID || ni.string_id == news); + return ((ni.reftype1 == NR_VEHICLE && ni.ref1 == vid) || (ni.reftype2 == NR_VEHICLE && ni.ref2 == vid)) && (advice_type == AdviceType::Invalid || ni.advice_type == advice_type); }); } diff --git a/src/news_type.h b/src/news_type.h index ee100f06d9..7f642a5425 100644 --- a/src/news_type.h +++ b/src/news_type.h @@ -40,6 +40,21 @@ enum NewsType : uint8_t { NT_END, ///< end-of-array marker }; +/** Sub type of the #NT_ADVICE to be able to remove specific news items. */ +enum class AdviceType : uint8_t { + AircraftDestinationTooFar, ///< Next (order) destination is too far for the aircraft type. + AutorenewFailed, ///< Autorenew or autoreplace failed. + Order, ///< Something wrong with the order, e.g. invalid or duplicate entries, too few entries + RefitFailed, ///< The refit order failed to execute. + TrainStuck, ///< The train got stuck and needs to be unstuck manually. + VehicleLost, ///< The vehicle has become lost. + VehicleOld, ///< The vehicle is starting to get old. + VehicleUnprofitable, ///< The vehicle is costing you money. + VehicleWaiting, ///< The vehicle is waiting in the depot. + + Invalid +}; + /** * References to objects in news. * @@ -63,7 +78,7 @@ enum NewsReferenceType : uint8_t { * Various OR-able news-item flags. * @note #NF_INCOLOUR is set automatically if needed. */ -enum NewsFlag { +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. @@ -130,6 +145,7 @@ struct NewsItem { TimerGameCalendar::Date date; ///< Calendar date to show for the news 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. NewsFlag flags; ///< NewsFlags bits @see NewsFlag NewsReferenceType reftype1; ///< Type of ref1 @@ -141,7 +157,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); + 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); }; /** diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 514cc3a895..2bcba9ca4a 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -626,11 +626,7 @@ static inline bool OrderGoesToStation(const Vehicle *v, const Order *o) */ static void DeleteOrderWarnings(const Vehicle *v) { - DeleteVehicleNews(v->index, STR_NEWS_VEHICLE_HAS_TOO_FEW_ORDERS); - DeleteVehicleNews(v->index, STR_NEWS_VEHICLE_HAS_VOID_ORDER); - DeleteVehicleNews(v->index, STR_NEWS_VEHICLE_HAS_DUPLICATE_ENTRY); - DeleteVehicleNews(v->index, STR_NEWS_VEHICLE_HAS_INVALID_ENTRY); - DeleteVehicleNews(v->index, STR_NEWS_PLANE_USES_TOO_SHORT_RUNWAY); + DeleteVehicleNews(v->index, AdviceType::Order); } /** @@ -1772,7 +1768,7 @@ void CheckOrders(const Vehicle *v) if (message == INVALID_STRING_ID) return; SetDParam(0, v->index); - AddVehicleAdviceNewsItem(message, v->index); + AddVehicleAdviceNewsItem(AdviceType::Order, message, v->index); } } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index c9fd74587d..26f62869ee 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -4009,7 +4009,7 @@ static bool TrainLocoHandler(Train *v, bool mode) /* 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(AdviceType::TrainStuck, STR_NEWS_TRAIN_IS_STUCK, v->index); } v->wait_counter = 0; } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 10443db5bc..a9983a5f4d 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -799,7 +799,7 @@ void Vehicle::HandlePathfindingResult(bool path_found) SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP); InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type)); /* Delete the news item. */ - DeleteVehicleNews(this->index, STR_NEWS_VEHICLE_IS_LOST); + DeleteVehicleNews(this->index, AdviceType::VehicleLost); return; } @@ -818,7 +818,7 @@ void Vehicle::HandlePathfindingResult(bool path_found) 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(AdviceType::VehicleLost, STR_NEWS_VEHICLE_IS_LOST, this->index); } } @@ -909,7 +909,7 @@ Vehicle::~Vehicle() UpdateVehicleTileHash(this, true); UpdateVehicleViewportHash(this, INVALID_COORD, 0, this->sprite_cache.old_coord.left, this->sprite_cache.old_coord.top); if (this->type != VEH_EFFECT) { - DeleteVehicleNews(this->index, INVALID_STRING_ID); + DeleteVehicleNews(this->index); DeleteNewGRFInspectWindow(GetGrfSpecFeature(this->type), this->index); } } @@ -1111,7 +1111,7 @@ void CallVehicleTicks() SetDParam(0, v->index); SetDParam(1, error_message); - AddVehicleAdviceNewsItem(message, v->index); + AddVehicleAdviceNewsItem(AdviceType::AutorenewFailed, message, v->index); } cur_company.Restore(); @@ -1478,7 +1478,7 @@ void AgeVehicle(Vehicle *v) } SetDParam(0, v->index); - AddVehicleAdviceNewsItem(str, v->index); + AddVehicleAdviceNewsItem(AdviceType::VehicleOld, str, v->index); } /** @@ -1634,7 +1634,7 @@ void VehicleEnterDepot(Vehicle *v) 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(AdviceType::RefitFailed, STR_NEWS_ORDER_REFIT_FAILED, v->index); } } else if (cost.GetCost() != 0) { v->profit_this_year -= cost.GetCost() << 8; @@ -1664,7 +1664,7 @@ void VehicleEnterDepot(Vehicle *v) /* Announce that the vehicle is waiting to players and AIs. */ if (v->owner == _local_company) { SetDParam(0, v->index); - AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_WAITING + v->type, v->index); + AddVehicleAdviceNewsItem(AdviceType::VehicleWaiting, STR_NEWS_TRAIN_IS_WAITING + v->type, v->index); } AI::NewEvent(v->owner, new ScriptEventVehicleWaitingInDepot(v->index)); } @@ -3027,7 +3027,7 @@ static IntervalTimer _economy_vehicles_yearly({TimerGameEconom if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company) { SetDParam(0, v->index); SetDParam(1, profit); - AddVehicleAdviceNewsItem( + AddVehicleAdviceNewsItem(AdviceType::VehicleUnprofitable, TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_VEHICLE_UNPROFITABLE_PERIOD : STR_NEWS_VEHICLE_UNPROFITABLE_YEAR, v->index); } diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 9e0d1b3420..d9905747a1 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -629,7 +629,7 @@ CommandCost CmdStartStopVehicle(DoCommandFlag flags, VehicleID veh_id, bool eval } if (flags & DC_EXEC) { - if (v->IsStoppedInDepot() && (flags & DC_AUTOREPLACE) == 0) DeleteVehicleNews(veh_id, STR_NEWS_TRAIN_IS_WAITING + v->type); + if (v->IsStoppedInDepot() && (flags & DC_AUTOREPLACE) == 0) DeleteVehicleNews(veh_id, AdviceType::VehicleWaiting); v->vehstatus ^= VS_STOPPED; if (v->type != VEH_TRAIN) v->cur_speed = 0; // trains can stop 'slowly'