1
0
Fork 0

Add tree generation for ExtemeHills and other biomes (#4713)

This commit is contained in:
mBornand 2020-05-06 17:31:52 +02:00 committed by GitHub
parent bdb8830b9c
commit b9f441294d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 132 additions and 98 deletions

View File

@ -50,14 +50,33 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc)
Dest = &a_ChunkDesc; Dest = &a_ChunkDesc;
} }
int NumTrees = GetNumTrees(BaseX, BaseZ, Dest->GetBiomeMap()); double NumTrees = GetNumTrees(BaseX, BaseZ, Dest->GetBiomeMap());
sSetBlockVector OutsideLogs, OutsideOther; sSetBlockVector OutsideLogs, OutsideOther;
for (int i = 0; i < NumTrees; i++) if (NumTrees < 1)
{ {
GenerateSingleTree(BaseX, BaseZ, i, *Dest, OutsideLogs, OutsideOther); Vector3i Pos;
} Pos.x = (m_Noise.IntNoise3DInt(BaseX + BaseZ, BaseZ, 0) / 19) % cChunkDef::Width;
Pos.z = (m_Noise.IntNoise3DInt(BaseX - BaseZ, 0, BaseZ) / 19) % cChunkDef::Width;
Pos.y = Dest->GetHeight(Pos.x, Pos.z);
if (std::abs(m_Noise.IntNoise3D(BaseX * cChunkDef::Width + Pos.x, Pos.y, BaseZ * cChunkDef::Width + Pos.z)) <= NumTrees)
{
GenerateSingleTree(BaseX, BaseZ, 0, Pos, *Dest, OutsideLogs, OutsideOther);
}
}
else
{
for (int i = 0; i < NumTrees; i++)
{
Vector3i Pos;
Pos.x = (m_Noise.IntNoise3DInt(BaseX + BaseZ, BaseZ, i) / 19) % cChunkDef::Width;
Pos.z = (m_Noise.IntNoise3DInt(BaseX - BaseZ, i, BaseZ) / 19) % cChunkDef::Width;
Pos.y = Dest->GetHeight(Pos.x, Pos.z);
GenerateSingleTree(BaseX, BaseZ, i, Pos, *Dest, OutsideLogs, OutsideOther);
}
}
sSetBlockVector IgnoredOverflow; sSetBlockVector IgnoredOverflow;
IgnoredOverflow.reserve(OutsideOther.size()); IgnoredOverflow.reserve(OutsideOther.size());
ApplyTreeImage(ChunkX, ChunkZ, a_ChunkDesc, OutsideOther, IgnoredOverflow); ApplyTreeImage(ChunkX, ChunkZ, a_ChunkDesc, OutsideOther, IgnoredOverflow);
@ -76,23 +95,19 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc)
void cStructGenTrees::GenerateSingleTree( void cStructGenTrees::GenerateSingleTree(
int a_ChunkX, int a_ChunkZ, int a_Seq, int a_ChunkX, int a_ChunkZ, int a_Seq,
Vector3i a_Pos,
cChunkDesc & a_ChunkDesc, cChunkDesc & a_ChunkDesc,
sSetBlockVector & a_OutsideLogs, sSetBlockVector & a_OutsideLogs,
sSetBlockVector & a_OutsideOther sSetBlockVector & a_OutsideOther
) )
{ {
int x = (m_Noise.IntNoise3DInt(a_ChunkX + a_ChunkZ, a_ChunkZ, a_Seq) / 19) % cChunkDef::Width; if ((a_Pos.y <= 0) || (a_Pos.y >= 230))
int z = (m_Noise.IntNoise3DInt(a_ChunkX - a_ChunkZ, a_Seq, a_ChunkZ) / 19) % cChunkDef::Width;
int Height = a_ChunkDesc.GetHeight(x, z);
if ((Height <= 0) || (Height >= 230))
{ {
return; return;
} }
// Check the block underneath the tree: // Check the block underneath the tree:
BLOCKTYPE TopBlock = a_ChunkDesc.GetBlockType(x, Height, z); BLOCKTYPE TopBlock = a_ChunkDesc.GetBlockType(a_Pos.x, a_Pos.y, a_Pos.z);
if ((TopBlock != E_BLOCK_DIRT) && (TopBlock != E_BLOCK_GRASS) && (TopBlock != E_BLOCK_FARMLAND)) if ((TopBlock != E_BLOCK_DIRT) && (TopBlock != E_BLOCK_GRASS) && (TopBlock != E_BLOCK_FARMLAND))
{ {
return; return;
@ -100,9 +115,9 @@ void cStructGenTrees::GenerateSingleTree(
sSetBlockVector TreeLogs, TreeOther; sSetBlockVector TreeLogs, TreeOther;
GetTreeImageByBiome( GetTreeImageByBiome(
{ a_ChunkX * cChunkDef::Width + x, Height + 1, a_ChunkZ * cChunkDef::Width + z }, { a_ChunkX * cChunkDef::Width + a_Pos.x, a_Pos.y + 1, a_ChunkZ * cChunkDef::Width + a_Pos.z },
m_Noise, a_Seq, m_Noise, a_Seq,
a_ChunkDesc.GetBiome(x, z), a_ChunkDesc.GetBiome(a_Pos.x, a_Pos.z),
TreeLogs, TreeOther TreeLogs, TreeOther
); );
@ -195,7 +210,7 @@ void cStructGenTrees::ApplyTreeImage(
int cStructGenTrees::GetNumTrees( double cStructGenTrees::GetNumTrees(
int a_ChunkX, int a_ChunkZ, int a_ChunkX, int a_ChunkZ,
const cChunkDef::BiomeMap & a_Biomes const cChunkDef::BiomeMap & a_Biomes
) )
@ -204,68 +219,68 @@ int cStructGenTrees::GetNumTrees(
{ {
switch (a_Biome) switch (a_Biome)
{ {
case biOcean: return 2; case biOcean: return 2.0;
case biPlains: return 1; case biPlains: return 0.03125;
case biDesert: return 0; case biDesert: return 0.0;
case biExtremeHills: return 3; case biExtremeHills: return 3.0;
case biForest: return 30; case biForest: return 30.0;
case biTaiga: return 30; case biTaiga: return 30.0;
case biSwampland: return 8; case biSwampland: return 8.0;
case biRiver: return 0; case biRiver: return 0.0;
case biNether: return 0; case biNether: return 0.0;
case biEnd: return 0; case biEnd: return 0.0;
case biFrozenOcean: return 0; case biFrozenOcean: return 0.0;
case biFrozenRiver: return 0; case biFrozenRiver: return 0.0;
case biIcePlains: return 1; case biIcePlains: return 0.03125;
case biIceMountains: return 1; case biIceMountains: return 0.125;
case biMushroomIsland: return 3; case biMushroomIsland: return 3.0;
case biMushroomShore: return 3; case biMushroomShore: return 3.0;
case biBeach: return 0; case biBeach: return 0.0;
case biDesertHills: return 0; case biDesertHills: return 0.0;
case biForestHills: return 20; case biForestHills: return 20.0;
case biTaigaHills: return 20; case biTaigaHills: return 20.0;
case biExtremeHillsEdge: return 5; case biExtremeHillsEdge: return 5.0;
case biJungle: return 120; case biJungle: return 120.0;
case biJungleHills: return 90; case biJungleHills: return 90.0;
case biJungleEdge: return 90; case biJungleEdge: return 90.0;
case biDeepOcean: return 0; case biDeepOcean: return 0.0;
case biStoneBeach: return 0; case biStoneBeach: return 0.0;
case biColdBeach: return 0; case biColdBeach: return 0.0;
case biBirchForest: return 30; case biBirchForest: return 30.0;
case biBirchForestHills: return 20; case biBirchForestHills: return 20.0;
case biRoofedForest: return 50; case biRoofedForest: return 50.0;
case biColdTaiga: return 20; case biColdTaiga: return 20.0;
case biColdTaigaHills: return 15; case biColdTaigaHills: return 15.0;
case biMegaTaiga: return 30; case biMegaTaiga: return 30.0;
case biMegaTaigaHills: return 25; case biMegaTaigaHills: return 25.0;
case biExtremeHillsPlus: return 3; case biExtremeHillsPlus: return 3.0;
case biSavanna: return 8; case biSavanna: return 8.0;
case biSavannaPlateau: return 12; case biSavannaPlateau: return 12.0;
case biMesa: return 2; case biMesa: return 2.0;
case biMesaPlateauF: return 8; case biMesaPlateauF: return 8.0;
case biMesaPlateau: return 8; case biMesaPlateau: return 8.0;
// Biome variants // Biome variants
case biSunflowerPlains: return 1; case biSunflowerPlains: return 0.03125;
case biDesertM: return 0; case biDesertM: return 0.0;
case biExtremeHillsM: return 4; case biExtremeHillsM: return 4.0;
case biFlowerForest: return 30; case biFlowerForest: return 2.0;
case biTaigaM: return 30; case biTaigaM: return 30.0;
case biSwamplandM: return 8; case biSwamplandM: return 8.0;
case biIcePlainsSpikes: return 1; case biIcePlainsSpikes: return 0.0078125;
case biJungleM: return 120; case biJungleM: return 120.0;
case biJungleEdgeM: return 90; case biJungleEdgeM: return 90.0;
case biBirchForestM: return 30; case biBirchForestM: return 30.0;
case biBirchForestHillsM: return 20; case biBirchForestHillsM: return 20.0;
case biRoofedForestM: return 40; case biRoofedForestM: return 40.0;
case biColdTaigaM: return 30; case biColdTaigaM: return 30.0;
case biMegaSpruceTaiga: return 30; case biMegaSpruceTaiga: return 30.0;
case biMegaSpruceTaigaHills: return 30; case biMegaSpruceTaigaHills: return 30.0;
case biExtremeHillsPlusM: return 4; case biExtremeHillsPlusM: return 4.0;
case biSavannaM: return 8; case biSavannaM: return 8.0;
case biSavannaPlateauM: return 12; case biSavannaPlateauM: return 12.0;
case biMesaBryce: return 4; case biMesaBryce: return 4.0;
case biMesaPlateauFM: return 12; case biMesaPlateauFM: return 12.0;
case biMesaPlateauM: return 12; case biMesaPlateauM: return 12.0;
// Non-biomes // Non-biomes
case biInvalidBiome: case biInvalidBiome:
case biNumBiomes: case biNumBiomes:
@ -273,18 +288,19 @@ int cStructGenTrees::GetNumTrees(
case biNumVariantBiomes: case biNumVariantBiomes:
{ {
ASSERT(!"Invalid biome in cStructGenTrees::GetNumTrees"); ASSERT(!"Invalid biome in cStructGenTrees::GetNumTrees");
return 0; return 0.0;
} }
} }
UNREACHABLE("Unsupported biome"); UNREACHABLE("Unsupported biome");
}; };
int NumTrees = 0; double NumTrees = 0.0;
for (auto Biome : a_Biomes) for (auto Biome : a_Biomes)
{ {
NumTrees += BiomeTrees(Biome); NumTrees += BiomeTrees(Biome);
} }
return NumTrees / 1024;
return NumTrees / (cChunkDef::Width * cChunkDef::Width * 4);
} }

View File

@ -18,8 +18,6 @@
class cStructGenTrees : class cStructGenTrees :
public cFinishGen public cFinishGen
{ {
@ -46,6 +44,7 @@ protected:
*/ */
void GenerateSingleTree( void GenerateSingleTree(
int a_ChunkX, int a_ChunkZ, int a_Seq, int a_ChunkX, int a_ChunkZ, int a_Seq,
Vector3i a_Pos,
cChunkDesc & a_ChunkDesc, cChunkDesc & a_ChunkDesc,
sSetBlockVector & a_OutsideLogs, sSetBlockVector & a_OutsideLogs,
sSetBlockVector & a_OutsideOther sSetBlockVector & a_OutsideOther
@ -59,7 +58,10 @@ protected:
sSetBlockVector & a_Overflow sSetBlockVector & a_Overflow
); );
int GetNumTrees( /** Get the the number of trees to generate in a_Chunk
If the value is between 0 and 1, it should be interpreted as the probability that a tree should be generated.
*/
double GetNumTrees(
int a_ChunkX, int a_ChunkZ, int a_ChunkX, int a_ChunkZ,
const cChunkDef::BiomeMap & a_Biomes const cChunkDef::BiomeMap & a_Biomes
); );

View File

@ -230,12 +230,12 @@ void GetTreeImageByBiome(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, EMCSB
switch (a_Biome) switch (a_Biome)
{ {
case biPlains: case biPlains:
case biExtremeHills:
case biExtremeHillsEdge:
case biForest: case biForest:
case biMushroomIsland: case biMushroomIsland:
case biMushroomShore: case biMushroomShore:
case biForestHills: case biForestHills:
case biSunflowerPlains:
case biFlowerForest:
case biDeepOcean: case biDeepOcean:
case biStoneBeach: case biStoneBeach:
case biColdBeach: case biColdBeach:
@ -252,10 +252,14 @@ void GetTreeImageByBiome(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, EMCSB
return; return;
} }
case biTaiga: case biColdTaiga:
case biColdTaigaM:
case biColdTaigaHills:
case biIcePlains: case biIcePlains:
case biIceMountains: case biIceMountains:
case biTaiga:
case biTaigaHills: case biTaigaHills:
case biTaigaM:
{ {
// Conifers // Conifers
GetConiferTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks); GetConiferTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
@ -273,6 +277,8 @@ void GetTreeImageByBiome(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, EMCSB
case biJungle: case biJungle:
case biJungleHills: case biJungleHills:
case biJungleEdge: case biJungleEdge:
case biJungleM:
case biJungleEdgeM:
{ {
// Apple bushes, large jungle trees, small jungle trees // Apple bushes, large jungle trees, small jungle trees
if (a_Noise.IntNoise3DInt(a_BlockPos.addedY(16 * a_Seq).addedZ(16 * a_Seq)) < 0x6fffffff) if (a_Noise.IntNoise3DInt(a_BlockPos.addedY(16 * a_Seq).addedZ(16 * a_Seq)) < 0x6fffffff)
@ -301,26 +307,34 @@ void GetTreeImageByBiome(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, EMCSB
return; return;
} }
case biColdTaiga:
case biColdTaigaHills:
case biMegaTaiga: case biMegaTaiga:
case biMegaTaigaHills: case biMegaTaigaHills:
case biExtremeHillsPlus: {
case biSunflowerPlains: // TODO: implement trees 2x2 huge conifers (spruce and pine)
case biDesertM: return;
case biExtremeHillsM: }
case biFlowerForest:
case biTaigaM:
case biIcePlainsSpikes:
case biJungleM:
case biJungleEdgeM:
case biColdTaigaM:
case biMegaSpruceTaiga: case biMegaSpruceTaiga:
case biMegaSpruceTaigaHills: case biMegaSpruceTaigaHills:
{
// TODO: implement trees 2x2 huge spruce
return;
}
case biExtremeHills:
case biExtremeHillsM:
case biExtremeHillsEdge:
case biExtremeHillsPlus:
case biExtremeHillsPlusM: case biExtremeHillsPlusM:
{ {
// TODO: These need their special trees if (a_Noise.IntNoise3DInt(a_BlockPos.addedY(16 * a_Seq).addedZ(16 * a_Seq)) < 0x6fffffff)
GetBirchTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks); {
GetConiferTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
}
else
{
GetAppleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
}
return; return;
} }
@ -352,6 +366,7 @@ void GetTreeImageByBiome(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, EMCSB
case biDesert: case biDesert:
case biDesertHills: case biDesertHills:
case biDesertM:
case biRiver: case biRiver:
case biBeach: case biBeach:
case biHell: case biHell:
@ -359,6 +374,7 @@ void GetTreeImageByBiome(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, EMCSB
case biOcean: case biOcean:
case biFrozenOcean: case biFrozenOcean:
case biFrozenRiver: case biFrozenRiver:
case biIcePlainsSpikes:
case biVariant: case biVariant:
case biNumBiomes: case biNumBiomes:
case biNumVariantBiomes: case biNumVariantBiomes: