summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/genworld_gui.cpp90
-rw-r--r--src/landscape.cpp93
-rw-r--r--src/lang/english.txt8
-rw-r--r--src/settings_gui.cpp1
-rw-r--r--src/settings_type.h1
-rw-r--r--src/table/settings.ini15
-rw-r--r--src/tgp.cpp11
-rw-r--r--src/tile_type.h1
-rw-r--r--src/widgets/genworld_widget.h7
9 files changed, 194 insertions, 33 deletions
diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp
index 94381fe89..20c12d8b4 100644
--- a/src/genworld_gui.cpp
+++ b/src/genworld_gui.cpp
@@ -111,7 +111,10 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = {
NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAX_HEIGHTLEVEL, STR_NULL), SetFill(1, 1),
- NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SNOW_COVERAGE, STR_NULL), SetFill(1, 1),
+ NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GL_CLIMATE_SEL_LABEL),
+ NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SNOW_COVERAGE, STR_NULL), SetFill(1, 1),
+ NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DESERT_COVERAGE, STR_NULL), SetFill(1, 1),
+ EndContainer(),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SMOOTHNESS, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_NULL), SetFill(1, 1),
@@ -124,11 +127,19 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = {
NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_MAX_HEIGHTLEVEL_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_MAX_HEIGHTLEVEL_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_MAX_HEIGHTLEVEL_UP), SetFill(0, 1),
EndContainer(),
- /* Snow line. */
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_SNOW_COVERAGE_DOWN), SetFill(0, 1),
- NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_TEXT), SetDataTip(STR_MAPGEN_SNOW_COVERAGE_TEXT, STR_NULL), SetFill(1, 0),
- NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_SNOW_COVERAGE_UP), SetFill(0, 1),
+ NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GL_CLIMATE_SEL_SELECTOR),
+ /* Snow coverage. */
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_SNOW_COVERAGE_DOWN), SetFill(0, 1),
+ NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_TEXT), SetDataTip(STR_MAPGEN_SNOW_COVERAGE_TEXT, STR_NULL), SetFill(1, 0),
+ NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_SNOW_COVERAGE_UP), SetFill(0, 1),
+ EndContainer(),
+ /* Desert coverage. */
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_DESERT_COVERAGE_DOWN), SetFill(0, 1),
+ NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_TEXT), SetDataTip(STR_MAPGEN_DESERT_COVERAGE_TEXT, STR_NULL), SetFill(1, 0),
+ NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_DESERT_COVERAGE_UP), SetFill(0, 1),
+ EndContainer(),
EndContainer(),
/* Starting date. */
NWidget(NWID_HORIZONTAL),
@@ -228,7 +239,10 @@ static const NWidgetPart _nested_heightmap_load_widgets[] = {
NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAX_HEIGHTLEVEL, STR_NULL), SetFill(1, 1),
- NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SNOW_COVERAGE, STR_NULL), SetFill(1, 1),
+ NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GL_CLIMATE_SEL_LABEL),
+ NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SNOW_COVERAGE, STR_NULL), SetFill(1, 1),
+ NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DESERT_COVERAGE, STR_NULL), SetFill(1, 1),
+ EndContainer(),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_GAME_OPTIONS_TOWN_NAMES_FRAME, STR_NULL), SetFill(1, 1),
EndContainer(),
@@ -238,10 +252,17 @@ static const NWidgetPart _nested_heightmap_load_widgets[] = {
NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_MAX_HEIGHTLEVEL_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_MAX_HEIGHTLEVEL_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_MAX_HEIGHTLEVEL_UP), SetFill(0, 1),
EndContainer(),
- NWidget(NWID_HORIZONTAL),
- NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_SNOW_COVERAGE_DOWN), SetFill(0, 1),
- NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0),
- NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_SNOW_COVERAGE_UP), SetFill(0, 1),
+ NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GL_CLIMATE_SEL_SELECTOR),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_SNOW_COVERAGE_DOWN), SetFill(0, 1),
+ NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_TEXT), SetDataTip(STR_MAPGEN_SNOW_COVERAGE_TEXT, STR_NULL), SetFill(1, 0),
+ NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_SNOW_COVERAGE_UP), SetFill(0, 1),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_DESERT_COVERAGE_DOWN), SetFill(0, 1),
+ NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_TEXT), SetDataTip(STR_MAPGEN_DESERT_COVERAGE_TEXT, STR_NULL), SetFill(1, 0),
+ NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_DESERT_COVERAGE_UP), SetFill(0, 1),
+ EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD), SetFill(0, 1),
@@ -367,6 +388,7 @@ struct GenerateLandscapeWindow : public Window {
case WID_GL_MAPSIZE_Y_PULLDOWN: SetDParam(0, 1LL << _settings_newgame.game_creation.map_y); break;
case WID_GL_MAX_HEIGHTLEVEL_TEXT: SetDParam(0, _settings_newgame.construction.max_heightlevel); break;
case WID_GL_SNOW_COVERAGE_TEXT: SetDParam(0, _settings_newgame.game_creation.snow_coverage); break;
+ case WID_GL_DESERT_COVERAGE_TEXT: SetDParam(0, _settings_newgame.game_creation.desert_coverage); break;
case WID_GL_TOWN_PULLDOWN:
if (_game_mode == GM_EDITOR) {
@@ -458,6 +480,19 @@ struct GenerateLandscapeWindow : public Window {
/* Disable snowline if not arctic */
this->SetWidgetDisabledState(WID_GL_SNOW_COVERAGE_TEXT, _settings_newgame.game_creation.landscape != LT_ARCTIC);
+ /* Disable desert if not tropic */
+ this->SetWidgetDisabledState(WID_GL_DESERT_COVERAGE_TEXT, _settings_newgame.game_creation.landscape != LT_TROPIC);
+
+ /* Set snow/rainforest selections */
+ int climate_plane = 0;
+ switch (_settings_newgame.game_creation.landscape) {
+ case LT_TEMPERATE: climate_plane = SZSP_VERTICAL; break;
+ case LT_ARCTIC: climate_plane = 0; break;
+ case LT_TROPIC: climate_plane = 1; break;
+ case LT_TOYLAND: climate_plane = SZSP_VERTICAL; break;
+ }
+ this->GetWidget<NWidgetStacked>(WID_GL_CLIMATE_SEL_LABEL)->SetDisplayedPlane(climate_plane);
+ this->GetWidget<NWidgetStacked>(WID_GL_CLIMATE_SEL_SELECTOR)->SetDisplayedPlane(climate_plane);
/* Update availability of decreasing / increasing start date and snow level */
this->SetWidgetDisabledState(WID_GL_MAX_HEIGHTLEVEL_DOWN, _settings_newgame.construction.max_heightlevel <= MIN_MAX_HEIGHTLEVEL);
@@ -466,6 +501,8 @@ struct GenerateLandscapeWindow : public Window {
this->SetWidgetDisabledState(WID_GL_START_DATE_UP, _settings_newgame.game_creation.starting_year >= MAX_YEAR);
this->SetWidgetDisabledState(WID_GL_SNOW_COVERAGE_DOWN, _settings_newgame.game_creation.snow_coverage <= 0 || _settings_newgame.game_creation.landscape != LT_ARCTIC);
this->SetWidgetDisabledState(WID_GL_SNOW_COVERAGE_UP, _settings_newgame.game_creation.snow_coverage >= 100 || _settings_newgame.game_creation.landscape != LT_ARCTIC);
+ this->SetWidgetDisabledState(WID_GL_DESERT_COVERAGE_DOWN, _settings_newgame.game_creation.desert_coverage <= 0 || _settings_newgame.game_creation.landscape != LT_TROPIC);
+ this->SetWidgetDisabledState(WID_GL_DESERT_COVERAGE_UP, _settings_newgame.game_creation.desert_coverage >= 100 || _settings_newgame.game_creation.landscape != LT_TROPIC);
/* Do not allow a custom sea level with the original land generator. */
if (_settings_newgame.game_creation.land_generator == LG_ORIGINAL &&
@@ -500,6 +537,11 @@ struct GenerateLandscapeWindow : public Window {
*size = maxdim(*size, GetStringBoundingBox(STR_MAPGEN_SNOW_COVERAGE_TEXT));
break;
+ case WID_GL_DESERT_COVERAGE_TEXT:
+ SetDParamMaxValue(0, MAX_TILE_HEIGHT);
+ *size = maxdim(*size, GetStringBoundingBox(STR_MAPGEN_DESERT_COVERAGE_TEXT));
+ break;
+
case WID_GL_HEIGHTMAP_SIZE_TEXT:
SetDParam(0, this->x);
SetDParam(1, this->y);
@@ -674,6 +716,24 @@ struct GenerateLandscapeWindow : public Window {
ShowQueryString(STR_JUST_INT, STR_MAPGEN_SNOW_COVERAGE_QUERY_CAPT, 4, this, CS_NUMERAL, QSF_ENABLE_DEFAULT);
break;
+ case WID_GL_DESERT_COVERAGE_DOWN:
+ case WID_GL_DESERT_COVERAGE_UP: // Desert coverage buttons
+ /* Don't allow too fast scrolling */
+ if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
+ this->HandleButtonClick(widget);
+
+ _settings_newgame.game_creation.desert_coverage = Clamp(_settings_newgame.game_creation.desert_coverage + (widget - WID_GL_DESERT_COVERAGE_TEXT) * 10, 0, 100);
+ this->InvalidateData();
+ }
+ _left_button_clicked = false;
+ break;
+
+ case WID_GL_DESERT_COVERAGE_TEXT: // Desert line text
+ this->widget_id = WID_GL_DESERT_COVERAGE_TEXT;
+ SetDParam(0, _settings_newgame.game_creation.desert_coverage);
+ ShowQueryString(STR_JUST_INT, STR_MAPGEN_DESERT_COVERAGE_QUERY_CAPT, 4, this, CS_NUMERAL, QSF_ENABLE_DEFAULT);
+ break;
+
case WID_GL_LANDSCAPE_PULLDOWN: // Landscape generator
ShowDropDownMenu(this, _landscape, _settings_newgame.game_creation.land_generator, WID_GL_LANDSCAPE_PULLDOWN, 0, 0);
break;
@@ -739,7 +799,7 @@ struct GenerateLandscapeWindow : public Window {
void OnTimeout() override
{
- static const int raise_widgets[] = {WID_GL_MAX_HEIGHTLEVEL_DOWN, WID_GL_MAX_HEIGHTLEVEL_UP, WID_GL_START_DATE_DOWN, WID_GL_START_DATE_UP, WID_GL_SNOW_COVERAGE_UP, WID_GL_SNOW_COVERAGE_DOWN, WIDGET_LIST_END};
+ static const int raise_widgets[] = {WID_GL_MAX_HEIGHTLEVEL_DOWN, WID_GL_MAX_HEIGHTLEVEL_UP, WID_GL_START_DATE_DOWN, WID_GL_START_DATE_UP, WID_GL_SNOW_COVERAGE_UP, WID_GL_SNOW_COVERAGE_DOWN, WID_GL_DESERT_COVERAGE_UP, WID_GL_DESERT_COVERAGE_DOWN, WIDGET_LIST_END};
for (const int *widget = raise_widgets; *widget != WIDGET_LIST_END; widget++) {
if (this->IsWidgetLowered(*widget)) {
this->RaiseWidget(*widget);
@@ -812,6 +872,7 @@ struct GenerateLandscapeWindow : public Window {
case WID_GL_MAX_HEIGHTLEVEL_TEXT: value = DEF_MAX_HEIGHTLEVEL; break;
case WID_GL_START_DATE_TEXT: value = DEF_START_YEAR; break;
case WID_GL_SNOW_COVERAGE_TEXT: value = DEF_SNOW_COVERAGE; break;
+ case WID_GL_DESERT_COVERAGE_TEXT: value = DEF_DESERT_COVERAGE; break;
case WID_GL_TOWN_PULLDOWN: value = 1; break;
case WID_GL_WATER_PULLDOWN: value = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE; break;
default: NOT_REACHED();
@@ -834,6 +895,11 @@ struct GenerateLandscapeWindow : public Window {
_settings_newgame.game_creation.snow_coverage = Clamp(value, 0, 100);
break;
+ case WID_GL_DESERT_COVERAGE_TEXT:
+ this->SetWidgetDirty(WID_GL_DESERT_COVERAGE_TEXT);
+ _settings_newgame.game_creation.desert_coverage = Clamp(value, 0, 100);
+ break;
+
case WID_GL_TOWN_PULLDOWN:
_settings_newgame.game_creation.custom_town_number = Clamp(value, 1, CUSTOM_TOWN_MAX_NUMBER);
break;
diff --git a/src/landscape.cpp b/src/landscape.cpp
index 98ff6fdbc..bdfcc51f1 100644
--- a/src/landscape.cpp
+++ b/src/landscape.cpp
@@ -968,11 +968,10 @@ static void GenerateTerrain(int type, uint flag)
#include "table/genland.h"
-static void CreateDesertOrRainForest()
+static void CreateDesertOrRainForest(uint desert_tropic_line)
{
TileIndex update_freq = MapSize() / 4;
const TileIndexDiffC *data;
- uint max_desert_height = CeilDiv(_settings_game.construction.max_heightlevel, 4);
for (TileIndex tile = 0; tile != MapSize(); ++tile) {
if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
@@ -982,7 +981,7 @@ static void CreateDesertOrRainForest()
for (data = _make_desert_or_rainforest_data;
data != endof(_make_desert_or_rainforest_data); ++data) {
TileIndex t = AddTileIndexDiffCWrap(tile, *data);
- if (t != INVALID_TILE && (TileHeight(t) >= max_desert_height || IsTileType(t, MP_WATER))) break;
+ if (t != INVALID_TILE && (TileHeight(t) >= desert_tropic_line || IsTileType(t, MP_WATER))) break;
}
if (data == endof(_make_desert_or_rainforest_data)) {
SetTropicZone(tile, TROPICZONE_DESERT);
@@ -1296,15 +1295,50 @@ static void CreateRivers()
}
/**
- * Calculate the line from which snow begins.
+ * Calculate what height would be needed to cover N% of the landmass.
+ *
+ * The function allows both snow and desert/tropic line to be calculated. It
+ * tries to find the closests height which covers N% of the landmass; it can
+ * be below or above it.
+ *
+ * Tropic has a mechanism where water and tropic tiles in mountains grow
+ * inside the desert. To better approximate the requested coverage, this is
+ * taken into account via an edge histogram, which tells how many neighbouring
+ * tiles are lower than the tiles of that height. The multiplier indicates how
+ * severe this has to be taken into account.
+ *
+ * @param coverage A value between 0 and 100 indicating a percentage of landmass that should be covered.
+ * @param edge_multiplier How much effect neighbouring tiles that are of a lower height level have on the score.
+ * @return The estimated best height to use to cover N% of the landmass.
*/
-static void CalculateSnowLine()
+static uint CalculateCoverageLine(uint coverage, uint edge_multiplier)
{
- /* Build a histogram of the map height. */
+ const DiagDirection neighbour_dir[] = {
+ DIAGDIR_NE,
+ DIAGDIR_SE,
+ DIAGDIR_SW,
+ DIAGDIR_NW,
+ };
+
+ /* Histogram of how many tiles per height level exist. */
std::array<int, MAX_TILE_HEIGHT + 1> histogram = {};
+ /* Histogram of how many neighbour tiles are lower than the tiles of the height level. */
+ std::array<int, MAX_TILE_HEIGHT + 1> edge_histogram = {};
+
+ /* Build a histogram of the map height. */
for (TileIndex tile = 0; tile < MapSize(); tile++) {
uint h = TileHeight(tile);
histogram[h]++;
+
+ if (edge_multiplier != 0) {
+ /* Check if any of our neighbours is below us. */
+ for (auto dir : neighbour_dir) {
+ TileIndex neighbour_tile = AddTileIndexDiffCWrap(tile, TileIndexDiffCByDiagDir(dir));
+ if (IsValidTile(neighbour_tile) && TileHeight(neighbour_tile) < h) {
+ edge_histogram[h]++;
+ }
+ }
+ }
}
/* The amount of land we have is the map size minus the first (sea) layer. */
@@ -1312,7 +1346,7 @@ static void CalculateSnowLine()
int best_score = land_tiles;
/* Our goal is the coverage amount of the land-mass. */
- int goal_tiles = land_tiles * _settings_game.game_creation.snow_coverage / 100;
+ int goal_tiles = land_tiles * coverage / 100;
/* We scan from top to bottom. */
uint h = MAX_TILE_HEIGHT;
@@ -1323,13 +1357,50 @@ static void CalculateSnowLine()
current_tiles += histogram[h];
int current_score = goal_tiles - current_tiles;
+ /* Tropic grows from water and mountains into the desert. This is a
+ * great visual, but it also means we* need to take into account how
+ * much less desert tiles are being created if we are on this
+ * height-level. We estimate this based on how many neighbouring
+ * tiles are below us for a given length, assuming that is where
+ * tropic is growing from.
+ */
+ if (edge_multiplier != 0 && h > 1) {
+ /* From water tropic tiles grow for a few tiles land inward. */
+ current_score -= edge_histogram[1] * edge_multiplier;
+ /* Tropic tiles grow into the desert for a few tiles. */
+ current_score -= edge_histogram[h] * edge_multiplier;
+ }
+
if (std::abs(current_score) < std::abs(best_score)) {
best_score = current_score;
best_h = h;
}
+
+ /* Always scan all height-levels, as h == 1 might give a better
+ * score than any before. This is true for example with 0% desert
+ * coverage. */
}
- _settings_game.game_creation.snow_line_height = std::max(best_h, 2u);
+ return best_h;
+}
+
+/**
+ * Calculate the line from which snow begins.
+ */
+static void CalculateSnowLine()
+{
+ /* We do not have snow sprites on coastal tiles, so never allow "1" as height. */
+ _settings_game.game_creation.snow_line_height = std::max(CalculateCoverageLine(_settings_game.game_creation.snow_coverage, 0), 2u);
+}
+
+/**
+ * Calculate the line (in height) between desert and tropic.
+ * @return The height of the line between desert and tropic.
+ */
+static uint8 CalculateDesertLine()
+{
+ /* CalculateCoverageLine() runs from top to bottom, so we need to invert the coverage. */
+ return _settings_game.game_creation.snow_line_height = CalculateCoverageLine(100 - _settings_game.game_creation.desert_coverage, 4);
}
void GenerateLandscape(byte mode)
@@ -1421,9 +1492,11 @@ void GenerateLandscape(byte mode)
CalculateSnowLine();
break;
- case LT_TROPIC:
- CreateDesertOrRainForest();
+ case LT_TROPIC: {
+ uint desert_tropic_line = CalculateDesertLine();
+ CreateDesertOrRainForest(desert_tropic_line);
break;
+ }
default:
break;
diff --git a/src/lang/english.txt b/src/lang/english.txt
index be1d50427..6c01914c0 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -1355,6 +1355,9 @@ STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Controls at wha
STR_CONFIG_SETTING_SNOW_COVERAGE :Snow coverage: {STRING2}
STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT :Controls the approximate amount of snow on the sub-arctic landscape. Snow also affects industry generation and town growth requirements. Only used during map generation. Land just above sea level is always without snow
STR_CONFIG_SETTING_SNOW_COVERAGE_VALUE :{NUM}%
+STR_CONFIG_SETTING_DESERT_COVERAGE :Desert coverage: {STRING2}
+STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT :Control the approximate amount of desert on the tropical landscape. Desert also affects industry generation. Only used during map generation
+STR_CONFIG_SETTING_DESERT_COVERAGE_VALUE :{NUM}%
STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Roughness of terrain: {STRING2}
STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT :(TerraGenesis only) Choose the frequency of hills: Smooth landscapes have fewer, more wide-spread hills. Rough landscapes have many hills, which may look repetitive
STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Very Smooth
@@ -2902,6 +2905,10 @@ STR_MAPGEN_SNOW_COVERAGE :{BLACK}Snow cov
STR_MAPGEN_SNOW_COVERAGE_UP :{BLACK}Increase snow coverage by ten percent
STR_MAPGEN_SNOW_COVERAGE_DOWN :{BLACK}Decrease snow coverage by ten percent
STR_MAPGEN_SNOW_COVERAGE_TEXT :{BLACK}{NUM}%
+STR_MAPGEN_DESERT_COVERAGE :{BLACK}Desert coverage:
+STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Increase desert coverage by ten percent
+STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Decrease desert coverage by ten percent
+STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}%
STR_MAPGEN_LAND_GENERATOR :{BLACK}Land generator:
STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terrain type:
STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Sea level:
@@ -2929,6 +2936,7 @@ STR_MAPGEN_HEIGHTMAP_SIZE :{ORANGE}{NUM} x
STR_MAPGEN_MAX_HEIGHTLEVEL_QUERY_CAPT :{WHITE}Change maximum map height
STR_MAPGEN_SNOW_COVERAGE_QUERY_CAPT :{WHITE}Snow coverage (in %)
+STR_MAPGEN_DESERT_COVERAGE_QUERY_CAPT :{WHITE}Desert coverage (in %)
STR_MAPGEN_START_DATE_QUERY_CAPT :{WHITE}Change starting year
# SE Map generation
diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp
index 884f7cb98..69a5bcf20 100644
--- a/src/settings_gui.cpp
+++ b/src/settings_gui.cpp
@@ -1691,6 +1691,7 @@ static SettingsContainer &GetSettingsTree()
genworld->Add(new SettingEntry("game_creation.variety"));
genworld->Add(new SettingEntry("game_creation.snow_coverage"));
genworld->Add(new SettingEntry("game_creation.snow_line_height"));
+ genworld->Add(new SettingEntry("game_creation.desert_coverage"));
genworld->Add(new SettingEntry("game_creation.amount_of_rivers"));
genworld->Add(new SettingEntry("game_creation.tree_placer"));
genworld->Add(new SettingEntry("vehicle.road_side"));
diff --git a/src/settings_type.h b/src/settings_type.h
index d99201b25..b774ff718 100644
--- a/src/settings_type.h
+++ b/src/settings_type.h
@@ -298,6 +298,7 @@ struct GameCreationSettings {
byte oil_refinery_limit; ///< distance oil refineries allowed from map edge
byte snow_line_height; ///< the configured snow line height (deduced from "snow_coverage")
byte snow_coverage; ///< the amount of snow coverage on the map
+ byte desert_coverage; ///< the amount of desert coverage on the map
byte tgen_smoothness; ///< how rough is the terrain from 0-3
byte tree_placer; ///< the tree placer algorithm
byte heightmap_rotation; ///< rotation director for the heightmap
diff --git a/src/table/settings.ini b/src/table/settings.ini
index 1a7eb12e3..55518ef76 100644
--- a/src/table/settings.ini
+++ b/src/table/settings.ini
@@ -1433,6 +1433,21 @@ strhelp = STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT
strval = STR_CONFIG_SETTING_SNOW_COVERAGE_VALUE
cat = SC_BASIC
+[SDT_VAR]
+base = GameSettings
+var = game_creation.desert_coverage
+type = SLE_UINT8
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+guiflags = SGF_NEWGAME_ONLY
+def = DEF_DESERT_COVERAGE
+min = 0
+max = 100
+interval = 10
+str = STR_CONFIG_SETTING_DESERT_COVERAGE
+strhelp = STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT
+strval = STR_CONFIG_SETTING_DESERT_COVERAGE_VALUE
+cat = SC_BASIC
+
[SDT_NULL]
length = 4
to = SLV_144
diff --git a/src/tgp.cpp b/src/tgp.cpp
index d47cdecac..fabc91e2a 100644
--- a/src/tgp.cpp
+++ b/src/tgp.cpp
@@ -236,17 +236,6 @@ static height_t TGPGetMaxHeight()
int map_size_bucket = std::min(MapLogX(), MapLogY()) - MIN_MAP_SIZE_BITS;
int max_height_from_table = max_height[_settings_game.difficulty.terrain_type][map_size_bucket];
-
- /* Tropic needs tropical forest to have all industries, so make sure we allow TGP to generate this high.
- * Tropic forest always starts at 1/4th of the max height. */
- if (_settings_game.game_creation.landscape == LT_TROPIC) {
- max_height_from_table += CeilDiv(_settings_game.construction.max_heightlevel, 4);
- /* Make flat a bit more flat by removing "very flat" from it, to somewhat compensate for the increase we just did. */
- if (_settings_game.difficulty.terrain_type > 0) {
- max_height_from_table -= max_height[_settings_game.difficulty.terrain_type - 1][map_size_bucket];
- }
- }
-
return I2H(std::min<uint>(max_height_from_table, _settings_game.construction.max_heightlevel));
}
diff --git a/src/tile_type.h b/src/tile_type.h
index e81d2799a..e9fc272a5 100644
--- a/src/tile_type.h
+++ b/src/tile_type.h
@@ -30,6 +30,7 @@ static const uint DEF_SNOWLINE_HEIGHT = 10; ///< Default snow
static const uint MAX_SNOWLINE_HEIGHT = (MAX_TILE_HEIGHT - 2); ///< Maximum allowed snowline height
static const uint DEF_SNOW_COVERAGE = 40; ///< Default snow coverage.
+static const uint DEF_DESERT_COVERAGE = 50; ///< Default desert coverage.
/**
diff --git a/src/widgets/genworld_widget.h b/src/widgets/genworld_widget.h
index 28e2a17a5..dfc7b1a78 100644
--- a/src/widgets/genworld_widget.h
+++ b/src/widgets/genworld_widget.h
@@ -38,6 +38,10 @@ enum GenerateLandscapeWidgets {
WID_GL_SNOW_COVERAGE_TEXT, ///< Snow coverage.
WID_GL_SNOW_COVERAGE_UP, ///< Increase snow coverage.
+ WID_GL_DESERT_COVERAGE_DOWN, ///< Decrease desert coverage.
+ WID_GL_DESERT_COVERAGE_TEXT, ///< Desert coverage.
+ WID_GL_DESERT_COVERAGE_UP, ///< Increase desert coverage.
+
WID_GL_LANDSCAPE_PULLDOWN, ///< Dropdown 'Land generator'.
WID_GL_HEIGHTMAP_NAME_TEXT, ///< Heightmap name.
@@ -55,6 +59,9 @@ enum GenerateLandscapeWidgets {
WID_GL_WATER_NE, ///< NE 'Water'/'Freeform'.
WID_GL_WATER_SE, ///< SE 'Water'/'Freeform'.
WID_GL_WATER_SW, ///< SW 'Water'/'Freeform'.
+
+ WID_GL_CLIMATE_SEL_LABEL, ///< NWID_SELECTION for snow or desert coverage label
+ WID_GL_CLIMATE_SEL_SELECTOR, ///< NWID_SELECTION for snow or desert coverage selector
};
/** Widgets of the #CreateScenarioWindow class. */