Merge pull request #16616 from Gymnasiast/fix/14155-15994

Fix #14155, #15994: Map Generator places non-tree objects as trees
This commit is contained in:
Michael Steenbeek 2022-02-09 21:50:50 +01:00 committed by GitHub
commit 052da74760
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 52 deletions

View File

@ -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.

View File

@ -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)
@ -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++)
{
@ -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;
}
}
@ -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;
@ -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());
}
}