Index: src/aircraft.h
===================================================================
--- src/aircraft.h (revision 27794)
+++ src/aircraft.h (working copy)
@@ -73,6 +73,7 @@
*/
struct Aircraft FINAL : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
uint16 crashed_counter; ///< Timer for handling crash animations.
+ uint64 flight_counter; ///< Timer for handling flight duration since last takeoff.
byte pos; ///< Next desired position of the aircraft.
byte previous_pos; ///< Previous desired position of the aircraft.
StationID targetairport; ///< Airport to go to next.
Index: src/aircraft_cmd.cpp
===================================================================
--- src/aircraft_cmd.cpp (revision 27794)
+++ src/aircraft_cmd.cpp (working copy)
@@ -37,6 +37,7 @@
#include "core/backup_type.hpp"
#include "zoom_func.h"
#include "disaster_vehicle.h"
+#include "settings_internal.h"
#include "table/strings.h"
@@ -1619,6 +1620,7 @@
static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *apc)
{
v->state = ENDLANDING;
+ v->flight_counter = 0;
AircraftLandAirplane(v); // maybe crash airplane
/* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */
@@ -1632,6 +1634,7 @@
static void AircraftEventHandler_HeliLanding(Aircraft *v, const AirportFTAClass *apc)
{
v->state = HELIENDLANDING;
+ v->flight_counter = 0;
v->UpdateDeltaXY(INVALID_DIR);
}
@@ -2034,6 +2037,20 @@
return true;
}
+static uint FlightTimeDelta()
+{
+ uint speed_factor_max = GetSettingFromName("vehicle.plane_speed", &speed_factor_max)->desc.max;
+ uint speed_factor_min = GetSettingFromName("vehicle.plane_speed", &speed_factor_min)->desc.min;
+
+ uint m = 1;
+ for (uint i = speed_factor_min; i <= speed_factor_max; i++) {
+ uint l = LeastCommonMultiple(i, speed_factor_max);
+ m = l > m ? l : m;
+ }
+
+ return m / _settings_game.vehicle.plane_speed;
+}
+
bool Aircraft::Tick()
{
if (!this->IsNormalAircraft()) return true;
@@ -2046,6 +2063,8 @@
this->current_order_time++;
+ if (this->state == FLYING) this->flight_counter += FlightTimeDelta();
+
for (uint i = 0; i != 2; i++) {
/* stop if the aircraft was deleted */
if (!AircraftEventHandler(this, i)) return false;
Index: src/lang/english.txt
===================================================================
--- src/lang/english.txt (revision 27794)
+++ src/lang/english.txt (working copy)
@@ -286,6 +286,7 @@
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
@@ -3662,6 +3663,7 @@
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_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_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY_LONG}
Index: src/saveload/afterload.cpp
===================================================================
--- src/saveload/afterload.cpp (revision 27794)
+++ src/saveload/afterload.cpp (working copy)
@@ -2977,6 +2977,12 @@
FOR_ALL_STATIONS(st) UpdateStationAcceptance(st, false);
}
+ /* Set lifetime vehicle profit to 0 if save game before 197 */
+ if (IsSavegameVersionBefore(197)) {
+ Vehicle *v;
+ FOR_ALL_VEHICLES(v) v->profit_lifetime = 0;
+ }
+
/* Road stops is 'only' updating some caches */
AfterLoadRoadStops();
AfterLoadLabelMaps();
Index: src/saveload/saveload.cpp
===================================================================
--- src/saveload/saveload.cpp (revision 27794)
+++ src/saveload/saveload.cpp (working copy)
@@ -264,8 +264,9 @@
* 194 26881 1.5.x, 1.6.0
* 195 27572 1.6.x
* 196 27778 1.7.x
+ * 197
*/
-extern const uint16 SAVEGAME_VERSION = 196; ///< Current savegame version of OpenTTD.
+extern const uint16 SAVEGAME_VERSION = 197; ///< Current savegame version of OpenTTD.
SavegameType _savegame_type; ///< type of savegame we are loading
FileToSaveLoad _file_to_saveload; ///< File to save or load in the openttd loop.
Index: src/saveload/vehicle_sl.cpp
===================================================================
--- src/saveload/vehicle_sl.cpp (revision 27794)
+++ src/saveload/vehicle_sl.cpp (working copy)
@@ -683,6 +683,7 @@
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(Vehicle, profit_lifetime, SLE_INT64, 197, SL_MAX_VERSION),
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),
Index: src/vehicle.cpp
===================================================================
--- src/vehicle.cpp (revision 27794)
+++ src/vehicle.cpp (working copy)
@@ -1237,6 +1237,10 @@
* >2 - vehicle is counting down to the actual breakdown event */
switch (this->breakdown_ctr) {
case 0:
+ if (this->type == VEH_AIRCRAFT) {
+ Aircraft *a = Aircraft::From(this);
+ if (false && a->flight_counter < 74 * 20 * 4 && !(this->vehstatus & VS_AIRCRAFT_BROKEN)) this->breakdown_ctr = 2;
+ }
return false;
case 2:
@@ -2704,6 +2708,7 @@
}
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);
}
Index: src/vehicle_base.h
===================================================================
--- src/vehicle_base.h (revision 27794)
+++ src/vehicle_base.h (working copy)
@@ -238,6 +238,7 @@
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
CargoPayment *cargo_payment; ///< The cargo payment we're currently in
@@ -571,6 +572,12 @@
*/
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);
/**
Index: src/vehicle_gui.cpp
===================================================================
--- src/vehicle_gui.cpp (revision 27794)
+++ src/vehicle_gui.cpp (working copy)
@@ -48,6 +48,7 @@
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;
@@ -64,6 +65,7 @@
&VehicleAgeSorter,
&VehicleProfitThisYearSorter,
&VehicleProfitLastYearSorter,
+ &VehicleProfitLifetimeSorter,
&VehicleCargoSorter,
&VehicleReliabilitySorter,
&VehicleMaxSpeedSorter,
@@ -80,6 +82,7 @@
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,
@@ -1132,6 +1135,13 @@
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)
{
@@ -1939,12 +1949,14 @@
STR_VEHICLE_INFO_MAX_SPEED,
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED,
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE,
- STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR,
STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS
};
for (uint i = 0; i < lengthof(info_strings); i++) {
dim = maxdim(dim, GetStringBoundingBox(info_strings[i]));
}
+ 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));
SetDParam(0, STR_VEHICLE_INFO_AGE);
dim = maxdim(dim, GetStringBoundingBox(STR_VEHICLE_INFO_AGE_RUNNING_COST_YR));
size->width = dim.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
@@ -2080,9 +2092,11 @@
y += FONT_HEIGHT_NORMAL;
/* Draw profit */
- 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;
/* Draw breakdown & reliability */