summaryrefslogtreecommitdiffstats
path: root/src/Generating/StructGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Generating/StructGen.cpp')
-rw-r--r--src/Generating/StructGen.cpp198
1 files changed, 105 insertions, 93 deletions
diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp
index 2b497e9a5..3e6a70996 100644
--- a/src/Generating/StructGen.cpp
+++ b/src/Generating/StructGen.cpp
@@ -37,12 +37,13 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc)
Dest = &WorkerDesc;
WorkerDesc.SetChunkCoords({BaseX, BaseZ});
- // TODO: This may cause a lot of wasted calculations, instead of pulling data out of a single (cChunkDesc) cache
+ // TODO: This may cause a lot of wasted calculations, instead of pulling data out of a single
+ // (cChunkDesc) cache
cChunkDesc::Shape workerShape;
- m_BiomeGen.GenBiomes ({BaseX, BaseZ}, WorkerDesc.GetBiomeMap());
- m_ShapeGen.GenShape ({BaseX, BaseZ}, workerShape);
- WorkerDesc.SetHeightFromShape (workerShape);
+ m_BiomeGen.GenBiomes({BaseX, BaseZ}, WorkerDesc.GetBiomeMap());
+ m_ShapeGen.GenShape({BaseX, BaseZ}, workerShape);
+ WorkerDesc.SetHeightFromShape(workerShape);
m_CompositionGen.ComposeTerrain(WorkerDesc, workerShape);
}
else
@@ -60,7 +61,9 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc)
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)
+ 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);
}
@@ -94,7 +97,9 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc)
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,
sSetBlockVector & a_OutsideLogs,
@@ -108,17 +113,20 @@ void cStructGenTrees::GenerateSingleTree(
// Check the block underneath the tree:
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) && (TopBlock != E_BLOCK_MYCELIUM))
+ if ((TopBlock != E_BLOCK_DIRT) && (TopBlock != E_BLOCK_GRASS) && (TopBlock != E_BLOCK_FARMLAND) &&
+ (TopBlock != E_BLOCK_MYCELIUM))
{
return;
}
sSetBlockVector TreeLogs, TreeOther;
GetTreeImageByBiome(
- { a_ChunkX * cChunkDef::Width + a_Pos.x, a_Pos.y + 1, a_ChunkZ * cChunkDef::Width + a_Pos.z },
- m_Noise, a_Seq,
+ {a_ChunkX * cChunkDef::Width + a_Pos.x, a_Pos.y + 1, a_ChunkZ * cChunkDef::Width + a_Pos.z},
+ m_Noise,
+ a_Seq,
a_ChunkDesc.GetBiome(a_Pos.x, a_Pos.z),
- TreeLogs, TreeOther
+ TreeLogs,
+ TreeOther
);
// Check if the generated image fits the terrain. Only the logs are checked:
@@ -138,20 +146,20 @@ void cStructGenTrees::GenerateSingleTree(
BLOCKTYPE Block = a_ChunkDesc.GetBlockType(itr->m_RelX, itr->m_RelY, itr->m_RelZ);
switch (Block)
{
- CASE_TREE_ALLOWED_BLOCKS:
- {
- break;
- }
- default:
- {
- // There's something in the way, abort this tree altogether
- return;
- }
+ CASE_TREE_ALLOWED_BLOCKS:
+ {
+ break;
+ }
+ default:
+ {
+ // There's something in the way, abort this tree altogether
+ return;
+ }
}
}
ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeOther, a_OutsideOther);
- ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeLogs, a_OutsideLogs);
+ ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeLogs, a_OutsideLogs);
}
@@ -159,7 +167,8 @@ void cStructGenTrees::GenerateSingleTree(
void cStructGenTrees::ApplyTreeImage(
- int a_ChunkX, int a_ChunkZ,
+ int a_ChunkX,
+ int a_ChunkZ,
cChunkDesc & a_ChunkDesc,
const sSetBlockVector & a_Image,
sSetBlockVector & a_Overflow
@@ -186,12 +195,11 @@ void cStructGenTrees::ApplyTreeImage(
}
CASE_TREE_OVERWRITTEN_BLOCKS:
{
- a_ChunkDesc.SetBlockTypeMeta(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
+ a_ChunkDesc
+ .SetBlockTypeMeta(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
// If grass is below our tree, turn it to dirt
- if (
- (cBlockInfo::IsSolid(itr->m_BlockType)) &&
- (a_ChunkDesc.GetBlockType(itr->m_RelX, itr->m_RelY - 1, itr->m_RelZ) == E_BLOCK_GRASS)
- )
+ if ((cBlockInfo::IsSolid(itr->m_BlockType)) &&
+ (a_ChunkDesc.GetBlockType(itr->m_RelX, itr->m_RelY - 1, itr->m_RelZ) == E_BLOCK_GRASS))
{
a_ChunkDesc.SetBlockType(itr->m_RelX, itr->m_RelY - 1, itr->m_RelZ, E_BLOCK_DIRT);
}
@@ -212,10 +220,7 @@ void cStructGenTrees::ApplyTreeImage(
-double cStructGenTrees::GetNumTrees(
- int a_ChunkX, int a_ChunkZ,
- const cChunkDef::BiomeMap & a_Biomes
-)
+double cStructGenTrees::GetNumTrees(int a_ChunkX, int a_ChunkZ, const cChunkDef::BiomeMap & a_Biomes)
{
auto BiomeTrees = [](EMCSBiome a_Biome)
{
@@ -316,22 +321,23 @@ void cStructGenLakes::GenFinish(cChunkDesc & a_ChunkDesc)
int ChunkX = a_ChunkDesc.GetChunkX();
int ChunkZ = a_ChunkDesc.GetChunkZ();
- for (int z = -1; z < 2; z++) for (int x = -1; x < 2; x++)
- {
- if (((m_Noise.IntNoise2DInt(ChunkX + x, ChunkZ + z) / 17) % 100) > m_Probability)
+ for (int z = -1; z < 2; z++)
+ for (int x = -1; x < 2; x++)
{
- continue;
- }
+ if (((m_Noise.IntNoise2DInt(ChunkX + x, ChunkZ + z) / 17) % 100) > m_Probability)
+ {
+ continue;
+ }
- cBlockArea Lake;
- CreateLakeImage(ChunkX + x, ChunkZ + z, a_ChunkDesc.GetMinHeight(), Lake);
+ cBlockArea Lake;
+ CreateLakeImage(ChunkX + x, ChunkZ + z, a_ChunkDesc.GetMinHeight(), Lake);
- int OfsX = Lake.GetOriginX() + x * cChunkDef::Width;
- int OfsZ = Lake.GetOriginZ() + z * cChunkDef::Width;
+ int OfsX = Lake.GetOriginX() + x * cChunkDef::Width;
+ int OfsZ = Lake.GetOriginZ() + z * cChunkDef::Width;
- // Merge the lake into the current data
- a_ChunkDesc.WriteBlockArea(Lake, OfsX, Lake.GetOriginY(), OfsZ, cBlockArea::msLake);
- } // for x, z - neighbor chunks
+ // Merge the lake into the current data
+ a_ChunkDesc.WriteBlockArea(Lake, OfsX, Lake.GetOriginY(), OfsZ, cBlockArea::msLake);
+ } // for x, z - neighbor chunks
}
@@ -343,13 +349,16 @@ void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeH
a_Lake.Create(16, 8, 16);
a_Lake.Fill(cBlockArea::baTypes, E_BLOCK_SPONGE); // Sponge is the NOP blocktype for lake merging strategy
- // Make a random position in the chunk by using a random 16 block XZ offset and random height up to chunk's max height minus 6
+ // Make a random position in the chunk by using a random 16 block XZ offset and random height up to chunk's max
+ // height minus 6
int MinHeight = std::max(a_MaxLakeHeight - 6, 2);
int Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 128, a_ChunkZ) / 11;
- // Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide and subtract to get range
+ // Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide
+ // and subtract to get range
int OffsetX = 4 * ((Rnd & 0x07) + ((Rnd & 0x38) >> 3) + ((Rnd & 0x1c0) >> 6) + ((Rnd & 0xe00) >> 9)) / 7 - 8;
Rnd >>= 12;
- // Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide and subtract to get range
+ // Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide
+ // and subtract to get range
int OffsetZ = 4 * ((Rnd & 0x07) + ((Rnd & 0x38) >> 3) + ((Rnd & 0x1c0) >> 6) + ((Rnd & 0xe00) >> 9)) / 7 - 8;
Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 512, a_ChunkZ) / 13;
// Random height [1 .. MinHeight] with preference to center heights
@@ -399,13 +408,14 @@ void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeH
// Turn air in the bottom half into liquid:
for (int y = 0; y < 4; y++)
{
- for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++)
- {
- if (BlockTypes[x + z * 16 + y * 16 * 16] == E_BLOCK_AIR)
+ for (int z = 0; z < 16; z++)
+ for (int x = 0; x < 16; x++)
{
- BlockTypes[x + z * 16 + y * 16 * 16] = m_Fluid;
- }
- } // for z, x
+ if (BlockTypes[x + z * 16 + y * 16 * 16] == E_BLOCK_AIR)
+ {
+ BlockTypes[x + z * 16 + y * 16 * 16] = m_Fluid;
+ }
+ } // for z, x
} // for y
// TODO: Turn sponge next to lava into stone
@@ -421,8 +431,7 @@ void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeH
// cStructGenDirectOverhangs:
cStructGenDirectOverhangs::cStructGenDirectOverhangs(int a_Seed) :
- m_Noise1(a_Seed),
- m_Noise2(a_Seed + 1000)
+ m_Noise1(a_Seed), m_Noise2(a_Seed + 1000)
{
}
@@ -443,9 +452,10 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc)
const int SEGMENT_HEIGHT = 8;
const int INTERPOL_X = 16; // Must be a divisor of 16
const int INTERPOL_Z = 16; // Must be a divisor of 16
- // Interpolate the chunk in 16 * SEGMENT_HEIGHT * 16 "segments", each SEGMENT_HEIGHT blocks high and each linearly interpolated separately.
- // Have two buffers, one for the lowest floor and one for the highest floor, so that Y-interpolation can be done between them
- // Then swap the buffers and use the previously-top one as the current-bottom, without recalculating it.
+ // Interpolate the chunk in 16 * SEGMENT_HEIGHT * 16 "segments", each SEGMENT_HEIGHT blocks high and each linearly
+ // interpolated separately. Have two buffers, one for the lowest floor and one for the highest floor, so that
+ // Y-interpolation can be done between them Then swap the buffers and use the previously-top one as the
+ // current-bottom, without recalculating it.
int FloorBuf1[17 * 17];
int FloorBuf2[17 * 17];
@@ -456,48 +466,50 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc)
int BaseY = 63;
// Interpolate the lowest floor:
- for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++)
- {
- FloorLo[INTERPOL_X * x + 17 * INTERPOL_Z * z] =
- m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) *
- m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) /
- 256;
- } // for x, z - FloorLo[]
+ for (int z = 0; z <= 16 / INTERPOL_Z; z++)
+ for (int x = 0; x <= 16 / INTERPOL_X; x++)
+ {
+ FloorLo[INTERPOL_X * x + 17 * INTERPOL_Z * z] =
+ m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) *
+ m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) / 256;
+ } // for x, z - FloorLo[]
LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo);
// Interpolate segments:
for (int Segment = BaseY; Segment < MaxHeight; Segment += SEGMENT_HEIGHT)
{
// First update the high floor:
- for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++)
- {
- FloorHi[INTERPOL_X * x + 17 * INTERPOL_Z * z] = (
- m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) *
- m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) / 256
- );
- } // for x, z - FloorLo[]
+ for (int z = 0; z <= 16 / INTERPOL_Z; z++)
+ for (int x = 0; x <= 16 / INTERPOL_X; x++)
+ {
+ FloorHi[INTERPOL_X * x + 17 * INTERPOL_Z * z] =
+ (m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) *
+ m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) /
+ 256);
+ } // for x, z - FloorLo[]
LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi);
// Interpolate between FloorLo and FloorHi:
- for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++)
- {
- EMCSBiome biome = a_ChunkDesc.GetBiome(x, z);
-
- if ((biome == biExtremeHills) || (biome == biExtremeHillsEdge))
+ for (int z = 0; z < 16; z++)
+ for (int x = 0; x < 16; x++)
{
- int Lo = FloorLo[x + 17 * z] / 256;
- int Hi = FloorHi[x + 17 * z] / 256;
- for (int y = 0; y < SEGMENT_HEIGHT; y++)
+ EMCSBiome biome = a_ChunkDesc.GetBiome(x, z);
+
+ if ((biome == biExtremeHills) || (biome == biExtremeHillsEdge))
{
- int Val = Lo + (Hi - Lo) * y / SEGMENT_HEIGHT;
- if (Val < 0)
+ int Lo = FloorLo[x + 17 * z] / 256;
+ int Hi = FloorHi[x + 17 * z] / 256;
+ for (int y = 0; y < SEGMENT_HEIGHT; y++)
{
- a_ChunkDesc.SetBlockType(x, y + Segment, z, E_BLOCK_AIR);
- }
- } // for y
- break;
- } // if (biome)
- } // for z, x
+ int Val = Lo + (Hi - Lo) * y / SEGMENT_HEIGHT;
+ if (Val < 0)
+ {
+ a_ChunkDesc.SetBlockType(x, y + Segment, z, E_BLOCK_AIR);
+ }
+ } // for y
+ break;
+ } // if (biome)
+ } // for z, x
// Swap the floors:
std::swap(FloorLo, FloorHi);
@@ -537,10 +549,7 @@ bool cStructGenDirectOverhangs::HasWantedBiome(cChunkDesc & a_ChunkDesc) const
// cStructGenDistortedMembraneOverhangs:
cStructGenDistortedMembraneOverhangs::cStructGenDistortedMembraneOverhangs(int a_Seed) :
- m_NoiseX(a_Seed + 1000),
- m_NoiseY(a_Seed + 2000),
- m_NoiseZ(a_Seed + 3000),
- m_NoiseH(a_Seed + 4000)
+ m_NoiseX(a_Seed + 1000), m_NoiseY(a_Seed + 2000), m_NoiseZ(a_Seed + 3000), m_NoiseH(a_Seed + 4000)
{
}
@@ -559,14 +568,17 @@ void cStructGenDistortedMembraneOverhangs::GenFinish(cChunkDesc & a_ChunkDesc)
BLOCKTYPE ReplacementBlock = (y > 62) ? E_BLOCK_AIR : E_BLOCK_STATIONARY_WATER;
for (int z = 0; z < cChunkDef::Width; z++)
{
- NOISE_DATATYPE NoiseZ = static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + z) / Frequency;
+ NOISE_DATATYPE NoiseZ =
+ static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + z) / Frequency;
for (int x = 0; x < cChunkDef::Width; x++)
{
- NOISE_DATATYPE NoiseX = static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkX() * cChunkDef::Width + x) / Frequency;
+ NOISE_DATATYPE NoiseX =
+ static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkX() * cChunkDef::Width + x) / Frequency;
NOISE_DATATYPE DistortX = m_NoiseX.CubicNoise3D(NoiseX, NoiseY, NoiseZ) * Amount;
NOISE_DATATYPE DistortY = m_NoiseY.CubicNoise3D(NoiseX, NoiseY, NoiseZ) * Amount;
NOISE_DATATYPE DistortZ = m_NoiseZ.CubicNoise3D(NoiseX, NoiseY, NoiseZ) * Amount;
- int MembraneHeight = 96 - static_cast<int>((DistortY + m_NoiseH.CubicNoise2D(NoiseX + DistortX, NoiseZ + DistortZ)) * 30);
+ int MembraneHeight = 96 -
+ static_cast<int>((DistortY + m_NoiseH.CubicNoise2D(NoiseX + DistortX, NoiseZ + DistortZ)) * 30);
if (MembraneHeight < y)
{
a_ChunkDesc.SetBlockType(x, y, z, ReplacementBlock);