From 0389ac2e3d24e975859c46a557f6835e09683427 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 9 Feb 2022 15:54:20 +0100 Subject: [PATCH 1/2] Fix #14155, #15994: Map Generator places non-tree objects as trees --- distribution/changelog.txt | 1 + src/openrct2/world/MapGen.cpp | 56 +++++++++++++++++------------------ 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 7f3f5ff9da5c..fced45e1030d 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -24,6 +24,7 @@ - Change: [#16424] Following an entity in the title sequence no longer toggles underground view when it's underground. - Change: [#16493] Boat Hire and Submarine Ride support costs now match their visual appearance. - Fix: [#13336] Can no longer place Bumble Bee track design (reverts #12707). +- Fix: [#14155] Map Generator sometimes places non-tree objects as trees. - Fix: [#15571] Non-ASCII characters in scenario description get distorted while saving. - Fix: [#15830] Objects with RCT1 images are very glitchy if OpenRCT2 is not linked to an RCT1 install. - Fix: [#15947, #15960] Removing a flat ride results in an error message and duplicate structures. diff --git a/src/openrct2/world/MapGen.cpp b/src/openrct2/world/MapGen.cpp index 4e94d522c631..6cb0fcd062e8 100644 --- a/src/openrct2/world/MapGen.cpp +++ b/src/openrct2/world/MapGen.cpp @@ -50,36 +50,36 @@ static struct static constexpr const char* GrassTrees[] = { // Dark - "rct2.tcf", // Caucasian Fir Tree - "rct2.trf", // Red Fir Tree - "rct2.trf2", // Red Fir Tree - "rct2.tsp", // Scots Pine Tree - "rct2.tmzp", // Montezuma Pine Tree - "rct2.tap", // Aleppo Pine Tree - "rct2.tcrp", // Corsican Pine Tree - "rct2.tbp", // Black Poplar Tree + "rct2.scenery_small.tcf", // Caucasian Fir Tree + "rct2.scenery_small.trf", // Red Fir Tree + "rct2.scenery_small.trf2", // Red Fir Tree + "rct2.scenery_small.tsp", // Scots Pine Tree + "rct2.scenery_small.tmzp", // Montezuma Pine Tree + "rct2.scenery_small.tap", // Aleppo Pine Tree + "rct2.scenery_small.tcrp", // Corsican Pine Tree + "rct2.scenery_small.tbp", // Black Poplar Tree // Light - "rct2.tcl", // Cedar of Lebanon Tree - "rct2.tel", // European Larch Tree + "rct2.scenery_small.tcl", // Cedar of Lebanon Tree + "rct2.scenery_small.tel", // European Larch Tree }; static constexpr const char* DesertTrees[] = { - "rct2.tmp", // Monkey-Puzzle Tree - "rct2.thl", // Honey Locust Tree - "rct2.th1", // Canary Palm Tree - "rct2.th2", // Palm Tree - "rct2.tpm", // Palm Tree - "rct2.tropt1", // Tree - "rct2.tbc", // Cactus - "rct2.tsc", // Cactus + "rct2.scenery_small.tmp", // Monkey-Puzzle Tree + "rct2.scenery_small.thl", // Honey Locust Tree + "rct2.scenery_small.th1", // Canary Palm Tree + "rct2.scenery_small.th2", // Palm Tree + "rct2.scenery_small.tpm", // Palm Tree + "rct2.scenery_small.tropt1", // Tree + "rct2.scenery_small.tbc", // Cactus + "rct2.scenery_small.tsc", // Cactus }; static constexpr const char* SnowTrees[] = { - "rct2.tcfs", // Snow-covered Caucasian Fir Tree - "rct2.tnss", // Snow-covered Norway Spruce Tree - "rct2.trf3", // Snow-covered Red Fir Tree - "rct2.trfs", // Snow-covered Red Fir Tree + "rct2.scenery_small.tcfs", // Snow-covered Caucasian Fir Tree + "rct2.scenery_small.tnss", // Snow-covered Norway Spruce Tree + "rct2.scenery_small.trf3", // Snow-covered Red Fir Tree + "rct2.scenery_small.trfs", // Snow-covered Red Fir Tree }; #pragma endregion @@ -235,7 +235,7 @@ void mapgen_generate(mapgen_settings* settings) mapgen_place_trees(); } -static void mapgen_place_tree(int32_t type, const CoordsXY& loc) +static void mapgen_place_tree(ObjectEntryIndex type, const CoordsXY& loc) { auto* sceneryEntry = get_small_scenery_entry(type); if (sceneryEntry == nullptr) @@ -279,9 +279,9 @@ static bool MapGenSurfaceTakesSnowTrees(const TerrainSurfaceObject& surface) */ static void mapgen_place_trees() { - std::vector grassTreeIds(std::size(GrassTrees), 0); - std::vector desertTreeIds(std::size(DesertTrees), 0); - std::vector snowTreeIds(std::size(SnowTrees), 0); + std::vector grassTreeIds(std::size(GrassTrees), OBJECT_ENTRY_INDEX_NULL); + std::vector desertTreeIds(std::size(DesertTrees), OBJECT_ENTRY_INDEX_NULL); + std::vector snowTreeIds(std::size(SnowTrees), OBJECT_ENTRY_INDEX_NULL); for (int32_t i = 0; i < object_entry_group_counts[EnumValue(ObjectType::SmallScenery)]; i++) { @@ -371,7 +371,7 @@ static void mapgen_place_trees() { pos = availablePositions[i]; - int32_t type = -1; + ObjectEntryIndex type = OBJECT_ENTRY_INDEX_NULL; auto* surfaceElement = map_get_surface_element_at(pos.ToCoordsXY()); if (surfaceElement == nullptr) continue; @@ -399,7 +399,7 @@ static void mapgen_place_trees() type = snowTreeIds[util_rand() % snowTreeIds.size()]; } - if (type != -1) + if (type != OBJECT_ENTRY_INDEX_NULL) mapgen_place_tree(type, pos.ToCoordsXY()); } } From af6f575e78df7060789527d2ddc27bfbce9a5a3d Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Wed, 9 Feb 2022 17:28:15 +0000 Subject: [PATCH 2/2] Remove empty vector entries and refactor --- src/openrct2/world/MapGen.cpp | 43 +++++++++++++---------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/src/openrct2/world/MapGen.cpp b/src/openrct2/world/MapGen.cpp index 6cb0fcd062e8..8787e543db3f 100644 --- a/src/openrct2/world/MapGen.cpp +++ b/src/openrct2/world/MapGen.cpp @@ -274,14 +274,24 @@ static bool MapGenSurfaceTakesSnowTrees(const TerrainSurfaceObject& surface) return id == "rct2.terrain_surface.ice"; } +template static bool TryFindTreeInList(std::string_view id, const T& treeList) +{ + for (size_t j = 0; j < std::size(treeList); j++) + { + if (treeList[j] == id) + return true; + } + return false; +} + /** * Randomly places a selection of preset trees on the map. Picks the right tree for the terrain it is placing it on. */ static void mapgen_place_trees() { - std::vector grassTreeIds(std::size(GrassTrees), OBJECT_ENTRY_INDEX_NULL); - std::vector desertTreeIds(std::size(DesertTrees), OBJECT_ENTRY_INDEX_NULL); - std::vector snowTreeIds(std::size(SnowTrees), OBJECT_ENTRY_INDEX_NULL); + std::vector grassTreeIds; + std::vector desertTreeIds; + std::vector snowTreeIds; for (int32_t i = 0; i < object_entry_group_counts[EnumValue(ObjectType::SmallScenery)]; i++) { @@ -291,38 +301,17 @@ static void mapgen_place_trees() if (sceneryEntry == nullptr) continue; - uint32_t j; - for (j = 0; j < std::size(GrassTrees); j++) - { - if (GrassTrees[j] == entry->GetIdentifier()) - break; - } - if (j != std::size(GrassTrees)) + if (TryFindTreeInList(entry->GetIdentifier(), GrassTrees)) { grassTreeIds.push_back(i); - continue; } - - for (j = 0; j < std::size(DesertTrees); j++) - { - if (DesertTrees[j] == entry->GetIdentifier()) - break; - } - if (j != std::size(DesertTrees)) + else if (TryFindTreeInList(entry->GetIdentifier(), DesertTrees)) { desertTreeIds.push_back(i); - continue; } - - for (j = 0; j < std::size(SnowTrees); j++) - { - if (SnowTrees[j] == entry->GetIdentifier()) - break; - } - if (j != std::size(SnowTrees)) + else if (TryFindTreeInList(entry->GetIdentifier(), SnowTrees)) { snowTreeIds.push_back(i); - continue; } }