diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 026fe129cb..52f4588fbc 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -71,7 +71,10 @@ bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company) switch (type) { case VEH_TRAIN: { /* make sure the railtypes are compatible */ - if ((GetRailTypeInfo(e_from->u.rail.railtype)->compatible_railtypes & GetRailTypeInfo(e_to->u.rail.railtype)->compatible_railtypes) == 0) return false; + if (!_settings_game.depot.allow_no_comp_railtype_replacements && + (GetRailTypeInfo(e_from->u.rail.railtype)->compatible_railtypes & GetRailTypeInfo(e_to->u.rail.railtype)->compatible_railtypes) == 0) { + return false; + } /* make sure we do not replace wagons with engines or vice versa */ if ((e_from->u.rail.railveh_type == RAILVEH_WAGON) != (e_to->u.rail.railveh_type == RAILVEH_WAGON)) return false; @@ -79,11 +82,15 @@ bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company) } case VEH_ROAD: - /* make sure the roadtypes are compatible */ - if ((GetRoadTypeInfo(e_from->u.road.roadtype)->powered_roadtypes & GetRoadTypeInfo(e_to->u.road.roadtype)->powered_roadtypes) == ROADTYPES_NONE) return false; + if (!_settings_game.depot.allow_no_comp_roadtype_replacements) { + /* make sure the roadtypes are compatible */ + if ((GetRoadTypeInfo(e_from->u.road.roadtype)->powered_roadtypes & GetRoadTypeInfo(e_to->u.road.roadtype)->powered_roadtypes) == ROADTYPES_NONE) { + return false; + } - /* make sure that we do not replace a tram with a normal road vehicles or vice versa */ - if (HasBit(e_from->info.misc_flags, EF_ROAD_TRAM) != HasBit(e_to->info.misc_flags, EF_ROAD_TRAM)) return false; + /* make sure that we do not replace a tram with a normal road vehicles or vice versa */ + if (HasBit(e_from->info.misc_flags, EF_ROAD_TRAM) != HasBit(e_to->info.misc_flags, EF_ROAD_TRAM)) return false; + } break; case VEH_AIRCRAFT: diff --git a/src/lang/english.txt b/src/lang/english.txt index 36f555620a..b00cb37577 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1464,6 +1464,7 @@ STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Allow construct STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Allow drive-through road stops on roads owned by competitors: {STRING2} STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT :Allow construction of drive-through road stops on roads owned by other companies STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Changing this setting is not possible when there are vehicles +STR_CONFIG_SETTING_REPLACEMENTS_DIFF_TYPE :{WHITE}Disabling this setting is not possible during a game STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Infrastructure maintenance: {STRING2} STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :When enabled, infrastructure causes maintenance costs. The cost grows over-proportional with the network size, thus affecting bigger companies more than smaller ones @@ -1621,6 +1622,10 @@ STR_CONFIG_SETTING_DISTANT_JOIN_DEPOTS :Allow to join d STR_CONFIG_SETTING_DISTANT_JOIN_DEPOTS_HELPTEXT :Allow adding parts to a depot without directly touching the existing parts. Needs Ctrl+Click while placing the new parts STR_CONFIG_SETTING_DEPOT_SPREAD :Maximum depot spread: {STRING2} STR_CONFIG_SETTING_DEPOT_SPREAD_HELPTEXT :Maximum area the parts of a single depot may be spread out on +STR_CONFIG_SETTING_REPLACE_INCOMPATIBLE_RAIL :Allow replacing rail vehicles with incompatible rail types: {STRING2} +STR_CONFIG_SETTING_REPLACE_INCOMPATIBLE_RAIL_HELPTEXT :Allow replacing rail vehicles even if they are not compatible by rail type +STR_CONFIG_SETTING_REPLACE_INCOMPATIBLE_ROAD :Allow replacing road vehicles with incompatible road types: {STRING2} +STR_CONFIG_SETTING_REPLACE_INCOMPATIBLE_ROAD_HELPTEXT :Allow replacing road vehicles even if they are not compatible by road type STR_CONFIG_SETTING_STATION_SPREAD :Maximum station spread: {STRING2} STR_CONFIG_SETTING_STATION_SPREAD_HELPTEXT :Maximum area the parts of a single station may be spread out on. Note that high values will slow the game diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 578e461b8f..d621a05962 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -804,6 +804,11 @@ bool AfterLoadGame() _settings_game.depot.distant_join_depots = true; } + if (IsSavegameVersionBefore(SLV_ALLOW_INCOMPATIBLE_REPLACEMENTS)) { + _settings_game.depot.allow_no_comp_railtype_replacements = false; + _settings_game.depot.allow_no_comp_roadtype_replacements = false; + } + /* Load the sprites */ GfxLoadSprites(); LoadStringWidthTable(); diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 22cd1c980a..d67f9a5bef 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -389,6 +389,7 @@ enum SaveLoadVersion : uint16_t { SLV_DEPOTID_BACKUP_ORDERS, ///< 341 PR#XXXXX Backup orders are indexed through DepotIDs. SLV_ADD_MEMBERS_TO_DEPOT_STRUCT, ///< 342 PR#XXXXX Add some members to depot struct. SLV_DEPOT_SPREAD, ///< 343 PR#XXXXX Add a setting for max depot spread. + SLV_ALLOW_INCOMPATIBLE_REPLACEMENTS, ///< 344 PR#XXXXX Allow incompatible vehicle replacements. SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 1b3fd4a8fe..739a339a7a 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -2149,6 +2149,9 @@ static SettingsContainer &GetSettingsTree() { depots->Add(new SettingEntry("depot.depot_spread")); depots->Add(new SettingEntry("depot.distant_join_depots")); + + depots->Add(new SettingEntry("depot.allow_no_comp_railtype_replacements")); + depots->Add(new SettingEntry("depot.allow_no_comp_roadtype_replacements")); } limitations->Add(new SettingEntry("construction.command_pause_level")); diff --git a/src/settings_table.cpp b/src/settings_table.cpp index 0fd874a38c..0f262ebfe3 100644 --- a/src/settings_table.cpp +++ b/src/settings_table.cpp @@ -380,6 +380,22 @@ static void SpriteZoomMinChanged(int32_t) MarkWholeScreenDirty(); } +static bool CheckDifferentRailRoadTypesReplacements(int32_t &new_value) +{ + if (_game_mode == GM_NORMAL) { + if (new_value == 0) { + ShowErrorMessage(STR_CONFIG_SETTING_REPLACEMENTS_DIFF_TYPE, INVALID_STRING_ID, WL_ERROR); + return false; + } + } + return true; +} + +static void InvalidateReplacementWindows(int32_t) +{ + InvalidateWindowClassesData(WC_REPLACE_VEHICLE); +} + /** * Update any possible saveload window and delete any newgrf dialogue as * its widget parts might change. Reinit all windows as it allows access to the diff --git a/src/settings_type.h b/src/settings_type.h index 6938578466..4d1451e0ae 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -574,6 +574,9 @@ struct StationSettings { struct DepotSettings { uint8_t depot_spread; ///< amount a depot may spread bool distant_join_depots; ///< allow to join non-adjacent depots + + bool allow_no_comp_railtype_replacements; ///< allow replacing rail vehicles even if rail type is not compatible + bool allow_no_comp_roadtype_replacements; ///< allow replacing road vehicles even if road type is not compatible }; /** Default settings for vehicles. */ diff --git a/src/table/settings/game_settings.ini b/src/table/settings/game_settings.ini index 286c517fee..269da0c70b 100644 --- a/src/table/settings/game_settings.ini +++ b/src/table/settings/game_settings.ini @@ -21,6 +21,8 @@ static bool CheckRoadSide(int32_t &new_value); static bool CheckDynamicEngines(int32_t &new_value); static void StationCatchmentChanged(int32_t new_value); static void MaxVehiclesChanged(int32_t new_value); +static bool CheckDifferentRailRoadTypesReplacements(int32_t &new_value); +static void InvalidateReplacementWindows(int32_t new_value); static const SettingVariant _game_settings_table[] = { [post-amble] @@ -166,6 +168,26 @@ strval = STR_CONFIG_SETTING_TILE_LENGTH post_cb = [](auto) { CloseWindowByClass(WC_SELECT_DEPOT); } cat = SC_BASIC +[SDT_BOOL] +var = depot.allow_no_comp_railtype_replacements +from = SLV_ALLOW_INCOMPATIBLE_REPLACEMENTS +def = false +str = STR_CONFIG_SETTING_REPLACE_INCOMPATIBLE_RAIL +strhelp = STR_CONFIG_SETTING_REPLACE_INCOMPATIBLE_RAIL_HELPTEXT +pre_cb = CheckDifferentRailRoadTypesReplacements +post_cb = InvalidateReplacementWindows +cat = SC_EXPERT + +[SDT_BOOL] +var = depot.allow_no_comp_roadtype_replacements +from = SLV_ALLOW_INCOMPATIBLE_REPLACEMENTS +def = false +str = STR_CONFIG_SETTING_REPLACE_INCOMPATIBLE_ROAD +strhelp = STR_CONFIG_SETTING_REPLACE_INCOMPATIBLE_ROAD_HELPTEXT +pre_cb = CheckDifferentRailRoadTypesReplacements +post_cb = InvalidateReplacementWindows +cat = SC_EXPERT + [SDT_OMANY] var = vehicle.road_side type = SLE_UINT8