mirror of https://github.com/OpenTTD/OpenTTD
Feature: Engine expiry setting to keep owned engines available for purchase
parent
4df44fea38
commit
2a17900f7d
|
@ -24,6 +24,7 @@
|
||||||
#include "engine_gui.h"
|
#include "engine_gui.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
#include "engine_base.h"
|
#include "engine_base.h"
|
||||||
|
#include "engine_type.h"
|
||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
#include "vehicle_func.h"
|
#include "vehicle_func.h"
|
||||||
#include "articulated_vehicles.h"
|
#include "articulated_vehicles.h"
|
||||||
|
@ -604,6 +605,32 @@ static void ClearLastVariant(EngineID engine_id, VehicleType type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is a given engine allowed to expire?
|
||||||
|
* @note This does not age or retire the engine, just check if expiry is allowed.
|
||||||
|
* @param e The engine in question.
|
||||||
|
* @return True iff the engine can be checked for retirement.
|
||||||
|
*/
|
||||||
|
static bool AllowEngineExpiry(Engine *e)
|
||||||
|
{
|
||||||
|
/* The vehicle is set to never expire. */
|
||||||
|
if (e->info.base_life == 0xFF) return false;
|
||||||
|
|
||||||
|
/* The player will not allow any vehicle to expire. */
|
||||||
|
if (_settings_game.vehicle.engine_expiry == EngineExpiryMode::Never) return false;
|
||||||
|
|
||||||
|
/* The player wants to keep buying vehicles someone already owns. */
|
||||||
|
if (_settings_game.vehicle.engine_expiry == EngineExpiryMode::Owned) {
|
||||||
|
for (const Company *c : Company::Iterate()) {
|
||||||
|
if (c == nullptr) continue;
|
||||||
|
if (GetGroupNumEngines(c->index, ALL_GROUP, e->index) > 0) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Vehicles expire normally. */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update #Engine::reliability and (if needed) update the engine GUIs.
|
* Update #Engine::reliability and (if needed) update the engine GUIs.
|
||||||
* @param e %Engine to update.
|
* @param e %Engine to update.
|
||||||
|
@ -620,7 +647,7 @@ void CalcEngineReliability(Engine *e, bool new_month)
|
||||||
if (new_month && re->index > e->index && age != INT32_MAX) age++; /* parent variant's age has not yet updated. */
|
if (new_month && re->index > e->index && age != INT32_MAX) age++; /* parent variant's age has not yet updated. */
|
||||||
|
|
||||||
/* Check for early retirement */
|
/* Check for early retirement */
|
||||||
if (e->company_avail != 0 && !_settings_game.vehicle.never_expire_vehicles && e->info.base_life != 0xFF) {
|
if (e->company_avail != 0 && AllowEngineExpiry(e)) {
|
||||||
int retire_early = e->info.retire_early;
|
int retire_early = e->info.retire_early;
|
||||||
uint retire_early_max_age = std::max(0, e->duration_phase_1 + e->duration_phase_2 - retire_early * 12);
|
uint retire_early_max_age = std::max(0, e->duration_phase_1 + e->duration_phase_2 - retire_early * 12);
|
||||||
if (retire_early != 0 && age >= retire_early_max_age) {
|
if (retire_early != 0 && age >= retire_early_max_age) {
|
||||||
|
@ -634,7 +661,7 @@ void CalcEngineReliability(Engine *e, bool new_month)
|
||||||
if (age < e->duration_phase_1) {
|
if (age < e->duration_phase_1) {
|
||||||
uint start = e->reliability_start;
|
uint start = e->reliability_start;
|
||||||
e->reliability = age * (e->reliability_max - start) / e->duration_phase_1 + start;
|
e->reliability = age * (e->reliability_max - start) / e->duration_phase_1 + start;
|
||||||
} else if ((age -= e->duration_phase_1) < e->duration_phase_2 || _settings_game.vehicle.never_expire_vehicles || e->info.base_life == 0xFF) {
|
} else if ((age -= e->duration_phase_1) < e->duration_phase_2 || !AllowEngineExpiry(e)) {
|
||||||
/* We are at the peak of this engines life. It will have max reliability.
|
/* We are at the peak of this engines life. It will have max reliability.
|
||||||
* This is also true if the engines never expire. They will not go bad over time */
|
* This is also true if the engines never expire. They will not go bad over time */
|
||||||
e->reliability = e->reliability_max;
|
e->reliability = e->reliability_max;
|
||||||
|
|
|
@ -195,6 +195,15 @@ enum EngineNameContext : uint8_t {
|
||||||
AutoreplaceVehicleInUse = 0x22, ///< Name is show in the autoreplace window 'Vehicles in use' panel.
|
AutoreplaceVehicleInUse = 0x22, ///< Name is show in the autoreplace window 'Vehicles in use' panel.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Possible values of the "engine_expiry" setting.
|
||||||
|
*/
|
||||||
|
enum EngineExpiryMode : uint8_t {
|
||||||
|
Off = 0, ///< Engines expire normally.
|
||||||
|
Never = 1, ///< Engines never expire.
|
||||||
|
Owned = 2, ///< Engines which are currently owned by any company never expire. Unowned vehicles expire normally.
|
||||||
|
};
|
||||||
|
|
||||||
/** Combine an engine ID and a name context to an engine name dparam. */
|
/** Combine an engine ID and a name context to an engine name dparam. */
|
||||||
inline uint64_t PackEngineNameDParam(EngineID engine_id, EngineNameContext context, uint32_t extra_data = 0)
|
inline uint64_t PackEngineNameDParam(EngineID engine_id, EngineNameContext context, uint32_t extra_data = 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1492,7 +1492,12 @@ STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT :When enabled, a
|
||||||
STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT_PERIOD :When enabled, a news message gets sent when a vehicle has not made any profit within a period
|
STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT_PERIOD :When enabled, a news message gets sent when a vehicle has not made any profit within a period
|
||||||
|
|
||||||
STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES :Vehicles never expire: {STRING2}
|
STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES :Vehicles never expire: {STRING2}
|
||||||
STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT :When enabled, all vehicle models remain available forever after their introduction
|
STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT :Choose if vehicle models remain available forever after their introduction
|
||||||
|
|
||||||
|
###length 3
|
||||||
|
STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_OFF :Off
|
||||||
|
STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_NEVER :All available forever
|
||||||
|
STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_OWNED :Owned vehicles available forever
|
||||||
|
|
||||||
STR_CONFIG_SETTING_TIMEKEEPING_UNITS :Timekeeping: {STRING2}
|
STR_CONFIG_SETTING_TIMEKEEPING_UNITS :Timekeeping: {STRING2}
|
||||||
STR_CONFIG_SETTING_TIMEKEEPING_UNITS_HELPTEXT :Select the timekeeping units of the game. This cannot be changed later.{}{}Calendar-based is the classic OpenTTD experience, with a year consisting of 12 months, and each month having 28-31 days.{}{}In Wallclock-based time, cargo production and financials are instead based on one-minute increments, which is about as long as a 30 day month takes in Calendar-based mode. These are grouped into 12-minute periods, equivalent to a year in Calendar-based mode.{}{}In either mode there is always a classic calendar, which is used for introduction dates of vehicles, houses, and other infrastructure
|
STR_CONFIG_SETTING_TIMEKEEPING_UNITS_HELPTEXT :Select the timekeeping units of the game. This cannot be changed later.{}{}Calendar-based is the classic OpenTTD experience, with a year consisting of 12 months, and each month having 28-31 days.{}{}In Wallclock-based time, cargo production and financials are instead based on one-minute increments, which is about as long as a 30 day month takes in Calendar-based mode. These are grouped into 12-minute periods, equivalent to a year in Calendar-based mode.{}{}In either mode there is always a classic calendar, which is used for introduction dates of vehicles, houses, and other infrastructure
|
||||||
|
|
|
@ -795,6 +795,11 @@ bool AfterLoadGame()
|
||||||
_settings_game.linkgraph.recalc_time *= CalendarTime::SECONDS_PER_DAY;
|
_settings_game.linkgraph.recalc_time *= CalendarTime::SECONDS_PER_DAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert old engine expiry setting. */
|
||||||
|
if (IsSavegameVersionBefore(SLV_ENGINE_EXPIRY_OWNED)) {
|
||||||
|
_settings_game.vehicle.engine_expiry = _settings_game.vehicle.never_expire_vehicles ? EngineExpiryMode::Never : EngineExpiryMode::Off;
|
||||||
|
}
|
||||||
|
|
||||||
/* Load the sprites */
|
/* Load the sprites */
|
||||||
GfxLoadSprites();
|
GfxLoadSprites();
|
||||||
LoadStringWidthTable();
|
LoadStringWidthTable();
|
||||||
|
|
|
@ -379,6 +379,8 @@ enum SaveLoadVersion : uint16_t {
|
||||||
SLV_SCRIPT_RANDOMIZER, ///< 333 PR#12063 v14.0-RC1 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
|
SLV_VEHICLE_ECONOMY_AGE, ///< 334 PR#12141 v14.0 Add vehicle age in economy year, for profit stats minimum age
|
||||||
|
|
||||||
|
SLV_ENGINE_EXPIRY_OWNED, ///< 335 PR#12598 Add engine expiry mode to keep owned engines available for purchase.
|
||||||
|
|
||||||
SL_MAX_VERSION, ///< Highest possible saveload version
|
SL_MAX_VERSION, ///< Highest possible saveload version
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2144,7 +2144,7 @@ static SettingsContainer &GetSettingsTree()
|
||||||
limitations->Add(new SettingEntry("construction.max_bridge_height"));
|
limitations->Add(new SettingEntry("construction.max_bridge_height"));
|
||||||
limitations->Add(new SettingEntry("construction.max_tunnel_length"));
|
limitations->Add(new SettingEntry("construction.max_tunnel_length"));
|
||||||
limitations->Add(new SettingEntry("station.never_expire_airports"));
|
limitations->Add(new SettingEntry("station.never_expire_airports"));
|
||||||
limitations->Add(new SettingEntry("vehicle.never_expire_vehicles"));
|
limitations->Add(new SettingEntry("vehicle.engine_expiry"));
|
||||||
limitations->Add(new SettingEntry("vehicle.max_trains"));
|
limitations->Add(new SettingEntry("vehicle.max_trains"));
|
||||||
limitations->Add(new SettingEntry("vehicle.max_roadveh"));
|
limitations->Add(new SettingEntry("vehicle.max_roadveh"));
|
||||||
limitations->Add(new SettingEntry("vehicle.max_aircraft"));
|
limitations->Add(new SettingEntry("vehicle.max_aircraft"));
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "economy_type.h"
|
#include "economy_type.h"
|
||||||
#include "town_type.h"
|
#include "town_type.h"
|
||||||
#include "transport_type.h"
|
#include "transport_type.h"
|
||||||
|
#include "engine_type.h"
|
||||||
#include "network/network_type.h"
|
#include "network/network_type.h"
|
||||||
#include "company_type.h"
|
#include "company_type.h"
|
||||||
#include "cargotype.h"
|
#include "cargotype.h"
|
||||||
|
@ -516,6 +517,8 @@ struct OrderSettings {
|
||||||
|
|
||||||
/** Settings related to vehicles. */
|
/** Settings related to vehicles. */
|
||||||
struct VehicleSettings {
|
struct VehicleSettings {
|
||||||
|
bool never_expire_vehicles; ///< Unused value, used to load old savegames.
|
||||||
|
|
||||||
uint8_t max_train_length; ///< maximum length for trains
|
uint8_t max_train_length; ///< maximum length for trains
|
||||||
uint8_t smoke_amount; ///< amount of smoke/sparks locomotives produce
|
uint8_t smoke_amount; ///< amount of smoke/sparks locomotives produce
|
||||||
uint8_t train_acceleration_model; ///< realistic acceleration for trains
|
uint8_t train_acceleration_model; ///< realistic acceleration for trains
|
||||||
|
@ -531,7 +534,7 @@ struct VehicleSettings {
|
||||||
uint8_t plane_speed; ///< divisor for speed of aircraft
|
uint8_t plane_speed; ///< divisor for speed of aircraft
|
||||||
uint8_t freight_trains; ///< value to multiply the weight of cargo by
|
uint8_t freight_trains; ///< value to multiply the weight of cargo by
|
||||||
bool dynamic_engines; ///< enable dynamic allocation of engine data
|
bool dynamic_engines; ///< enable dynamic allocation of engine data
|
||||||
bool never_expire_vehicles; ///< never expire vehicles
|
EngineExpiryMode engine_expiry; ///< engine expiry
|
||||||
uint8_t extend_vehicle_life; ///< extend vehicle life by this many years
|
uint8_t extend_vehicle_life; ///< extend vehicle life by this many years
|
||||||
uint8_t road_side; ///< the side of the road vehicles drive on
|
uint8_t road_side; ///< the side of the road vehicles drive on
|
||||||
uint8_t plane_crashes; ///< number of plane crashes, 0 = none, 1 = reduced, 2 = normal
|
uint8_t plane_crashes; ///< number of plane crashes, 0 = none, 1 = reduced, 2 = normal
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
[pre-amble]
|
[pre-amble]
|
||||||
static constexpr std::initializer_list<const char*> _roadsides{"left", "right"};
|
static constexpr std::initializer_list<const char*> _roadsides{"left", "right"};
|
||||||
|
static constexpr std::initializer_list<const char*> _engine_expiry_modes{"off", "never", "owned"};
|
||||||
|
|
||||||
static void StationSpreadChanged(int32_t new_value);
|
static void StationSpreadChanged(int32_t new_value);
|
||||||
static void UpdateConsists(int32_t new_value);
|
static void UpdateConsists(int32_t new_value);
|
||||||
|
@ -243,8 +244,21 @@ strval = STR_CONFIG_SETTING_NONE
|
||||||
var = vehicle.never_expire_vehicles
|
var = vehicle.never_expire_vehicles
|
||||||
flags = SF_NO_NETWORK
|
flags = SF_NO_NETWORK
|
||||||
def = false
|
def = false
|
||||||
|
to = SLV_ENGINE_EXPIRY_OWNED
|
||||||
|
|
||||||
|
[SDT_OMANY]
|
||||||
|
var = vehicle.engine_expiry
|
||||||
|
type = SLE_UINT8
|
||||||
|
from = SLV_ENGINE_EXPIRY_OWNED
|
||||||
|
flags = SF_GUI_DROPDOWN | SF_NO_NETWORK
|
||||||
|
def = EngineExpiryMode::Off
|
||||||
|
min = EngineExpiryMode::Off
|
||||||
|
max = EngineExpiryMode::Owned
|
||||||
|
full = _engine_expiry_modes
|
||||||
str = STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES
|
str = STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES
|
||||||
strhelp = STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT
|
strhelp = STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT
|
||||||
|
strval = STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_OFF
|
||||||
|
cat = SC_BASIC
|
||||||
|
|
||||||
[SDT_VAR]
|
[SDT_VAR]
|
||||||
var = vehicle.max_trains
|
var = vehicle.max_trains
|
||||||
|
|
Loading…
Reference in New Issue