From df5dcfce48516f78c039d1012f6e04e39952980f Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Tue, 10 Sep 2024 20:45:38 +0200 Subject: [PATCH] Add settings for number of trees, min/max tree altitude --- data/language/en-GB.txt | 4 ++ src/openrct2-ui/UiStringIds.h | 4 ++ src/openrct2-ui/windows/MapGen.cpp | 101 +++++++++++++++++++++++++++-- src/openrct2/world/MapGen.cpp | 18 ++--- src/openrct2/world/MapGen.h | 3 + 5 files changed, 118 insertions(+), 12 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 36bef2753f..8454248cbc 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3758,6 +3758,10 @@ STR_6683 :Map Generator - Generator STR_6684 :Map Generator - Terrain STR_6685 :Map Generator - Water STR_6686 :Map Generator - Forests +STR_6687 :Tree to land ratio: +STR_6688 :Min. tree altitude: +STR_6689 :Max. tree altitude: +STR_6690 :{UINT16}% ############# # Scenarios # diff --git a/src/openrct2-ui/UiStringIds.h b/src/openrct2-ui/UiStringIds.h index 1356d81440..27a76ab70e 100644 --- a/src/openrct2-ui/UiStringIds.h +++ b/src/openrct2-ui/UiStringIds.h @@ -923,6 +923,10 @@ namespace OpenRCT2 STR_MAPGEN_SMOOTH_HEIGHTMAP = 6044, STR_MAPGEN_SMOOTH_STRENGTH = 6045, STR_MAPGEN_SMOOTH_TILE = 6047, + STR_MAPGEN_TREE_MAX_ALTITUDE = 6689, + STR_MAPGEN_TREE_MIN_ALTITUDE = 6688, + STR_MAPGEN_TREE_TO_LAND_RATIO = 6687, + STR_MAPGEN_TREE_TO_LAND_RATIO_PCT = 6690, STR_TERRAIN_LABEL = 2693, STR_WATER_LEVEL = 5185, STR_WATER_LEVEL_LABEL = 2692, diff --git a/src/openrct2-ui/windows/MapGen.cpp b/src/openrct2-ui/windows/MapGen.cpp index cbd24ffcfd..691dae889c 100644 --- a/src/openrct2-ui/windows/MapGen.cpp +++ b/src/openrct2-ui/windows/MapGen.cpp @@ -77,8 +77,6 @@ namespace OpenRCT2::Ui::Windows WIDX_HEIGHTMAP_STRENGTH_UP, WIDX_HEIGHTMAP_STRENGTH_DOWN, - WIDX_FORESTS_PLACE_TREES = TAB_BEGIN, - WIDX_BASE_HEIGHT = TAB_BEGIN, WIDX_BASE_HEIGHT_UP, WIDX_BASE_HEIGHT_DOWN, @@ -97,6 +95,17 @@ namespace OpenRCT2::Ui::Windows WIDX_WATER_LEVEL_UP, WIDX_WATER_LEVEL_DOWN, WIDX_ADD_BEACHES, + + WIDX_FORESTS_PLACE_TREES = TAB_BEGIN, + WIDX_TREE_LAND_RATIO, + WIDX_TREE_LAND_RATIO_UP, + WIDX_TREE_LAND_RATIO_DOWN, + WIDX_TREE_ALTITUDE_MIN, + WIDX_TREE_ALTITUDE_MIN_UP, + WIDX_TREE_ALTITUDE_MIN_DOWN, + WIDX_TREE_ALTITUDE_MAX, + WIDX_TREE_ALTITUDE_MAX_UP, + WIDX_TREE_ALTITUDE_MAX_DOWN, }; #pragma region Widgets @@ -154,7 +163,10 @@ namespace OpenRCT2::Ui::Windows static Widget ForestsWidgets[] = { SHARED_WIDGETS(STR_MAPGEN_CAPTION_FORESTS), - MakeWidget({ 10, 52}, {255, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_MAPGEN_OPTION_PLACE_TREES ), + MakeWidget ({ 10, 52}, {255, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_MAPGEN_OPTION_PLACE_TREES), + MakeSpinnerWidgets({179, 70}, { 95, 12}, WindowWidgetType::Spinner, WindowColour::Secondary), // WIDX_TREE_LAND_RATIO{,_UP,_DOWN} + MakeSpinnerWidgets({179, 88}, { 95, 12}, WindowWidgetType::Spinner, WindowColour::Secondary), // WIDX_TREE_ALTITUDE_MIN{,_UP,_DOWN} + MakeSpinnerWidgets({179, 106}, { 95, 12}, WindowWidgetType::Spinner, WindowColour::Secondary), // WIDX_TREE_ALTITUDE_MAX{,_UP,_DOWN} kWidgetsEnd, }; @@ -207,7 +219,12 @@ namespace OpenRCT2::Ui::Windows (1uLL << WIDX_WATER_LEVEL_UP) | (1uLL << WIDX_WATER_LEVEL_DOWN), - 0, + (1uLL << WIDX_TREE_LAND_RATIO_UP) | + (1uLL << WIDX_TREE_LAND_RATIO_DOWN) | + (1uLL << WIDX_TREE_ALTITUDE_MIN_UP) | + (1uLL << WIDX_TREE_ALTITUDE_MIN_DOWN) | + (1uLL << WIDX_TREE_ALTITUDE_MAX_UP) | + (1uLL << WIDX_TREE_ALTITUDE_MAX_DOWN), }; static uint64_t PressedWidgets[WINDOW_MAPGEN_PAGE_COUNT] = { @@ -276,6 +293,9 @@ namespace OpenRCT2::Ui::Windows // Features (e.g. tree, rivers, lakes etc.) .trees = true, + .treeToLandRatio = 25, + .minTreeAltitude = 10, + .maxTreeAltitude = 50, .beaches = true, // Simplex Noise Parameters @@ -680,6 +700,39 @@ namespace OpenRCT2::Ui::Windows } } + void ForestsMouseDown(WidgetIndex widgetIndex, Widget* widget) + { + switch (widgetIndex) + { + case WIDX_TREE_LAND_RATIO_UP: + _settings.treeToLandRatio = std::min(_settings.treeToLandRatio + 1, 50); + InvalidateWidget(WIDX_TREE_LAND_RATIO); + break; + case WIDX_TREE_LAND_RATIO_DOWN: + _settings.treeToLandRatio = std::max(_settings.treeToLandRatio - 1, 10); + InvalidateWidget(WIDX_TREE_LAND_RATIO); + break; + case WIDX_TREE_ALTITUDE_MIN_UP: + _settings.minTreeAltitude = std::min(_settings.minTreeAltitude + 1, kMaximumLandHeight / 2 - 1); + _settings.maxTreeAltitude = std::max(_settings.maxTreeAltitude, _settings.minTreeAltitude + 1); + InvalidateWidget(WIDX_TREE_ALTITUDE_MIN); + break; + case WIDX_TREE_ALTITUDE_MIN_DOWN: + _settings.minTreeAltitude = std::max(_settings.minTreeAltitude - 1, 2); + InvalidateWidget(WIDX_TREE_ALTITUDE_MIN); + break; + case WIDX_TREE_ALTITUDE_MAX_UP: + _settings.maxTreeAltitude = std::min(_settings.maxTreeAltitude + 1, kMaximumLandHeight - 1); + InvalidateWidget(WIDX_TREE_ALTITUDE_MAX); + break; + case WIDX_TREE_ALTITUDE_MAX_DOWN: + _settings.maxTreeAltitude = std::max(_settings.maxTreeAltitude - 1, 2 + 1); + _settings.minTreeAltitude = std::min(_settings.minTreeAltitude, _settings.maxTreeAltitude - 1); + InvalidateWidget(WIDX_TREE_ALTITUDE_MAX); + break; + } + } + void ForestsUpdate() { // Tab animation @@ -707,6 +760,44 @@ namespace OpenRCT2::Ui::Windows { DrawWidgets(dpi); DrawTabImages(dpi); + + const auto textColour = colours[1]; + + // Tree to land ratio, label and value + DrawTextBasic( + dpi, windowPos + ScreenCoordsXY{ 10, widgets[WIDX_TREE_LAND_RATIO].top + 1 }, STR_MAPGEN_TREE_TO_LAND_RATIO, {}, + { textColour }); + + auto ft = Formatter(); + ft.Add(_settings.treeToLandRatio); + DrawTextBasic( + dpi, + windowPos + ScreenCoordsXY{ widgets[WIDX_TREE_LAND_RATIO].left + 1, widgets[WIDX_TREE_LAND_RATIO].top + 1 }, + STR_MAPGEN_TREE_TO_LAND_RATIO_PCT, ft, { textColour }); + + // Minimum tree altitude, label and value + DrawTextBasic( + dpi, windowPos + ScreenCoordsXY{ 10, widgets[WIDX_TREE_ALTITUDE_MIN].top + 1 }, STR_MAPGEN_TREE_MIN_ALTITUDE, + {}, { textColour }); + + ft = Formatter(); + ft.Add(_settings.minTreeAltitude); + DrawTextBasic( + dpi, + windowPos + ScreenCoordsXY{ widgets[WIDX_TREE_ALTITUDE_MIN].left + 1, widgets[WIDX_TREE_ALTITUDE_MIN].top + 1 }, + STR_COMMA16, ft, { textColour }); + + // Maximum tree altitude, label and value + DrawTextBasic( + dpi, windowPos + ScreenCoordsXY{ 10, widgets[WIDX_TREE_ALTITUDE_MAX].top + 1 }, STR_MAPGEN_TREE_MAX_ALTITUDE, + {}, { textColour }); + + ft = Formatter(); + ft.Add(_settings.maxTreeAltitude); + DrawTextBasic( + dpi, + windowPos + ScreenCoordsXY{ widgets[WIDX_TREE_ALTITUDE_MAX].left + 1, widgets[WIDX_TREE_ALTITUDE_MAX].top + 1 }, + STR_COMMA16, ft, { textColour }); } #pragma endregion @@ -1263,6 +1354,8 @@ namespace OpenRCT2::Ui::Windows return TerrainMouseDown(widgetIndex, &widgets[widgetIndex]); case WINDOW_MAPGEN_PAGE_WATER: return WaterMouseDown(widgetIndex, &widgets[widgetIndex]); + case WINDOW_MAPGEN_PAGE_FORESTS: + return ForestsMouseDown(widgetIndex, &widgets[widgetIndex]); } } diff --git a/src/openrct2/world/MapGen.cpp b/src/openrct2/world/MapGen.cpp index c0e0ba214a..f169e36cb3 100644 --- a/src/openrct2/world/MapGen.cpp +++ b/src/openrct2/world/MapGen.cpp @@ -97,7 +97,7 @@ static void MapGenGenerateBlank(MapGenSettings* settings); static void MapGenGenerateSimplex(MapGenSettings* settings); static void MapGenGenerateFromHeightmapImage(MapGenSettings* settings); -static void MapGenPlaceTrees(); +static void MapGenPlaceTrees(MapGenSettings* settings); static void MapGenAddBeaches(MapGenSettings* settings); void MapGenGenerate(MapGenSettings* settings) @@ -125,7 +125,7 @@ void MapGenGenerate(MapGenSettings* settings) // Place trees? if (settings->trees) - MapGenPlaceTrees(); + MapGenPlaceTrees(settings); } static void MapGenSetWaterLevel(int32_t waterLevel); @@ -365,7 +365,7 @@ template static bool TryFindTreeInList(std::string_view id, const T& /** * Randomly places a selection of preset trees on the map. Picks the right tree for the terrain it is placing it on. */ -static void MapGenPlaceTrees() +static void MapGenPlaceTrees(MapGenSettings* settings) { std::vector grassTreeIds; std::vector desertTreeIds; @@ -394,16 +394,14 @@ static void MapGenPlaceTrees() } // Place trees - CoordsXY pos; - float treeToLandRatio = (10 + (UtilRand() % 30)) / 100.0f; + float treeToLandRatio = static_cast(settings->treeToLandRatio) / 100.0f; + auto& gameState = GetGameState(); for (int32_t y = 1; y < gameState.MapSize.y - 1; y++) { for (int32_t x = 1; x < gameState.MapSize.x - 1; x++) { - pos.x = x * kCoordsXYStep; - pos.y = y * kCoordsXYStep; - + auto pos = CoordsXY{ x, y } * kCoordsXYStep; auto* surfaceElement = MapGetSurfaceElementAt(pos); if (surfaceElement == nullptr) continue; @@ -412,6 +410,10 @@ static void MapGenPlaceTrees() if (surfaceElement->GetWaterHeight() > 0) continue; + if (settings->minTreeAltitude > surfaceElement->BaseHeight + || settings->maxTreeAltitude < surfaceElement->BaseHeight) + continue; + // On sand surfaces, give the tile a score based on nearby water, to be used to determine whether to spawn // vegetation float oasisScore = 0.0f; diff --git a/src/openrct2/world/MapGen.h b/src/openrct2/world/MapGen.h index 7ead7c318f..a20bdc6aa1 100644 --- a/src/openrct2/world/MapGen.h +++ b/src/openrct2/world/MapGen.h @@ -35,6 +35,9 @@ struct MapGenSettings // Features (e.g. tree, rivers, lakes etc.) bool trees; + int32_t treeToLandRatio; + int32_t minTreeAltitude; + int32_t maxTreeAltitude; bool beaches; // Simplex Noise Parameters