mirror of
https://github.com/OpenTTD/OpenTTD
synced 2026-01-18 09:52:44 +01:00
Feature: Add worldgen setting for average height (#14989)
This commit is contained in:
@@ -97,6 +97,7 @@ static constexpr std::initializer_list<NWidgetPart> _nested_generate_landscape_w
|
||||
NWidget(NWID_VERTICAL, NWidContainerFlag::EqualSize), SetPIP(0, WidgetDimensions::unscaled.vsep_sparse, 0),
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_MAPSIZE, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_TERRAIN_TYPE, STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT), SetFill(1, 1),
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_AVERAGE_HEIGHT, STR_CONFIG_SETTING_AVERAGE_HEIGHT_HELPTEXT), SetFill(1, 1),
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_VARIETY, STR_CONFIG_SETTING_VARIETY_HELPTEXT), SetFill(1, 1),
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_SMOOTHNESS, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT), SetFill(1, 1),
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT), SetFill(1, 1),
|
||||
@@ -111,7 +112,8 @@ static constexpr std::initializer_list<NWidgetPart> _nested_generate_landscape_w
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_BY), SetFill(0, 1), SetAlignment(SA_CENTER),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetToolTip(STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
|
||||
EndContainer(),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TERRAIN_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT), SetFill(1, 1),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAX_HEIGHT_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT), SetFill(1, 1),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_AVERAGE_HEIGHT_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_AVERAGE_HEIGHT_HELPTEXT), SetFill(1, 1),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_VARIETY_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_VARIETY_HELPTEXT), SetFill(1, 1),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_SMOOTHNESS_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT), SetFill(1, 1),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT), SetFill(1, 1),
|
||||
@@ -133,6 +135,8 @@ static constexpr std::initializer_list<NWidgetPart> _nested_generate_landscape_w
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_MAPGEN_NUMBER_OF_TOWNS_TOOLTIP), SetFill(1, 1),
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_MAPGEN_NUMBER_OF_INDUSTRIES_TOOLTIP), SetFill(1, 1),
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_SEA_LEVEL, STR_MAPGEN_SEA_LEVEL_TOOLTIP), SetFill(1, 1),
|
||||
/* Spacer due to fewer items in columns 3-4 than in 1-2. */
|
||||
NWidget(NWID_SPACER), SetFill(1, 1),
|
||||
EndContainer(),
|
||||
|
||||
/* Widgets on the right side (global column 4). */
|
||||
@@ -164,6 +168,8 @@ static constexpr std::initializer_list<NWidgetPart> _nested_generate_landscape_w
|
||||
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetToolTip(STR_MAPGEN_NUMBER_OF_TOWNS_TOOLTIP), SetFill(1, 1),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetToolTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES_TOOLTIP), SetFill(1, 1),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_WATER_PULLDOWN), SetToolTip(STR_MAPGEN_SEA_LEVEL_TOOLTIP), SetFill(1, 1),
|
||||
/* Spacer due to fewer items in columns 3-4 than in 1-2. */
|
||||
NWidget(NWID_SPACER), SetFill(1, 1),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
@@ -376,7 +382,7 @@ static DropDownList BuildTownNameDropDown()
|
||||
}
|
||||
|
||||
|
||||
static const StringID _elevations[] = {STR_TERRAIN_TYPE_VERY_FLAT, STR_TERRAIN_TYPE_FLAT, STR_TERRAIN_TYPE_HILLY, STR_TERRAIN_TYPE_MOUNTAINOUS, STR_TERRAIN_TYPE_ALPINIST, STR_TERRAIN_TYPE_CUSTOM};
|
||||
static const StringID _max_height[] = {STR_TERRAIN_TYPE_VERY_FLAT, STR_TERRAIN_TYPE_FLAT, STR_TERRAIN_TYPE_HILLY, STR_TERRAIN_TYPE_MOUNTAINOUS, STR_TERRAIN_TYPE_ALPINIST, STR_TERRAIN_TYPE_CUSTOM};
|
||||
static const StringID _sea_lakes[] = {STR_SEA_LEVEL_VERY_LOW, STR_SEA_LEVEL_LOW, STR_SEA_LEVEL_MEDIUM, STR_SEA_LEVEL_HIGH, STR_SEA_LEVEL_CUSTOM};
|
||||
static const StringID _rivers[] = {STR_RIVERS_NONE, STR_RIVERS_FEW, STR_RIVERS_MODERATE, STR_RIVERS_LOT};
|
||||
static const StringID _borders[] = {STR_MAPGEN_BORDER_RANDOMIZE, STR_MAPGEN_BORDER_MANUAL, STR_MAPGEN_BORDER_INFINITE_WATER};
|
||||
@@ -385,6 +391,7 @@ static const StringID _rotation[] = {STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_CO
|
||||
static const StringID _num_towns[] = {STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, STR_NUM_CUSTOM};
|
||||
static const StringID _num_inds[] = {STR_FUNDING_ONLY, STR_MINIMAL, STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, STR_NUM_CUSTOM};
|
||||
static const StringID _variety[] = {STR_VARIETY_NONE, STR_VARIETY_VERY_LOW, STR_VARIETY_LOW, STR_VARIETY_MEDIUM, STR_VARIETY_HIGH, STR_VARIETY_VERY_HIGH};
|
||||
static const StringID _average_height[] = {STR_CONFIG_SETTING_AVERAGE_HEIGHT_AUTO, STR_CONFIG_SETTING_AVERAGE_HEIGHT_LOWLANDS, STR_CONFIG_SETTING_AVERAGE_HEIGHT_NORMAL, STR_CONFIG_SETTING_AVERAGE_HEIGHT_PLATEAUS};
|
||||
|
||||
static_assert(std::size(_num_inds) == ID_END);
|
||||
|
||||
@@ -413,7 +420,7 @@ struct GenerateLandscapeWindow : public Window {
|
||||
|
||||
/* If original landgenerator is selected and alpinist terrain_type was selected, revert to mountainous. */
|
||||
if (_settings_newgame.game_creation.land_generator == LG_ORIGINAL) {
|
||||
_settings_newgame.difficulty.terrain_type = Clamp(_settings_newgame.difficulty.terrain_type, TT_VERY_FLAT, TT_MOUNTAINOUS);
|
||||
_settings_newgame.difficulty.terrain_type = Clamp(_settings_newgame.difficulty.terrain_type, GenworldMaxHeight::VeryFlat, GenworldMaxHeight::Mountainous);
|
||||
}
|
||||
|
||||
this->OnInvalidateData();
|
||||
@@ -456,11 +463,11 @@ struct GenerateLandscapeWindow : public Window {
|
||||
}
|
||||
return GetString(_num_inds[_settings_newgame.difficulty.industry_density]);
|
||||
|
||||
case WID_GL_TERRAIN_PULLDOWN:
|
||||
if (_settings_newgame.difficulty.terrain_type == TT_CUSTOM) {
|
||||
case WID_GL_MAX_HEIGHT_PULLDOWN:
|
||||
if (_settings_newgame.difficulty.terrain_type == GenworldMaxHeight::Custom) {
|
||||
return GetString(STR_TERRAIN_TYPE_CUSTOM_VALUE, _settings_newgame.game_creation.custom_terrain_type);
|
||||
}
|
||||
return GetString(_elevations[_settings_newgame.difficulty.terrain_type]);
|
||||
return GetString(_max_height[to_underlying(_settings_newgame.difficulty.terrain_type)]);
|
||||
|
||||
case WID_GL_WATER_PULLDOWN:
|
||||
if (_settings_newgame.difficulty.quantity_sea_lakes == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) {
|
||||
@@ -472,6 +479,7 @@ struct GenerateLandscapeWindow : public Window {
|
||||
case WID_GL_RIVER_PULLDOWN: return GetString(_rivers[_settings_newgame.game_creation.amount_of_rivers]);
|
||||
case WID_GL_SMOOTHNESS_PULLDOWN: return GetString(_smoothness[_settings_newgame.game_creation.tgen_smoothness]);
|
||||
case WID_GL_VARIETY_PULLDOWN: return GetString(_variety[_settings_newgame.game_creation.variety]);
|
||||
case WID_GL_AVERAGE_HEIGHT_PULLDOWN: return GetString(_average_height[to_underlying(_settings_newgame.game_creation.average_height)]);
|
||||
case WID_GL_BORDERS_PULLDOWN: return GetString(_borders[_settings_newgame.game_creation.water_border_presets]);
|
||||
case WID_GL_WATER_NE: return GetString((_settings_newgame.game_creation.water_borders == BorderFlag::Random) ? STR_MAPGEN_BORDER_RANDOM : _settings_newgame.game_creation.water_borders.Test(BorderFlag::NorthEast) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM);
|
||||
case WID_GL_WATER_NW: return GetString((_settings_newgame.game_creation.water_borders == BorderFlag::Random) ? STR_MAPGEN_BORDER_RANDOM : _settings_newgame.game_creation.water_borders.Test(BorderFlag::NorthWest) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM);
|
||||
@@ -518,7 +526,7 @@ struct GenerateLandscapeWindow : public Window {
|
||||
this->SetWidgetLoweredState(WID_GL_WATER_SW, _settings_newgame.game_creation.water_borders.Test(BorderFlag::SouthWest));
|
||||
|
||||
this->SetWidgetsDisabledState(_settings_newgame.game_creation.land_generator == LG_ORIGINAL && (_settings_newgame.game_creation.landscape == LandscapeType::Arctic || _settings_newgame.game_creation.landscape == LandscapeType::Tropic),
|
||||
WID_GL_TERRAIN_PULLDOWN, WID_GL_WATER_PULLDOWN);
|
||||
WID_GL_MAX_HEIGHT_PULLDOWN, WID_GL_WATER_PULLDOWN);
|
||||
}
|
||||
|
||||
/* Disable snowline if not arctic */
|
||||
@@ -554,8 +562,8 @@ struct GenerateLandscapeWindow : public Window {
|
||||
if (_settings_newgame.difficulty.quantity_sea_lakes == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) {
|
||||
_settings_newgame.difficulty.quantity_sea_lakes = 1;
|
||||
}
|
||||
if (_settings_newgame.difficulty.terrain_type == TT_CUSTOM) {
|
||||
_settings_newgame.difficulty.terrain_type = TT_FLAT;
|
||||
if (_settings_newgame.difficulty.terrain_type == GenworldMaxHeight::Custom) {
|
||||
_settings_newgame.difficulty.terrain_type = GenworldMaxHeight::Flat;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -607,8 +615,8 @@ struct GenerateLandscapeWindow : public Window {
|
||||
d = GetStringBoundingBox(GetString(STR_NUM_CUSTOM_NUMBER, GetParamMaxValue(IndustryPool::MAX_SIZE)));
|
||||
break;
|
||||
|
||||
case WID_GL_TERRAIN_PULLDOWN:
|
||||
strs = _elevations;
|
||||
case WID_GL_MAX_HEIGHT_PULLDOWN:
|
||||
strs = _max_height;
|
||||
d = GetStringBoundingBox(GetString(STR_TERRAIN_TYPE_CUSTOM_VALUE, GetParamMaxValue(MAX_MAP_HEIGHT_LIMIT)));
|
||||
break;
|
||||
|
||||
@@ -619,6 +627,7 @@ struct GenerateLandscapeWindow : public Window {
|
||||
|
||||
case WID_GL_RIVER_PULLDOWN: strs = _rivers; break;
|
||||
case WID_GL_SMOOTHNESS_PULLDOWN: strs = _smoothness; break;
|
||||
case WID_GL_AVERAGE_HEIGHT_PULLDOWN: strs = _variety; break;
|
||||
case WID_GL_VARIETY_PULLDOWN: strs = _variety; break;
|
||||
case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: strs = _rotation; break;
|
||||
case WID_GL_BORDERS_PULLDOWN: strs = _borders; break;
|
||||
@@ -776,9 +785,9 @@ struct GenerateLandscapeWindow : public Window {
|
||||
ShowDropDownMenu(this, _rotation, _settings_newgame.game_creation.heightmap_rotation, WID_GL_HEIGHTMAP_ROTATION_PULLDOWN, 0, 0);
|
||||
break;
|
||||
|
||||
case WID_GL_TERRAIN_PULLDOWN: // Terrain type
|
||||
case WID_GL_MAX_HEIGHT_PULLDOWN: // Max height
|
||||
/* For the original map generation only the first four are valid. */
|
||||
ShowDropDownMenu(this, _elevations, _settings_newgame.difficulty.terrain_type, WID_GL_TERRAIN_PULLDOWN, 0, _settings_newgame.game_creation.land_generator == LG_ORIGINAL ? ~0xF : 0);
|
||||
ShowDropDownMenu(this, _max_height, to_underlying(_settings_newgame.difficulty.terrain_type), WID_GL_MAX_HEIGHT_PULLDOWN, 0, _settings_newgame.game_creation.land_generator == LG_ORIGINAL ? ~0xF : 0);
|
||||
break;
|
||||
|
||||
case WID_GL_WATER_PULLDOWN: { // Water quantity
|
||||
@@ -803,6 +812,10 @@ struct GenerateLandscapeWindow : public Window {
|
||||
ShowDropDownMenu(this, _variety, _settings_newgame.game_creation.variety, WID_GL_VARIETY_PULLDOWN, 0, 0);
|
||||
break;
|
||||
|
||||
case WID_GL_AVERAGE_HEIGHT_PULLDOWN: // Average height
|
||||
ShowDropDownMenu(this, _average_height, to_underlying(_settings_newgame.game_creation.average_height), WID_GL_AVERAGE_HEIGHT_PULLDOWN, 0, 0);
|
||||
break;
|
||||
|
||||
/* Map borders */
|
||||
case WID_GL_BORDERS_PULLDOWN:
|
||||
ShowDropDownMenu(this, _borders, _settings_newgame.game_creation.water_border_presets, WID_GL_BORDERS_PULLDOWN, 0, 0);
|
||||
@@ -863,6 +876,7 @@ struct GenerateLandscapeWindow : public Window {
|
||||
case WID_GL_RIVER_PULLDOWN: _settings_newgame.game_creation.amount_of_rivers = index; break;
|
||||
case WID_GL_SMOOTHNESS_PULLDOWN: _settings_newgame.game_creation.tgen_smoothness = index; break;
|
||||
case WID_GL_VARIETY_PULLDOWN: _settings_newgame.game_creation.variety = index; break;
|
||||
case WID_GL_AVERAGE_HEIGHT_PULLDOWN: _settings_newgame.game_creation.average_height = static_cast<GenworldAverageHeight>(index); break;
|
||||
|
||||
case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: _settings_newgame.game_creation.heightmap_rotation = index; break;
|
||||
|
||||
@@ -889,12 +903,12 @@ struct GenerateLandscapeWindow : public Window {
|
||||
_settings_newgame.difficulty.industry_density = index;
|
||||
break;
|
||||
|
||||
case WID_GL_TERRAIN_PULLDOWN: {
|
||||
if ((uint)index == TT_CUSTOM) {
|
||||
case WID_GL_MAX_HEIGHT_PULLDOWN: {
|
||||
if (static_cast<GenworldMaxHeight>(index) == GenworldMaxHeight::Custom) {
|
||||
this->widget_id = widget;
|
||||
ShowQueryString(GetString(STR_JUST_INT, _settings_newgame.game_creation.custom_terrain_type), STR_MAPGEN_TERRAIN_TYPE_QUERY_CAPT, 4, this, CS_NUMERAL, {});
|
||||
}
|
||||
_settings_newgame.difficulty.terrain_type = static_cast<TerrainType>(index);
|
||||
_settings_newgame.difficulty.terrain_type = static_cast<GenworldMaxHeight>(index);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -948,7 +962,7 @@ struct GenerateLandscapeWindow : public Window {
|
||||
case WID_GL_DESERT_COVERAGE_TEXT: value = DEF_DESERT_COVERAGE; break;
|
||||
case WID_GL_TOWN_PULLDOWN: value = 1; break;
|
||||
case WID_GL_INDUSTRY_PULLDOWN: value = 1; break;
|
||||
case WID_GL_TERRAIN_PULLDOWN: value = MIN_MAP_HEIGHT_LIMIT; break;
|
||||
case WID_GL_MAX_HEIGHT_PULLDOWN: value = MIN_MAP_HEIGHT_LIMIT; break;
|
||||
case WID_GL_WATER_PULLDOWN: value = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE; break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
@@ -983,7 +997,7 @@ struct GenerateLandscapeWindow : public Window {
|
||||
_settings_newgame.game_creation.custom_industry_number = Clamp(value, 1, IndustryPool::MAX_SIZE);
|
||||
break;
|
||||
|
||||
case WID_GL_TERRAIN_PULLDOWN:
|
||||
case WID_GL_MAX_HEIGHT_PULLDOWN:
|
||||
_settings_newgame.game_creation.custom_terrain_type = Clamp(value, MIN_CUSTOM_TERRAIN_TYPE, GetMapHeightLimit());
|
||||
break;
|
||||
|
||||
|
||||
@@ -1034,7 +1034,7 @@ static bool FindSpring(TileIndex tile)
|
||||
uint required_num_hills = 3;
|
||||
|
||||
/* If we don't have many hills, loosen the standards so we still get rivers. */
|
||||
if (_settings_game.difficulty.terrain_type < TT_HILLY) {
|
||||
if (_settings_game.difficulty.terrain_type < GenworldMaxHeight::Hilly) {
|
||||
max_hill_distance = 3;
|
||||
required_num_hills = 1;
|
||||
};
|
||||
@@ -1676,7 +1676,7 @@ bool GenerateLandscape(uint8_t mode)
|
||||
uint i = Map::ScaleBySize(GB(r, 0, 7) + (3 - _settings_game.difficulty.quantity_sea_lakes) * 256 + 100);
|
||||
for (; i != 0; --i) {
|
||||
/* Make sure we do not overflow. */
|
||||
GenerateTerrain(Clamp(_settings_game.difficulty.terrain_type, TT_VERY_FLAT, TT_MOUNTAINOUS), 0);
|
||||
GenerateTerrain(static_cast<int>(Clamp(_settings_game.difficulty.terrain_type, GenworldMaxHeight::VeryFlat, GenworldMaxHeight::Mountainous)), 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1598,7 +1598,7 @@ STR_CONFIG_SETTING_LAND_GENERATOR_HELPTEXT :The original ge
|
||||
STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL :Original
|
||||
STR_CONFIG_SETTING_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
|
||||
|
||||
STR_CONFIG_SETTING_TERRAIN_TYPE :Terrain type: {STRING2}
|
||||
STR_CONFIG_SETTING_TERRAIN_TYPE :Maximum height preset: {STRING2}
|
||||
STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :Choose the height of hills and mountains of the landscape
|
||||
|
||||
STR_CONFIG_SETTING_INDUSTRY_DENSITY :Industry density: {STRING2}
|
||||
@@ -1626,6 +1626,14 @@ STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_SMOOTH :Smooth
|
||||
STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_ROUGH :Rough
|
||||
STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Very Rough
|
||||
|
||||
STR_CONFIG_SETTING_AVERAGE_HEIGHT :Average height: {STRING2}
|
||||
STR_CONFIG_SETTING_AVERAGE_HEIGHT_HELPTEXT :Choose the average height of land. 'Automatic' uses the default based on the selected climate: 'Lowlands' for Subtropical, 'Normal' for Temperate and Toyland, and 'Plateaus' for Subarctic.
|
||||
###length 4
|
||||
STR_CONFIG_SETTING_AVERAGE_HEIGHT_AUTO :Automatic
|
||||
STR_CONFIG_SETTING_AVERAGE_HEIGHT_LOWLANDS :Lowlands
|
||||
STR_CONFIG_SETTING_AVERAGE_HEIGHT_NORMAL :Normal
|
||||
STR_CONFIG_SETTING_AVERAGE_HEIGHT_PLATEAUS :Plateaus
|
||||
|
||||
STR_CONFIG_SETTING_VARIETY :Variety distribution: {STRING2}
|
||||
STR_CONFIG_SETTING_VARIETY_HELPTEXT :Choose if the map contains both mountains and flat areas. The higher the variety, the more differences in elevation between mountainous and flat areas
|
||||
|
||||
@@ -3386,7 +3394,8 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Desert c
|
||||
STR_MAPGEN_DESERT_COVERAGE_UP_TOOLTIP :{BLACK}Increase desert coverage by ten percent
|
||||
STR_MAPGEN_DESERT_COVERAGE_DOWN_TOOLTIP :{BLACK}Decrease desert coverage by ten percent
|
||||
STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}%
|
||||
STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terrain type:
|
||||
STR_MAPGEN_TERRAIN_TYPE :{BLACK}Maximum height:
|
||||
STR_MAPGEN_AVERAGE_HEIGHT :{BLACK}Average height:
|
||||
STR_MAPGEN_SEA_LEVEL :{BLACK}Sea level:
|
||||
STR_MAPGEN_SEA_LEVEL_TOOLTIP :{BLACK}Select the sea level
|
||||
STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Rivers:
|
||||
|
||||
@@ -841,6 +841,7 @@ SettingsContainer &GetSettingsTree()
|
||||
genworld->Add(new SettingEntry("game_creation.landscape"));
|
||||
genworld->Add(new SettingEntry("game_creation.land_generator"));
|
||||
genworld->Add(new SettingEntry("difficulty.terrain_type"));
|
||||
genworld->Add(new SettingEntry("game_creation.average_height"));
|
||||
genworld->Add(new SettingEntry("game_creation.tgen_smoothness"));
|
||||
genworld->Add(new SettingEntry("game_creation.variety"));
|
||||
genworld->Add(new SettingEntry("game_creation.snow_coverage"));
|
||||
|
||||
@@ -51,16 +51,6 @@ enum SettingsProfile : uint8_t {
|
||||
SP_HIGHSCORE_END, ///< End of highscore tables.
|
||||
};
|
||||
|
||||
/** Available terrain types (heights). */
|
||||
enum TerrainType : uint8_t {
|
||||
TT_VERY_FLAT,
|
||||
TT_FLAT,
|
||||
TT_HILLY,
|
||||
TT_MOUNTAINOUS,
|
||||
TT_ALPINIST,
|
||||
TT_CUSTOM,
|
||||
};
|
||||
|
||||
/** Available industry map generation densities. */
|
||||
enum IndustryDensity : uint8_t {
|
||||
ID_FUND_ONLY, ///< The game does not build industries.
|
||||
@@ -75,6 +65,24 @@ enum IndustryDensity : uint8_t {
|
||||
ID_END, ///< Number of industry density settings.
|
||||
};
|
||||
|
||||
/** Possible options for the Maximum Height pulldown in the Genworld GUI. */
|
||||
enum class GenworldMaxHeight : uint8_t {
|
||||
VeryFlat,
|
||||
Flat,
|
||||
Hilly,
|
||||
Mountainous,
|
||||
Alpinist,
|
||||
Custom,
|
||||
};
|
||||
|
||||
/** Possible options for the Average Height pulldown in the Genworld GUI. */
|
||||
enum class GenworldAverageHeight : uint8_t {
|
||||
Auto,
|
||||
Lowlands,
|
||||
Normal,
|
||||
Plateaus,
|
||||
};
|
||||
|
||||
/** Possible options for the Borders pulldown in the Genworld GUI. */
|
||||
enum BorderFlagPresets : uint8_t {
|
||||
BFP_RANDOM = 0,
|
||||
@@ -151,7 +159,7 @@ struct DifficultySettings {
|
||||
uint8_t subsidy_multiplier; ///< payment multiplier for subsidized deliveries
|
||||
uint16_t subsidy_duration; ///< duration of subsidies
|
||||
uint8_t construction_cost; ///< how expensive is building
|
||||
TerrainType terrain_type; ///< the mountainousness of the landscape
|
||||
GenworldMaxHeight terrain_type; ///< the mountainousness of the landscape
|
||||
uint8_t quantity_sea_lakes; ///< the amount of seas/lakes
|
||||
bool economy; ///< how volatile is the economy
|
||||
bool line_reverse_mode; ///< reversing at stations or not
|
||||
@@ -415,6 +423,7 @@ struct GameCreationSettings {
|
||||
uint16_t custom_town_number; ///< manually entered number of towns
|
||||
uint16_t custom_industry_number; ///< manually entered number of industries
|
||||
uint8_t variety; ///< variety level applied to TGP
|
||||
GenworldAverageHeight average_height; ///< adjustment applied to TGP based on climate, or manually set by the player.
|
||||
uint8_t custom_terrain_type; ///< manually entered height for TGP to aim for
|
||||
uint8_t custom_sea_level; ///< manually entered percentage of water in the map
|
||||
uint8_t min_river_length; ///< the minimum river length
|
||||
|
||||
@@ -231,9 +231,9 @@ var = difficulty.terrain_type
|
||||
type = SLE_UINT8
|
||||
from = SLV_97
|
||||
flags = SettingFlag::GuiDropdown, SettingFlag::NewgameOnly
|
||||
def = TT_FLAT
|
||||
min = TT_VERY_FLAT
|
||||
max = TT_CUSTOM
|
||||
def = GenworldMaxHeight::Flat
|
||||
min = GenworldMaxHeight::VeryFlat
|
||||
max = GenworldMaxHeight::Custom
|
||||
str = STR_CONFIG_SETTING_TERRAIN_TYPE
|
||||
strhelp = STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT
|
||||
strval = STR_TERRAIN_TYPE_VERY_FLAT
|
||||
|
||||
@@ -185,6 +185,18 @@ strhelp = STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT
|
||||
strval = STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH
|
||||
cat = SC_BASIC
|
||||
|
||||
[SDT_VAR]
|
||||
var = game_creation.average_height
|
||||
type = SLE_UINT8
|
||||
flags = SettingFlag::GuiDropdown, SettingFlag::NewgameOnly
|
||||
def = GenworldAverageHeight::Auto
|
||||
min = GenworldAverageHeight::Auto
|
||||
max = GenworldAverageHeight::Plateaus
|
||||
str = STR_CONFIG_SETTING_AVERAGE_HEIGHT
|
||||
strhelp = STR_CONFIG_SETTING_AVERAGE_HEIGHT_HELPTEXT
|
||||
strval = STR_CONFIG_SETTING_AVERAGE_HEIGHT_AUTO
|
||||
cat = SC_BASIC
|
||||
|
||||
[SDT_VAR]
|
||||
var = game_creation.variety
|
||||
type = SLE_UINT8
|
||||
|
||||
148
src/tgp.cpp
148
src/tgp.cpp
@@ -215,7 +215,7 @@ static const int64_t _water_percent[4] = {70, 170, 270, 420};
|
||||
*/
|
||||
static Height TGPGetMaxHeight()
|
||||
{
|
||||
if (_settings_game.difficulty.terrain_type == TT_CUSTOM) {
|
||||
if (_settings_game.difficulty.terrain_type == GenworldMaxHeight::Custom) {
|
||||
/* TGP never reaches this height; this means that if a user inputs "2",
|
||||
* it would create a flat map without the "+ 1". But that would
|
||||
* overflow on "255". So we reduce it by 1 to get back in range. */
|
||||
@@ -242,7 +242,7 @@ static Height TGPGetMaxHeight()
|
||||
};
|
||||
|
||||
int map_size_bucket = std::min(Map::LogX(), Map::LogY()) - MIN_MAP_SIZE_BITS;
|
||||
int max_height_from_table = max_height[_settings_game.difficulty.terrain_type][map_size_bucket];
|
||||
int max_height_from_table = max_height[to_underlying(_settings_game.difficulty.terrain_type)][map_size_bucket];
|
||||
|
||||
/* If there is a manual map height limit, clamp to it. */
|
||||
if (_settings_game.construction.map_height_limit != 0) {
|
||||
@@ -455,6 +455,81 @@ static int *HeightMapMakeHistogram(Height h_min, [[maybe_unused]] Height h_max,
|
||||
return hist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the landscape to create lowlands on average (tropic landscape).
|
||||
* @param fheight The height to adjust.
|
||||
* @return The adjusted height.
|
||||
*/
|
||||
static double SineTransformLowlands(double fheight)
|
||||
{
|
||||
double height = fheight;
|
||||
|
||||
/* Half of tiles should be at lowest (0..25%) heights */
|
||||
double sine_lower_limit = 0.5;
|
||||
double linear_compression = 2;
|
||||
if (height <= sine_lower_limit) {
|
||||
/* Under the limit we do linear compression down */
|
||||
height = height / linear_compression;
|
||||
} else {
|
||||
double m = sine_lower_limit / linear_compression;
|
||||
/* Get sine_lower_limit..1 into -1..1 */
|
||||
height = 2.0 * ((height - sine_lower_limit) / (1.0 - sine_lower_limit)) - 1.0;
|
||||
/* Sine wave transform */
|
||||
height = sin(height * M_PI_2);
|
||||
/* Get -1..1 back to (sine_lower_limit / linear_compression)..1.0 */
|
||||
height = 0.5 * ((1.0 - m) * height + (1.0 + m));
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the landscape to create normal average height (temperate and toyland landscapes).
|
||||
* @param fheight The height to adjust.
|
||||
* @return The adjusted height.
|
||||
*/
|
||||
static double SineTransformNormal(double &fheight)
|
||||
{
|
||||
double height = fheight;
|
||||
|
||||
/* Move and scale 0..1 into -1..+1 */
|
||||
height = 2 * height - 1;
|
||||
/* Sine transform */
|
||||
height = sin(height * M_PI_2);
|
||||
/* Transform it back from -1..1 into 0..1 space */
|
||||
height = 0.5 * (height + 1);
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the landscape to create plateaus on average (arctic landscape).
|
||||
* @param fheight The height to adjust.
|
||||
* @return The adjusted height.
|
||||
*/
|
||||
static double SineTransformPlateaus(double &fheight)
|
||||
{
|
||||
double height = fheight;
|
||||
|
||||
/* Redistribute heights to have more tiles at highest (75%..100%) range */
|
||||
double sine_upper_limit = 0.75;
|
||||
double linear_compression = 2;
|
||||
if (height >= sine_upper_limit) {
|
||||
/* Over the limit we do linear compression up */
|
||||
height = 1.0 - (1.0 - height) / linear_compression;
|
||||
} else {
|
||||
double m = 1.0 - (1.0 - sine_upper_limit) / linear_compression;
|
||||
/* Get 0..sine_upper_limit into -1..1 */
|
||||
height = 2.0 * height / sine_upper_limit - 1.0;
|
||||
/* Sine wave transform */
|
||||
height = sin(height * M_PI_2);
|
||||
/* Get -1..1 back to 0..(1 - (1 - sine_upper_limit) / linear_compression) == 0.0..m */
|
||||
height = 0.5 * (height + 1.0) * m;
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/** Applies sine wave redistribution onto height map */
|
||||
static void HeightMapSineTransform(Height h_min, Height h_max)
|
||||
{
|
||||
@@ -465,66 +540,27 @@ static void HeightMapSineTransform(Height h_min, Height h_max)
|
||||
|
||||
/* Transform height into 0..1 space */
|
||||
fheight = (double)(h - h_min) / (double)(h_max - h_min);
|
||||
/* Apply sine transform depending on landscape type */
|
||||
switch (_settings_game.game_creation.landscape) {
|
||||
case LandscapeType::Toyland:
|
||||
case LandscapeType::Temperate:
|
||||
/* Move and scale 0..1 into -1..+1 */
|
||||
fheight = 2 * fheight - 1;
|
||||
/* Sine transform */
|
||||
fheight = sin(fheight * M_PI_2);
|
||||
/* Transform it back from -1..1 into 0..1 space */
|
||||
fheight = 0.5 * (fheight + 1);
|
||||
break;
|
||||
|
||||
case LandscapeType::Arctic:
|
||||
{
|
||||
/* Arctic terrain needs special height distribution.
|
||||
* Redistribute heights to have more tiles at highest (75%..100%) range */
|
||||
double sine_upper_limit = 0.75;
|
||||
double linear_compression = 2;
|
||||
if (fheight >= sine_upper_limit) {
|
||||
/* Over the limit we do linear compression up */
|
||||
fheight = 1.0 - (1.0 - fheight) / linear_compression;
|
||||
} else {
|
||||
double m = 1.0 - (1.0 - sine_upper_limit) / linear_compression;
|
||||
/* Get 0..sine_upper_limit into -1..1 */
|
||||
fheight = 2.0 * fheight / sine_upper_limit - 1.0;
|
||||
/* Sine wave transform */
|
||||
fheight = sin(fheight * M_PI_2);
|
||||
/* Get -1..1 back to 0..(1 - (1 - sine_upper_limit) / linear_compression) == 0.0..m */
|
||||
fheight = 0.5 * (fheight + 1.0) * m;
|
||||
}
|
||||
switch (_settings_game.game_creation.average_height) {
|
||||
case GenworldAverageHeight::Auto:
|
||||
/* Apply sine transform depending on landscape type */
|
||||
switch (_settings_game.game_creation.landscape) {
|
||||
case LandscapeType::Temperate: fheight = SineTransformNormal(fheight); break;
|
||||
case LandscapeType::Tropic: fheight = SineTransformLowlands(fheight); break;
|
||||
case LandscapeType::Arctic: fheight = SineTransformPlateaus(fheight); break;
|
||||
case LandscapeType::Toyland: fheight = SineTransformNormal(fheight); break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
break;
|
||||
|
||||
case LandscapeType::Tropic:
|
||||
{
|
||||
/* Desert terrain needs special height distribution.
|
||||
* Half of tiles should be at lowest (0..25%) heights */
|
||||
double sine_lower_limit = 0.5;
|
||||
double linear_compression = 2;
|
||||
if (fheight <= sine_lower_limit) {
|
||||
/* Under the limit we do linear compression down */
|
||||
fheight = fheight / linear_compression;
|
||||
} else {
|
||||
double m = sine_lower_limit / linear_compression;
|
||||
/* Get sine_lower_limit..1 into -1..1 */
|
||||
fheight = 2.0 * ((fheight - sine_lower_limit) / (1.0 - sine_lower_limit)) - 1.0;
|
||||
/* Sine wave transform */
|
||||
fheight = sin(fheight * M_PI_2);
|
||||
/* Get -1..1 back to (sine_lower_limit / linear_compression)..1.0 */
|
||||
fheight = 0.5 * ((1.0 - m) * fheight + (1.0 + m));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
break;
|
||||
case GenworldAverageHeight::Lowlands: fheight = SineTransformLowlands(fheight); break;
|
||||
case GenworldAverageHeight::Normal: fheight = SineTransformNormal(fheight); break;
|
||||
case GenworldAverageHeight::Plateaus: fheight = SineTransformPlateaus(fheight); break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
/* Transform it back into h_min..h_max space */
|
||||
h = (Height)(fheight * (h_max - h_min) + h_min);
|
||||
h = static_cast<Height>(fheight * (h_max - h_min) + h_min);
|
||||
if (h < 0) h = I2H(0);
|
||||
if (h >= h_max) h = h_max - 1;
|
||||
}
|
||||
|
||||
@@ -48,11 +48,12 @@ enum GenerateLandscapeWidgets : WidgetID {
|
||||
WID_GL_HEIGHTMAP_SIZE_TEXT, ///< Size of heightmap.
|
||||
WID_GL_HEIGHTMAP_ROTATION_PULLDOWN, ///< Dropdown 'Heightmap rotation'.
|
||||
|
||||
WID_GL_TERRAIN_PULLDOWN, ///< Dropdown 'Terrain type'.
|
||||
WID_GL_MAX_HEIGHT_PULLDOWN, ///< Dropdown 'Maximum height'.
|
||||
WID_GL_WATER_PULLDOWN, ///< Dropdown 'Sea level'.
|
||||
WID_GL_RIVER_PULLDOWN, ///< Dropdown 'Rivers'.
|
||||
WID_GL_SMOOTHNESS_PULLDOWN, ///< Dropdown 'Smoothness'.
|
||||
WID_GL_VARIETY_PULLDOWN, ///< Dropdown 'Variety distribution'.
|
||||
WID_GL_AVERAGE_HEIGHT_PULLDOWN, ///< Dropdown 'Average height'.
|
||||
|
||||
WID_GL_BORDERS_PULLDOWN, ///< Dropdown 'Map edges'.
|
||||
WID_GL_WATER_NW, ///< NW 'Water'/'Freeform'.
|
||||
|
||||
Reference in New Issue
Block a user