diff --git a/src/lang/english.txt b/src/lang/english.txt index e29372c651..3f4c426c0e 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -287,6 +287,7 @@ STR_SORT_BY_TRANSPORTED :Transported STR_SORT_BY_NUMBER :Number STR_SORT_BY_PROFIT_LAST_YEAR :Profit last year STR_SORT_BY_PROFIT_THIS_YEAR :Profit this year +STR_SORT_BY_PROFIT_LIFETIME :Lifetime profit STR_SORT_BY_AGE :Age STR_SORT_BY_RELIABILITY :Reliability STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Total capacity per cargo type @@ -4109,9 +4110,10 @@ STR_VEHICLE_INFO_MAX_SPEED_RANGE :{BLACK}Max. spe STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Weight: {LTBLUE}{WEIGHT_SHORT} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Weight: {LTBLUE}{WEIGHT_SHORT} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE} -STR_VEHICLE_INFO_TRAIN_LENGTH :{BLACK}Train length {LTBLUE}{DECIMAL} tile{P "" s} {STRING3} +STR_VEHICLE_INFO_TRAIN_LENGTH :{BLACK}Train length {LTBLUE}{DECIMAL} tile{P "" s} {STRING4} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY_LONG} (last year: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_LIFETIME :{STRING2} (lifetime: {CURRENCY_LONG}) STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA} STR_VEHICLE_INFO_GROUP :{BLACK}Group: {LTBLUE}{GROUP} diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 02686bc1ae..57918691af 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3197,6 +3197,12 @@ bool AfterLoadGame() } } + /* Set lifetime vehicle profit to 0 if lifetime profit feature is missing */ + if (SlXvIsFeatureMissing(XSLFI_VEH_LIFETIME_PROFIT)) { + Vehicle *v; + FOR_ALL_VEHICLES(v) v->profit_lifetime = 0; + } + /* Road stops is 'only' updating some caches */ AfterLoadRoadStops(); AfterLoadLabelMaps(); diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 7d670acdb1..4e28088d65 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -66,6 +66,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_MORE_COND_ORDERS, XSCF_NULL, 1, 1, "more_cond_orders", NULL, NULL, NULL }, { XSLFI_EXTRA_LARGE_MAP, XSCF_NULL, 0, 1, "extra_large_map", NULL, NULL, NULL }, { XSLFI_REVERSE_AT_WAYPOINT, XSCF_NULL, 1, 1, "reverse_at_waypoint", NULL, NULL, NULL }, + { XSLFI_VEH_LIFETIME_PROFIT, XSCF_NULL, 1, 1, "veh_lifetime_profit", NULL, NULL, NULL }, { XSLFI_NULL, XSCF_NULL, 0, 0, NULL, NULL, NULL, NULL },// This is the end marker }; diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index eef153a3d6..9dd206f471 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -38,6 +38,9 @@ enum SlXvFeatureIndex { XSLFI_VARIABLE_DAY_LENGTH, ///< Variable day length patch XSLFI_ORDER_OCCUPANCY, ///< Running average of order occupancy XSLFI_MORE_COND_ORDERS, ///< More conditional orders patch + XSLFI_EXTRA_LARGE_MAP, ///< Extra large map + XSLFI_REVERSE_AT_WAYPOINT, ///< Reverse at waypoint orders + XSLFI_VEH_LIFETIME_PROFIT, ///< Vehicle lifetime profit patch XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk @@ -45,8 +48,6 @@ enum SlXvFeatureIndex { XSLFI_TRAFFIC_LIGHTS, ///< This save game uses road traffic lights XSLFI_RAIL_AGEING, ///< This save game uses the rail aging patch XSLFI_SPRINGPP, ///< This is a SpringPP game, use this for loading some settings - XSLFI_EXTRA_LARGE_MAP, ///< Extra large map - XSLFI_REVERSE_AT_WAYPOINT, ///< Reverse at waypoint orders XSLFI_SIZE, ///< Total count of features, including null feature }; diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 7b073f4e37..35f6418392 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -706,6 +706,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) SLE_CONDVAR(Vehicle, profit_this_year, SLE_INT64, 65, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, profit_last_year, SLE_FILE_I32 | SLE_VAR_I64, 0, 64), SLE_CONDVAR(Vehicle, profit_last_year, SLE_INT64, 65, SL_MAX_VERSION), + SLE_CONDVAR_X(Vehicle,profit_lifetime, SLE_INT64, 0, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VEH_LIFETIME_PROFIT)), SLEG_CONDVAR( _cargo_feeder_share, SLE_FILE_I32 | SLE_VAR_I64, 51, 64), SLEG_CONDVAR( _cargo_feeder_share, SLE_INT64, 65, 67), SLEG_CONDVAR( _cargo_loaded_at_xy, SLE_UINT32, 51, 67), diff --git a/src/vehicle.cpp b/src/vehicle.cpp index b44db4d528..1df1ad4c90 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -3124,6 +3124,7 @@ void VehiclesYearlyLoop() } v->profit_last_year = v->profit_this_year; + v->profit_lifetime += v->profit_this_year; v->profit_this_year = 0; SetWindowDirty(WC_VEHICLE_DETAILS, v->index); } diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 1d4a6fa24f..3e80993731 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -190,6 +190,7 @@ public: Money profit_this_year; ///< Profit this year << 8, low 8 bits are fract Money profit_last_year; ///< Profit last year << 8, low 8 bits are fract + Money profit_lifetime; ///< Profit lifetime << 8, low 8 bits are fract Money value; ///< Value of the vehicle Money repair_cost; ///< Cost to repair one breakdown @@ -536,6 +537,12 @@ public: */ Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); } + /** + * Gets the lifetime profit of vehicle. It can be sent into SetDParam for string processing. + * @return the vehicle's lifetime profit + */ + Money GetDisplayProfitLifetime() const { return ((this->profit_lifetime + this->profit_this_year) >> 8); } + void SetNext(Vehicle *next); /** diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 2f53dd725c..511609db7b 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -50,6 +50,7 @@ static GUIVehicleList::SortFunction VehicleNumberSorter; static GUIVehicleList::SortFunction VehicleNameSorter; static GUIVehicleList::SortFunction VehicleAgeSorter; static GUIVehicleList::SortFunction VehicleProfitThisYearSorter; +static GUIVehicleList::SortFunction VehicleProfitLifetimeSorter; static GUIVehicleList::SortFunction VehicleProfitLastYearSorter; static GUIVehicleList::SortFunction VehicleCargoSorter; static GUIVehicleList::SortFunction VehicleReliabilitySorter; @@ -66,6 +67,7 @@ GUIVehicleList::SortFunction * const BaseVehicleListWindow::vehicle_sorter_funcs &VehicleAgeSorter, &VehicleProfitThisYearSorter, &VehicleProfitLastYearSorter, + &VehicleProfitLifetimeSorter, &VehicleCargoSorter, &VehicleReliabilitySorter, &VehicleMaxSpeedSorter, @@ -82,6 +84,7 @@ const StringID BaseVehicleListWindow::vehicle_sorter_names[] = { STR_SORT_BY_AGE, STR_SORT_BY_PROFIT_THIS_YEAR, STR_SORT_BY_PROFIT_LAST_YEAR, + STR_SORT_BY_PROFIT_LIFETIME, STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE, STR_SORT_BY_RELIABILITY, STR_SORT_BY_MAX_SPEED, @@ -1185,6 +1188,13 @@ static int CDECL VehicleProfitLastYearSorter(const Vehicle * const *a, const Veh return (r != 0) ? r : VehicleNumberSorter(a, b); } +/** Sort vehicles by lifetime profit */ +static int CDECL VehicleProfitLifetimeSorter(const Vehicle * const *a, const Vehicle * const *b) +{ + int r = ClampToI32((*a)->GetDisplayProfitLifetime() - (*b)->GetDisplayProfitLifetime()); + return (r != 0) ? r : VehicleNumberSorter(a, b); +} + /** Sort vehicles by their cargo */ static int CDECL VehicleCargoSorter(const Vehicle * const *a, const Vehicle * const *b) { @@ -2033,10 +2043,14 @@ struct VehicleDetailsWindow : Window { if (v->type == VEH_TRAIN && _settings_client.gui.show_train_length_in_details) { SetDParamMaxValue(0, _settings_game.vehicle.max_train_length * 10); SetDParam(1, 1); - SetDParam(2, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR); + SetDParam(2, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_LIFETIME); + SetDParam(3, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR); + for (uint i = 4; i < 7; i++) SetDParamMaxValue(i, 1 << 24); dim = maxdim(dim, GetStringBoundingBox(STR_VEHICLE_INFO_TRAIN_LENGTH)); } else { - dim = maxdim(dim, GetStringBoundingBox(STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR)); + SetDParam(0, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR); + for (uint i = 1; i < 4; i++) SetDParamMaxValue(i, 1 << 24); + dim = maxdim(dim, GetStringBoundingBox(STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_LIFETIME)); } if (this->vehicle_group_line_shown) { SetDParam(0, v->group_id); @@ -2181,14 +2195,18 @@ struct VehicleDetailsWindow : Window { const GroundVehicleCache *gcache = v->GetGroundVehicleCache(); SetDParam(0, CeilDiv(gcache->cached_total_length * 10, TILE_SIZE)); SetDParam(1, 1); - SetDParam(2, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR); - SetDParam(3, v->GetDisplayProfitThisYear()); - SetDParam(4, v->GetDisplayProfitLastYear()); + SetDParam(2, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_LIFETIME); + SetDParam(3, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR); + SetDParam(4, v->GetDisplayProfitThisYear()); + SetDParam(5, v->GetDisplayProfitLastYear()); + SetDParam(6, v->GetDisplayProfitLifetime()); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_TRAIN_LENGTH); } else { - SetDParam(0, v->GetDisplayProfitThisYear()); - SetDParam(1, v->GetDisplayProfitLastYear()); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR); + SetDParam(0, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR); + SetDParam(1, v->GetDisplayProfitThisYear()); + SetDParam(2, v->GetDisplayProfitLastYear()); + SetDParam(3, v->GetDisplayProfitLifetime()); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_LIFETIME); } y += FONT_HEIGHT_NORMAL;