diff --git a/src/landscape.cpp b/src/landscape.cpp index 795055a04a..a9c985b592 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -1001,22 +1001,52 @@ static void GenerateTerrain(int type, uint flag) #include "table/genland.h" +static std::pair GetDesertOrRainforestData() +{ + switch (_settings_game.game_creation.coast_tropics_width) { + case 0: + return { _make_desert_or_rainforest_data, endof(_make_desert_or_rainforest_data) }; + case 1: + return { _make_desert_or_rainforest_data_medium, endof(_make_desert_or_rainforest_data_medium) }; + case 2: + return { _make_desert_or_rainforest_data_large, endof(_make_desert_or_rainforest_data_large) }; + case 3: + return { _make_desert_or_rainforest_data_extralarge, endof(_make_desert_or_rainforest_data_extralarge) }; + default: + NOT_REACHED(); + } +} + +template +void DesertOrRainforestProcessTiles(const std::pair desert_rainforest_data, const Rect16 *&data, TileIndex tile, F handle_tile) +{ + for (data = desert_rainforest_data.first; data != desert_rainforest_data.second; ++data) { + const Rect16 r = *data; + for (int16 x = r.left; x <= r.right; x++) { + for (int16 y = r.top; y <= r.bottom; y++) { + TileIndex t = AddTileIndexDiffCWrap(tile, { x, y }); + if (handle_tile(t)) return; + } + } + } +} + static void CreateDesertOrRainForest(uint desert_tropic_line) { TileIndex update_freq = MapSize() / 4; - const TileIndexDiffC *data; + const Rect16 *data; + + const std::pair desert_rainforest_data = GetDesertOrRainforestData(); for (TileIndex tile = 0; tile != MapSize(); ++tile) { if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE); if (!IsValidTile(tile)) continue; - 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) >= desert_tropic_line || IsTileType(t, MP_WATER))) break; - } - if (data == endof(_make_desert_or_rainforest_data)) { + DesertOrRainforestProcessTiles(desert_rainforest_data, data, tile, [&](TileIndex t) -> bool { + return (t != INVALID_TILE && (TileHeight(t) >= desert_tropic_line || IsTileType(t, MP_WATER))); + }); + if (data == desert_rainforest_data.second) { SetTropicZone(tile, TROPICZONE_DESERT); } } @@ -1032,12 +1062,10 @@ static void CreateDesertOrRainForest(uint desert_tropic_line) if (!IsValidTile(tile)) continue; - for (data = _make_desert_or_rainforest_data; - data != endof(_make_desert_or_rainforest_data); ++data) { - TileIndex t = AddTileIndexDiffCWrap(tile, *data); - if (t != INVALID_TILE && IsTileType(t, MP_CLEAR) && IsClearGround(t, CLEAR_DESERT)) break; - } - if (data == endof(_make_desert_or_rainforest_data)) { + DesertOrRainforestProcessTiles(desert_rainforest_data, data, tile, [&](TileIndex t) -> bool { + return (t != INVALID_TILE && IsTileType(t, MP_CLEAR) && IsClearGround(t, CLEAR_DESERT)); + }); + if (data == desert_rainforest_data.second) { SetTropicZone(tile, TROPICZONE_RAINFOREST); } } @@ -1128,7 +1156,7 @@ static bool MakeLake(TileIndex tile, void *user_data) MarkTileDirtyByTile(tile); /* Remove desert directly around the river tile. */ TileIndex t = tile; - CircularTileSearch(&t, _settings_game.game_creation.river_tropics_width, RiverModifyDesertZone, nullptr); + CircularTileSearch(&t, _settings_game.game_creation.lake_tropics_width, RiverModifyDesertZone, nullptr); return false; } } @@ -1218,7 +1246,7 @@ static void River_FoundEndNode(AyStar *aystar, OpenListNode *current) const uint current_river_length = DistanceManhattan(_current_spring, path->node.tile); const uint long_river_length = _settings_game.game_creation.min_river_length * 4; const uint radius = std::min(3u, (current_river_length / (long_river_length / 3u)) + 1u); - + MarkTileDirtyByTile(tile); if (_is_main_river && (radius > 1)) { diff --git a/src/lang/english.txt b/src/lang/english.txt index 311017f1cc..0d7143f951 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1678,7 +1678,16 @@ STR_CONFIG_SETTING_RIVER_ROUTE_RANDOM_HELPTEXT :Choose how rand STR_CONFIG_SETTING_RIVERS_TOP_OF_HILL :Rivers require their springs to generate at the top of hills: {STRING} STR_CONFIG_SETTING_RIVERS_TOP_OF_HILL_HELPTEXT :Choose whether rivers require their springs to generate towards the top of hills. STR_CONFIG_SETTING_RIVER_TROPICS_WIDTH :Tropics width around rivers: {STRING} -STR_CONFIG_SETTING_RIVER_TROPICS_WIDTH_HELPTEXT :Controls the width of the tropic zone that surrounds rivers in sub-tropic landscape. +STR_CONFIG_SETTING_RIVER_TROPICS_WIDTH_HELPTEXT :Controls the width of the tropic zone that surrounds rivers in sub-tropic landscape.{}This is the total width of the zone on both sides of the river. +STR_CONFIG_SETTING_LAKE_TROPICS_WIDTH :Tropics width around lakes: {STRING} +STR_CONFIG_SETTING_LAKE_TROPICS_WIDTH_HELPTEXT :Controls the width of the tropic zone that surrounds lakes in sub-tropic landscape.{}This is the total width of the zone on both sides of the lake. +STR_CONFIG_SETTING_COAST_TROPICS_WIDTH :Tropics width around coasts: {STRING} +STR_CONFIG_SETTING_COAST_TROPICS_WIDTH_HELPTEXT :Controls the width of the tropic zone that surrounds coasts in sub-tropic landscape. +###length 4 +STR_CONFIG_SETTING_COAST_TROPICS_WIDTH_DEFAULT :Default +STR_CONFIG_SETTING_COAST_TROPICS_WIDTH_MEDIUM :Medium +STR_CONFIG_SETTING_COAST_TROPICS_WIDTH_LARGE :Large +STR_CONFIG_SETTING_COAST_TROPICS_WIDTH_EXTRALARGE :Extra Large STR_CONFIG_SETTING_LAKE_SIZE :Size of lakes: {STRING} STR_CONFIG_SETTING_LAKE_SIZE_HELPTEXT :Controls the size of lakes that are generated along rivers. STR_CONFIG_SETTING_LAKE_SIZE_VALUE :{NUM} diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 832f3e401c..1f8782380e 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -2108,6 +2108,8 @@ static SettingsContainer &GetSettingsTree() rivers->Add(new SettingEntry("game_creation.river_route_random")); rivers->Add(new SettingEntry("game_creation.rivers_top_of_hill")); rivers->Add(new SettingEntry("game_creation.river_tropics_width")); + rivers->Add(new SettingEntry("game_creation.lake_tropics_width")); + rivers->Add(new SettingEntry("game_creation.coast_tropics_width")); rivers->Add(new SettingEntry("game_creation.lake_size")); rivers->Add(new SettingEntry("game_creation.lakes_allowed_in_deserts")); } diff --git a/src/settings_type.h b/src/settings_type.h index 5899719ed3..bc7629abd9 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -413,6 +413,8 @@ struct GameCreationSettings { byte amount_of_rivers; ///< the amount of rivers bool rivers_top_of_hill; ///< do rivers require starting near the tops of hills? uint8 river_tropics_width; ///< the configured width of tropics around rivers + uint8 lake_tropics_width; ///< the configured width of tropics around lakes + uint8 coast_tropics_width; ///< the configured width of tropics around coasts uint8 lake_size; ///< how large can lakes get? bool lakes_allowed_in_deserts; ///< are lakes allowed in deserts? uint8 amount_of_rocks; ///< the amount of rocks diff --git a/src/table/genland.h b/src/table/genland.h index 7bc6294ec7..3ddc0e05f3 100644 --- a/src/table/genland.h +++ b/src/table/genland.h @@ -7,160 +7,82 @@ /** @file genland.h Table used to generate deserts and/or rain forests. */ -#define M(x, y) {x, y} +#define R(x1, x2, y1, y2) {x1, y1, x2, y2} -static const TileIndexDiffC _make_desert_or_rainforest_data[] = { - M(-5, -5), - M(-4, -5), - M(-3, -5), - M(-2, -5), - M(-1, -5), - M( 0, -5), - M( 1, -5), - M( 2, -5), - M( 3, -5), - M( 4, -5), - M( 5, -5), - M(-5, -4), - M(-4, -4), - M(-3, -4), - M(-2, -4), - M(-1, -4), - M( 0, -4), - M( 1, -4), - M( 2, -4), - M( 3, -4), - M( 4, -4), - M( 5, -4), - M(-5, -3), - M(-4, -3), - M(-3, -3), - M(-2, -3), - M(-1, -3), - M( 0, -3), - M( 1, -3), - M( 2, -3), - M( 3, -3), - M( 4, -3), - M( 5, -3), - M(-5, -2), - M(-4, -2), - M(-3, -2), - M(-2, -2), - M(-1, -2), - M( 0, -2), - M( 1, -2), - M( 2, -2), - M( 3, -2), - M( 4, -2), - M( 5, -2), - M(-5, -1), - M(-4, -1), - M(-3, -1), - M(-2, -1), - M(-1, -1), - M( 0, -1), - M( 1, -1), - M( 2, -1), - M( 3, -1), - M( 4, -1), - M( 5, -1), - M(-5, 0), - M(-4, 0), - M(-3, 0), - M(-2, 0), - M(-1, 0), - M( 0, 0), - M( 1, 0), - M( 2, 0), - M( 3, 0), - M( 4, 0), - M( 5, 0), - M(-5, 1), - M(-4, 1), - M(-3, 1), - M(-2, 1), - M(-1, 1), - M( 0, 1), - M( 1, 1), - M( 2, 1), - M( 3, 1), - M( 4, 1), - M( 5, 1), - M(-5, 2), - M(-4, 2), - M(-3, 2), - M(-2, 2), - M(-1, 2), - M( 0, 2), - M( 1, 2), - M( 2, 2), - M( 3, 2), - M( 4, 2), - M( 5, 2), - M(-5, 3), - M(-4, 3), - M(-3, 3), - M(-2, 3), - M(-1, 3), - M( 0, 3), - M( 1, 3), - M( 2, 3), - M( 3, 3), - M( 4, 3), - M( 5, 3), - M(-5, 4), - M(-4, 4), - M(-3, 4), - M(-2, 4), - M(-1, 4), - M( 0, 4), - M( 1, 4), - M( 2, 4), - M( 3, 4), - M( 4, 4), - M( 5, 4), - M(-5, 5), - M(-4, 5), - M(-3, 5), - M(-2, 5), - M(-1, 5), - M( 0, 5), - M( 1, 5), - M( 2, 5), - M( 3, 5), - M( 4, 5), - M( 5, 5), - M( 6, -3), - M(-6, -3), - M(-3, 6), - M(-3, -6), - M( 6, -2), - M(-6, -2), - M(-2, 6), - M(-2, -6), - M( 6, -1), - M(-6, -1), - M(-1, 6), - M(-1, -6), - M( 6, 0), - M(-6, 0), - M( 0, 6), - M( 0, -6), - M( 6, 1), - M(-6, 1), - M( 1, 6), - M( 1, -6), - M( 6, 2), - M(-6, 2), - M( 2, 6), - M( 2, -6), - M( 6, 3), - M(-6, 3), - M( 3, 6), - M( 3, -6) +// This default array draws a filled circle 13 tiles in diameter +static const Rect16 _make_desert_or_rainforest_data[] = { + R(-5, 5, -5, 5), + R( 6, 6, -3, 3), + R(-6, -6, -3, 3), + R(-3, 3, 6, 6), + R(-3, 3, -6, -6) }; +// This array draws a filled circle 19 tiles in diameter +static const Rect16 _make_desert_or_rainforest_data_medium[] = { + R(-3, 3, -9, -9), + R(-5, 5, -8, -8), + R(-6, 6, -7, -7), + R(-7, 7, -6, -6), + R(-8, 8, -5, -4), + R(-9, 9, -3, 3), + R(-8, 8, 4, 5), + R(-7, 7, 6, 6), + R(-6, 6, 7, 7), + R(-5, 5, 8, 8), + R(-3, 3, 9, 9) +}; +// This array draws a filled circle 25 tiles in diameter +static const Rect16 _make_desert_or_rainforest_data_large[] = { + R( -3, 3, -12, -12), + R( -5, 5, -11, -11), + R( -7, 7, -10, -10), + R( -8, 8, -9, -9), + R( -9, 9, -8, -8), + R(-10, 10, -7, -6), + R(-11, 11, -5, -4), + R(-12, 12, -3, 3), + R(-11, 11, 4, 5), + R(-10, 10, 6, 7), + R( -9, 9, 8, 8), + R( -8, 8, 9, 9), + R( -7, 7, 10, 10), + R( -5, 5, 11, 11), + R( -3, 3, 12, 12) +}; -#undef M +// This array draws a filled circle 51 tiles in diameter. +static const Rect16 _make_desert_or_rainforest_data_extralarge[] = { + R( -5, 5, -25, -25), + R( -8, 8, -24, -24), + R(-11, 11, -23, -23), + R(-12, 12, -22, -22), + R(-14, 14, -21, -21), + R(-15, 15, -20, -20), + R(-17, 17, -19, -19), + R(-18, 18, -18, -18), + R(-19, 19, -17, -16), + R(-20, 20, -15, -15), + R(-21, 21, -14, -13), + R(-22, 22, -12, -12), + R(-23, 23, -11, -9), + R(-24, 24, -8, -6), + R(-25, 25, -5, 5), + R(-24, 24, 6, 8), + R(-23, 23, 9, 11), + R(-22, 22, 12, 12), + R(-21, 21, 13, 14), + R(-20, 20, 15, 15), + R(-19, 19, 16, 17), + R(-18, 18, 18, 18), + R(-17, 17, 19, 19), + R(-15, 15, 20, 20), + R(-14, 14, 21, 21), + R(-12, 12, 22, 22), + R(-11, 11, 23, 23), + R( -8, 8, 24, 24), + R( -5, 5, 25, 25) +}; + +#undef R diff --git a/src/table/settings/settings.ini b/src/table/settings/settings.ini index 5727f2f379..86f1acbe93 100644 --- a/src/table/settings/settings.ini +++ b/src/table/settings/settings.ini @@ -3881,8 +3881,8 @@ var = game_creation.river_tropics_width type = SLE_UINT8 flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO def = 5 -min = 1 -max = 12 +min = 2 +max = 51 interval = 1 str = STR_CONFIG_SETTING_RIVER_TROPICS_WIDTH strhelp = STR_CONFIG_SETTING_RIVER_TROPICS_WIDTH_HELPTEXT @@ -3890,6 +3890,34 @@ strval = STR_JUST_COMMA cat = SC_BASIC patxname = ""rivers.game_creation.river_tropics_width"" +[SDT_VAR] +var = game_creation.lake_tropics_width +type = SLE_UINT8 +flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO +def = 5 +min = 2 +max = 51 +interval = 1 +str = STR_CONFIG_SETTING_LAKE_TROPICS_WIDTH +strhelp = STR_CONFIG_SETTING_LAKE_TROPICS_WIDTH_HELPTEXT +strval = STR_JUST_COMMA +cat = SC_BASIC +patxname = ""rivers.game_creation.lake_tropics_width"" + +[SDT_VAR] +var = game_creation.coast_tropics_width +type = SLE_UINT8 +flags = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY +def = 0 +min = 0 +max = 3 +interval = 1 +str = STR_CONFIG_SETTING_COAST_TROPICS_WIDTH +strhelp = STR_CONFIG_SETTING_COAST_TROPICS_WIDTH_HELPTEXT +strval = STR_CONFIG_SETTING_COAST_TROPICS_WIDTH_DEFAULT +cat = SC_BASIC +patxname = ""rivers.game_creation.coast_tropics_width"" + [SDT_VAR] var = game_creation.lake_size type = SLE_UINT8