Index: source/cChunkGenerator.cpp =================================================================== --- source/cChunkGenerator.cpp (revision 730) +++ source/cChunkGenerator.cpp (working copy) @@ -294,7 +294,7 @@ void cChunkGenerator::InitStructureGens(cIniFile & a_IniFile) { - AString Structures = a_IniFile.GetValueSet("Generator", "Structures", "Trees,MarbleCaves,OreNests"); + AString Structures = a_IniFile.GetValueSet("Generator", "Structures", "Trees,MarbleCaves,OreNests,Veins"); AStringVector Str = StringSplit(Structures, ","); for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) @@ -316,6 +316,10 @@ { m_StructureGens.push_back(new cStructGenOreNests(m_Seed)); } + else if (NoCaseCompare(*itr, "veins") == 0) + { + m_StructureGens.push_back(new cStructGenVeins(m_Seed)); + } else if (NoCaseCompare(*itr, "ravines") == 0) { m_StructureGens.push_back(new cStructGenRavines(m_Seed, 128)); Index: source/StructGen.cpp =================================================================== --- source/StructGen.cpp (revision 730) +++ source/StructGen.cpp (working copy) @@ -7,9 +7,18 @@ #include "Trees.h" +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStructGenVeins configuration: +const int MAX_HEIGHT_DIRT = 127; +const int NUM_NESTS_DIRT = 20; +const int NEST_SIZE_DIRT = 32; +const int MAX_HEIGHT_GRAVEL = 70; +const int NUM_NESTS_GRAVEL = 15; +const int NEST_SIZE_GRAVEL = 32; + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cStructGenOreNests configuration: @@ -401,5 +410,102 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cStructGenVeins: +void cStructGenVeins::GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted +) +{ + GenerateVein(a_ChunkX, a_ChunkZ, E_BLOCK_DIRT, MAX_HEIGHT_DIRT, NUM_NESTS_DIRT, NEST_SIZE_DIRT, a_BlockTypes, 10); + GenerateVein(a_ChunkX, a_ChunkZ, E_BLOCK_GRAVEL, MAX_HEIGHT_GRAVEL, NUM_NESTS_GRAVEL, NEST_SIZE_GRAVEL, a_BlockTypes, 11); +} + + + +void cStructGenVeins::GenerateVein(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_VeinType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq) +{ + // This function generates several "nests" of ore, each nest consisting of number of ore blocks relatively adjacent to each other. + // It does so by making a random XYZ walk and adding ore along the way in cuboids of different (random) sizes + // Only stone gets replaced with ore, all other blocks stay (so the nest can actually be smaller than specified). + + for (int i = 0; i < a_NumNests; i++) + { + int rnd = m_Noise.IntNoise3DInt(a_ChunkX + i, a_Seq, a_ChunkZ + 64 * i) / 8; + int BaseX = rnd % cChunkDef::Width; + rnd /= cChunkDef::Width; + int BaseZ = rnd % cChunkDef::Width; + rnd /= cChunkDef::Width; + int BaseY = rnd % a_MaxHeight; + rnd /= a_MaxHeight; + int NestSize = a_NestSize + (rnd % (a_NestSize / 4)); // The actual nest size may be up to 1/4 larger + int Num = 0; + while (Num < NestSize) + { + // Put a cuboid around [BaseX, BaseY, BaseZ] + int rnd = m_Noise.IntNoise3DInt(a_ChunkX + 64 * i, 2 * a_Seq + Num, a_ChunkZ + 32 * i) / 8; + int xsize = rnd % 2; + int ysize = (rnd / 4) % 2; + int zsize = (rnd / 16) % 2; + rnd >>= 8; + for (int x = xsize; x >= 0; --x) + { + int BlockX = BaseX + x; + if ((BlockX < 0) || (BlockX >= cChunkDef::Width)) + { + Num++; // So that the cycle finishes even if the base coords wander away from the chunk + continue; + } + for (int y = ysize; y >= 0; --y) + { + int BlockY = BaseY + y; + if ((BlockY < 0) || (BlockY >= cChunkDef::Height)) + { + Num++; // So that the cycle finishes even if the base coords wander away from the chunk + continue; + } + for (int z = zsize; z >= 0; --z) + { + int BlockZ = BaseZ + z; + if ((BlockZ < 0) || (BlockZ >= cChunkDef::Width)) + { + Num++; // So that the cycle finishes even if the base coords wander away from the chunk + continue; + } + + int Index = cChunkDef::MakeIndexNoCheck(BlockX, BlockY, BlockZ); + if (a_BlockTypes[Index] == E_BLOCK_STONE) + { + a_BlockTypes[Index] = a_VeinType; + } + Num++; + } // for z + } // for y + } // for x + + // Move the base to a neighbor voxel + switch (rnd % 4) + { + case 0: BaseX--; break; + case 1: BaseX++; break; + } + switch ((rnd >> 3) % 4) + { + case 0: BaseY--; break; + case 1: BaseY++; break; + } + switch ((rnd >> 6) % 4) + { + case 0: BaseZ--; break; + case 1: BaseZ++; break; + } + } // while (Num < NumBlocks) + } // for i - NumNests +} + Index: source/StructGen.h =================================================================== --- source/StructGen.h (revision 730) +++ source/StructGen.h (working copy) @@ -5,6 +5,7 @@ - cStructGenTrees - cStructGenMarbleCaves - cStructGenOres + - cStructGenVeins */ @@ -110,3 +111,29 @@ +class cStructGenVeins : + public cStructureGen +{ +public: + cStructGenVeins(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed) {} + +protected: + cNoise m_Noise; + int m_Seed; + + // cStructureGen override: + virtual void GenStructures( + int a_ChunkX, int a_ChunkZ, + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change + cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data + cEntityList & a_Entities, // Entities may be added or deleted + cBlockEntityList & a_BlockEntities // Block entities may be added or deleted + ) override; + + void GenerateVein(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq); +} ; + + + +