summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Generating/ComposableGenerator.cpp4
-rw-r--r--src/Generating/FinishGen.cpp105
-rw-r--r--src/Generating/FinishGen.h18
3 files changed, 97 insertions, 30 deletions
diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp
index e964bca46..c73ecf6cc 100644
--- a/src/Generating/ComposableGenerator.cpp
+++ b/src/Generating/ComposableGenerator.cpp
@@ -525,7 +525,9 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
}
else if (NoCaseCompare(finisher, "SprinkleFoliage") == 0)
{
- m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSprinkleFoliage(Seed)));
+ int MaxCactusHeight = a_IniFile.GetValueI("Plants", "MaxCactusHeight", 3);
+ int MaxSugarcaneHeight = a_IniFile.GetValueI("Plants", "MaxSugarcaneHeight", 3);
+ m_FinishGens.push_back(std::make_shared<cFinishGenSprinkleFoliage>(Seed, MaxCactusHeight, MaxSugarcaneHeight));
}
else if (NoCaseCompare(finisher, "TallGrass") == 0)
{
diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp
index 8c54be0d0..ec5c0c144 100644
--- a/src/Generating/FinishGen.cpp
+++ b/src/Generating/FinishGen.cpp
@@ -671,24 +671,66 @@ void cFinishGenVines::GenFinish(cChunkDesc & a_ChunkDesc)
////////////////////////////////////////////////////////////////////////////////
// cFinishGenSprinkleFoliage:
-bool cFinishGenSprinkleFoliage::TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelY, int a_RelZ)
+bool cFinishGenSprinkleFoliage::TryAddCactus(cChunkDesc & a_ChunkDesc, int a_RelX, HEIGHTTYPE & a_RelY, int a_RelZ)
{
+ if (!IsDesertVariant(a_ChunkDesc.GetBiome(a_RelX, a_RelZ)))
+ {
+ return false;
+ }
+
+ int CactusHeight = 1 + (m_Noise.IntNoise2DInt(a_RelX, a_RelZ) % m_MaxCactusHeight);
+
+ // We'll be doing comparison with blocks above, so the coords should be 1 block away from chunk top
+ if (a_RelY + CactusHeight >= cChunkDef::Height - 1)
+ {
+ CactusHeight = cChunkDef::Height - a_RelY - 1;
+ }
+
// We'll be doing comparison to neighbors, so require the coords to be 1 block away from the chunk edges:
if (
- (a_RelX < 1) || (a_RelX >= cChunkDef::Width - 1) ||
- (a_RelY < 1) || (a_RelY >= cChunkDef::Height - 2) ||
- (a_RelZ < 1) || (a_RelZ >= cChunkDef::Width - 1)
+ (a_RelX < 1) || (a_RelX >= cChunkDef::Width - 1) ||
+ (a_RelZ < 1) || (a_RelZ >= cChunkDef::Width - 1)
)
{
return false;
}
- // Only allow dirt, grass or sand below sugarcane:
+ for (int i = 0; i < CactusHeight; i++)
+ {
+ const bool cactusExists = i != 0;
+
+ const int y = a_RelY + 1;
+ if (
+ cBlockInfo::IsSolid(a_ChunkDesc.GetBlockType(a_RelX + 1, y, a_RelZ)) ||
+ cBlockInfo::IsSolid(a_ChunkDesc.GetBlockType(a_RelX - 1, y, a_RelZ)) ||
+ cBlockInfo::IsSolid(a_ChunkDesc.GetBlockType(a_RelX, y, a_RelZ + 1)) ||
+ cBlockInfo::IsSolid(a_ChunkDesc.GetBlockType(a_RelX, y, a_RelZ - 1))
+ )
+ {
+ return cactusExists;
+ }
+
+ // All conditions are met, we can place a cactus here
+ a_ChunkDesc.SetBlockType(a_RelX, ++a_RelY, a_RelZ, E_BLOCK_CACTUS);
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// cFinishGenSprinkleFoliage:
+
+bool cFinishGenSprinkleFoliage::TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_RelX, HEIGHTTYPE & a_RelY, int a_RelZ)
+{
+ int SugarcaneHeight = 1 + (m_Noise.IntNoise2DInt(a_RelX, a_RelZ) % m_MaxSugarcaneHeight);
+
+ // Only allow dirt, grass, sand and sugarcane below sugarcane:
switch (a_ChunkDesc.GetBlockType(a_RelX, a_RelY, a_RelZ))
{
case E_BLOCK_DIRT:
case E_BLOCK_GRASS:
case E_BLOCK_SAND:
+ case E_BLOCK_SUGARCANE:
{
break;
}
@@ -698,19 +740,39 @@ bool cFinishGenSprinkleFoliage::TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_
}
}
- // Water is required next to the block below the sugarcane:
+ // We'll be doing comparison with blocks above, so the coords should be 1 block away from chunk top
+ if (a_RelY + SugarcaneHeight >= cChunkDef::Height - 1)
+ {
+ SugarcaneHeight = cChunkDef::Height - a_RelY - 1;
+ }
+
+ // We'll be doing comparison to neighbors, so require the coords to be 1 block away from the chunk edges:
+ if (
+ (a_RelX < 1) || (a_RelX >= cChunkDef::Width - 1) ||
+ (a_RelZ < 1) || (a_RelZ >= cChunkDef::Width - 1)
+ )
+ {
+ return false;
+ }
+
+ // Water is required next to the block below the sugarcane (if the block below isn't sugarcane already)
if (
!IsWater(a_ChunkDesc.GetBlockType(a_RelX - 1, a_RelY, a_RelZ)) &&
!IsWater(a_ChunkDesc.GetBlockType(a_RelX + 1, a_RelY, a_RelZ)) &&
!IsWater(a_ChunkDesc.GetBlockType(a_RelX, a_RelY, a_RelZ - 1)) &&
- !IsWater(a_ChunkDesc.GetBlockType(a_RelX, a_RelY, a_RelZ + 1))
+ !IsWater(a_ChunkDesc.GetBlockType(a_RelX, a_RelY, a_RelZ + 1)) &&
+ a_ChunkDesc.GetBlockType(a_RelX, a_RelY, a_RelZ) != E_BLOCK_SUGARCANE
)
{
return false;
}
- // All conditions met, place a sugarcane here:
- a_ChunkDesc.SetBlockType(a_RelX, a_RelY + 1, a_RelZ, E_BLOCK_SUGARCANE);
+ for (int i = 0; i < SugarcaneHeight; i++)
+ {
+ // All conditions met, place a sugarcane here
+ a_ChunkDesc.SetBlockType(a_RelX, ++a_RelY, a_RelZ, E_BLOCK_SUGARCANE);
+ }
+
return true;
}
@@ -778,7 +840,7 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc)
}
else if (TryAddSugarcane(a_ChunkDesc, x, Top, z))
{
- ++Top;
+ // Checks and block placing are handled in the TryAddSugarcane method
}
else if ((val1 > 0.5) && (val2 < -0.5))
{
@@ -789,29 +851,22 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc)
case E_BLOCK_SAND:
{
- int y = Top + 1;
- if (
- (x > 0) && (x < cChunkDef::Width - 1) &&
- (z > 0) && (z < cChunkDef::Width - 1) &&
- (val1 + val2 > 0.5f) &&
- (a_ChunkDesc.GetBlockType(x + 1, y, z) == E_BLOCK_AIR) &&
- (a_ChunkDesc.GetBlockType(x - 1, y, z) == E_BLOCK_AIR) &&
- (a_ChunkDesc.GetBlockType(x, y, z + 1) == E_BLOCK_AIR) &&
- (a_ChunkDesc.GetBlockType(x, y, z - 1) == E_BLOCK_AIR) &&
- IsDesertVariant(a_ChunkDesc.GetBiome(x, z))
- )
+ if (val1 + val2 > 0.5f)
{
- a_ChunkDesc.SetBlockType(x, ++Top, z, E_BLOCK_CACTUS);
+ if (!TryAddCactus(a_ChunkDesc, x, Top, z))
+ {
+ TryAddSugarcane(a_ChunkDesc, x, Top, z);
+ }
}
- else if (TryAddSugarcane(a_ChunkDesc, x, Top, z))
+ else
{
- ++Top;
+ TryAddSugarcane(a_ChunkDesc, x, Top, z);
}
break;
}
} // switch (TopBlock)
a_ChunkDesc.SetHeight(x, z, Top);
- } // for y
+ } // for x
} // for z
}
diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h
index 0138c84bc..b6edce84f 100644
--- a/src/Generating/FinishGen.h
+++ b/src/Generating/FinishGen.h
@@ -260,14 +260,24 @@ class cFinishGenSprinkleFoliage :
public cFinishGen
{
public:
- cFinishGenSprinkleFoliage(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed) {}
-
+ cFinishGenSprinkleFoliage(int a_Seed, int a_MaxCactusHeight, int a_MaxSugarcaneHeight):
+ m_Noise(a_Seed),
+ m_Seed(a_Seed),
+ m_MaxCactusHeight(a_MaxCactusHeight),
+ m_MaxSugarcaneHeight(a_MaxSugarcaneHeight)
+ {
+ }
protected:
cNoise m_Noise;
int m_Seed;
+ int m_MaxCactusHeight;
+ int m_MaxSugarcaneHeight;
+
+ /** Tries to place sugarcane at the coords specified, returns true if successful, updates the top variable (hence the & a_RefY) */
+ bool TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_RelX, HEIGHTTYPE & a_RelY, int a_RelZ);
- /** Tries to place sugarcane at the coords specified, returns true if successful */
- bool TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelY, int a_RelZ);
+ /** Tries to place cactus at the coords specified, returns true if successful, updates the top variable (hence the & a_RefY) */
+ bool TryAddCactus(cChunkDesc & a_ChunkDesc, int a_RelX, HEIGHTTYPE & a_RelY, int a_RelZ);
// Returns true is the specified biome is a desert or its variant
static bool IsDesertVariant(EMCSBiome a_biome);