diff --git a/src/lang/english.txt b/src/lang/english.txt index 36f75ff67e..92253d00b5 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1935,6 +1935,12 @@ STR_CONFIG_SETTING_INDUSTRY_CARGO_FACTOR :Industry cargo STR_CONFIG_SETTING_INDUSTRY_CARGO_FACTOR_HELPTEXT :Primary industry cargo production is scaled by approximately 2^factor (exponential). This excludes tree-cutting industries.{}This is not guaranteed to be fully compatible with all industry NewGRFs. STR_CONFIG_SETTING_TOWN_ABOVE_HEIGHT :No towns above height level: {STRING2} STR_CONFIG_SETTING_TOWN_ABOVE_HEIGHT_HELPTEXT :No towns above the specified height level are built during map creation. +STR_CONFIG_SETTING_MIN_TOWN_LAND_AREA :Minimum contiguous land area for towns: {STRING2} +STR_CONFIG_SETTING_MIN_TOWN_LAND_AREA_HELPTEXT :Towns can only be placed on contiguous landmasses of at least this many tiles. +STR_CONFIG_SETTING_MIN_CITY_LAND_AREA :Minimum contiguous land area for cities: {STRING2} +STR_CONFIG_SETTING_MIN_CITY_LAND_AREA_HELPTEXT :Cities can only be placed on contiguous landmasses of at least this many tiles. +STR_CONFIG_SETTING_MIN_LAND_AREA_VALUE :{NUM} +STR_CONFIG_SETTING_MIN_LAND_AREA_ZERO :Off STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :In game placement of trees: {STRING2} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Control random appearance of trees during the game. This might affect industries which rely on tree growth, for example lumber mills diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 248f9216c1..56518e716e 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -2067,6 +2067,8 @@ static SettingsContainer &GetSettingsTree() genworld->Add(new SettingEntry("economy.town_layout")); genworld->Add(new SettingEntry("economy.town_min_distance")); genworld->Add(new SettingEntry("economy.max_town_heightlevel")); + genworld->Add(new SettingEntry("economy.min_town_land_area")); + genworld->Add(new SettingEntry("economy.min_city_land_area")); genworld->Add(new SettingEntry("game_creation.build_public_roads")); genworld->Add(new SettingEntry("difficulty.industry_density")); genworld->Add(new SettingEntry("gui.pause_on_newgame")); diff --git a/src/settings_type.h b/src/settings_type.h index 5cb9cfd3f7..57bad87e0b 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -638,6 +638,8 @@ struct EconomySettings { bool allow_town_roads; ///< towns are allowed to build roads (always allowed when generating world / in SE) uint16 town_min_distance; ///< minimum distance between towns uint8 max_town_heightlevel; ///< maximum height level for towns + uint16 min_town_land_area; ///< minimum contiguous lang area for towns. + uint16 min_city_land_area; ///< minimum contiguous lang area for cities. TownFounding found_town; ///< town founding. bool station_noise_level; ///< build new airports when the town noise level is still within accepted limits uint16 town_noise_population[3]; ///< population to base decision on noise evaluation (@see town_council_tolerance) diff --git a/src/table/settings.ini b/src/table/settings.ini index 13c19b490d..1abaee37d5 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -961,6 +961,36 @@ strval = STR_JUST_INT cat = SC_BASIC patxname = ""max_town_heightlevel.economy.max_town_heightlevel"" +[SDT_VAR] +base = GameSettings +var = economy.min_town_land_area +type = SLE_UINT16 +guiflags = SGF_0ISDISABLED +def = 0 +min = 0 +max = 400 +interval = 5 +str = STR_CONFIG_SETTING_MIN_TOWN_LAND_AREA +strhelp = STR_CONFIG_SETTING_MIN_TOWN_LAND_AREA_HELPTEXT +strval = STR_CONFIG_SETTING_MIN_LAND_AREA_VALUE +cat = SC_BASIC +patxname = ""max_town_heightlevel.economy.min_town_land_area"" + +[SDT_VAR] +base = GameSettings +var = economy.min_city_land_area +type = SLE_UINT16 +guiflags = SGF_0ISDISABLED +def = 75 +min = 0 +max = 400 +interval = 5 +str = STR_CONFIG_SETTING_MIN_CITY_LAND_AREA +strhelp = STR_CONFIG_SETTING_MIN_CITY_LAND_AREA_HELPTEXT +strval = STR_CONFIG_SETTING_MIN_LAND_AREA_VALUE +cat = SC_BASIC +patxname = ""max_town_heightlevel.economy.min_city_land_area"" + ; link graph [SDT_VAR] diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 07f80a9c5b..c7c7927265 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -2108,7 +2108,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize * @param tile tile to check * @return error value or zero cost */ -static CommandCost TownCanBePlacedHere(TileIndex tile) +static CommandCost TownCanBePlacedHere(TileIndex tile, bool city) { /* Check if too close to the edge of map */ if (DistanceFromEdge(tile) < 12) { @@ -2130,6 +2130,17 @@ static CommandCost TownCanBePlacedHere(TileIndex tile) return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } + uint min_land_area = city ? _settings_game.economy.min_city_land_area : _settings_game.economy.min_town_land_area; + if (min_land_area > 0) { + if (!EnoughContiguousTilesMatchingCondition(tile, min_land_area, [](TileIndex t, void *data) -> bool { + if (!HasTileWaterClass(t) || GetWaterClass(t) == WATER_CLASS_INVALID) return true; + if (IsCoastTile(t) && !IsSlopeWithOneCornerRaised(GetTileSlope(t))) return true; + return false; + }, nullptr)) { + return_cmd_error(STR_ERROR_SITE_UNSUITABLE); + } + } + return CommandCost(EXPENSES_OTHER); } @@ -2197,7 +2208,7 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (!Town::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_TOWNS); if (!random) { - CommandCost ret = TownCanBePlacedHere(tile); + CommandCost ret = TownCanBePlacedHere(tile, city); if (ret.Failed()) return ret; } @@ -2408,7 +2419,7 @@ static Town *CreateRandomTown(uint attempts, uint32 townnameparts, TownSize size } /* Make sure town can be placed here */ - if (TownCanBePlacedHere(tile).Failed()) continue; + if (TownCanBePlacedHere(tile, city).Failed()) continue; /* Allocate a town struct */ Town *t = new Town(tile);