1
0
Fork 0

Codechange: use AdviceType over StringID to remove vehicle advice news

pull/13292/head
Rubidium 2025-01-07 21:34:19 +01:00 committed by rubidium42
parent 0437701ebe
commit 08d84b2f4a
9 changed files with 48 additions and 34 deletions

View File

@ -2064,7 +2064,7 @@ static void AircraftHandleDestTooFar(Aircraft *v, bool too_far)
if (v->owner == _local_company) { if (v->owner == _local_company) {
/* Post a news message. */ /* Post a news message. */
SetDParam(0, v->index); 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; return;
@ -2074,7 +2074,7 @@ static void AircraftHandleDestTooFar(Aircraft *v, bool too_far)
/* Not too far anymore, clear flag and message. */ /* Not too far anymore, clear flag and message. */
ClrBit(v->flags, VAF_DEST_TOO_FAR); ClrBit(v->flags, VAF_DEST_TOO_FAR);
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
DeleteVehicleNews(v->index, STR_NEWS_AIRCRAFT_DEST_TOO_FAR); DeleteVehicleNews(v->index, AdviceType::AircraftDestinationTooFar);
} }
} }

View File

@ -348,7 +348,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
SetDParam(2, CargoSpec::Get(old_veh->cargo_type)->name); 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(); return CommandCost();
} }

View File

@ -15,7 +15,7 @@
#include "station_type.h" #include "station_type.h"
#include "industry_type.h" #include "industry_type.h"
void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1 = NR_NONE, uint32_t ref1 = UINT32_MAX, NewsReferenceType reftype2 = NR_NONE, uint32_t ref2 = UINT32_MAX, std::unique_ptr<NewsAllocatedData> &&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<NewsAllocatedData> &&data = nullptr, AdviceType advice_type = AdviceType::Invalid);
inline void AddCompanyNewsItem(StringID string, std::unique_ptr<CompanyNewsInformation> cni) inline void AddCompanyNewsItem(StringID string, std::unique_ptr<CompanyNewsInformation> cni)
{ {
@ -37,9 +37,9 @@ inline void AddVehicleNewsItem(StringID string, NewsType type, VehicleID vehicle
* *
* @warning DParam 0 must reference the vehicle! * @warning DParam 0 must reference the vehicle!
*/ */
inline void AddVehicleAdviceNewsItem(StringID string, VehicleID vehicle) inline void AddVehicleAdviceNewsItem(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<NewsAllocatedData> &&data = nullptr, StationID station = INVALID_STATION) inline void AddTileNewsItem(StringID string, NewsType type, TileIndex tile, std::unique_ptr<NewsAllocatedData> &&data = nullptr, StationID station = INVALID_STATION)
@ -58,7 +58,7 @@ void InitNewsItemStructs();
const NewsItem *GetStatusbarNews(); const NewsItem *GetStatusbarNews();
void DeleteInvalidEngineNews(); void DeleteInvalidEngineNews();
void DeleteVehicleNews(VehicleID vid, StringID news); void DeleteVehicleNews(VehicleID vid, AdviceType advice_type = AdviceType::Invalid);
void DeleteStationNews(StationID sid); void DeleteStationNews(StationID sid);
void DeleteIndustryNews(IndustryID iid); void DeleteIndustryNews(IndustryID iid);

View File

@ -870,11 +870,12 @@ static std::list<NewsItem>::iterator DeleteNewsItem(std::list<NewsItem>::iterato
* @param reftype2 Type of ref2. * @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 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 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 * @see NewsSubtype
*/ */
NewsItem::NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, std::unique_ptr<NewsAllocatedData> &&data) : NewsItem::NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, std::unique_ptr<NewsAllocatedData> &&data, AdviceType advice_type) :
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)) 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? */ /* show this news message in colour? */
if (TimerGameCalendar::year >= _settings_client.gui.coloured_news_year) this->flags |= NF_INCOLOUR; if (TimerGameCalendar::year >= _settings_client.gui.coloured_news_year) this->flags |= NF_INCOLOUR;
@ -891,15 +892,16 @@ NewsItem::NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsRefere
* @param reftype2 Type of ref2 * @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 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 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 * @see NewsSubtype
*/ */
void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, std::unique_ptr<NewsAllocatedData> &&data) void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, std::unique_ptr<NewsAllocatedData> &&data, AdviceType advice_type)
{ {
if (_game_mode == GM_MENU) return; if (_game_mode == GM_MENU) return;
/* Create new news item node */ /* 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 */ /* Keep the number of stored news items to a managable number */
if (std::size(_news) > MAX_NEWS_AMOUNT) { if (std::size(_news) > MAX_NEWS_AMOUNT) {
@ -990,15 +992,15 @@ void DeleteNews(Tpredicate predicate)
} }
/** /**
* Delete a news item type about a vehicle. * Delete news with a given advice type about a vehicle.
* When the news item type is INVALID_STRING_ID all news about the vehicle gets deleted. * When the advice_type is #AdviceType::Invalid all news about the vehicle gets deleted.
* @param vid The vehicle to remove the news for. * @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) { 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);
}); });
} }

View File

@ -40,6 +40,21 @@ enum NewsType : uint8_t {
NT_END, ///< end-of-array marker 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. * References to objects in news.
* *
@ -63,7 +78,7 @@ enum NewsReferenceType : uint8_t {
* Various OR-able news-item flags. * Various OR-able news-item flags.
* @note #NF_INCOLOUR is set automatically if needed. * @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_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_NO_TRANSPARENT = 1, ///< News item disables transparency in the viewport.
NFB_SHADE = 2, ///< News item uses shaded colours. NFB_SHADE = 2, ///< News item uses shaded colours.
@ -130,6 +145,7 @@ struct NewsItem {
TimerGameCalendar::Date date; ///< Calendar date to show for the news 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 TimerGameEconomy::Date economy_date; ///< Economy date of the news item, never shown but used to calculate age
NewsType type; ///< Type of the news 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 NewsFlag flags; ///< NewsFlags bits @see NewsFlag
NewsReferenceType reftype1; ///< Type of ref1 NewsReferenceType reftype1; ///< Type of ref1
@ -141,7 +157,7 @@ struct NewsItem {
std::vector<StringParameterData> params; ///< Parameters for string resolving. std::vector<StringParameterData> 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<NewsAllocatedData> &&data); NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, std::unique_ptr<NewsAllocatedData> &&data, AdviceType advice_type);
}; };
/** /**

View File

@ -626,11 +626,7 @@ static inline bool OrderGoesToStation(const Vehicle *v, const Order *o)
*/ */
static void DeleteOrderWarnings(const Vehicle *v) static void DeleteOrderWarnings(const Vehicle *v)
{ {
DeleteVehicleNews(v->index, STR_NEWS_VEHICLE_HAS_TOO_FEW_ORDERS); DeleteVehicleNews(v->index, AdviceType::Order);
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);
} }
/** /**
@ -1772,7 +1768,7 @@ void CheckOrders(const Vehicle *v)
if (message == INVALID_STRING_ID) return; if (message == INVALID_STRING_ID) return;
SetDParam(0, v->index); SetDParam(0, v->index);
AddVehicleAdviceNewsItem(message, v->index); AddVehicleAdviceNewsItem(AdviceType::Order, message, v->index);
} }
} }

View File

@ -4009,7 +4009,7 @@ static bool TrainLocoHandler(Train *v, bool mode)
/* Show message to player. */ /* Show message to player. */
if (_settings_client.gui.lost_vehicle_warn && v->owner == _local_company) { if (_settings_client.gui.lost_vehicle_warn && v->owner == _local_company) {
SetDParam(0, v->index); 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; v->wait_counter = 0;
} }

View File

@ -799,7 +799,7 @@ void Vehicle::HandlePathfindingResult(bool path_found)
SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP); SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type)); InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type));
/* Delete the news item. */ /* Delete the news item. */
DeleteVehicleNews(this->index, STR_NEWS_VEHICLE_IS_LOST); DeleteVehicleNews(this->index, AdviceType::VehicleLost);
return; return;
} }
@ -818,7 +818,7 @@ void Vehicle::HandlePathfindingResult(bool path_found)
AI::NewEvent(this->owner, new ScriptEventVehicleLost(this->index)); AI::NewEvent(this->owner, new ScriptEventVehicleLost(this->index));
if (_settings_client.gui.lost_vehicle_warn && this->owner == _local_company) { if (_settings_client.gui.lost_vehicle_warn && this->owner == _local_company) {
SetDParam(0, this->index); 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); UpdateVehicleTileHash(this, true);
UpdateVehicleViewportHash(this, INVALID_COORD, 0, this->sprite_cache.old_coord.left, this->sprite_cache.old_coord.top); UpdateVehicleViewportHash(this, INVALID_COORD, 0, this->sprite_cache.old_coord.left, this->sprite_cache.old_coord.top);
if (this->type != VEH_EFFECT) { if (this->type != VEH_EFFECT) {
DeleteVehicleNews(this->index, INVALID_STRING_ID); DeleteVehicleNews(this->index);
DeleteNewGRFInspectWindow(GetGrfSpecFeature(this->type), this->index); DeleteNewGRFInspectWindow(GetGrfSpecFeature(this->type), this->index);
} }
} }
@ -1111,7 +1111,7 @@ void CallVehicleTicks()
SetDParam(0, v->index); SetDParam(0, v->index);
SetDParam(1, error_message); SetDParam(1, error_message);
AddVehicleAdviceNewsItem(message, v->index); AddVehicleAdviceNewsItem(AdviceType::AutorenewFailed, message, v->index);
} }
cur_company.Restore(); cur_company.Restore();
@ -1478,7 +1478,7 @@ void AgeVehicle(Vehicle *v)
} }
SetDParam(0, v->index); 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) { if (v->owner == _local_company) {
/* Notify the user that we stopped the vehicle */ /* Notify the user that we stopped the vehicle */
SetDParam(0, v->index); 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) { } else if (cost.GetCost() != 0) {
v->profit_this_year -= cost.GetCost() << 8; 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. */ /* Announce that the vehicle is waiting to players and AIs. */
if (v->owner == _local_company) { if (v->owner == _local_company) {
SetDParam(0, v->index); 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)); AI::NewEvent(v->owner, new ScriptEventVehicleWaitingInDepot(v->index));
} }
@ -3027,7 +3027,7 @@ static IntervalTimer<TimerGameEconomy> _economy_vehicles_yearly({TimerGameEconom
if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company) { if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company) {
SetDParam(0, v->index); SetDParam(0, v->index);
SetDParam(1, profit); SetDParam(1, profit);
AddVehicleAdviceNewsItem( AddVehicleAdviceNewsItem(AdviceType::VehicleUnprofitable,
TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_VEHICLE_UNPROFITABLE_PERIOD : STR_NEWS_VEHICLE_UNPROFITABLE_YEAR, TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_VEHICLE_UNPROFITABLE_PERIOD : STR_NEWS_VEHICLE_UNPROFITABLE_YEAR,
v->index); v->index);
} }

View File

@ -629,7 +629,7 @@ CommandCost CmdStartStopVehicle(DoCommandFlag flags, VehicleID veh_id, bool eval
} }
if (flags & DC_EXEC) { 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; v->vehstatus ^= VS_STOPPED;
if (v->type != VEH_TRAIN) v->cur_speed = 0; // trains can stop 'slowly' if (v->type != VEH_TRAIN) v->cur_speed = 0; // trains can stop 'slowly'