summaryrefslogtreecommitdiffstats
path: root/src/Generating/FinishGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Generating/FinishGen.cpp')
-rw-r--r--src/Generating/FinishGen.cpp223
1 files changed, 155 insertions, 68 deletions
diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp
index 78b28bff5..5f8099922 100644
--- a/src/Generating/FinishGen.cpp
+++ b/src/Generating/FinishGen.cpp
@@ -247,25 +247,34 @@ void cFinishGenClumpTopBlock::TryPlaceFoliageClump(cChunkDesc & a_ChunkDesc, int
int NumBlocks = m_Noise.IntNoise2DInt(a_CenterX + ChunkX * 16, a_CenterZ + ChunkZ * 16) % (MAX_NUM_FOLIAGE - MIN_NUM_FOLIAGE) + MIN_NUM_FOLIAGE + 1;
for (int i = 1; i < NumBlocks; i++)
{
- int rnd = m_Noise.IntNoise2DInt(ChunkX + ChunkZ + i, ChunkX - ChunkZ - i) / 59;
- int x = a_CenterX + (((rnd % 256) % RANGE_FROM_CENTER * 2) - RANGE_FROM_CENTER);
- int z = a_CenterZ + (((rnd / 256) % RANGE_FROM_CENTER * 2) - RANGE_FROM_CENTER);
+ int Rnd = m_Noise.IntNoise2DInt(ChunkX + ChunkZ + i, ChunkX - ChunkZ - i) / 59;
+ int x = a_CenterX + (((Rnd % 59) % RANGE_FROM_CENTER * 2) - RANGE_FROM_CENTER);
+ int z = a_CenterZ + (((Rnd / 97) % RANGE_FROM_CENTER * 2) - RANGE_FROM_CENTER);
int Top = a_ChunkDesc.GetHeight(x, z);
- if (a_ChunkDesc.GetBlockType(x, Top, z) != E_BLOCK_GRASS)
+ // Doesn't place if the blocks can't be placed. Checked value also depends on a_IsDoubleTall
+ if (Top + 1 + (a_IsDoubleTall ? 1 : 0) >= cChunkDef::Height)
{
continue;
}
- a_ChunkDesc.SetBlockTypeMeta(x, Top + 1, z, a_BlockType, a_BlockMeta);
- if (a_IsDoubleTall)
- {
- a_ChunkDesc.SetBlockTypeMeta(x, Top + 2, z, E_BLOCK_BIG_FLOWER, E_META_BIG_FLOWER_TOP);
- a_ChunkDesc.SetHeight(x, z, static_cast<HEIGHTTYPE>(Top + 2));
- }
- else
+ auto GroundBlockType = a_ChunkDesc.GetBlockType(x, Top, z);
+ if (
+ (GroundBlockType == E_BLOCK_GRASS) || (
+ (GroundBlockType == E_BLOCK_MYCELIUM) && ((a_BlockType == E_BLOCK_RED_MUSHROOM) || (a_BlockType == E_BLOCK_BROWN_MUSHROOM))
+ )
+ )
{
- a_ChunkDesc.SetHeight(x, z, static_cast<HEIGHTTYPE>(Top + 1));
+ a_ChunkDesc.SetBlockTypeMeta(x, Top + 1, z, a_BlockType, a_BlockMeta);
+ if (a_IsDoubleTall)
+ {
+ a_ChunkDesc.SetBlockTypeMeta(x, Top + 2, z, E_BLOCK_BIG_FLOWER, E_META_BIG_FLOWER_TOP);
+ a_ChunkDesc.SetHeight(x, z, static_cast<HEIGHTTYPE>(Top + 2));
+ }
+ else
+ {
+ a_ChunkDesc.SetHeight(x, z, static_cast<HEIGHTTYPE>(Top + 1));
+ }
}
}
@@ -278,9 +287,10 @@ void cFinishGenClumpTopBlock::TryPlaceFoliageClump(cChunkDesc & a_ChunkDesc, int
void cFinishGenClumpTopBlock::ParseConfigurationString(const AString & a_RawClumpInfo, std::vector<BiomeInfo> & a_Output)
{
// Initialize the vector for all biomes.
- for (int i = static_cast<int>(a_Output.size()); i < static_cast<int>(biMaxVariantBiome); i++)
+ for (int i = static_cast<int>(a_Output.size()); i <= static_cast<int>(biMaxVariantBiome); i++)
{
- a_Output.push_back(BiomeInfo());
+ // Push empty BiomeInfo structure to be later directly accessed by index:
+ a_Output.emplace_back();
}
AStringVector ClumpInfo = StringSplitAndTrim(a_RawClumpInfo, "=");
@@ -297,15 +307,18 @@ void cFinishGenClumpTopBlock::ParseConfigurationString(const AString & a_RawClum
for (const auto & RawBiomeInfo : Biomes)
{
- AStringVector BiomeInfo = StringSplitAndTrim(RawBiomeInfo, ",");
- AString BiomeName = BiomeInfo[0];
- EMCSBiome Biome = StringToBiome(BiomeName);
+ const AStringVector BiomeInfo = StringSplitAndTrim(RawBiomeInfo, ",");
+ const AString & BiomeName = BiomeInfo[0];
+ const EMCSBiome Biome = StringToBiome(BiomeName);
if (Biome == biInvalidBiome)
{
LOGWARNING("Biome \"%s\" is invalid.", BiomeName.c_str());
continue;
}
+ // The index of Biome in the output vector.
+ const size_t BiomeIndex = static_cast<size_t>(Biome);
+
if (BiomeInfo.size() == 2)
{
// Only the minimum amount of clumps per chunk is changed.
@@ -315,10 +328,10 @@ void cFinishGenClumpTopBlock::ParseConfigurationString(const AString & a_RawClum
LOGWARNING("OverworldClumpFoliage: Invalid data in \"%s\". Second parameter is either not existing or a number", RawBiomeInfo.c_str());
continue;
}
- a_Output[static_cast<size_t>(Biome)].m_MinNumClumpsPerChunk = MinNumClump;
+ a_Output[BiomeIndex].m_MinNumClumpsPerChunk = MinNumClump;
// In case the minimum number is higher than the current maximum value we change the max to the minimum value.
- a_Output[static_cast<size_t>(Biome)].m_MaxNumClumpsPerChunk = std::max(MinNumClump, a_Output[static_cast<size_t>(Biome)].m_MaxNumClumpsPerChunk);
+ a_Output[BiomeIndex].m_MaxNumClumpsPerChunk = std::max(MinNumClump, a_Output[BiomeIndex].m_MaxNumClumpsPerChunk);
}
else if (BiomeInfo.size() == 3)
{
@@ -330,22 +343,24 @@ void cFinishGenClumpTopBlock::ParseConfigurationString(const AString & a_RawClum
continue;
}
- a_Output[static_cast<size_t>(Biome)].m_MaxNumClumpsPerChunk = MaxNumClumps + 1;
- a_Output[static_cast<size_t>(Biome)].m_MinNumClumpsPerChunk = MinNumClumps;
+ a_Output[BiomeIndex].m_MaxNumClumpsPerChunk = MaxNumClumps + 1;
+ a_Output[BiomeIndex].m_MinNumClumpsPerChunk = MinNumClumps;
}
// TODO: Make the weight configurable.
for (const auto & BlockName : Blocks)
{
- cItem Block = cItem();
- if (!StringToItem(BlockName, Block) && IsValidBlock(Block.m_ItemType))
+ cItem Block;
+ if (!StringToItem(BlockName, Block) || !IsValidBlock(Block.m_ItemType))
{
LOGWARNING("Block \"%s\" is invalid", BlockName.c_str());
continue;
}
- FoliageInfo info = FoliageInfo(static_cast<BLOCKTYPE>(Block.m_ItemType), static_cast<NIBBLETYPE>(Block.m_ItemDamage), 100);
- a_Output[static_cast<size_t>(Biome)].m_Blocks.push_back(info);
+ // Construct the FoliageInfo:
+ a_Output[BiomeIndex].m_Blocks.emplace_back(
+ static_cast<BLOCKTYPE>(Block.m_ItemType), static_cast<NIBBLETYPE>(Block.m_ItemDamage), 100
+ );
}
}
}
@@ -354,12 +369,9 @@ void cFinishGenClumpTopBlock::ParseConfigurationString(const AString & a_RawClum
-std::vector<cFinishGenClumpTopBlock::BiomeInfo> cFinishGenClumpTopBlock::ParseIniFile(cIniFile & a_IniFile, AString a_ClumpPrefix)
+std::vector<cFinishGenClumpTopBlock::BiomeInfo> cFinishGenClumpTopBlock::ParseIniFile(cIniFile & a_IniFile, const AString & a_ClumpPrefix)
{
- // Also check dashes in case we will get more configuration options with the same prefix.
- a_ClumpPrefix += "-";
-
- std::vector<cFinishGenClumpTopBlock::BiomeInfo> foliage;
+ std::vector<cFinishGenClumpTopBlock::BiomeInfo> Foliage;
int NumGeneratorValues = a_IniFile.GetNumValues("Generator");
int GeneratorKeyId = a_IniFile.FindKey("Generator");
for (int i = 0; i < NumGeneratorValues; i++)
@@ -368,20 +380,22 @@ std::vector<cFinishGenClumpTopBlock::BiomeInfo> cFinishGenClumpTopBlock::ParseIn
if (ValueName.substr(0, a_ClumpPrefix.size()) == a_ClumpPrefix)
{
AString RawClump = a_IniFile.GetValue(GeneratorKeyId, i);
- cFinishGenClumpTopBlock::ParseConfigurationString(RawClump, foliage);
+ cFinishGenClumpTopBlock::ParseConfigurationString(RawClump, Foliage);
}
}
- if (foliage.size() == 0)
+ if (Foliage.empty())
{
- cFinishGenClumpTopBlock::ParseConfigurationString(a_IniFile.GetValueSet("Generator", a_ClumpPrefix + "-1", "Forest, -2, 2; ForestHills, -3, 2; FlowerForest = yellowflower, redflower, lilac, rosebush"), foliage);
- cFinishGenClumpTopBlock::ParseConfigurationString(a_IniFile.GetValueSet("Generator", a_ClumpPrefix + "-2", "Plains, -2, 1; SunflowerPlains = yellowflower, redflower, azurebluet, oxeyedaisy"), foliage);
- cFinishGenClumpTopBlock::ParseConfigurationString(a_IniFile.GetValueSet("Generator", a_ClumpPrefix + "-3", "SunflowerPlains, 1, 2 = sunflower"), foliage);
- cFinishGenClumpTopBlock::ParseConfigurationString(a_IniFile.GetValueSet("Generator", a_ClumpPrefix + "-4", "FlowerForest, 2, 5 = allium, redtulip, orangetulip, whitetulip, pinktulip, oxeyedaisy"), foliage);
- cFinishGenClumpTopBlock::ParseConfigurationString(a_IniFile.GetValueSet("Generator", a_ClumpPrefix + "-5", "Swampland, SwamplandM = brownmushroom, redmushroom, blueorchid"), foliage);
+ cFinishGenClumpTopBlock::ParseConfigurationString(a_IniFile.GetValueSet("Generator", a_ClumpPrefix + "-1", "Forest, -2, 2; ForestHills, -3, 2; FlowerForest = yellowflower; redflower; lilac; rosebush"), Foliage);
+ cFinishGenClumpTopBlock::ParseConfigurationString(a_IniFile.GetValueSet("Generator", a_ClumpPrefix + "-2", "Plains, -2, 1; SunflowerPlains = yellowflower; redflower; azurebluet; redtulip; orangetulip; whitetulip; pinktulip; oxeyedaisy"), Foliage);
+ cFinishGenClumpTopBlock::ParseConfigurationString(a_IniFile.GetValueSet("Generator", a_ClumpPrefix + "-3", "SunflowerPlains, 1, 2 = sunflower"), Foliage);
+ cFinishGenClumpTopBlock::ParseConfigurationString(a_IniFile.GetValueSet("Generator", a_ClumpPrefix + "-4", "FlowerForest, 2, 5 = allium; redtulip; orangetulip; whitetulip; pinktulip; oxeyedaisy"), Foliage);
+ cFinishGenClumpTopBlock::ParseConfigurationString(a_IniFile.GetValueSet("Generator", a_ClumpPrefix + "-5", "Swampland; SwamplandM = brownmushroom; redmushroom; blueorchid"), Foliage);
+ cFinishGenClumpTopBlock::ParseConfigurationString(a_IniFile.GetValueSet("Generator", a_ClumpPrefix + "-6", "MushroomIsland; MushroomShore; MegaTaiga; MegaTaigaHills; MegaSpruceTaiga; MegaSpruceTaigaHills = brownmushroom; redmushroom"), Foliage);
+ cFinishGenClumpTopBlock::ParseConfigurationString(a_IniFile.GetValueSet("Generator", a_ClumpPrefix + "-7", "RoofedForest, 1, 5; RoofedForestM, 1, 5 = rosebush; peony; lilac; grass"), Foliage);
}
- return foliage;
+ return Foliage;
}
@@ -541,21 +555,26 @@ void cFinishGenTallGrass::GenFinish(cChunkDesc & a_ChunkDesc)
int GrassType = m_Noise.IntNoise2DInt(xx * 50, zz * 50) / 7 % 100;
if (GrassType < 60)
{
- a_ChunkDesc.SetBlockTypeMeta(x, y, z, E_BLOCK_TALL_GRASS, 1);
+ a_ChunkDesc.SetBlockTypeMeta(x, y, z, E_BLOCK_TALL_GRASS, E_META_TALL_GRASS_GRASS);
}
- else if (GrassType < 90)
+ else if ((GrassType < 90) && CanFernGrow(a_ChunkDesc.GetBiome(x, z)))
{
- a_ChunkDesc.SetBlockTypeMeta(x, y, z, E_BLOCK_TALL_GRASS, 2);
+ a_ChunkDesc.SetBlockTypeMeta(x, y, z, E_BLOCK_TALL_GRASS, E_META_TALL_GRASS_FERN);
}
else if (!IsBiomeVeryCold(a_ChunkDesc.GetBiome(x, z)))
{
// If double long grass we have to choose what type we should use:
if (a_ChunkDesc.GetBlockType(x, y + 1, z) == E_BLOCK_AIR)
{
- NIBBLETYPE Meta = (m_Noise.IntNoise2DInt(xx * 100, zz * 100) / 7 % 100) > 25 ? 2 : 3;
- a_ChunkDesc.SetBlockTypeMeta(x, y, z, E_BLOCK_BIG_FLOWER, Meta);
- a_ChunkDesc.SetBlockTypeMeta(x, y + 1, z, E_BLOCK_BIG_FLOWER, E_META_BIG_FLOWER_TOP);
- a_ChunkDesc.SetHeight(x, z, static_cast<HEIGHTTYPE>(y + 1));
+ NIBBLETYPE Meta = (m_Noise.IntNoise2DInt(xx * 100, zz * 100) / 7 % 100) > 25 ?
+ E_META_BIG_FLOWER_DOUBLE_TALL_GRASS : E_META_BIG_FLOWER_LARGE_FERN;
+
+ if ((Meta != E_META_BIG_FLOWER_LARGE_FERN) || CanLargeFernGrow(a_ChunkDesc.GetBiome(x, z)))
+ {
+ a_ChunkDesc.SetBlockTypeMeta(x, y, z, E_BLOCK_BIG_FLOWER, Meta);
+ a_ChunkDesc.SetBlockTypeMeta(x, y + 1, z, E_BLOCK_BIG_FLOWER, E_META_BIG_FLOWER_TOP);
+ a_ChunkDesc.SetHeight(x, z, static_cast<HEIGHTTYPE>(y + 1));
+ }
}
}
else
@@ -572,6 +591,95 @@ void cFinishGenTallGrass::GenFinish(cChunkDesc & a_ChunkDesc)
+bool cFinishGenTallGrass::CanFernGrow(EMCSBiome a_Biome)
+{
+ switch (a_Biome)
+ {
+ case biJungle:
+ case biJungleEdge:
+ case biJungleEdgeM:
+ case biJungleHills:
+ case biJungleM:
+ {
+ return true;
+ }
+
+ default:
+ {
+ return CanLargeFernGrow(a_Biome);
+ }
+ }
+}
+
+
+
+
+
+bool cFinishGenTallGrass::CanLargeFernGrow(EMCSBiome a_Biome)
+{
+ switch (a_Biome)
+ {
+ case biColdTaiga:
+ case biColdTaigaHills:
+ case biColdTaigaM:
+
+ case biTaiga:
+ case biTaigaHills:
+ case biTaigaM:
+
+ case biMegaSpruceTaiga:
+ case biMegaSpruceTaigaHills:
+ case biMegaTaiga:
+ case biMegaTaigaHills:
+ {
+ return true;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+}
+
+
+
+
+
+int cFinishGenTallGrass::GetBiomeDensity(EMCSBiome a_Biome)
+{
+ switch (a_Biome)
+ {
+ case biSavanna:
+ case biSavannaM:
+ case biSavannaPlateau:
+ case biSavannaPlateauM:
+ case biPlains:
+ {
+ return 70;
+ }
+
+ case biExtremeHillsEdge:
+ case biExtremeHillsPlus:
+ case biExtremeHills:
+ case biExtremeHillsPlusM:
+ case biExtremeHillsM:
+ case biIceMountains:
+ {
+ return 3;
+ }
+
+ default:
+ {
+ return 20;
+ }
+ }
+}
+
+
+
+
+
////////////////////////////////////////////////////////////////////////////////
// cFinishGenVines
@@ -816,34 +924,13 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc)
{
case E_BLOCK_GRASS:
{
- float val3 = m_Noise.CubicNoise2D(xx * 0.01f + 10, zz * 0.01f + 10);
- float val4 = m_Noise.CubicNoise2D(xx * 0.05f + 20, zz * 0.05f + 20);
- if (val1 + val2 > 0.2f)
- {
- a_ChunkDesc.SetBlockType(x, ++Top, z, E_BLOCK_YELLOW_FLOWER);
- }
- else if (val2 + val3 > 0.2f)
- {
- a_ChunkDesc.SetBlockType(x, ++Top, z, E_BLOCK_RED_ROSE);
- }
- else if (val3 + val4 > 0.2f)
- {
- a_ChunkDesc.SetBlockType(x, ++Top, z, E_BLOCK_RED_MUSHROOM);
- }
- else if (val1 + val4 > 0.2f)
- {
- a_ChunkDesc.SetBlockType(x, ++Top, z, E_BLOCK_BROWN_MUSHROOM);
- }
- else if (val1 + val2 + val3 + val4 < -0.1)
- {
- a_ChunkDesc.SetBlockTypeMeta(x, ++Top, z, E_BLOCK_TALL_GRASS, E_META_TALL_GRASS_GRASS);
- }
- else if (TryAddSugarcane(a_ChunkDesc, x, Top, z))
+ if (TryAddSugarcane(a_ChunkDesc, x, Top, z))
{
// Checks and block placing are handled in the TryAddSugarcane method
}
else if ((val1 > 0.5) && (val2 < -0.5))
{
+ float val3 = m_Noise.CubicNoise2D(xx * 0.01f + 10, zz * 0.01f + 10);
a_ChunkDesc.SetBlockTypeMeta(x, ++Top, z, E_BLOCK_PUMPKIN, static_cast<int>(val3 * 8) % 4);
}
break;