Skip to content

Commit

Permalink
Merge pull request #16616 from Gymnasiast/fix/14155-15994
Browse files Browse the repository at this point in the history
Fix #14155, #15994: Map Generator places non-tree objects as trees
  • Loading branch information
Gymnasiast committed Feb 9, 2022
2 parents 9466e27 + af6f575 commit 052da74
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 52 deletions.
1 change: 1 addition & 0 deletions distribution/changelog.txt
Expand Up @@ -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.
Expand Down
93 changes: 41 additions & 52 deletions src/openrct2/world/MapGen.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -274,14 +274,24 @@ static bool MapGenSurfaceTakesSnowTrees(const TerrainSurfaceObject& surface)
return id == "rct2.terrain_surface.ice";
}

template<typename T> 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<int32_t> grassTreeIds(std::size(GrassTrees), 0);
std::vector<int32_t> desertTreeIds(std::size(DesertTrees), 0);
std::vector<int32_t> snowTreeIds(std::size(SnowTrees), 0);
std::vector<int32_t> grassTreeIds;
std::vector<int32_t> desertTreeIds;
std::vector<int32_t> snowTreeIds;

for (int32_t i = 0; i < object_entry_group_counts[EnumValue(ObjectType::SmallScenery)]; i++)
{
Expand All @@ -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;
}
}

Expand Down Expand Up @@ -371,7 +360,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;
Expand Down Expand Up @@ -399,7 +388,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());
}
}
Expand Down

0 comments on commit 052da74

Please sign in to comment.