From 32b0fb9f6ebe5f607550d4d35ce112b2e1c7442e Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Sat, 9 Mar 2024 09:38:52 -0500 Subject: [PATCH] Fix #12010: Use economy timer for vehicle stats minimum age, not calendar (#12142) --- src/aircraft_cmd.cpp | 1 + src/economy.cpp | 2 +- src/group_cmd.cpp | 4 ++-- src/roadveh_cmd.cpp | 1 + src/saveload/saveload.h | 3 ++- src/saveload/vehicle_sl.cpp | 8 ++++++++ src/ship_cmd.cpp | 2 ++ src/train_cmd.cpp | 2 ++ src/vehicle.cpp | 19 ++++++++++++++----- src/vehicle_base.h | 3 ++- src/vehicle_func.h | 4 +++- src/vehicle_gui.cpp | 2 +- src/vehicle_gui_base.h | 6 +++--- 13 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 78260edb9b..14a7eceeda 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -456,6 +456,7 @@ void Aircraft::OnNewCalendarDay() void Aircraft::OnNewEconomyDay() { if (!this->IsNormalAircraft()) return; + EconomyAgeVehicle(this); if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this); diff --git a/src/economy.cpp b/src/economy.cpp index cd739cde88..27d43e1d63 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -215,7 +215,7 @@ int UpdateCompanyRatingAndValue(Company *c, bool update) if (v->owner != owner) continue; if (IsCompanyBuildableVehicleType(v->type) && v->IsPrimaryVehicle()) { if (v->profit_last_year > 0) num++; // For the vehicle score only count profitable vehicles - if (v->age > 730) { + if (v->economy_age > VEHICLE_PROFIT_MIN_AGE) { /* Find the vehicle with the lowest amount of profit */ if (min_profit_first || min_profit > v->profit_last_year) { min_profit = v->profit_last_year; diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index bc379e3212..e7a49dd570 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -142,7 +142,7 @@ uint16_t GroupStatistics::GetNumEngines(EngineID engine) const stats.num_vehicle += delta; stats.profit_last_year += v->GetDisplayProfitLastYear() * delta; - if (v->age > VEHICLE_PROFIT_MIN_AGE) { + if (v->economy_age > VEHICLE_PROFIT_MIN_AGE) { stats_all.num_vehicle_min_age += delta; stats_all.profit_last_year_min_age += v->GetDisplayProfitLastYear() * delta; stats.num_vehicle_min_age += delta; @@ -209,7 +209,7 @@ uint16_t GroupStatistics::GetNumEngines(EngineID engine) const for (const Vehicle *v : Vehicle::Iterate()) { if (v->IsPrimaryVehicle()) { GroupStatistics::AddProfitLastYear(v); - if (v->age > VEHICLE_PROFIT_MIN_AGE) GroupStatistics::VehicleReachedMinAge(v); + if (v->economy_age > VEHICLE_PROFIT_MIN_AGE) GroupStatistics::VehicleReachedMinAge(v); } } } diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 6aace6b3e9..6674425845 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -1728,6 +1728,7 @@ void RoadVehicle::OnNewCalendarDay() void RoadVehicle::OnNewEconomyDay() { if (!this->IsFrontEngine()) return; + EconomyAgeVehicle(this); if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this); if (this->blocked_ctr == 0) CheckVehicleBreakdown(this); diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 9b072bd6a5..d270d10827 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -376,7 +376,8 @@ enum SaveLoadVersion : uint16_t { SLV_MAX_LOAN_FOR_COMPANY, ///< 330 PR#11224 Separate max loan for each company. SLV_DEPOT_UNBUNCHING, ///< 331 PR#11945 Allow unbunching shared order vehicles at a depot. SLV_AI_LOCAL_CONFIG, ///< 332 PR#12003 Config of running AI is stored inside Company. - SLV_SCRIPT_RANDOMIZER, ///< 333 PR#12063 v14.0 Save script randomizers. + SLV_SCRIPT_RANDOMIZER, ///< 333 PR#12063 v14.0-RC1 Save script randomizers. + SLV_VEHICLE_ECONOMY_AGE, ///< 334 PR#12141 v14.0 Add vehicle age in economy year, for profit stats minimum age SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 38b602c50c..302af3c517 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -398,6 +398,13 @@ void AfterLoadVehicles(bool part_of_load) v->timetable_start = GetStartTickFromDate(v->timetable_start); } } + + if (IsSavegameVersionBefore(SLV_VEHICLE_ECONOMY_AGE)) { + /* Set vehicle economy age based on calendar age. */ + for (Vehicle *v : Vehicle::Iterate()) { + v->economy_age = v->age.base(); + } + } } CheckValidVehicles(); @@ -718,6 +725,7 @@ public: SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), SLE_CONDVAR(Vehicle, age, SLE_INT32, SLV_31, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, economy_age, SLE_INT32, SLV_VEHICLE_ECONOMY_AGE, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, max_age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), SLE_CONDVAR(Vehicle, max_age, SLE_INT32, SLV_31, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, date_of_last_service, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index b9b6b8a4f0..b19520d954 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -266,6 +266,8 @@ void Ship::OnNewCalendarDay() /** Economy day handler. */ void Ship::OnNewEconomyDay() { + EconomyAgeVehicle(this); + if ((++this->day_counter & 7) == 0) { DecreaseVehicleValue(this); } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 1189607161..7de169d526 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -4186,6 +4186,8 @@ void Train::OnNewCalendarDay() /** Economy day handler. */ void Train::OnNewEconomyDay() { + EconomyAgeVehicle(this); + if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this); if (this->IsFrontEngine()) { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 2a03d75301..bdf76efa6c 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1418,16 +1418,25 @@ bool Vehicle::HandleBreakdown() } } +/** + * Update economy age of a vehicle. + * @param v Vehicle to update. + */ +void EconomyAgeVehicle(Vehicle *v) +{ + if (v->economy_age < EconomyTime::MAX_DATE) { + v->economy_age++; + if (v->IsPrimaryVehicle() && v->economy_age == VEHICLE_PROFIT_MIN_AGE + 1) GroupStatistics::VehicleReachedMinAge(v); + } +} + /** * Update age of a vehicle. * @param v Vehicle to update. */ void AgeVehicle(Vehicle *v) { - if (v->age < CalendarTime::MAX_DATE) { - v->age++; - if (v->IsPrimaryVehicle() && v->age == VEHICLE_PROFIT_MIN_AGE + 1) GroupStatistics::VehicleReachedMinAge(v); - } + if (v->age < CalendarTime::MAX_DATE) v->age++; if (!v->IsPrimaryVehicle() && (v->type != VEH_TRAIN || !Train::From(v)->IsEngine())) return; @@ -2990,7 +2999,7 @@ static IntervalTimer _economy_vehicles_yearly({TimerGameEconom if (v->IsPrimaryVehicle()) { /* show warning if vehicle is not generating enough income last 2 years (corresponds to a red icon in the vehicle list) */ Money profit = v->GetDisplayProfitThisYear(); - if (v->age >= 730 && profit < 0) { + if (v->economy_age >= VEHICLE_PROFIT_MIN_AGE && profit < 0) { if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company) { SetDParam(0, v->index); SetDParam(1, profit); diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 947e6f86a0..8ffd0701bd 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -285,7 +285,8 @@ public: /* Related to age and service time */ TimerGameCalendar::Year build_year; ///< Year the vehicle has been built. - TimerGameCalendar::Date age; ///< Age in days + TimerGameCalendar::Date age; ///< Age in calendar days. + TimerGameEconomy::Date economy_age; ///< Age in economy days. TimerGameCalendar::Date max_age; ///< Maximum age TimerGameEconomy::Date date_of_last_service; ///< Last economy date the vehicle had a service at a depot. TimerGameCalendar::Date date_of_last_service_newgrf; ///< Last calendar date the vehicle had a service at a depot, unchanged by the date cheat to protect against unsafe NewGRF behavior. diff --git a/src/vehicle_func.h b/src/vehicle_func.h index e426391b7d..add2d48e16 100644 --- a/src/vehicle_func.h +++ b/src/vehicle_func.h @@ -12,6 +12,7 @@ #include "gfx_type.h" #include "direction_type.h" +#include "timer/timer_game_economy.h" #include "command_type.h" #include "vehicle_type.h" #include "engine_type.h" @@ -24,7 +25,7 @@ #define IS_CUSTOM_FIRSTHEAD_SPRITE(x) (x == 0xFD) #define IS_CUSTOM_SECONDHEAD_SPRITE(x) (x == 0xFE) -static const int VEHICLE_PROFIT_MIN_AGE = CalendarTime::DAYS_IN_YEAR * 2; ///< Only vehicles older than this have a meaningful profit. +static const TimerGameEconomy::Date VEHICLE_PROFIT_MIN_AGE = CalendarTime::DAYS_IN_YEAR * 2; ///< Only vehicles older than this have a meaningful profit. static const Money VEHICLE_PROFIT_THRESHOLD = 10000; ///< Threshold for a vehicle to be considered making good profit. /** @@ -61,6 +62,7 @@ CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle void DecreaseVehicleValue(Vehicle *v); void CheckVehicleBreakdown(Vehicle *v); +void EconomyAgeVehicle(Vehicle *v); void AgeVehicle(Vehicle *v); void RunVehicleCalendarDayProc(); void VehicleEnteredDepotThisTick(Vehicle *v); diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 7f8a28fa35..7c12256061 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -486,7 +486,7 @@ void DepotSortList(VehicleList *list) } /** draw the vehicle profit button in the vehicle list window. */ -static void DrawVehicleProfitButton(TimerGameCalendar::Date age, Money display_profit_last_year, uint num_vehicles, int x, int y) +static void DrawVehicleProfitButton(TimerGameEconomy::Date age, Money display_profit_last_year, uint num_vehicles, int x, int y) { SpriteID spr; diff --git a/src/vehicle_gui_base.h b/src/vehicle_gui_base.h index 6eac9aa0d3..9815d01529 100644 --- a/src/vehicle_gui_base.h +++ b/src/vehicle_gui_base.h @@ -53,12 +53,12 @@ struct GUIVehicleGroup { }); } - TimerGameCalendar::Date GetOldestVehicleAge() const + TimerGameEconomy::Date GetOldestVehicleAge() const { const Vehicle *oldest = *std::max_element(this->vehicles_begin, this->vehicles_end, [](const Vehicle *v_a, const Vehicle *v_b) { - return v_a->age < v_b->age; + return v_a->economy_age < v_b->economy_age; }); - return oldest->age; + return oldest->economy_age; } };