diff --git a/src/engine.cpp b/src/engine.cpp index 0bebc81ec3..da3587adf3 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -654,7 +654,7 @@ void SetYearEngineAgingStops() * @param e The engine to initialise. * @param aging_date The date used for age calculations. */ -void StartupOneEngine(Engine *e, Date aging_date) +void StartupOneEngine(Engine *e, Date aging_date, Date no_introduce_after_date) { const EngineInfo *ei = &e->info; @@ -677,7 +677,7 @@ void StartupOneEngine(Engine *e, Date aging_date) * of engines in early starting games. * Note: TTDP uses fixed 1922 */ e->intro_date = ei->base_intro <= ConvertYMDToDate(_settings_game.game_creation.starting_year + 2, 0, 1) ? ei->base_intro : (Date)GB(r, 0, 9) + ei->base_intro; - if (e->intro_date <= _date) { + if (e->intro_date <= _date && e->intro_date <= no_introduce_after_date) { e->age = (aging_date - e->intro_date) >> 5; e->company_avail = (CompanyMask)-1; e->flags |= ENGINE_AVAILABLE; @@ -715,8 +715,13 @@ void StartupEngines() /* Aging of vehicles stops, so account for that when starting late */ const Date aging_date = std::min(_date, ConvertYMDToDate(_year_engine_aging_stops, 0, 1)); + Date no_introduce_after_date = INT_MAX; + if (_settings_game.vehicle.no_introduce_vehicles_after > 0) { + no_introduce_after_date = ConvertYMDToDate(_settings_game.vehicle.no_introduce_vehicles_after, 0, 1) - 1; + } + for (Engine *e : Engine::Iterate()) { - StartupOneEngine(e, aging_date); + StartupOneEngine(e, aging_date, no_introduce_after_date); } /* Update the bitmasks for the vehicle lists */ @@ -1049,6 +1054,11 @@ static void NewVehicleAvailable(Engine *e) void EnginesMonthlyLoop() { if (_cur_year < _year_engine_aging_stops) { + Date no_introduce_after = INT_MAX; + if (_settings_game.vehicle.no_introduce_vehicles_after > 0) { + no_introduce_after = ConvertYMDToDate(_settings_game.vehicle.no_introduce_vehicles_after, 0, 1) - 1; + } + for (Engine *e : Engine::Iterate()) { /* Age the vehicle */ if ((e->flags & ENGINE_AVAILABLE) && e->age != MAX_DAY) { @@ -1059,6 +1069,8 @@ void EnginesMonthlyLoop() /* Do not introduce invalid engines */ if (!e->IsEnabled()) continue; + if (e->intro_date > no_introduce_after) continue; + if (!(e->flags & ENGINE_AVAILABLE) && _date >= (e->intro_date + DAYS_IN_YEAR)) { /* Introduce it to all companies */ NewVehicleAvailable(e); diff --git a/src/engine_func.h b/src/engine_func.h index 97bfd0894b..b046490c1f 100644 --- a/src/engine_func.h +++ b/src/engine_func.h @@ -26,7 +26,7 @@ bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company); bool IsEngineRefittable(EngineID engine); void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, CargoTypes *refits, CargoID cargo_type, uint cargo_capacity); void SetYearEngineAgingStops(); -void StartupOneEngine(Engine *e, Date aging_date); +void StartupOneEngine(Engine *e, Date aging_date, Date no_introduce_after_date); uint GetTotalCapacityOfArticulatedParts(EngineID engine); diff --git a/src/lang/english.txt b/src/lang/english.txt index a167adfb0f..b7cf65202f 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1361,6 +1361,10 @@ STR_CONFIG_SETTING_NO_EXPIRE_VEHICLES_AFTER :No vehicles exp STR_CONFIG_SETTING_NO_EXPIRE_VEHICLES_AFTER_HELPTEXT :Vehicles which would otherwise expire after this year remain available forever STR_CONFIG_SETTING_NO_EXPIRE_VEHICLES_AFTER_VALUE :{NUM} STR_CONFIG_SETTING_NO_EXPIRE_VEHICLES_AFTER_ZERO :Off +STR_CONFIG_SETTING_NO_INTRODUCE_VEHICLES_AFTER :No vehicles introduced after: {STRING2} +STR_CONFIG_SETTING_NO_INTRODUCE_VEHICLES_AFTER_HELPTEXT :Vehicles which would otherwise be introduced during or after this year are never introduced +STR_CONFIG_SETTING_NO_INTRODUCE_VEHICLES_AFTER_VALUE :{NUM} +STR_CONFIG_SETTING_NO_INTRODUCE_VEHICLES_AFTER_ZERO :Off STR_CONFIG_SETTING_AUTORENEW_VEHICLE :Autorenew vehicle when it gets old: {STRING2} STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :When enabled, a vehicle nearing its end of life gets automatically replaced when the renew conditions are fulfilled STR_CONFIG_SETTING_AUTORENEW_MONTHS :Autorenew when vehicle is {STRING2} maximum age diff --git a/src/rail.cpp b/src/rail.cpp index 6cb8264d63..b8074a1855 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -315,6 +315,10 @@ RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date) { RailTypes rts = current; + if (_settings_game.vehicle.no_introduce_vehicles_after > 0) { + date = std::min(date, ConvertYMDToDate(_settings_game.vehicle.no_introduce_vehicles_after, 0, 1) - 1); + } + for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { const RailtypeInfo *rti = GetRailTypeInfo(rt); /* Unused rail type. */ @@ -348,11 +352,16 @@ RailTypes GetCompanyRailtypes(CompanyID company, bool introduces) { RailTypes rts = RAILTYPES_NONE; + Date date = _date; + if (_settings_game.vehicle.no_introduce_vehicles_after > 0) { + date = std::min(date, ConvertYMDToDate(_settings_game.vehicle.no_introduce_vehicles_after, 0, 1) - 1); + } + for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { const EngineInfo *ei = &e->info; if (HasBit(ei->climates, _settings_game.game_creation.landscape) && - (HasBit(e->company_avail, company) || _date >= e->intro_date + DAYS_IN_YEAR)) { + (HasBit(e->company_avail, company) || date >= e->intro_date + DAYS_IN_YEAR)) { const RailVehicleInfo *rvi = &e->u.rail; if (rvi->railveh_type != RAILVEH_WAGON) { diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 9c1a0d5e30..63758d4ff9 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -402,7 +402,7 @@ static bool FixTTOEngines() if (oi == 255) { /* Default engine is used */ _date += DAYS_TILL_ORIGINAL_BASE_YEAR; - StartupOneEngine(e, aging_date); + StartupOneEngine(e, aging_date, INT_MAX); e->intro_date -= DAYS_TILL_ORIGINAL_BASE_YEAR; _date -= DAYS_TILL_ORIGINAL_BASE_YEAR; diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index b98c571588..4c51308b88 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1770,6 +1770,7 @@ static SettingsContainer &GetSettingsTree() limitations->Add(new SettingEntry("station.never_expire_airports")); limitations->Add(new SettingEntry("vehicle.never_expire_vehicles")); limitations->Add(new SettingEntry("vehicle.no_expire_vehicles_after")); + limitations->Add(new SettingEntry("vehicle.no_introduce_vehicles_after")); limitations->Add(new SettingEntry("vehicle.max_trains")); limitations->Add(new SettingEntry("vehicle.max_roadveh")); limitations->Add(new SettingEntry("vehicle.max_aircraft")); diff --git a/src/settings_type.h b/src/settings_type.h index d71f5ace18..b4b7c4b370 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -566,6 +566,7 @@ struct VehicleSettings { bool dynamic_engines; ///< enable dynamic allocation of engine data bool never_expire_vehicles; ///< never expire vehicles Year no_expire_vehicles_after; ///< do not expire vehicles ater this year + Year no_introduce_vehicles_after; ///< do not introduce vehicles ater this year byte extend_vehicle_life; ///< extend vehicle life by this many years byte road_side; ///< the side of the road vehicles drive on uint8 plane_crashes; ///< number of plane crashes, 0 = none, 1 = reduced, 2 = normal diff --git a/src/table/settings.ini b/src/table/settings.ini index f6ea4ffe9c..b6fd2e3cfc 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -1489,6 +1489,21 @@ strval = STR_CONFIG_SETTING_NO_EXPIRE_VEHICLES_AFTER_VALUE cat = SC_EXPERT patxname = ""vehicle.no_expire_vehicles_after"" +[SDT_VAR] +base = GameSettings +var = vehicle.no_introduce_vehicles_after +type = SLE_INT32 +guiflags = SGF_NO_NETWORK | SGF_0ISDISABLED +def = 0 +min = MIN_YEAR +max = MAX_YEAR +interval = 1 +str = STR_CONFIG_SETTING_NO_INTRODUCE_VEHICLES_AFTER +strhelp = STR_CONFIG_SETTING_NO_INTRODUCE_VEHICLES_AFTER_HELPTEXT +strval = STR_CONFIG_SETTING_NO_INTRODUCE_VEHICLES_AFTER_VALUE +cat = SC_EXPERT +patxname = ""vehicle.no_introduce_vehicles_after"" + ;; vehicle.exact_intro_date [SDT_NULL] length = 1