diff options
author | Julian Laubstein <julianlaubstein@yahoo.de> | 2016-02-06 11:37:34 +0100 |
---|---|---|
committer | Julian Laubstein <julianlaubstein@yahoo.de> | 2016-02-06 11:37:34 +0100 |
commit | 6fdd7194c81be7234a126bdc3b48f0291fce3567 (patch) | |
tree | 7d5ac74b7385ce4ebf77588d80549c884c2b993c /src/Generating | |
parent | Merge pull request #2958 from LogicParrot/fence (diff) | |
parent | Bulk clearing of whitespace (diff) | |
download | cuberite-6fdd7194c81be7234a126bdc3b48f0291fce3567.tar cuberite-6fdd7194c81be7234a126bdc3b48f0291fce3567.tar.gz cuberite-6fdd7194c81be7234a126bdc3b48f0291fce3567.tar.bz2 cuberite-6fdd7194c81be7234a126bdc3b48f0291fce3567.tar.lz cuberite-6fdd7194c81be7234a126bdc3b48f0291fce3567.tar.xz cuberite-6fdd7194c81be7234a126bdc3b48f0291fce3567.tar.zst cuberite-6fdd7194c81be7234a126bdc3b48f0291fce3567.zip |
Diffstat (limited to 'src/Generating')
40 files changed, 606 insertions, 606 deletions
diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index ff8827511..4c58e8547 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -101,26 +101,26 @@ void cBioGenCache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a } // Found it in the cache size_t Idx = m_CacheOrder[i]; - + // Move to front: for (size_t j = i; j > 0; j--) { m_CacheOrder[j] = m_CacheOrder[j - 1]; } m_CacheOrder[0] = Idx; - + // Use the cached data: memcpy(a_BiomeMap, m_CacheData[Idx].m_BiomeMap, sizeof(a_BiomeMap)); - + m_NumHits++; m_TotalChain += i; return; } // for i - cache - + // Not in the cache: m_NumMisses++; m_BioGenToCache->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); - + // Insert it as the first item in the MRU order: size_t Idx = m_CacheOrder[m_CacheSize - 1]; for (size_t i = m_CacheSize - 1; i > 0; i--) @@ -346,7 +346,7 @@ void cBioGenDistortedVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::B { int BaseZ = cChunkDef::Width * a_ChunkZ; int BaseX = cChunkDef::Width * a_ChunkX; - + // Distortions for linear interpolation: int DistortX[cChunkDef::Width + 1][cChunkDef::Width + 1]; int DistortZ[cChunkDef::Width + 1][cChunkDef::Width + 1]; @@ -354,10 +354,10 @@ void cBioGenDistortedVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::B { Distort(BaseX + x * 4, BaseZ + z * 4, DistortX[4 * x][4 * z], DistortZ[4 * x][4 * z]); } - + LinearUpscale2DArrayInPlace<cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4>(&DistortX[0][0]); LinearUpscale2DArrayInPlace<cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4>(&DistortZ[0][0]); - + for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) @@ -391,7 +391,7 @@ void cBioGenDistortedVoronoi::Distort(int a_BlockX, int a_BlockZ, int & a_Distor double NoiseZ = m_Noise.CubicNoise3D(static_cast<float>(a_BlockX / m_CellSize), static_cast<float>(a_BlockZ / m_CellSize), 4000); NoiseZ += 0.5 * m_Noise.CubicNoise3D(2 * static_cast<float>(a_BlockX / m_CellSize), 2 * static_cast<float>(a_BlockZ / m_CellSize), 5000); NoiseZ += 0.08 * m_Noise.CubicNoise3D(16 * static_cast<float>(a_BlockX / m_CellSize), 16 * static_cast<float>(a_BlockZ / m_CellSize), 6000); - + a_DistortedX = a_BlockX + static_cast<int>(m_CellSize * 0.5 * NoiseX); a_DistortedZ = a_BlockZ + static_cast<int>(m_CellSize * 0.5 * NoiseZ); } @@ -450,7 +450,7 @@ void cBioGenMultiStepMap::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::Biome void cBioGenMultiStepMap::DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) { // Distorted Voronoi over 3 biomes, with mushroom having only a special occurence. - + // Prepare a distortion lookup table, by distorting a 5x5 area and using that as 1:4 zoom (linear interpolate): int BaseZ = cChunkDef::Width * a_ChunkZ; int BaseX = cChunkDef::Width * a_ChunkX; @@ -463,7 +463,7 @@ void cBioGenMultiStepMap::DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cC } LinearUpscale2DArrayInPlace<cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4>(&DistortX[0][0]); LinearUpscale2DArrayInPlace<cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4>(&DistortZ[0][0]); - + // Prepare a 9x9 area of neighboring cell seeds // (assuming that 7x7 cell area is larger than a chunk being generated) const int NEIGHBORHOOD_SIZE = 4; // How many seeds in each direction to check @@ -487,7 +487,7 @@ void cBioGenMultiStepMap::DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cC SeedV[xc][zc] = (((m_Noise6.IntNoise3DInt(RealCellX, RealCellX - RealCellZ + 1000, RealCellZ) / 11) % 256) > 90) ? biOcean : (biInvalidBiome); } // for z } // for x - + for (int xc = 1; xc < 2 * NEIGHBORHOOD_SIZE; xc++) for (int zc = 1; zc < 2 * NEIGHBORHOOD_SIZE; zc++) { if ( @@ -505,7 +505,7 @@ void cBioGenMultiStepMap::DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cC SeedV[xc][zc] = biMushroomIsland; } } - + // For each column find the nearest distorted cell and use its value as the biome: int MushroomOceanThreshold = m_OceanCellSize * m_OceanCellSize * m_MushroomIslandSize / 1024; int MushroomShoreThreshold = m_OceanCellSize * m_OceanCellSize * m_MushroomIslandSize / 2048; @@ -562,13 +562,13 @@ void cBioGenMultiStepMap::AddRivers(int a_ChunkX, int a_ChunkZ, cChunkDef::Biome // Biome already set, skip this column continue; } - + float NoiseCoordX = static_cast<float>(a_ChunkX * cChunkDef::Width + x) / m_RiverCellSize; - + double Noise = m_Noise1.CubicNoise2D( NoiseCoordX, NoiseCoordZ); Noise += 0.5 * m_Noise3.CubicNoise2D(2 * NoiseCoordX, 2 * NoiseCoordZ); Noise += 0.1 * m_Noise5.CubicNoise2D(8 * NoiseCoordX, 8 * NoiseCoordZ); - + if ((Noise > 0) && (Noise < m_RiverWidthThreshold)) { cChunkDef::SetBiome(a_BiomeMap, x, z, biRiver); @@ -586,7 +586,7 @@ void cBioGenMultiStepMap::ApplyTemperatureHumidity(int a_ChunkX, int a_ChunkZ, c IntMap TemperatureMap; IntMap HumidityMap; BuildTemperatureHumidityMaps(a_ChunkX, a_ChunkZ, TemperatureMap, HumidityMap); - + FreezeWaterBiomes(a_BiomeMap, TemperatureMap); DecideLandBiomes(a_BiomeMap, TemperatureMap, HumidityMap); } @@ -603,7 +603,7 @@ void cBioGenMultiStepMap::Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX double NoiseZ = m_Noise6.CubicNoise2D( static_cast<float>(a_BlockX / a_CellSize), static_cast<float>(a_BlockZ / a_CellSize)); NoiseZ += 0.5 * m_Noise5.CubicNoise2D(2 * static_cast<float>(a_BlockX / a_CellSize), 2 * static_cast<float>(a_BlockZ / a_CellSize)); NoiseZ += 0.1 * m_Noise4.CubicNoise2D(16 * static_cast<float>(a_BlockX / a_CellSize), 16 * static_cast<float>(a_BlockZ / a_CellSize)); - + a_DistortedX = a_BlockX + static_cast<int>(a_CellSize * 0.5 * NoiseX); a_DistortedZ = a_BlockZ + static_cast<int>(a_CellSize * 0.5 * NoiseZ); } @@ -623,7 +623,7 @@ void cBioGenMultiStepMap::BuildTemperatureHumidityMaps(int a_ChunkX, int a_Chunk for (int x = 0; x < 17; x += 8) { float NoiseCoordX = static_cast<float>(a_ChunkX * cChunkDef::Width + x) / m_LandBiomesSize; - + double NoiseT = m_Noise1.CubicNoise2D( NoiseCoordX, NoiseCoordZ); NoiseT += 0.5 * m_Noise2.CubicNoise2D(2 * NoiseCoordX, 2 * NoiseCoordZ); NoiseT += 0.1 * m_Noise3.CubicNoise2D(8 * NoiseCoordX, 8 * NoiseCoordZ); @@ -637,7 +637,7 @@ void cBioGenMultiStepMap::BuildTemperatureHumidityMaps(int a_ChunkX, int a_Chunk } // for z LinearUpscale2DArrayInPlace<17, 17, 8, 8>(TemperatureMap); LinearUpscale2DArrayInPlace<17, 17, 8, 8>(HumidityMap); - + // Re-map into integral values in [0 .. 255] range: for (size_t idx = 0; idx < ARRAYCOUNT(a_TemperatureMap); idx++) { @@ -756,7 +756,7 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap { int BaseZ = cChunkDef::Width * a_ChunkZ; int BaseX = cChunkDef::Width * a_ChunkX; - + // Distortions for linear interpolation: int DistortX[cChunkDef::Width + 1][cChunkDef::Width + 1]; int DistortZ[cChunkDef::Width + 1][cChunkDef::Width + 1]; @@ -770,14 +770,14 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap double NoiseZ = m_AmpZ1 * m_Noise4.CubicNoise2D(BlockX * m_FreqZ1, BlockZ * m_FreqZ1); NoiseZ += m_AmpZ2 * m_Noise5.CubicNoise2D(BlockX * m_FreqZ2, BlockZ * m_FreqZ2); NoiseZ += m_AmpZ3 * m_Noise6.CubicNoise2D(BlockX * m_FreqZ3, BlockZ * m_FreqZ3); - + DistortX[4 * x][4 * z] = static_cast<int>(BlockX + NoiseX); DistortZ[4 * x][4 * z] = static_cast<int>(BlockZ + NoiseZ); } - + LinearUpscale2DArrayInPlace<cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4>(&DistortX[0][0]); LinearUpscale2DArrayInPlace<cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4>(&DistortZ[0][0]); - + // Apply distortion to each block coord, then query the voronoi maps for biome group and biome index and choose biome based on that: for (int z = 0; z < cChunkDef::Width; z++) { @@ -804,7 +804,7 @@ EMCSBiome cBioGenTwoLevel::SelectBiome(int a_BiomeGroup, size_t a_BiomeIdx, int EMCSBiome InnerBiome; EMCSBiome OuterBiome; } ; - + static BiomeLevels bgOcean[] = { { biOcean, biOcean, }, @@ -941,7 +941,7 @@ public: cBioGenGrown(int a_Seed) { auto FinalRivers = - + std::make_shared<cIntGenChoice<2, 7>>(a_Seed + 12) | MakeIntGen<cIntGenZoom <10>>(a_Seed + 11) | MakeIntGen<cIntGenSmooth<8>>(a_Seed + 6) diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h index a5b8cc7e7..576c6b83d 100644 --- a/src/Generating/BioGen.h +++ b/src/Generating/BioGen.h @@ -27,7 +27,7 @@ class cBioGenConstant : { public: cBioGenConstant(void) : m_Biome(biPlains) {} - + protected: EMCSBiome m_Biome; @@ -46,32 +46,32 @@ class cBioGenCache : public cBiomeGen { typedef cBiomeGen super; - + public: cBioGenCache(cBiomeGenPtr a_BioGenToCache, size_t a_CacheSize); virtual ~cBioGenCache(); - + protected: cBiomeGenPtr m_BioGenToCache; - + struct sCacheData { int m_ChunkX; int m_ChunkZ; cChunkDef::BiomeMap m_BiomeMap; } ; - + // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data size_t m_CacheSize; size_t * m_CacheOrder; // MRU-ized order, indices into m_CacheData array sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used - + // Cache statistics size_t m_NumHits; size_t m_NumMisses; size_t m_TotalChain; // Number of cache items walked to get to a hit (only added for hits) - + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void InitializeBiomeGen(cIniFile & a_IniFile) override; } ; @@ -117,13 +117,13 @@ class cBiomeGenList : public cBiomeGen { typedef cBiomeGen super; - + protected: // List of biomes that the generator is allowed to generate: typedef std::vector<EMCSBiome> EMCSBiomes; EMCSBiomes m_Biomes; int m_BiomesCount; // Pulled out of m_Biomes for faster access - + /** Parses the INI file setting string into m_Biomes. */ void InitializeBiomes(const AString & a_Biomes); } ; @@ -136,10 +136,10 @@ class cBioGenCheckerboard : public cBiomeGenList { typedef cBiomeGenList super; - + protected: int m_BiomeSize; - + // cBiomeGen overrides: virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void InitializeBiomeGen(cIniFile & a_IniFile) override; @@ -153,20 +153,20 @@ class cBioGenVoronoi : public cBiomeGenList { typedef cBiomeGenList super; - + public: cBioGenVoronoi(int a_Seed) : m_Voronoi(a_Seed) { } - + protected: cVoronoiMap m_Voronoi; - + // cBiomeGen overrides: virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void InitializeBiomeGen(cIniFile & a_IniFile) override; - + EMCSBiome VoronoiBiome(int a_BlockX, int a_BlockZ); } ; @@ -178,7 +178,7 @@ class cBioGenDistortedVoronoi : public cBiomeGenList { typedef cBiomeGenList super; - + public: cBioGenDistortedVoronoi(int a_Seed) : m_Noise(a_Seed), @@ -190,17 +190,17 @@ public: protected: /** Noise used for the distortion */ cNoise m_Noise; - + /** The underlying Voronoi map of the biomes */ cVoronoiMap m_Voronoi; - + /** Size of the Voronoi cells, also used for distortion amplitude */ int m_CellSize; - + // cBiomeGen overrides: virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void InitializeBiomeGen(cIniFile & a_IniFile) override; - + /** Distorts the coords using a Perlin-like noise */ void Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ); } ; @@ -213,10 +213,10 @@ class cBioGenMultiStepMap : public cBiomeGen { typedef cBiomeGen super; - + public: cBioGenMultiStepMap(int a_Seed); - + protected: // Noises used for composing the perlin-noise: cNoise m_Noise1; @@ -225,42 +225,42 @@ protected: cNoise m_Noise4; cNoise m_Noise5; cNoise m_Noise6; - + int m_Seed; int m_OceanCellSize; int m_MushroomIslandSize; int m_RiverCellSize; double m_RiverWidthThreshold; float m_LandBiomesSize; - + typedef int IntMap[17 * 17]; // x + 17 * z, expected trimmed into [0..255] range typedef double DblMap[17 * 17]; // x + 17 * z, expected trimmed into [0..1] range - + // cBiomeGen overrides: virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void InitializeBiomeGen(cIniFile & a_IniFile) override; - + /** Step 1: Decides between ocean, land and mushroom, using a DistVoronoi with special conditions and post-processing for mushroom islands Sets biomes to biOcean, -1 (i.e. land), biMushroomIsland or biMushroomShore. */ void DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap); - + /** Step 2: Add rivers to the land Flips some "-1" biomes into biRiver. */ void AddRivers(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap); - + /** Step 3: Decide land biomes using a temperature / humidity map; freeze ocean / river in low temperatures. Flips all remaining "-1" biomes into land biomes. Also flips some biOcean and biRiver into biFrozenOcean, biFrozenRiver, based on temp map. */ void ApplyTemperatureHumidity(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap); - + /** Distorts the coords using a Perlin-like noise, with a specified cell-size */ void Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ, int a_CellSize); - + /** Builds two Perlin-noise maps, one for temperature, the other for humidity. Trims both into [0..255] range */ void BuildTemperatureHumidityMaps(int a_ChunkX, int a_ChunkZ, IntMap & a_TemperatureMap, IntMap & a_HumidityMap); - + /** Flips all remaining "-1" biomes into land biomes using the two maps */ void DecideLandBiomes(cChunkDef::BiomeMap & a_BiomeMap, const IntMap & a_TemperatureMap, const IntMap & a_HumidityMap); - + /** Flips biOcean and biRiver into biFrozenOcean and biFrozenRiver if the temperature is too low */ void FreezeWaterBiomes(cChunkDef::BiomeMap & a_BiomeMap, const IntMap & a_TemperatureMap); } ; @@ -273,17 +273,17 @@ class cBioGenTwoLevel : public cBiomeGen { typedef cBiomeGen super; - + public: cBioGenTwoLevel(int a_Seed); - + protected: /** The Voronoi map that decides the groups of biomes */ cVoronoiMap m_VoronoiLarge; - + /** The Voronoi map that decides biomes inside individual biome groups */ cVoronoiMap m_VoronoiSmall; - + // The noises used for the distortion: cNoise m_Noise1; cNoise m_Noise2; diff --git a/src/Generating/Caves.h b/src/Generating/Caves.h index 691ef3e62..af5e3b5eb 100644 --- a/src/Generating/Caves.h +++ b/src/Generating/Caves.h @@ -23,11 +23,11 @@ class cStructGenMarbleCaves : { public: cStructGenMarbleCaves(int a_Seed) : m_Seed(a_Seed) {} - + protected: int m_Seed; - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -47,13 +47,13 @@ public: m_Threshold(a_Threshold) { } - + protected: cNoise m_Noise1; cNoise m_Noise2; int m_Seed; float m_Threshold; - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -75,7 +75,7 @@ public: m_Grid(a_Grid) { } - + protected: class cCaveSystem; // fwd: Caves.cpp diff --git a/src/Generating/ChunkDesc.cpp b/src/Generating/ChunkDesc.cpp index 07855b1d0..fcbebf1ca 100644 --- a/src/Generating/ChunkDesc.cpp +++ b/src/Generating/ChunkDesc.cpp @@ -185,7 +185,7 @@ void cChunkDesc::GetShapeFromHeight(Shape & a_Shape) const { a_Shape[y + x * 256 + z * 16 * 256] = 1; } - + for (int y = height + 1; y < cChunkDef::Height; y++) { a_Shape[y + x * 256 + z * 16 * 256] = 0; @@ -590,7 +590,7 @@ cBlockEntity * cChunkDesc::GetBlockEntity(int a_RelX, int a_RelY, int a_RelZ) return *itr; } } // for itr - m_BlockEntities[] - + // The block entity is not created yet, try to create it and add to list: cBlockEntity * be = cBlockEntity::CreateByBlockType(GetBlockType(a_RelX, a_RelY, a_RelZ), GetBlockMeta(a_RelX, a_RelY, a_RelZ), AbsX, a_RelY, AbsZ); if (be == nullptr) diff --git a/src/Generating/ChunkDesc.h b/src/Generating/ChunkDesc.h index 1033242f8..aa689fcd6 100644 --- a/src/Generating/ChunkDesc.h +++ b/src/Generating/ChunkDesc.h @@ -35,28 +35,28 @@ public: 1 = solid Indexed as [y + 256 * x + 256 * 16 * z]. */ typedef Byte Shape[256 * 16 * 16]; - + /** Uncompressed block metas, 1 meta per byte */ typedef NIBBLETYPE BlockNibbleBytes[cChunkDef::NumBlocks]; - + cChunkDesc(int a_ChunkX, int a_ChunkZ); ~cChunkDesc(); void SetChunkCoords(int a_ChunkX, int a_ChunkZ); - + // tolua_begin int GetChunkX(void) const { return m_ChunkX; } int GetChunkZ(void) const { return m_ChunkZ; } - + void FillBlocks(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); void SetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); void SetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType); BLOCKTYPE GetBlockType(int a_RelX, int a_RelY, int a_RelZ); - + void SetBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockMeta); NIBBLETYPE GetBlockMeta(int a_RelX, int a_RelY, int a_RelZ); @@ -100,7 +100,7 @@ public: /** Returns the minimum height value in the heightmap. */ HEIGHTTYPE GetMinHeight(void) const; - + /** Fills the relative cuboid with specified block; allows cuboid out of range of this chunk */ void FillRelCuboid( int a_MinX, int a_MaxX, @@ -108,7 +108,7 @@ public: int a_MinZ, int a_MaxZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ); - + /** Fills the relative cuboid with specified block; allows cuboid out of range of this chunk */ void FillRelCuboid(const cCuboid & a_RelCuboid, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { @@ -119,7 +119,7 @@ public: a_BlockType, a_BlockMeta ); } - + /** Replaces the specified src blocks in the cuboid by the dst blocks; allows cuboid out of range of this chunk */ void ReplaceRelCuboid( int a_MinX, int a_MaxX, @@ -128,7 +128,7 @@ public: BLOCKTYPE a_SrcType, NIBBLETYPE a_SrcMeta, BLOCKTYPE a_DstType, NIBBLETYPE a_DstMeta ); - + /** Replaces the specified src blocks in the cuboid by the dst blocks; allows cuboid out of range of this chunk */ void ReplaceRelCuboid( const cCuboid & a_RelCuboid, @@ -152,7 +152,7 @@ public: int a_MinZ, int a_MaxZ, BLOCKTYPE a_DstType, NIBBLETYPE a_DstMeta ); - + /** Replaces the blocks in the cuboid by the dst blocks if they are considered non-floor (air, water); allows cuboid out of range of this chunk */ void FloorRelCuboid( const cCuboid & a_RelCuboid, @@ -166,7 +166,7 @@ public: a_DstType, a_DstMeta ); } - + /** Fills the relative cuboid with specified block with a random chance; allows cuboid out of range of this chunk */ void RandomFillRelCuboid( int a_MinX, int a_MaxX, @@ -175,7 +175,7 @@ public: BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_RandomSeed, int a_ChanceOutOf10k ); - + /** Fills the relative cuboid with specified block with a random chance; allows cuboid out of range of this chunk */ void RandomFillRelCuboid( const cCuboid & a_RelCuboid, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, @@ -190,18 +190,18 @@ public: a_RandomSeed, a_ChanceOutOf10k ); } - + /** Returns the block entity at the specified coords. If there is no block entity at those coords, tries to create one, based on the block type If the blocktype doesn't support a block entity, returns nullptr. */ cBlockEntity * GetBlockEntity(int a_RelX, int a_RelY, int a_RelZ); - + /** Updates the heightmap to match the current contents. Useful for plugins when writing custom block areas into the chunk */ void UpdateHeightmap(void); - + // tolua_end - + // Accessors used by cChunkGenerator::Generator descendants: inline cChunkDef::BiomeMap & GetBiomeMap (void) { return m_BiomeMap; } inline cChunkDef::BlockTypes & GetBlockTypes (void) { return *(reinterpret_cast<cChunkDef::BlockTypes *>(m_BlockArea.GetBlockTypes())); } @@ -211,19 +211,19 @@ public: inline cChunkDef::HeightMap & GetHeightMap (void) { return m_HeightMap; } inline cEntityList & GetEntities (void) { return m_Entities; } inline cBlockEntityList & GetBlockEntities (void) { return m_BlockEntities; } - + /** Compresses the metas from the BlockArea format (1 meta per byte) into regular format (2 metas per byte) */ void CompressBlockMetas(cChunkDef::BlockNibbles & a_DestMetas); - + #ifdef _DEBUG /** Verifies that the heightmap corresponds to blocktype contents; if not, asserts on that column */ void VerifyHeightmap(void); #endif // _DEBUG - + private: int m_ChunkX; int m_ChunkZ; - + cChunkDef::BiomeMap m_BiomeMap; cBlockArea m_BlockArea; cChunkDef::HeightMap m_HeightMap; diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index bfa3344b9..50b77363a 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -64,7 +64,7 @@ bool cChunkGenerator::Start(cPluginInterface & a_PluginInterface, cChunkSink & a LOGINFO("Chosen a new random seed for world: %d", m_Seed); a_IniFile.SetValueI("Seed", "Seed", m_Seed); } - + // Get the generator engine based on the INI file settings: AString GeneratorName = a_IniFile.GetValueSet("Generator", "Generator", "Composable"); if (NoCaseCompare(GeneratorName, "Noise3D") == 0) diff --git a/src/Generating/ChunkGenerator.h b/src/Generating/ChunkGenerator.h index b7968356f..5c778fda4 100644 --- a/src/Generating/ChunkGenerator.h +++ b/src/Generating/ChunkGenerator.h @@ -37,7 +37,7 @@ class cChunkGenerator : cIsThread { typedef cIsThread super; - + public: /** The interface that a class has to implement to become a generator */ class cGenerator @@ -48,7 +48,7 @@ public: /** Called to initialize the generator on server startup. */ virtual void Initialize(cIniFile & a_IniFile); - + /** Generates the biomes for the specified chunk (directly, not in a separate thread). Used by the world loader if biomes failed loading. */ virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) = 0; @@ -57,47 +57,47 @@ public: /** Called in a separate thread to do the actual chunk generation. Generator should generate into a_ChunkDesc. */ virtual void DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a_ChunkDesc) = 0; - + protected: cChunkGenerator & m_ChunkGenerator; } ; - - + + /** The interface through which the plugins are called for their OnChunkGenerating / OnChunkGenerated hooks. */ class cPluginInterface { public: // Force a virtual destructor virtual ~cPluginInterface() {} - + /** Called when the chunk is about to be generated. The generator may be partly or fully overriden by the implementation. */ virtual void CallHookChunkGenerating(cChunkDesc & a_ChunkDesc) = 0; - + /** Called after the chunk is generated, before it is handed to the chunk sink. a_ChunkDesc contains the generated chunk data. Implementation may modify this data. */ virtual void CallHookChunkGenerated(cChunkDesc & a_ChunkDesc) = 0; } ; - - + + /** The interface through which the generated chunks are handed to the cWorld or whoever created us. */ class cChunkSink { public: // Force a virtual destructor virtual ~cChunkSink() {} - + /** Called after the chunk has been generated The interface may store the chunk, send it over network, whatever. The chunk is not expected to be modified, but the generator will survive if the implementation changes the data within. All changes are ignored, though. */ virtual void OnChunkGenerated(cChunkDesc & a_ChunkDesc) = 0; - + /** Called just before the chunk generation is started, to verify that it hasn't been generated in the meantime. If this callback returns true, the chunk is not generated. */ virtual bool IsChunkValid(int a_ChunkX, int a_ChunkZ) = 0; - + /** Called when the generator is overloaded to skip chunks that are no longer needed. If this callback returns false, the chunk is not generated. */ virtual bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) = 0; @@ -106,7 +106,7 @@ public: Currently used only in Debug-mode asserts. */ virtual bool IsChunkQueued(int a_ChunkX, int a_ChunkZ) = 0; } ; - + cChunkGenerator (void); ~cChunkGenerator(); @@ -120,22 +120,22 @@ public: It is legal to set the callback to nullptr, no callback is called then. If the generator becomes overloaded and skips this chunk, the callback is still called. */ void QueueGenerateChunk(int a_ChunkX, int a_ChunkZ, bool a_ForceGenerate, cChunkCoordCallback * a_Callback = nullptr); - + /** Generates the biomes for the specified chunk (directly, not in a separate thread). Used by the world loader if biomes failed loading. */ void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap); - + void WaitForQueueEmpty(void); - + int GetQueueLength(void); - + int GetSeed(void) const { return m_Seed; } - + /** Returns the biome at the specified coords. Used by ChunkMap if an invalid chunk is queried for biome */ EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ); /** Reads a block type from the ini file; returns the blocktype on success, emits a warning and returns a_Default's representation on failure. */ static BLOCKTYPE GetIniBlock(cIniFile & a_IniFile, const AString & a_SectionName, const AString & a_ValueName, const AString & a_Default); - + private: struct cQueueItem @@ -167,16 +167,16 @@ private: /** Set when an item is removed from the queue. */ cEvent m_evtRemoved; - + /** The actual generator engine used to generate chunks. */ cGenerator * m_Generator; - + /** The plugin interface that may modify the generated chunks */ cPluginInterface * m_PluginInterface; - + /** The destination where the generated chunks are sent */ cChunkSink * m_ChunkSink; - + // cIsThread override: virtual void Execute(void) override; diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp index 00a19b72b..22bc05f03 100644 --- a/src/Generating/CompoGen.cpp +++ b/src/Generating/CompoGen.cpp @@ -92,7 +92,7 @@ void cCompoGenDebugBiomes::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunk E_BLOCK_NETHER_BRICK, E_BLOCK_BEDROCK, } ; - + a_ChunkDesc.SetHeightFromShape(a_Shape); a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); @@ -153,7 +153,7 @@ void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc static int PatternLength = ARRAYCOUNT(PatternGround); ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternBeach)); ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternOcean)); - + for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) @@ -172,19 +172,19 @@ void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc { Pattern = PatternOcean; } - + // Fill water from sealevel down to height (if any): for (int y = m_SeaLevel; y >= Height; --y) { a_ChunkDesc.SetBlockType(x, y, z, m_BlockSea); } - + // Fill from height till the bottom: for (int y = Height; y >= 1; y--) { a_ChunkDesc.SetBlockType(x, y, z, (Height - y < PatternLength) ? Pattern[Height - y] : m_BlockBottom); } - + // The last layer is always bedrock: a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); } // for x @@ -229,21 +229,21 @@ cCompoGenNether::cCompoGenNether(int a_Seed) : void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { HEIGHTTYPE MaxHeight = a_ChunkDesc.GetMaxHeight(); - + 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. - + int FloorBuf1[17 * 17]; int FloorBuf2[17 * 17]; int * FloorHi = FloorBuf1; int * FloorLo = FloorBuf2; int BaseX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; int BaseZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; - + // Interpolate the lowest floor: for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++) { @@ -259,7 +259,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc: //*/ } // for x, z - FloorLo[] LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo); - + // Interpolate segments: for (int Segment = 0; Segment < MaxHeight; Segment += SEGMENT_HEIGHT) { @@ -278,7 +278,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc: //*/ } // 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++) { @@ -294,11 +294,11 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc: } } } - + // Swap the floors: std::swap(FloorLo, FloorHi); } - + // Bedrock at the bottom and at the top: for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++) { @@ -380,10 +380,10 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc:: LOGD("CompoGenCache: Avg cache chain length: %.2f", static_cast<float>(m_TotalChain) / m_NumHits); } #endif // _DEBUG - + int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); - + for (int i = 0; i < m_CacheSize; i++) { if ( @@ -395,28 +395,28 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc:: } // Found it in the cache int Idx = m_CacheOrder[i]; - + // Move to front: for (int j = i; j > 0; j--) { m_CacheOrder[j] = m_CacheOrder[j - 1]; } m_CacheOrder[0] = Idx; - + // Use the cached data: memcpy(a_ChunkDesc.GetBlockTypes(), m_CacheData[Idx].m_BlockTypes, sizeof(a_ChunkDesc.GetBlockTypes())); memcpy(a_ChunkDesc.GetBlockMetasUncompressed(), m_CacheData[Idx].m_BlockMetas, sizeof(a_ChunkDesc.GetBlockMetasUncompressed())); memcpy(a_ChunkDesc.GetHeightMap(), m_CacheData[Idx].m_HeightMap, sizeof(a_ChunkDesc.GetHeightMap())); - + m_NumHits++; m_TotalChain += i; return; } // for i - cache - + // Not in the cache: m_NumMisses++; m_Underlying->ComposeTerrain(a_ChunkDesc, a_Shape); - + // Insert it as the first item in the MRU order: int Idx = m_CacheOrder[m_CacheSize - 1]; for (int i = m_CacheSize - 1; i > 0; i--) diff --git a/src/Generating/CompoGen.h b/src/Generating/CompoGen.h index d4d38bfdd..b5108bac6 100644 --- a/src/Generating/CompoGen.h +++ b/src/Generating/CompoGen.h @@ -31,12 +31,12 @@ public: m_BlockType(E_BLOCK_STONE), m_IsBedrocked(true) {} - + protected: BLOCKTYPE m_BlockType; bool m_IsBedrocked; - + // cTerrainCompositionGen overrides: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; @@ -51,9 +51,9 @@ class cCompoGenDebugBiomes : { public: cCompoGenDebugBiomes(void) {} - + protected: - + // cTerrainCompositionGen overrides: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; } ; @@ -67,7 +67,7 @@ class cCompoGenClassic : { public: cCompoGenClassic(void); - + protected: int m_SeaLevel; @@ -79,7 +79,7 @@ protected: BLOCKTYPE m_BlockBeach; BLOCKTYPE m_BlockBeachBottom; BLOCKTYPE m_BlockSea; - + // cTerrainCompositionGen overrides: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; @@ -94,13 +94,13 @@ class cCompoGenNether : { public: cCompoGenNether(int a_Seed); - + protected: cNoise m_Noise1; cNoise m_Noise2; - + double m_MaxThreshold; - + // cTerrainCompositionGen overrides: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; @@ -117,15 +117,15 @@ class cCompoGenCache : public: cCompoGenCache(cTerrainCompositionGenPtr a_Underlying, int a_CacheSize); // Doesn't take ownership of a_Underlying ~cCompoGenCache(); - + // cTerrainCompositionGen override: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; - + protected: cTerrainCompositionGenPtr m_Underlying; - + struct sCacheData { int m_ChunkX; @@ -134,12 +134,12 @@ protected: cChunkDesc::BlockNibbleBytes m_BlockMetas; // The metas are uncompressed, 1 meta per byte cChunkDef::HeightMap m_HeightMap; } ; - + // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data int m_CacheSize; int * m_CacheOrder; // MRU-ized order, indices into m_CacheData array sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used - + // Cache statistics int m_NumHits; int m_NumMisses; diff --git a/src/Generating/CompoGenBiomal.cpp b/src/Generating/CompoGenBiomal.cpp index 43e98387f..0606477a1 100644 --- a/src/Generating/CompoGenBiomal.cpp +++ b/src/Generating/CompoGenBiomal.cpp @@ -39,7 +39,7 @@ public: { m_Pattern[i] = a_TopBlocks[i]; } - + // Fill the rest with stone: static BlockInfo Stone = {E_BLOCK_STONE, 0}; for (int i = static_cast<int>(a_Count); i < cChunkDef::Height; i++) @@ -47,9 +47,9 @@ public: m_Pattern[i] = Stone; } } - + const BlockInfo * Get(void) const { return m_Pattern; } - + protected: BlockInfo m_Pattern[cChunkDef::Height]; } ; @@ -192,14 +192,14 @@ public: { initMesaPattern(a_Seed); } - + protected: /** The block height at which water is generated instead of air. */ HEIGHTTYPE m_SeaLevel; /** The pattern used for mesa biomes. Initialized by seed on generator creation. */ cPattern::BlockInfo m_MesaPattern[2 * cChunkDef::Height]; - + /** Noise used for selecting between dirt and sand on the ocean floor. */ cNoise m_OceanFloorSelect; @@ -226,7 +226,7 @@ protected: { m_SeaLevel = static_cast<HEIGHTTYPE>(a_IniFile.GetValueSetI("Generator", "SeaLevel", m_SeaLevel)); } - + /** Initializes the m_MesaPattern with a pattern based on the generator's seed. */ @@ -309,7 +309,7 @@ protected: // Frequencies for the podzol floor selecting noise: const NOISE_DATATYPE FrequencyX = 8; const NOISE_DATATYPE FrequencyZ = 8; - + EMCSBiome Biome = a_ChunkDesc.GetBiome(a_RelX, a_RelZ); switch (Biome) { @@ -381,7 +381,7 @@ protected: FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patSand.Get(), a_ShapeColumn); return; } - + case biMushroomIsland: case biMushroomShore: { @@ -426,7 +426,7 @@ protected: } } // switch (Biome) } - + /** Fills the specified column with the specified pattern; restarts the pattern when air is reached, @@ -445,23 +445,23 @@ protected: PatternIdx++; continue; } - + // "air" or "water" part: // Reset the pattern index to zero, so that the pattern is repeated from the top again: PatternIdx = 0; - + if (y >= m_SeaLevel) { // "air" part, do nothing continue; } - + a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); if (HasHadWater) { continue; } - + // Select the ocean-floor pattern to use: if (a_ChunkDesc.GetBiome(a_RelX, a_RelZ) == biDeepOcean) { @@ -500,7 +500,7 @@ protected: { ClayFloor = Top - 1; } - + if (Top - m_SeaLevel < 5) { // Simple case: top is red sand, then hardened clay down to ClayFloor, then stone: @@ -516,7 +516,7 @@ protected: a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); return; } - + // Difficult case: use the mesa pattern and watch for overhangs: int PatternIdx = cChunkDef::Height - (Top - ClayFloor); // We want the block at index ClayFloor to be pattern's 256th block (first stone) const cPattern::BlockInfo * Pattern = m_MesaPattern; @@ -536,7 +536,7 @@ protected: // "air" part, do nothing continue; } - + // "water" part, fill with water and choose new pattern for ocean floor, if not chosen already: PatternIdx = 0; a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); @@ -544,7 +544,7 @@ protected: { continue; } - + // Select the ocean-floor pattern to use: Pattern = ChooseOceanFloorPattern(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), a_RelX, a_RelZ); HasHadWater = true; @@ -567,7 +567,7 @@ protected: } - + /** Returns the pattern to use for an ocean floor in the specified column. The returned pattern is guaranteed to be 256 blocks long. */ const cPattern::BlockInfo * ChooseOceanFloorPattern(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ) diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 478404d45..e9ab96aec 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -47,7 +47,7 @@ cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile LOGWARN("[Generator] CompositionGen value not set in world.ini, using \"Biomal\"."); CompoGenName = "Biomal"; } - + // Compositor list is alpha-sorted cTerrainCompositionGenPtr res; if (NoCaseCompare(CompoGenName, "Biomal") == 0) @@ -96,10 +96,10 @@ cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile return CreateCompositionGen(a_IniFile, a_BiomeGen, a_ShapeGen, a_Seed); } ASSERT(res != nullptr); - + // Read the settings from the ini file: res->InitializeCompoGen(a_IniFile); - + return cTerrainCompositionGenPtr(res); } @@ -125,7 +125,7 @@ cComposableGenerator::cComposableGenerator(cChunkGenerator & a_ChunkGenerator) : void cComposableGenerator::Initialize(cIniFile & a_IniFile) { super::Initialize(a_IniFile); - + InitBiomeGen(a_IniFile); InitShapeGen(a_IniFile); InitCompositionGen(a_IniFile); @@ -154,7 +154,7 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a { m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, a_ChunkDesc.GetBiomeMap()); } - + cChunkDesc::Shape shape; if (a_ChunkDesc.IsUsingDefaultHeight()) { @@ -166,7 +166,7 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a // Convert the heightmap in a_ChunkDesc into shape: a_ChunkDesc.GetShapeFromHeight(shape); } - + bool ShouldUpdateHeightmap = false; if (a_ChunkDesc.IsUsingDefaultComposition()) { @@ -181,7 +181,7 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a } // for itr - m_FinishGens[] ShouldUpdateHeightmap = true; } - + if (ShouldUpdateHeightmap) { a_ChunkDesc.UpdateHeightmap(); @@ -196,7 +196,7 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile) { bool CacheOffByDefault = false; m_BiomeGen = cBiomeGen::CreateBiomeGen(a_IniFile, m_ChunkGenerator.GetSeed(), CacheOffByDefault); - + // Add a cache, if requested: // The default is 16 * 128 caches, which is 2 MiB of RAM. Reasonable, for the amount of work this is saving. int CacheSize = a_IniFile.GetValueSetI("Generator", "BiomeGenCacheSize", CacheOffByDefault ? 0 : 16); @@ -232,7 +232,7 @@ void cComposableGenerator::InitShapeGen(cIniFile & a_IniFile) { bool CacheOffByDefault = false; m_ShapeGen = cTerrainShapeGen::CreateShapeGen(a_IniFile, m_BiomeGen, m_ChunkGenerator.GetSeed(), CacheOffByDefault); - + /* // TODO // Add a cache, if requested: @@ -259,7 +259,7 @@ void cComposableGenerator::InitShapeGen(cIniFile & a_IniFile) void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile) { m_CompositionGen = cTerrainCompositionGen::CreateCompositionGen(a_IniFile, m_BiomeGen, m_ShapeGen, m_ChunkGenerator.GetSeed()); - + // Add a cache over the composition generator: // Even a cache of size 1 is useful due to the CompositedHeiGen cache after us doing re-composition on its misses int CompoGenCacheSize = a_IniFile.GetValueSetI("Generator", "CompositionGenCacheSize", 64); diff --git a/src/Generating/ComposableGenerator.h b/src/Generating/ComposableGenerator.h index 32345fc79..056303db1 100644 --- a/src/Generating/ComposableGenerator.h +++ b/src/Generating/ComposableGenerator.h @@ -48,10 +48,10 @@ class cBiomeGen { public: virtual ~cBiomeGen() {} // Force a virtual destructor in descendants - + /** Generates biomes for the given chunk */ virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) = 0; - + /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeBiomeGen(cIniFile & a_IniFile) {} @@ -79,13 +79,13 @@ class cTerrainShapeGen { public: virtual ~cTerrainShapeGen() {} // Force a virtual destructor in descendants - + /** Generates the shape for the given chunk */ virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) = 0; - + /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeShapeGen(cIniFile & a_IniFile) {} - + /** Creates the correct TerrainShapeGen descendant based on the ini file settings and the seed provided. a_BiomeGen is the underlying biome generator, some shape generators may depend on it providing additional biomes data around the chunk a_CacheOffByDefault gets set to whether the cache should be disabled by default @@ -142,14 +142,14 @@ class cTerrainCompositionGen { public: virtual ~cTerrainCompositionGen() {} // Force a virtual destructor in descendants - + /** Generates the chunk's composition into a_ChunkDesc, using the terrain shape provided in a_Shape. Is expected to fill a_ChunkDesc's heightmap with the data from a_Shape. */ virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) = 0; - + /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeCompoGen(cIniFile & a_IniFile) {} - + /** Creates the correct TerrainCompositionGen descendant based on the ini file settings and the seed provided. a_BiomeGen is the underlying biome generator, some composition generators may depend on it providing additional biomes around the chunk a_ShapeGen is the underlying shape generator, some composition generators may depend on it providing additional shape around the chunk @@ -172,7 +172,7 @@ class cFinishGen { public: virtual ~cFinishGen() {} // Force a virtual destructor in descendants - + virtual void GenFinish(cChunkDesc & a_ChunkDesc) = 0; } ; @@ -186,10 +186,10 @@ class cComposableGenerator : public cChunkGenerator::cGenerator { typedef cChunkGenerator::cGenerator super; - + public: cComposableGenerator(cChunkGenerator & a_ChunkGenerator); - + // cChunkGenerator::cGenerator overrides: virtual void Initialize(cIniFile & a_IniFile) override; virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; @@ -211,17 +211,17 @@ protected: /** The finisher generators, in the order in which they are applied. */ cFinishGenList m_FinishGens; - - + + /** Reads the BiomeGen settings from the ini and initializes m_BiomeGen accordingly */ void InitBiomeGen(cIniFile & a_IniFile); - + /** Reads the ShapeGen settings from the ini and initializes m_ShapeGen accordingly */ void InitShapeGen(cIniFile & a_IniFile); - + /** Reads the CompositionGen settings from the ini and initializes m_CompositionGen accordingly */ void InitCompositionGen(cIniFile & a_IniFile); - + /** Reads the finishers from the ini and initializes m_FinishGens accordingly */ void InitFinishGens(cIniFile & a_IniFile); } ; diff --git a/src/Generating/DistortedHeightmap.cpp b/src/Generating/DistortedHeightmap.cpp index 835780f95..405f436b0 100644 --- a/src/Generating/DistortedHeightmap.cpp +++ b/src/Generating/DistortedHeightmap.cpp @@ -68,7 +68,7 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] = /* biMesa */ { 2.0f, 2.0f}, // 37 /* biMesaPlateauF */ { 2.0f, 2.0f}, // 38 /* biMesaPlateau */ { 2.0f, 2.0f}, // 39 - + // biomes 40 .. 128 are unused, 89 empty placeholders here: {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 40 .. 49 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 50 .. 59 @@ -79,7 +79,7 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] = {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 100 .. 109 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 110 .. 119 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 120 .. 128 - + // Release 1.7 biome variants: /* biSunflowerPlains */ { 1.0f, 1.0f}, // 129 /* biDesertM */ { 1.0f, 1.0f}, // 130 @@ -87,12 +87,12 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] = /* biFlowerForest */ { 4.0f, 4.0f}, // 132 /* biTaigaM */ { 3.0f, 3.0f}, // 133 /* biSwamplandM */ { 0.0f, 0.0f}, // 134 - + // Biomes 135 .. 139 unused, 5 empty placeholders here: {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 135 .. 139 /* biIcePlainsSpikes */ { 1.0f, 1.0f}, // 140 - + // Biomes 141 .. 148 unused, 8 empty placeholders here: {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 141 .. 148 @@ -358,7 +358,7 @@ void cDistortedHeightmap::GetDistortAmpsAt(BiomeNeighbors & a_Neighbors, int a_R { continue; } - + /* // Sanity checks for biome parameters, enable them to check the biome param table in runtime (slow): ASSERT(m_GenParam[i].m_DistortAmpX >= 0); diff --git a/src/Generating/DistortedHeightmap.h b/src/Generating/DistortedHeightmap.h index 79fc35542..eaa6aa8d9 100644 --- a/src/Generating/DistortedHeightmap.h +++ b/src/Generating/DistortedHeightmap.h @@ -27,7 +27,7 @@ class cDistortedHeightmap : { public: cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen); - + protected: typedef cChunkDef::BiomeMap BiomeNeighbors[3][3]; @@ -61,10 +61,10 @@ protected: /** Cache for m_UnderlyingHeiGen. */ cHeiGenCache m_HeightGen; - + /** Heightmap for the current chunk, before distortion (from m_HeightGen). Used for optimization. */ cChunkDef::HeightMap m_CurChunkHeights; - + // Per-biome terrain generator parameters: struct sGenParam { @@ -72,34 +72,34 @@ protected: NOISE_DATATYPE m_DistortAmpZ; } ; static const sGenParam m_GenParam[256]; - + // Distortion amplitudes for each direction, before linear upscaling NOISE_DATATYPE m_DistortAmpX[DIM_X * DIM_Z]; NOISE_DATATYPE m_DistortAmpZ[DIM_X * DIM_Z]; - + /** True if Initialize() has been called. Used to initialize-once even with multiple init entrypoints (HeiGen / CompoGen). */ bool m_IsInitialized; - + /** Unless the LastChunk coords are equal to coords given, prepares the internal state (noise arrays, heightmap). */ void PrepareState(int a_ChunkX, int a_ChunkZ); - + /** Generates the m_DistortedHeightmap array for the current chunk. */ void GenerateHeightArray(void); - + /** Calculates the heightmap value (before distortion) at the specified (floating-point) coords. */ int GetHeightmapAt(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Z); - + /** Updates m_DistortAmpX/Z[] based on m_CurChunkX and m_CurChunkZ. */ void UpdateDistortAmps(void); - + /** Calculates the X and Z distortion amplitudes based on the neighbors' biomes. */ void GetDistortAmpsAt(BiomeNeighbors & a_Neighbors, int a_RelX, int a_RelZ, NOISE_DATATYPE & a_DistortAmpX, NOISE_DATATYPE & a_DistortAmpZ); - + /** Reads the settings from the ini file. Skips reading if already initialized. */ void Initialize(cIniFile & a_IniFile); - - + + // cTerrainShapeGen overrides: virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; virtual void InitializeShapeGen(cIniFile & a_IniFile) override; diff --git a/src/Generating/EndGen.h b/src/Generating/EndGen.h index f914dc340..5008c2670 100644 --- a/src/Generating/EndGen.h +++ b/src/Generating/EndGen.h @@ -22,12 +22,12 @@ class cEndGen : { public: cEndGen(int a_Seed); - + protected: /** Seed for the noise */ int m_Seed; - + /** The Perlin noise used for generating */ cPerlinNoise m_Perlin; @@ -35,16 +35,16 @@ protected: int m_IslandSizeX; int m_IslandSizeY; int m_IslandSizeZ; - + // XYZ Frequencies of the noise functions: NOISE_DATATYPE m_FrequencyX; NOISE_DATATYPE m_FrequencyY; NOISE_DATATYPE m_FrequencyZ; - + // Minimum and maximum chunk coords for chunks inside the island area. Chunks outside won't get calculated at all int m_MinChunkX, m_MaxChunkX; int m_MinChunkZ, m_MaxChunkZ; - + // Noise array for the last chunk (in the noise range) int m_LastChunkX; int m_LastChunkZ; @@ -53,10 +53,10 @@ protected: /** Unless the LastChunk coords are equal to coords given, prepares the internal state (noise array) */ void PrepareState(int a_ChunkX, int a_ChunkZ); - + /** Generates the m_NoiseArray array for the current chunk */ void GenerateNoiseArray(void); - + /** Returns true if the chunk is outside of the island's dimensions */ bool IsChunkOutsideRange(int a_ChunkX, int a_ChunkZ); diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index f3a62e8e3..d35d77eac 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -186,7 +186,7 @@ void cFinishGenGlowStone::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); - + // Change the number of attempts to create a vein depending on the maximum height of the chunk. A standard Nether could have 5 veins at most. int NumGlowStone = m_Noise.IntNoise2DInt(ChunkX, ChunkZ) % a_ChunkDesc.GetMaxHeight() / 23; @@ -198,7 +198,7 @@ void cFinishGenGlowStone::GenFinish(cChunkDesc & a_ChunkDesc) // Generate X / Z coordinates. int X = Size + (m_Noise.IntNoise2DInt(i, Size) % (cChunkDef::Width - Size * 2)); int Z = Size + (m_Noise.IntNoise2DInt(X, i) % (cChunkDef::Width - Size * 2)); - + int Height = a_ChunkDesc.GetHeight(X, Z); for (int y = Height; y > Size; y--) { @@ -234,14 +234,14 @@ void cFinishGenGlowStone::TryPlaceGlowstone(cChunkDesc & a_ChunkDesc, int a_RelX { // The starting point of every glowstone string Vector3i StartPoint = Vector3i(a_RelX, a_RelY, a_RelZ); - + // Array with possible directions for a string of glowstone to go to. const Vector3i AvailableDirections[] = { { -1, 0, 0 }, { 1, 0, 0 }, { 0, -1, 0 }, // Don't let the glowstone go up { 0, 0, -1 }, { 0, 0, 1 }, - + // Diagonal direction. Only X or Z with Y. // If all were changed the glowstone string looks awkward { 0, -1, 1 }, { 1, -1, 0 }, diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index 464ed209f..8e90f9f2a 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -372,7 +372,7 @@ class cFinishGenPassiveMobs : public cFinishGen { public: - + cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, eDimension a_Dimension); protected: diff --git a/src/Generating/GridStructGen.cpp b/src/Generating/GridStructGen.cpp index bcf66795c..0068783eb 100644 --- a/src/Generating/GridStructGen.cpp +++ b/src/Generating/GridStructGen.cpp @@ -20,13 +20,13 @@ class cEmptyStructure : public cGridStructGen::cStructure { typedef cGridStructGen::cStructure super; - + public: cEmptyStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) : super(a_GridX, a_GridZ, a_OriginX, a_OriginZ) { } - + protected: virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override { diff --git a/src/Generating/GridStructGen.h b/src/Generating/GridStructGen.h index b27f218f4..30cb9d670 100644 --- a/src/Generating/GridStructGen.h +++ b/src/Generating/GridStructGen.h @@ -51,11 +51,11 @@ public: public: /** The grid point for which the structure is generated. */ int m_GridX, m_GridZ; - + /** The origin (the coords for which the structure is generated) */ int m_OriginX, m_OriginZ; - - + + /** Creates a structure that has its origin set at the specified coords. */ cStructure (int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) : m_GridX(a_GridX), @@ -64,20 +64,20 @@ public: m_OriginZ(a_OriginZ) { } - + // Force a virtual destructor in descendants: virtual ~cStructure() {} - + /** Draws self into the specified chunk */ virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) = 0; - + /** Returns the cost of keeping this structure in the cache */ virtual size_t GetCacheCost(void) const { return 1; } } ; typedef SharedPtr<cStructure> cStructurePtr; typedef std::list<cStructurePtr> cStructurePtrs; - - + + cGridStructGen( int a_Seed, int a_GridSizeX, int a_GridSizeZ, @@ -96,7 +96,7 @@ public: // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - + protected: /** Base seed of the world for which the generator generates chunk. */ int m_BaseSeed; @@ -104,43 +104,43 @@ protected: /** Seed for generating grid offsets and also available for descendants. Calculated from m_BaseSeed by adding the SeedOffset parameter loaded from the cubeset file (if applicable); otherwise the same as m_BaseSeed. */ int m_Seed; - + /** The noise used for generating grid offsets. */ cNoise m_Noise; - + /** The size of each grid's cell in the X axis */ int m_GridSizeX; - + /** The size of each grid's cell in the Z axis */ int m_GridSizeZ; - + /** The maximum offset of the structure's origin from the grid midpoint, in X coord. */ int m_MaxOffsetX; - + /** The maximum offset of the structure's origin from the grid midpoint, in Z coord. */ int m_MaxOffsetZ; - + /** Maximum theoretical size of the structure in the X axis. This limits the structures considered for a single chunk, so the lesser the number, the better performance. Structures large than this may get cropped. */ int m_MaxStructureSizeX; - + /** Maximum theoretical size of the structure in the Z axis. This limits the structures considered for a single chunk, so the lesser the number, the better performance. Structures large than this may get cropped. */ int m_MaxStructureSizeZ; - + /** Maximum allowed sum of costs for items in the cache. Items that are over this cost are removed from the cache, oldest-first */ size_t m_MaxCacheSize; - + /** Cache for the most recently generated structures, ordered by the recentness. */ cStructurePtrs m_Cache; - - + + /** Clears everything from the cache */ void ClearCache(void); - + /** Returns all structures that may intersect the given chunk. The structures are considered as intersecting iff their bounding box (defined by m_MaxStructureSize) around their gridpoint intersects the chunk. */ diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index 2b3f342bb..b724a1dde 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -144,7 +144,7 @@ void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap LOGD("HeiGenCache: Avg cache chain length: %.2f", static_cast<double>(m_TotalChain) / m_NumHits); } //*/ - + for (size_t i = 0; i < m_CacheSize; i++) { if ( @@ -156,26 +156,26 @@ void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap } // Found it in the cache auto Idx = m_CacheOrder[i]; - + // Move to front: for (size_t j = i; j > 0; j--) { m_CacheOrder[j] = m_CacheOrder[j - 1]; } m_CacheOrder[0] = Idx; - + // Use the cached data: memcpy(a_HeightMap, m_CacheData[Idx].m_HeightMap, sizeof(a_HeightMap)); - + m_NumHits++; m_TotalChain += i; return; } // for i - cache - + // Not in the cache: m_NumMisses++; m_HeiGenToCache->GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap); - + // Insert it as the first item in the MRU order: auto Idx = m_CacheOrder[m_CacheSize - 1]; for (auto i = m_CacheSize - 1; i > 0; i--) @@ -341,7 +341,7 @@ void cHeiGenClassic::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightM for (int x = 0; x < cChunkDef::Width; x++) { const float xx = static_cast<float>(a_ChunkX * cChunkDef::Width + x); - + HEIGHTTYPE hei = static_cast<HEIGHTTYPE>(Clamp(static_cast<int>(64 + (GetNoise(xx * 0.05f, zz * 0.05f) * 16)), 10, 250)); cChunkDef::SetHeight(a_HeightMap, x, z, hei); } // for x @@ -474,7 +474,7 @@ const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[256] = /* biMesa */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 70}, // 165 /* biMesaPlateauF */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 80}, /* biMesaPlateau */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 80}, - + // biomes 40 .. 128 are unused, 89 empty placeholders here: {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 40 .. 49 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 50 .. 59 @@ -485,22 +485,22 @@ const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[256] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 100 .. 109 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 110 .. 119 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 120 .. 128 - + /* biSunflowerPlains */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 129 /* biDesertM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 130 /* biExtremeHillsM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 131 /* biFlowerForest */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 132 /* biTaigaM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 133 /* biSwamplandM */ { 1.0f, 3.0f, 1.10f, 7.0f, 0.01f, 0.01f, 60}, // 134 - + // Biomes 135 .. 139 unused, 5 empty placeholders here: {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 135 .. 139 - + /* biIcePlainsSpikes */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 140 - + // Biomes 141 .. 148 unused, 8 empty placeholders here: {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 141 .. 148 - + /* biJungleM */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // 149 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 150 /* biJungleEdgeM */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // 151 @@ -535,13 +535,13 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa m_BiomeGen->GenBiomes(a_ChunkX + x, a_ChunkZ + z, Biomes[x + 1][z + 1]); } // for x } // for z - + /* _X 2013_04_22: There's no point in precalculating the entire perlin noise arrays, too many values are calculated uselessly, resulting in speed DEcrease. */ - + //* // Linearly interpolate 4x4 blocks of heightmap: // Must be done on a floating point datatype, else the results are ugly! @@ -556,7 +556,7 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa } } LinearUpscale2DArrayInPlace<17, 17, STEPX, STEPZ>(Height); - + // Copy into the heightmap for (int z = 0; z < cChunkDef::Width; z++) { @@ -566,7 +566,7 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa } } //*/ - + /* // For each height, go through neighboring biomes and add up their idea of height: for (int z = 0; z < cChunkDef::Width; z++) @@ -615,7 +615,7 @@ NOISE_DATATYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, Sum += WeightX + WeightZ; } // for x } // for z - + // For each biome type that has a nonzero count, calc its height and add it: if (Sum > 0) { @@ -628,7 +628,7 @@ NOISE_DATATYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, { continue; } - + /* // Sanity checks for biome parameters, enable them to check the biome param table in runtime (slow): ASSERT(m_GenParam[i].m_HeightFreq1 >= 0); @@ -638,7 +638,7 @@ NOISE_DATATYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, ASSERT(m_GenParam[i].m_HeightFreq3 >= 0); ASSERT(m_GenParam[i].m_HeightFreq3 < 1000); */ - + NOISE_DATATYPE oct1 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq1, BlockZ * m_GenParam[i].m_HeightFreq1) * m_GenParam[i].m_HeightAmp1; NOISE_DATATYPE oct2 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq2, BlockZ * m_GenParam[i].m_HeightFreq2) * m_GenParam[i].m_HeightAmp2; NOISE_DATATYPE oct3 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq3, BlockZ * m_GenParam[i].m_HeightFreq3) * m_GenParam[i].m_HeightAmp3; @@ -647,7 +647,7 @@ NOISE_DATATYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, NOISE_DATATYPE res = Height / Sum; return std::min(static_cast<NOISE_DATATYPE>(250), std::max(res, static_cast<NOISE_DATATYPE>(5))); } - + // No known biome around? Weird. Return a bogus value: ASSERT(!"cHeiGenBiomal: Biome sum failed, no known biome around"); return 5; @@ -756,7 +756,7 @@ public: } } - + virtual void InitializeHeightGen(cIniFile & a_IniFile) { // No settings available @@ -872,7 +872,7 @@ cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cB LOGWARN("[Generator] HeightGen value not set in world.ini, using \"Biomal\"."); HeightGenName = "Biomal"; } - + a_CacheOffByDefault = false; cTerrainHeightGenPtr res; if (NoCaseCompare(HeightGenName, "Flat") == 0) @@ -944,7 +944,7 @@ cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cB a_IniFile.SetValue("Generator", "HeightGen", "Biomal"); return CreateHeightGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault); } - + // Read the settings: res->InitializeHeightGen(a_IniFile); diff --git a/src/Generating/HeiGen.h b/src/Generating/HeiGen.h index e3b951b44..67c6c00cd 100644 --- a/src/Generating/HeiGen.h +++ b/src/Generating/HeiGen.h @@ -30,14 +30,14 @@ class cHeiGenCache : public: cHeiGenCache(cTerrainHeightGenPtr a_HeiGenToCache, size_t a_CacheSize); ~cHeiGenCache(); - + // cTerrainHeightGen overrides: virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; virtual HEIGHTTYPE GetHeightAt(int a_BlockX, int a_BlockZ) override; - + /** Retrieves height at the specified point in the cache, returns true if found, false if not found */ bool GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, HEIGHTTYPE & a_Height); - + protected: struct sCacheData { @@ -45,15 +45,15 @@ protected: int m_ChunkZ; cChunkDef::HeightMap m_HeightMap; } ; - + /** The terrain height generator that is being cached. */ cTerrainHeightGenPtr m_HeiGenToCache; - + // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data size_t m_CacheSize; size_t * m_CacheOrder; // MRU-ized order, indices into m_CacheData array sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used - + // Cache statistics size_t m_NumHits; size_t m_NumMisses; @@ -74,7 +74,7 @@ public: // cTerrainHeightGen overrides: virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; virtual HEIGHTTYPE GetHeightAt(int a_BlockX, int a_BlockZ) override; - + /** Retrieves height at the specified point in the cache, returns true if found, false if not found */ bool GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, HEIGHTTYPE & a_Height); @@ -102,7 +102,7 @@ class cHeiGenFlat : { public: cHeiGenFlat(void) : m_Height(5) {} - + protected: HEIGHTTYPE m_Height; @@ -121,7 +121,7 @@ class cHeiGenClassic : { public: cHeiGenClassic(int a_Seed); - + protected: int m_Seed; @@ -129,7 +129,7 @@ protected: float m_HeightFreq1, m_HeightAmp1; float m_HeightFreq2, m_HeightAmp2; float m_HeightFreq3, m_HeightAmp3; - + float GetNoise(float x, float y); // cTerrainHeightGen overrides: @@ -146,14 +146,14 @@ class cHeiGenMountains : { public: cHeiGenMountains(int a_Seed); - + protected: int m_Seed; cRidgedMultiNoise m_MountainNoise; cRidgedMultiNoise m_DitchNoise; cPerlinNoise m_Perlin; - + // cTerrainHeightGen overrides: virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; virtual void InitializeHeightGen(cIniFile & a_IniFile) override; @@ -189,7 +189,7 @@ protected: cNoise m_Noise; cBiomeGenPtr m_BiomeGen; - + // Per-biome terrain generator parameters: struct sGenParam { diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp index ef06285ad..a9f2d1568 100644 --- a/src/Generating/MineShafts.cpp +++ b/src/Generating/MineShafts.cpp @@ -64,7 +64,7 @@ public: m_BoundingBox(a_BoundingBox) { } - + virtual ~cMineShaft() {} /** Returns true if this mineshaft intersects the specified cuboid */ diff --git a/src/Generating/MineShafts.h b/src/Generating/MineShafts.h index efb11cfee..401b1d31e 100644 --- a/src/Generating/MineShafts.h +++ b/src/Generating/MineShafts.h @@ -25,7 +25,7 @@ public: int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxSystemSize, int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase ); - + protected: friend class cMineShaft; friend class cMineShaftDirtRoom; @@ -33,14 +33,14 @@ protected: friend class cMineShaftCrossing; friend class cMineShaftStaircase; class cMineShaftSystem; // fwd: MineShafts.cpp - + cNoise m_Noise; int m_GridSize; ///< Average spacing of the systems int m_MaxSystemSize; ///< Maximum blcok size of a mineshaft system int m_ProbLevelCorridor; ///< Probability level of a branch object being the corridor int m_ProbLevelCrossing; ///< Probability level of a branch object being the crossing, minus Corridor int m_ProbLevelStaircase; ///< Probability level of a branch object being the staircase, minus Crossing - + // cGridStructGen overrides: virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override; } ; diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index f9317abe2..1bbae2584 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -24,21 +24,21 @@ class cNoise3DGenerator : public cChunkGenerator::cGenerator { typedef cChunkGenerator::cGenerator super; - + public: cNoise3DGenerator(cChunkGenerator & a_ChunkGenerator); virtual ~cNoise3DGenerator(); - + virtual void Initialize(cIniFile & a_IniFile) override; virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a_ChunkDesc) override; - + protected: // Linear interpolation step sizes, must be divisors of cChunkDef::Width and cChunkDef::Height, respectively: static const int UPSCALE_X = 4; static const int UPSCALE_Y = 8; static const int UPSCALE_Z = 4; - + // Linear interpolation buffer dimensions, calculated from the step sizes: static const int DIM_X = 1 + cChunkDef::Width / UPSCALE_X; static const int DIM_Y = 1 + cChunkDef::Height / UPSCALE_Y; @@ -49,7 +49,7 @@ protected: /** The noise used for heightmap directing. */ cOctavedNoise<cInterp5DegNoise> m_Cubic; - + int m_SeaLevel; NOISE_DATATYPE m_HeightAmplification; NOISE_DATATYPE m_MidPoint; // Where the vertical "center" of the noise should be @@ -57,13 +57,13 @@ protected: NOISE_DATATYPE m_FrequencyY; NOISE_DATATYPE m_FrequencyZ; NOISE_DATATYPE m_AirThreshold; - + /** Generates the 3D noise array used for terrain generation; a_Noise is of ChunkData-size */ void GenerateNoiseArray(int a_ChunkX, int a_ChunkZ, NOISE_DATATYPE * a_Noise); - + /** Updates heightmap based on the chunk's contents */ void UpdateHeightmap(cChunkDesc & a_ChunkDesc); - + /** Composes terrain - adds dirt, grass and sand */ void ComposeTerrain(cChunkDesc & a_ChunkDesc); } ; @@ -92,7 +92,7 @@ protected: /** Heightmap-like noise used to provide variance for low-amplitude biomes. */ cOctavedNoise<cInterpolNoise<Interp5Deg>> m_BaseNoise; - + /** The main parameter of the generator, specifies the slope of the vertical linear gradient. A higher value means a steeper slope and a smaller total amplitude of the generated terrain. */ NOISE_DATATYPE m_HeightAmplification; @@ -116,16 +116,16 @@ protected: // Threshold for when the values are considered air: NOISE_DATATYPE m_AirThreshold; - + // Cache for the last calculated chunk (reused between heightmap and composition queries): int m_LastChunkX; int m_LastChunkZ; NOISE_DATATYPE m_NoiseArray[17 * 17 * 257]; // x + 17 * z + 17 * 17 * y - - + + /** Generates the 3D noise array used for terrain generation (m_NoiseArray), unless the LastChunk coords are equal to coords given */ void GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ); - + // cTerrainHeightGen overrides: virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; virtual void InitializeShapeGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } @@ -165,7 +165,7 @@ protected: /** The underlying biome generator. */ cBiomeGenPtr m_BiomeGen; - + /** Block height of the sealevel, used for composing the terrain. */ int m_SeaLevel; @@ -185,7 +185,7 @@ protected: // Threshold for when the values are considered air: NOISE_DATATYPE m_AirThreshold; - + // Cache for the last calculated chunk (reused between heightmap and composition queries): int m_LastChunkX; int m_LastChunkZ; @@ -196,8 +196,8 @@ protected: /** The sum of m_Weight[]. */ NOISE_DATATYPE m_WeightSum; - - + + /** Generates the 3D noise array used for terrain generation (m_NoiseArray), unless the LastChunk coords are equal to coords given */ void GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ); @@ -206,7 +206,7 @@ protected: /** Returns the parameters for the specified biome. */ void GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE & a_HeightAmp, NOISE_DATATYPE & a_MidPoint); - + // cTerrainShapeGen overrides: virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; virtual void InitializeShapeGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index 1d58157ba..d6204ce85 100644 --- a/src/Generating/PieceGenerator.cpp +++ b/src/Generating/PieceGenerator.cpp @@ -84,7 +84,7 @@ Vector3i cPiece::RotatePos(const Vector3i & a_Pos, int a_NumCCWRotations) const cPiece::cConnector cPiece::RotateMoveConnector(const cConnector & a_Connector, int a_NumCCWRotations, int a_MoveX, int a_MoveY, int a_MoveZ) const { cPiece::cConnector res(a_Connector); - + // Rotate the res connector: switch (a_NumCCWRotations) { @@ -113,12 +113,12 @@ cPiece::cConnector cPiece::RotateMoveConnector(const cConnector & a_Connector, i } } res.m_Pos = RotatePos(a_Connector.m_Pos, a_NumCCWRotations); - + // Move the res connector: res.m_Pos.x += a_MoveX; res.m_Pos.y += a_MoveY; res.m_Pos.z += a_MoveZ; - + return res; } @@ -262,7 +262,7 @@ cPlacedPiece * cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockZ, c { m_PiecePool.Reset(); int rnd = m_Noise.IntNoise2DInt(a_BlockX, a_BlockZ) / 7; - + // Choose a random one of the starting pieces: cPieces StartingPieces = m_PiecePool.GetStartingPieces(); int Total = 0; @@ -291,7 +291,7 @@ cPlacedPiece * cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockZ, c StartingPiece = StartingPieces[static_cast<size_t>(rnd) % StartingPieces.size()]; } rnd = rnd >> 16; - + // Choose a random supported rotation: int Rotations[4] = {0}; int NumRotations = 1; @@ -344,7 +344,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector( /* XM */ { 0, 0, 3, 1, 2, 0}, /* XP */ { 0, 0, 1, 3, 0, 2}, }; - + // Get a list of available connections: const int * RotTable = DirectionRotationTable[a_Connector.m_Direction]; cConnections Connections; @@ -362,7 +362,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector( { continue; } - + // Try fitting each of the piece's connector: cPiece::cConnectors Connectors = (*itrP)->GetConnectors(); auto verticalLimit = (*itrP)->GetVerticalLimit(); @@ -402,7 +402,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector( return false; } ASSERT(WeightTotal > 0); - + // Choose a random connection from the list, based on the weights: int rnd = (m_Noise.IntNoise3DInt(a_Connector.m_Pos.x, a_Connector.m_Pos.y, a_Connector.m_Pos.z) / 7) % WeightTotal; size_t ChosenIndex = 0; @@ -416,13 +416,13 @@ bool cPieceGenerator::TryPlacePieceAtConnector( } } cConnection & Conn = Connections[ChosenIndex]; - + // Place the piece: Vector3i NewPos = Conn.m_Piece->RotatePos(Conn.m_Connector.m_Pos, Conn.m_NumCCWRotations); ConnPos -= NewPos; cPlacedPiece * PlacedPiece = new cPlacedPiece(&a_ParentPiece, *(Conn.m_Piece), ConnPos, Conn.m_NumCCWRotations); a_OutPieces.push_back(PlacedPiece); - + // Add the new piece's connectors to the list of free connectors: cPiece::cConnectors Connectors = Conn.m_Piece->GetConnectors(); for (cPiece::cConnectors::const_iterator itr = Connectors.begin(), end = Connectors.end(); itr != end; ++itr) @@ -434,7 +434,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector( } a_OutConnectors.push_back(cFreeConnector(PlacedPiece, Conn.m_Piece->RotateMoveConnector(*itr, Conn.m_NumCCWRotations, ConnPos.x, ConnPos.y, ConnPos.z))); } - + return true; } @@ -538,10 +538,10 @@ void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockZ, int a_MaxDepth, { a_OutPieces.clear(); cFreeConnectors ConnectorPool; - + // Place the starting piece: a_OutPieces.push_back(PlaceStartingPiece(a_BlockX, a_BlockZ, ConnectorPool)); - + /* // DEBUG: printf("Placed the starting piece at {%d, %d, %d}\n", a_BlockX, a_BlockY, a_BlockZ); @@ -554,7 +554,7 @@ void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockZ, int a_MaxDepth, ); DebugConnectorPool(ConnectorPool, 0); //*/ - + // Place pieces at the available connectors: /* Instead of removing them one by one from the pool, we process them sequentially and take note of the last diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h index 13ef05e42..1d0e9deda 100644 --- a/src/Generating/PieceGenerator.h +++ b/src/Generating/PieceGenerator.h @@ -33,20 +33,20 @@ class cPiece public: // Force a virtual destructor in all descendants virtual ~cPiece() {} - + struct cConnector { /** Position relative to the piece */ Vector3i m_Pos; - + /** Type of the connector. Any arbitrary number; the generator connects only connectors of opposite (negative) types. */ int m_Type; - + /** Direction in which the connector is facing. Will be matched by the opposite direction for the connecting connector. */ eBlockFace m_Direction; - + cConnector(int a_X, int a_Y, int a_Z, int a_Type, eBlockFace a_Direction); cConnector(const Vector3i & a_Pos, int a_Type, eBlockFace a_Direction); }; @@ -117,15 +117,15 @@ public: /** Returns all of the available connectors that the piece has. Each connector has a (relative) position in the piece, and a type associated with it. */ virtual cConnectors GetConnectors(void) const = 0; - + /** Returns the dimensions of this piece. The dimensions cover the entire piece, there is no block that the piece generates outside of this size. */ virtual Vector3i GetSize(void) const = 0; - + /** Returns the "hitbox" of this piece. A hitbox is what is compared and must not intersect other pieces' hitboxes when generating. */ virtual cCuboid GetHitBox(void) const = 0; - + /** Returns true if the piece can be rotated CCW the specific number of 90-degree turns. */ virtual bool CanRotateCCW(int a_NumRotations) const = 0; @@ -139,7 +139,7 @@ public: } return -1; } - + void SetVerticalStrategy(cVerticalStrategyPtr a_VerticalStrategy) { m_VerticalStrategy = a_VerticalStrategy; @@ -170,10 +170,10 @@ public: /** Returns a copy of the connector that is rotated and then moved by the specified amounts. */ cConnector RotateMoveConnector(const cConnector & a_Connector, int a_NumCCWRotations, int a_MoveX, int a_MoveY, int a_MoveZ) const; - + /** Returns the hitbox after the specified number of rotations and moved so that a_MyConnector is placed at a_ToConnectorPos. */ cCuboid RotateHitBoxToConnector(const cConnector & a_MyConnector, const Vector3i & a_ToConnectorPos, int a_NumCCWRotations) const; - + /** Returns the hitbox after the specified number of CCW rotations and moved by the specified amounts. */ cCuboid RotateMoveHitBox(int a_NumCCWRotations, int a_MoveX, int a_MoveY, int a_MoveZ) const; }; @@ -198,15 +198,15 @@ class cPiecePool public: // Force a virtual destructor in all descendants: virtual ~cPiecePool() {} - + /** Returns a list of pieces that contain the specified connector type. The cPiece pointers returned are managed by the pool and the caller doesn't free them. */ virtual cPieces GetPiecesWithConnector(int a_ConnectorType) = 0; - + /** Returns the pieces that should be used as the starting point. Multiple starting points are supported, one of the returned piece will be chosen. */ virtual cPieces GetStartingPieces(void) = 0; - + /** Returns the relative weight with which the a_NewPiece is to be selected for placing under a_PlacedPiece through a_ExistingConnector. a_ExistingConnector is the original connector, before any movement or rotation is applied to it. This allows the pool to tweak the piece's chances, based on the previous pieces in the tree and the connector used. @@ -219,7 +219,7 @@ public: { return 1; } - + /** Returns the relative weight with which the a_NewPiece is to be selected for placing as the first piece. This allows the pool to tweak the piece's chances. The higher the number returned, the higher the chance the piece will be chosen. 0 means the piece will not be chosen. @@ -232,7 +232,7 @@ public: /** Called after a piece is placed, to notify the pool that it has been used. The pool may adjust the pieces it will return the next time. */ virtual void PiecePlaced(const cPiece & a_Piece) = 0; - + /** Called when the pool has finished the current structure and should reset any piece-counters it has for a new structure. */ virtual void Reset(void) = 0; @@ -247,7 +247,7 @@ class cPlacedPiece { public: cPlacedPiece(const cPlacedPiece * a_Parent, const cPiece & a_Piece, const Vector3i & a_Coords, int a_NumCCWRotations); - + const cPlacedPiece * GetParent (void) const { return m_Parent; } const cPiece & GetPiece (void) const { return *m_Piece; } const Vector3i & GetCoords (void) const { return m_Coords; } @@ -255,23 +255,23 @@ public: const cCuboid & GetHitBox (void) const { return m_HitBox; } int GetDepth (void) const { return m_Depth; } bool HasBeenMovedToGround(void) const { return m_HasBeenMovedToGround; } - + /** Returns the coords as a modifiable object. */ Vector3i & GetCoords(void) { return m_Coords; } - + /** Returns the connector at the specified index, rotated in the actual placement. Undefined behavior if a_Index is out of range. */ cPiece::cConnector GetRotatedConnector(size_t a_Index) const; - + /** Returns a copy of the specified connector, modified to account for the translation and rotation for this placement. */ cPiece::cConnector GetRotatedConnector(const cPiece::cConnector & a_Connector) const; - + /** Moves the placed piece Y-wise by the specified offset. Sets m_HasBeenMovedToGround to true, too. Used eg. by village houses. */ void MoveToGroundBy(int a_OffsetY); - + protected: const cPlacedPiece * m_Parent; const cPiece * m_Piece; @@ -279,7 +279,7 @@ protected: int m_NumCCWRotations; cCuboid m_HitBox; // Hitbox of the placed piece, in world coords int m_Depth; // Depth in the generated piece tree - + /** Set to true once the piece has been moved Y-wise. Used eg. by village houses. */ bool m_HasBeenMovedToGround; @@ -295,11 +295,11 @@ class cPieceGenerator { public: cPieceGenerator(cPiecePool & a_PiecePool, int a_Seed); - + /** Cleans up all the memory used by the placed pieces. Call this utility function instead of freeing the items on your own. */ static void FreePieces(cPlacedPieces & a_PlacedPieces); - + protected: /** The type used for storing a connection from one piece to another, while building the piece tree. */ struct cConnection @@ -308,17 +308,17 @@ protected: cPiece::cConnector m_Connector; // The piece's connector being used (relative non-rotated coords) int m_NumCCWRotations; // Number of rotations necessary to match the two connectors int m_Weight; // Relative chance that this connection will be chosen - + cConnection(cPiece & a_Piece, cPiece::cConnector & a_Connector, int a_NumCCWRotations, int a_Weight); }; typedef std::vector<cConnection> cConnections; - + /** The type used for storing a pool of connectors that will be attempted to expand by another piece. */ struct cFreeConnector { cPlacedPiece * m_Piece; cPiece::cConnector m_Connector; - + cFreeConnector(cPlacedPiece * a_Piece, const cPiece::cConnector & a_Connector); }; typedef std::vector<cFreeConnector> cFreeConnectors; @@ -328,11 +328,11 @@ protected: cNoise m_Noise; int m_Seed; - + /** Selects a starting piece and places it, including its height and rotation. Also puts the piece's connectors in a_OutConnectors. */ cPlacedPiece * PlaceStartingPiece(int a_BlockX, int a_BlockZ, cFreeConnectors & a_OutConnectors); - + /** Tries to place a new piece at the specified (placed) connector. Returns true if successful. */ bool TryPlacePieceAtConnector( const cPlacedPiece & a_ParentPiece, // The existing piece to a new piece should be placed @@ -355,7 +355,7 @@ protected: int a_NumCCWRotations, // Number of rotations for the new piece to align the connector const cPlacedPieces & a_OutPieces // All the already-placed pieces to check ); - + /** DEBUG: Outputs all the connectors in the pool into stdout. a_NumProcessed signals the number of connectors from the pool that should be considered processed (not listed). */ void DebugConnectorPool(const cPieceGenerator::cFreeConnectors & a_ConnectorPool, size_t a_NumProcessed); @@ -388,7 +388,7 @@ class cDFSPieceGenerator : { public: cDFSPieceGenerator(cPiecePool & a_PiecePool, int a_Seed); - + /** Generates a placement for pieces at the specified coords. The Y coord is generated automatically based on the starting piece that is chosen. Caller must free each individual cPlacedPiece in a_OutPieces using cPieceGenerator::FreePieces(). */ diff --git a/src/Generating/PieceStructuresGen.h b/src/Generating/PieceStructuresGen.h index bcad86353..c8e2f2b0c 100644 --- a/src/Generating/PieceStructuresGen.h +++ b/src/Generating/PieceStructuresGen.h @@ -58,7 +58,7 @@ protected: /** The underlying biome generator that defines whether the structure is created or not */ cBiomeGenPtr m_BiomeGen; - + /** The underlying height generator, used to position the prefabs crossing chunk borders if they are set to FitGround. */ cTerrainHeightGenPtr m_HeightGen; diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index e5e6a1e06..6805167a9 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -26,7 +26,7 @@ static const cPrefab::sDef g_TestPrefabDef = // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ 6, 5, 6, // MaxX, MaxY, MaxZ - + // Block definitions: ".: 0: 0\n" /* 0 */ "a:112: 0\n" /* netherbrick */ @@ -86,17 +86,17 @@ static const cPrefab::sDef g_TestPrefabDef = "a.....a" "a.....a" "aaaaaaa", - + // Connections: "0: 0, 3, 2: 4\n" "0: 2, 3, 0: 2\n", - + // AllowedRotations: 7, /* 1, 2, 3 CCW rotations */ - + // Merge strategy: cBlockArea::msImprint, - + // ShouldExtendFloor: false, @@ -108,7 +108,7 @@ static const cPrefab::sDef g_TestPrefabDef = // AddWeightIfSame: 1000, - + // MoveToGround: false, }; @@ -139,7 +139,7 @@ cPrefab::cPrefab(const cPrefab::sDef & a_Def) : ParseBlockImage(cm, a_Def.m_Image); ParseConnectors(a_Def.m_Connectors); ParseDepthWeight(a_Def.m_DepthWeight); - + AddRotatedBlockAreas(); } @@ -213,7 +213,7 @@ void cPrefab::AddRotatedBlockAreas(void) m_BlockArea[1].CopyFrom(m_BlockArea[0]); m_BlockArea[1].RotateCCW(); } - + // 2 rotations are the same as mirroring twice; mirroring is faster because it has no reallocations if ((m_AllowedRotations & 0x02) != 0) { @@ -221,7 +221,7 @@ void cPrefab::AddRotatedBlockAreas(void) m_BlockArea[2].MirrorXY(); m_BlockArea[2].MirrorYZ(); } - + // 3 CCW rotations = 1 CW rotation: if ((m_AllowedRotations & 0x04) != 0) { @@ -250,7 +250,7 @@ void cPrefab::Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumR int ChunkStartZ = a_Dest.GetChunkZ() * cChunkDef::Width; Placement.Move(-ChunkStartX, 0, -ChunkStartZ); const cBlockArea & Image = m_BlockArea[a_NumRotations]; - + // If the placement is outside this chunk, bail out: if ( (Placement.x > cChunkDef::Width) || (Placement.x + Image.GetSizeX() < 0) || @@ -259,10 +259,10 @@ void cPrefab::Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumR { return; } - + // Write the image: a_Dest.WriteBlockArea(Image, Placement.x, Placement.y, Placement.z, m_MergeStrategy); - + // If requested, draw the floor (from the bottom of the prefab down to the nearest non-air) if (m_ShouldExtendFloor) { @@ -332,7 +332,7 @@ int cPrefab::GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cC // Use the default or per-depth weight: cDepthWeight::const_iterator itr = m_DepthWeight.find(a_PlacedPiece.GetDepth() + 1); int res = (itr == m_DepthWeight.end()) ? m_DefaultWeight : itr->second; - + // If the piece is the same as the parent, apply the m_AddWeightIfSame modifier: const cPiece * ParentPiece = &a_PlacedPiece.GetPiece(); const cPiece * ThisPiece = this; @@ -378,14 +378,14 @@ void cPrefab::SetAllowedRotations(int a_AllowedRotations) void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) { ASSERT(a_CharMapDef != nullptr); - + // Initialize the charmap to all-invalid values: for (size_t i = 0; i < ARRAYCOUNT(a_CharMapOut); i++) { a_CharMapOut[i].m_BlockType = 0; a_CharMapOut[i].m_BlockMeta = 16; // Mark unassigned entries with a meta that is impossible otherwise } - + // Process the lines in the definition: AStringVector Lines = StringSplitAndTrim(a_CharMapDef, "\n"); for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) @@ -439,7 +439,7 @@ void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockIma void cPrefab::ParseConnectors(const char * a_ConnectorsDef) { ASSERT(a_ConnectorsDef != nullptr); - + AStringVector Lines = StringSplitAndTrim(a_ConnectorsDef, "\n"); for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) { @@ -460,7 +460,7 @@ void cPrefab::ParseConnectors(const char * a_ConnectorsDef) LOGWARNING("Bad prefab Connector coords definition: \"%s\", skipping.", Defs[1].c_str()); continue; } - + // Check that the BlockFace is within range: int BlockFace = atoi(Defs[2].c_str()); if ((BlockFace < 0) || (BlockFace >= 6)) @@ -489,10 +489,10 @@ void cPrefab::ParseDepthWeight(const char * a_DepthWeightDef) { return; } - + // Split into individual records: "Record | Record | Record" AStringVector Defs = StringSplitAndTrim(a_DepthWeightDef, "|"); - + // Add each record's contents: for (AStringVector::const_iterator itr = Defs.begin(), end = Defs.end(); itr != end; ++itr) { @@ -503,7 +503,7 @@ void cPrefab::ParseDepthWeight(const char * a_DepthWeightDef) LOGWARNING("Bad prefab DepthWeight record: \"%s\", skipping.", itr->c_str()); continue; } - + // Parse depth: int Depth = atoi(Components[0].c_str()); if ((Depth == 0) && (Components[0] != "0")) @@ -511,7 +511,7 @@ void cPrefab::ParseDepthWeight(const char * a_DepthWeightDef) LOGWARNING("Bad prefab DepthWeight record, cannot parse depth \"%s\", skipping.", Components[0].c_str()); continue; } - + // Parse weight: int Weight = atoi(Components[1].c_str()); if ((Weight == 0) && (Components[1] != "0")) @@ -519,7 +519,7 @@ void cPrefab::ParseDepthWeight(const char * a_DepthWeightDef) LOGWARNING("Bad prefab DepthWeight record, cannot parse weight \"%s\", skipping.", Components[1].c_str()); continue; } - + // Save to map: ASSERT(m_DepthWeight.find(Depth) == m_DepthWeight.end()); // Not a duplicate m_DepthWeight[Depth] = Weight; diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index c62a68f97..5f937260d 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -37,31 +37,31 @@ public: int m_SizeX; int m_SizeY; int m_SizeZ; - + /** The hitbox used for collision-checking between prefabs. Relative to the bounds. */ int m_HitboxMinX, m_HitboxMinY, m_HitboxMinZ; int m_HitboxMaxX, m_HitboxMaxY, m_HitboxMaxZ; - + /** The mapping between characters in m_Image and the blocktype / blockmeta. Format: "Char: BlockType: BlockMeta \n Char: BlockType : BlockMeta \n ..." */ const char * m_CharMap; - + /** The actual image to be used for the prefab. Organized YZX (Y changes the least often). Each character represents a single block, the type is mapped through m_CharMap. */ const char * m_Image; - + /** List of connectors. Format: "Type: X, Y, Z : Direction \n Type : X, Y, Z : Direction \n ...". Type is an arbitrary number, Direction is the BlockFace constant value (0 .. 5). */ const char * m_Connectors; - + /** Bitmask specifying the allowed rotations. N rotations CCW are allowed if bit N is set. */ int m_AllowedRotations; - + /** The merge strategy to use while drawing the prefab. */ cBlockArea::eMergeStrategy m_MergeStrategy; - + /** If set to true, the prefab will extend its lowermost blocks until a solid block is found, thus creating a foundation for the prefab. This is used for houses to be "on the ground", as well as nether fortresses not to float. */ @@ -69,7 +69,7 @@ public: /** Chance of this piece being used, if no other modifier is active. */ int m_DefaultWeight; - + /** Chances of this piece being used, per depth of the generated piece tree. The starting piece has a depth of 0, the pieces connected to it are depth 1, etc. The specified depth stands for the depth of the new piece (not the existing already-placed piece), @@ -77,56 +77,56 @@ public: Format: "Depth : Weight | Depth : Weight | Depth : Weight ..." Depths that are not specified will use the m_DefaultWeight value. */ const char * m_DepthWeight; - + /** The weight to add to this piece's base per-depth chance if the previous piece is the same. Can be positive or negative. This is used e. g. to make nether bridges prefer spanning multiple segments or to penalize turrets next to each other. */ int m_AddWeightIfSame; - + /** If true, the piece will be moved Y-wise so that its first connector is sitting on the terrain. This is used e. g. for village houses. */ bool m_MoveToGround; }; - - + + /** Creates a prefab from the provided definition. */ cPrefab(const sDef & a_Def); - + /** Creates a prefab based on the given BlockArea and allowed rotations. */ cPrefab(const cBlockArea & a_Image, int a_AllowedRotations); - + /** Creates a prefab based on the given BlockArea. Allowed rotations can be added later on using SetAllowedRotations(). */ cPrefab(const cBlockArea & a_Image); - + /** Creates a prefab based on the specified block data, using the char-to-block map in a_BlockDefinitions. Allowed rotations can be added later on using SetAllowedRotations(). */ cPrefab(const AString & a_BlockDefinitions, const AString & a_BlockData, int a_SizeX, int a_SizeY, int a_SizeZ); - + /** Draws the prefab into the specified chunk, according to the placement stored in the PlacedPiece. */ void Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const; - + /** Draws the prefab into the specified chunks, according to the specified placement and rotations. */ void Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumRotations) const; - + /** Returns true if the prefab has any connector of the specified type. */ bool HasConnectorType(int a_ConnectorType) const; - + /** Returns the weight (chance) of this prefab generating as the next piece after the specified placed piece. PiecePool implementations can use this for their GetPieceWeight() implementations. */ int GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector) const; - + /** Sets the (unmodified) DefaultWeight property for this piece. */ void SetDefaultWeight(int a_DefaultWeight); - + /** Returns the unmodified DefaultWeight property for the piece. */ int GetDefaultWeight(void) const { return m_DefaultWeight; } - + /** Sets the AddWeightIfSame member, that is used to modify the weight when the previous piece is the same prefab */ void SetAddWeightIfSame(int a_AddWeightIfSame) { m_AddWeightIfSame = a_AddWeightIfSame; } - + /** Adds the specified connector to the list of connectors this piece supports. */ void AddConnector(int a_RelX, int a_RelY, int a_RelZ, eBlockFace a_Direction, int a_Type); - + /** Returns whether the prefab should be moved Y-wise to ground before drawing, rather than staying at the coords governed by the connectors. */ bool ShouldMoveToGround(void) const { return m_MoveToGround; } @@ -156,30 +156,30 @@ protected: BLOCKTYPE m_BlockType; NIBBLETYPE m_BlockMeta; }; - + /** Maps letters in the sDef::m_Image onto a sBlockTypeDef block type definition. */ typedef sBlockTypeDef CharMap[256]; - + /** Maps generator tree depth to weight. */ typedef std::map<int, int> cDepthWeight; - - + + /** The cBlockArea that contains the block definitions for the prefab. The index identifies the number of CCW rotations applied (0 = no rotation, 1 = 1 CCW rotation, ...). */ cBlockArea m_BlockArea[4]; - + /** The size of the prefab */ Vector3i m_Size; - + /** The hitbox used for collision-checking between prefabs. */ cCuboid m_HitBox; - + /** The connectors through which the piece connects to other pieces */ cConnectors m_Connectors; - + /** Bitmask, bit N set -> N rotations CCW supported */ int m_AllowedRotations; - + /** The merge strategy to use when drawing the prefab into a block area */ cBlockArea::eMergeStrategy m_MergeStrategy; @@ -190,14 +190,14 @@ protected: /** Chance of this piece being used, if no other modifier is active. */ int m_DefaultWeight; - + /** Chances of this piece being used, per depth of the generated piece tree. The starting piece has a depth of 0, the pieces connected to it are depth 1, etc. The specified depth stands for the depth of the new piece (not the existing already-placed piece), so valid depths start at 1. Depths that are not specified will use the m_DefaultWeight value. */ cDepthWeight m_DepthWeight; - + /** The weight to add to this piece's base per-depth chance if the previous piece is the same. Can be positive or negative. This is used e. g. to make nether bridges prefer spanning multiple segments or to penalize turrets next to each other. */ @@ -206,24 +206,24 @@ protected: /** If true, the piece will be moved Y-wise so that its first connector is sitting on the terrain. This is used e. g. for village houses. */ bool m_MoveToGround; - - + + // cPiece overrides: virtual cConnectors GetConnectors(void) const override; virtual Vector3i GetSize(void) const override; virtual cCuboid GetHitBox(void) const override; virtual bool CanRotateCCW(int a_NumRotations) const override; - + /** Based on the m_AllowedRotations, adds rotated cBlockAreas to the m_BlockArea array. To be called only from this class's constructor! */ void AddRotatedBlockAreas(void); - + /** Parses the CharMap in the definition into a CharMap binary data used for translating the definition into BlockArea. */ void ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef); - + /** Parses the Image in the definition into m_BlockArea[0]'s block types and metas, using the specified CharMap. */ void ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockImage); - + /** Parses the connectors definition text into m_Connectors member. */ void ParseConnectors(const char * a_ConnectorsDef); }; diff --git a/src/Generating/PrefabPiecePool.h b/src/Generating/PrefabPiecePool.h index 1c51c4963..af342f023 100644 --- a/src/Generating/PrefabPiecePool.h +++ b/src/Generating/PrefabPiecePool.h @@ -30,7 +30,7 @@ class cPrefabPiecePool : public: /** Creates an empty instance. Prefabs can be added by calling AddPieceDefs() and AddStartingPieceDefs(). */ cPrefabPiecePool(void); - + /** Creates a piece pool with prefabs from the specified definitions. If both a_PieceDefs and a_StartingPieceDefs are given, only the a_StartingPieceDefs are used as starting pieces for the pool, and they do not participate in the generation any further. @@ -44,22 +44,22 @@ public: const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs, int a_DefaultStartingPieceHeight = -1 ); - + /** Creates a pool and loads the contents of the specified file into it. If a_LogWarnings is true, logs a warning to console when loading fails. */ cPrefabPiecePool(const AString & a_FileName, bool a_LogWarnings); /** Destroys the pool, freeing all pieces. */ ~cPrefabPiecePool(); - + /** Removes and frees all pieces from this pool. */ void Clear(void); - + /** Adds pieces from the specified definitions into m_AllPieces. Also adds the pieces into the m_PiecesByConnector map. May be called multiple times with different PieceDefs, will add all such pieces. */ void AddPieceDefs(const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs); - + /** Adds pieces from the specified definitions into m_StartingPieces. Doesn't add them to the m_PiecesByConnector map. May be called multiple times with different PieceDefs, will add all such pieces. @@ -70,7 +70,7 @@ public: size_t a_NumStartingPieceDefs, int a_DefaultPieceHeight = -1 ); - + /** Loads the pieces from the specified file. Returns true if successful, false on error. If a_LogWarnings is true, logs a warning to console when loading fails. */ bool LoadFromFile(const AString & a_FileName, bool a_LogWarnings); @@ -132,11 +132,11 @@ protected: /** All the pieces that are allowed for building. This is the list that's used for memory allocation and deallocation for the pieces. */ cPieces m_AllPieces; - + /** The pieces that are used as starting pieces. This list is not shared and the pieces need deallocation. */ cPieces m_StartingPieces; - + /** The map that has all pieces by their connector types The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */ cPiecesMap m_PiecesByConnector; @@ -158,7 +158,7 @@ protected: /** The block type used for the village roads if the road is on water. */ BLOCKTYPE m_VillageWaterRoadBlockType; - + /** The block meta used for the village roads if the road is on water. */ NIBBLETYPE m_VillageWaterRoadBlockMeta; @@ -196,7 +196,7 @@ protected: const AString & a_PieceName, bool a_LogWarnings ); - + /** Reads a single piece's connectors from the cubeset file parsed into the specified Lua state. The piece's definition table is expected to be at the top of the Lua stack. Returns true on success, false on failure. diff --git a/src/Generating/Ravines.cpp b/src/Generating/Ravines.cpp index d79697a79..40022aefb 100644 --- a/src/Generating/Ravines.cpp +++ b/src/Generating/Ravines.cpp @@ -22,7 +22,7 @@ struct cRavDefPoint int m_Radius; int m_Top; int m_Bottom; - + cRavDefPoint(int a_BlockX, int a_BlockZ, int a_Radius, int a_Top, int a_Bottom) : m_BlockX(a_BlockX), m_BlockZ(a_BlockZ), @@ -46,23 +46,23 @@ class cStructGenRavines::cRavine : cRavDefPoints m_Points; - + /** Generates the shaping defpoints for the ravine, based on the ravine block coords and noise */ void GenerateBaseDefPoints(int a_BlockX, int a_BlockZ, int a_Size, cNoise & a_Noise); - + /** Refines (adds and smooths) defpoints from a_Src into a_Dst */ void RefineDefPoints(const cRavDefPoints & a_Src, cRavDefPoints & a_Dst); - + /** Does one round of smoothing, two passes of RefineDefPoints() */ void Smooth(void); - + /** Linearly interpolates the points so that the maximum distance between two neighbors is max 1 block */ void FinishLinear(void); - + public: - + cRavine(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_Size, cNoise & a_Noise); - + #ifdef _DEBUG /** Exports itself as a SVG line definition */ AString ExportAsSVG(int a_Color, int a_OffsetX = 0, int a_OffsetZ = 0) const; @@ -109,11 +109,11 @@ cStructGenRavines::cRavine::cRavine(int a_GridX, int a_GridZ, int a_OriginX, int { // Calculate the ravine shape-defining points: GenerateBaseDefPoints(a_OriginX, a_OriginZ, a_Size, a_Noise); - + // Smooth the ravine. Two passes are needed: Smooth(); Smooth(); - + // Linearly interpolate the neighbors so that they're close enough together: FinishLinear(); } @@ -126,18 +126,18 @@ void cStructGenRavines::cRavine::GenerateBaseDefPoints(int a_BlockX, int a_Block { // Modify the size slightly to have different-sized ravines (1 / 2 to 1 / 1 of a_Size): a_Size = (512 + ((a_Noise.IntNoise3DInt(19 * a_BlockX, 11 * a_BlockZ, a_BlockX + a_BlockZ) / 17) % 512)) * a_Size / 1024; - + // The complete offset of the ravine from its cellpoint, up to 2 * a_Size in each direction int OffsetX = (((a_Noise.IntNoise3DInt(50 * a_BlockX, 30 * a_BlockZ, 0) / 9) % (2 * a_Size)) + ((a_Noise.IntNoise3DInt(30 * a_BlockX, 50 * a_BlockZ, 1000) / 7) % (2 * a_Size)) - 2 * a_Size) / 2; int OffsetZ = (((a_Noise.IntNoise3DInt(50 * a_BlockX, 30 * a_BlockZ, 2000) / 7) % (2 * a_Size)) + ((a_Noise.IntNoise3DInt(30 * a_BlockX, 50 * a_BlockZ, 3000) / 9) % (2 * a_Size)) - 2 * a_Size) / 2; int CenterX = a_BlockX + OffsetX; int CenterZ = a_BlockZ + OffsetZ; - + // Get the base angle in which the ravine "axis" goes: float Angle = static_cast<float>((static_cast<float>((a_Noise.IntNoise3DInt(20 * a_BlockX, 70 * a_BlockZ, 6000) / 9) % 16384)) / 16384.0 * M_PI); float xc = sinf(Angle); float zc = cosf(Angle); - + // Calculate the definition points and radii: int MaxRadius = static_cast<int>(sqrt(12.0 + ((a_Noise.IntNoise2DInt(61 * a_BlockX, 97 * a_BlockZ) / 13) % a_Size) / 16)); int Top = 32 + ((a_Noise.IntNoise2DInt(13 * a_BlockX, 17 * a_BlockZ) / 23) % 32); @@ -234,10 +234,10 @@ void cStructGenRavines::cRavine::FinishLinear(void) // For each segment, use Bresenham's line algorithm to draw a "line" of defpoints // _X 2012_07_20: I tried modifying this algorithm to produce "thick" lines (only one coord change per point) // But the results were about the same as the original, so I disposed of it again - no need to use twice the count of points - + cRavDefPoints Pts; std::swap(Pts, m_Points); - + m_Points.reserve(Pts.size() * 3); int PrevX = Pts.front().m_BlockX; int PrevZ = Pts.front().m_BlockZ; @@ -299,12 +299,12 @@ AString cStructGenRavines::cRavine::ExportAsSVG(int a_Color, int a_OffsetX, int AppendPrintf(SVG, "<path style=\"fill:none;stroke:#ff0000;stroke-width:1px;\"\nd=\"M %d, %d L %d, %d\"/>\n", a_OffsetX + m_OriginX, a_OffsetZ + m_OriginZ - 5, a_OffsetX + m_OriginX, a_OffsetZ + m_OriginZ + 5 ); - + // A gray line from the base point to the first point of the ravine, for identification: AppendPrintf(SVG, "<path style=\"fill:none;stroke:#cfcfcf;stroke-width:1px;\"\nd=\"M %d, %d L %d, %d\"/>\n", a_OffsetX + m_OriginX, a_OffsetZ + m_OriginZ, a_OffsetX + m_Points.front().m_BlockX, a_OffsetZ + m_Points.front().m_BlockZ ); - + // Offset guides: if (a_OffsetX > 0) { @@ -344,7 +344,7 @@ void cStructGenRavines::cRavine::DrawIntoChunk(cChunkDesc & a_ChunkDesc) // Cannot intersect, bail out early continue; } - + // Carve out a cylinder around the xz point, m_Radius in diameter, from Bottom to Top: int RadiusSq = itr->m_Radius * itr->m_Radius; // instead of doing sqrt for each distance, we do sqr of the radius int DifX = BlockStartX - itr->m_BlockX; // substitution for faster calc @@ -358,7 +358,7 @@ void cStructGenRavines::cRavine::DrawIntoChunk(cChunkDesc & a_ChunkDesc) a_ChunkDesc.SetBlockType(x, 4, z, E_BLOCK_LAPIS_ORE); } #endif // _DEBUG - + int DistSq = (DifX + x) * (DifX + x) + (DifZ + z) * (DifZ + z); if (DistSq <= RadiusSq) { diff --git a/src/Generating/Ravines.h b/src/Generating/Ravines.h index b11037433..0bcdffa3b 100644 --- a/src/Generating/Ravines.h +++ b/src/Generating/Ravines.h @@ -22,13 +22,13 @@ class cStructGenRavines : public: cStructGenRavines(int a_Seed, int a_Size); - + protected: class cRavine; // fwd: Ravines.cpp - + cNoise m_Noise; int m_Size; // Max size, in blocks, of the ravines generated - + // cGridStructGen overrides: virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override; diff --git a/src/Generating/RoughRavines.cpp b/src/Generating/RoughRavines.cpp index a7621569d..c8e4fc9dd 100644 --- a/src/Generating/RoughRavines.cpp +++ b/src/Generating/RoughRavines.cpp @@ -18,7 +18,7 @@ class cRoughRavine : public cGridStructGen::cStructure { typedef cGridStructGen::cStructure super; - + public: cRoughRavine( int a_Seed, size_t a_Size, @@ -44,15 +44,15 @@ public: m_DefPoints[0].Set (a_OriginX - OfsX, a_OriginZ - OfsZ, 1, a_CeilingHeightEdge1, a_FloorHeightEdge1); m_DefPoints[Half].Set(static_cast<float>(a_OriginX), static_cast<float>(a_OriginZ), a_CenterWidth, a_CeilingHeightCenter, a_FloorHeightCenter); m_DefPoints[Max].Set (a_OriginX + OfsX, a_OriginZ + OfsZ, 1, a_CeilingHeightEdge2, a_FloorHeightEdge2); - + // Calculate the points in between, recursively: SubdivideLine(0, Half); SubdivideLine(Half, Max); - + // Initialize the per-height radius modifiers: InitPerHeightRadius(a_GridX, a_GridZ); } - + protected: struct sRavineDefPoint { @@ -61,7 +61,7 @@ protected: float m_Radius; float m_Top; float m_Bottom; - + void Set(float a_X, float a_Z, float a_Radius, float a_Top, float a_Bottom) { m_X = a_X; @@ -72,21 +72,21 @@ protected: } }; typedef std::vector<sRavineDefPoint> sRavineDefPoints; - + int m_Seed; - + cNoise m_Noise; - + int m_MaxSize; - + sRavineDefPoints m_DefPoints; - + float m_Roughness; - + /** Number to add to the radius based on the height. This creates the "ledges" in the ravine walls. */ float m_PerHeightRadius[cChunkDef::Height]; - - + + /** Recursively subdivides the line between the points of the specified index. Sets the midpoint to the center of the line plus or minus a random offset, then calls itself for each half of the new line. */ @@ -116,7 +116,7 @@ protected: } size_t MidIdx = (a_Idx1 + a_Idx2) / 2; m_DefPoints[MidIdx].Set(MidX, MidZ, MidR, MidT, MidB); - + // Recurse the two halves, if they are worth recursing: if (MidIdx - a_Idx1 > 1) { @@ -127,8 +127,8 @@ protected: SubdivideLine(MidIdx, a_Idx2); } } - - + + void InitPerHeightRadius(int a_GridX, int a_GridZ) { int h = 0; @@ -150,8 +150,8 @@ protected: h += NumBlocks; } } - - + + virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override { int BlockStartX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; @@ -170,7 +170,7 @@ protected: // Cannot intersect, bail out early continue; } - + // Carve out a cylinder around the xz point, up to (m_Radius + 2) in diameter, from Bottom to Top: // On each height level, use m_PerHeightRadius[] to modify the actual radius used // EnlargedRadiusSq is the square of the radius enlarged by the maximum m_PerHeightRadius offset - anything outside it will never be touched. @@ -186,14 +186,14 @@ protected: a_ChunkDesc.SetBlockType(x, 4, z, E_BLOCK_LAPIS_ORE); } #endif // _DEBUG - + // If the column is outside the enlarged radius, bail out completely float DistSq = (DifX + x) * (DifX + x) + (DifZ + z) * (DifZ + z); if (DistSq > RadiusSq) { continue; } - + int Top = std::min(static_cast<int>(ceilf(itr->m_Top)), +cChunkDef::Height); for (int y = std::max(static_cast<int>(floorf(itr->m_Bottom)), 1); y <= Top; y++) { @@ -284,7 +284,7 @@ cGridStructGen::cStructurePtr cRoughRavines::CreateStructure(int a_GridX, int a_ float CeilingHeightEdge1 = m_Noise.IntNoise2DInRange(a_GridX + 60, a_GridZ, m_MinCeilingHeightEdge, m_MaxCeilingHeightEdge); float CeilingHeightEdge2 = m_Noise.IntNoise2DInRange(a_GridX + 70, a_GridZ, m_MinCeilingHeightEdge, m_MaxCeilingHeightEdge); float CeilingHeightCenter = m_Noise.IntNoise2DInRange(a_GridX + 80, a_GridZ, m_MinCeilingHeightCenter, m_MaxCeilingHeightCenter); - + // Create a ravine: return cStructurePtr(new cRoughRavine( m_Seed, diff --git a/src/Generating/RoughRavines.h b/src/Generating/RoughRavines.h index 4c905b641..a5ce13357 100644 --- a/src/Generating/RoughRavines.h +++ b/src/Generating/RoughRavines.h @@ -18,7 +18,7 @@ class cRoughRavines : public cGridStructGen { typedef cGridStructGen super; - + public: cRoughRavines( int a_Seed, @@ -31,22 +31,22 @@ public: float a_MaxCeilingHeightCenter, float a_MinCeilingHeightCenter, int a_GridSize, int a_MaxOffset ); - + protected: int m_Seed; - + /** Maximum size of the ravine, in each of the X / Z axis */ int m_MaxSize; - + /** Minimum size of the ravine */ int m_MinSize; /** Maximum width of the ravine's center, in blocks */ float m_MaxCenterWidth; - + /** Minimum width of the ravine's center, in blocks */ float m_MinCenterWidth; - + /** Maximum roughness of the ravine */ float m_MaxRoughness; @@ -55,25 +55,25 @@ protected: /** Maximum floor height at the ravine's edge */ float m_MaxFloorHeightEdge; - + /** Minimum floor height at the ravine's edge */ float m_MinFloorHeightEdge; - + /** Maximum floor height at the ravine's center */ float m_MaxFloorHeightCenter; - + /** Minimum floor height at the ravine's center */ float m_MinFloorHeightCenter; - + /** Maximum ceiling height at the ravine's edge */ float m_MaxCeilingHeightEdge; - + /** Minimum ceiling height at the ravine's edge */ float m_MinCeilingHeightEdge; - + /** Maximum ceiling height at the ravine's center */ float m_MaxCeilingHeightCenter; - + /** Minimum ceiling height at the ravine's center */ float m_MinCeilingHeightCenter; diff --git a/src/Generating/ShapeGen.cpp b/src/Generating/ShapeGen.cpp index 43601ee20..e3de6e733 100644 --- a/src/Generating/ShapeGen.cpp +++ b/src/Generating/ShapeGen.cpp @@ -83,7 +83,7 @@ cTerrainShapeGenPtr cTerrainShapeGen::CreateShapeGen(cIniFile & a_IniFile, cBiom LOGWARN("[Generator] ShapeGen value not set in world.ini, using \"BiomalNoise3D\"."); shapeGenName = "BiomalNoise3D"; } - + // If the shapegen is HeightMap, redirect to older HeightMap-based generators: if (NoCaseCompare(shapeGenName, "HeightMap") == 0) { @@ -133,10 +133,10 @@ cTerrainShapeGenPtr cTerrainShapeGen::CreateShapeGen(cIniFile & a_IniFile, cBiom a_IniFile.SetValue("Generator", "ShapeGen", "BiomalNoise3D"); return CreateShapeGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault); } - + // Read the settings: res->InitializeShapeGen(a_IniFile); - + return res; } diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index edd2f6b87..9b4eb67ef 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -19,9 +19,9 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); - + cChunkDesc WorkerDesc(ChunkX, ChunkZ); - + // Generate trees: for (int x = 0; x <= 2; x++) { @@ -29,14 +29,14 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) for (int z = 0; z <= 2; z++) { int BaseZ = ChunkZ + z - 1; - + cChunkDesc * Dest; if ((x != 1) || (z != 1)) { 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 cChunkDesc::Shape workerShape; @@ -66,7 +66,7 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) ApplyTreeImage(ChunkX, ChunkZ, a_ChunkDesc, OutsideLogs, IgnoredOverflow); } // for z } // for x - + // Update the heightmap: for (int x = 0; x < cChunkDef::Width; x++) { @@ -97,9 +97,9 @@ void cStructGenTrees::GenerateSingleTree( { int x = (m_Noise.IntNoise3DInt(a_ChunkX + a_ChunkZ, a_ChunkZ, a_Seq) / 19) % cChunkDef::Width; 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; @@ -111,7 +111,7 @@ void cStructGenTrees::GenerateSingleTree( { return; } - + sSetBlockVector TreeLogs, TreeOther; GetTreeImageByBiome( a_ChunkX * cChunkDef::Width + x, Height + 1, a_ChunkZ * cChunkDef::Width + z, @@ -148,7 +148,7 @@ void cStructGenTrees::GenerateSingleTree( } } } - + ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeOther, a_OutsideOther); ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeLogs, a_OutsideLogs); } @@ -185,11 +185,11 @@ void cStructGenTrees::ApplyTreeImage( a_ChunkDesc.SetBlockTypeMeta(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta); break; } - + } // switch (GetBlock()) continue; } - + // Outside the chunk, push into a_Overflow. // Don't check if already present there, by separating logs and others we don't need the checks anymore: a_Overflow.push_back(*itr); @@ -279,20 +279,20 @@ 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) { continue; } - + 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; - + // Merge the lake into the current data a_ChunkDesc.WriteBlockArea(Lake, OfsX, Lake.GetOriginY(), OfsZ, cBlockArea::msLake); } // for x, z - neighbor chunks @@ -306,7 +306,7 @@ 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 int MinHeight = std::max(a_MaxLakeHeight - 6, 2); int Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 128, a_ChunkZ) / 11; @@ -318,9 +318,9 @@ void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeH Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 512, a_ChunkZ) / 13; // Random height [1 .. MinHeight] with preference to center heights int HeightY = 1 + (((Rnd & 0x1ff) % MinHeight) + (((Rnd >> 9) & 0x1ff) % MinHeight)) / 2; - + a_Lake.SetOrigin(OffsetX, HeightY, OffsetZ); - + // Hollow out a few bubbles inside the blockarea: int NumBubbles = 4 + ((Rnd >> 18) & 0x03); // 4 .. 7 bubbles BLOCKTYPE * BlockTypes = a_Lake.GetBlockTypes(); @@ -371,9 +371,9 @@ void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeH } } // for z, x } // for y - + // TODO: Turn sponge next to lava into stone - + // a_Lake.SaveToSchematicFile(Printf("Lake_%d_%d.schematic", a_ChunkX, a_ChunkZ)); } @@ -401,7 +401,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) { return; } - + HEIGHTTYPE MaxHeight = a_ChunkDesc.GetMaxHeight(); const int SEGMENT_HEIGHT = 8; @@ -410,7 +410,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) // 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]; int * FloorHi = FloorBuf1; @@ -418,7 +418,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) int BaseX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; int BaseZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; 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++) { @@ -428,7 +428,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) 256; } // for x, z - FloorLo[] LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo); - + // Interpolate segments: for (int Segment = BaseY; Segment < MaxHeight; Segment += SEGMENT_HEIGHT) { @@ -441,12 +441,12 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) ); } // 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)) { int Lo = FloorLo[x + 17 * z] / 256; @@ -462,7 +462,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) break; } // if (biome) } // for z, x - + // Swap the floors: std::swap(FloorLo, FloorHi); } diff --git a/src/Generating/StructGen.h b/src/Generating/StructGen.h index b5cfcb07c..a9ada6c1e 100644 --- a/src/Generating/StructGen.h +++ b/src/Generating/StructGen.h @@ -31,7 +31,7 @@ public: m_ShapeGen(a_ShapeGen), m_CompositionGen(a_CompositionGen) {} - + protected: int m_Seed; @@ -39,7 +39,7 @@ protected: cBiomeGenPtr m_BiomeGen; cTerrainShapeGenPtr m_ShapeGen; cTerrainCompositionGenPtr m_CompositionGen; - + /** Generates and applies an image of a single tree. Parts of the tree inside the chunk are applied to a_ChunkDesc. Parts of the tree outside the chunk are stored in a_OutsideXYZ @@ -50,7 +50,7 @@ protected: sSetBlockVector & a_OutsideLogs, sSetBlockVector & a_OutsideOther ) ; - + /** Applies an image into chunk blockdata; all blocks outside the chunk will be appended to a_Overflow. */ void ApplyTreeImage( int a_ChunkX, int a_ChunkZ, @@ -63,7 +63,7 @@ protected: int a_ChunkX, int a_ChunkZ, const cChunkDef::BiomeMap & a_Biomes ); - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -84,7 +84,7 @@ public: m_Probability(a_Probability) { } - + protected: cNoise m_Noise; int m_Seed; @@ -93,11 +93,11 @@ protected: /** Chance, [0 .. 100], of a chunk having the lake. */ int m_Probability; - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - + /** Creates a lake image for the specified chunk into a_Lake. */ void CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeHeight, cBlockArea & a_Lake); } ; @@ -116,7 +116,7 @@ public: protected: cNoise m_Noise1; cNoise m_Noise2; - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; @@ -138,7 +138,7 @@ protected: cNoise m_NoiseY; cNoise m_NoiseZ; cNoise m_NoiseH; - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index 37afaaac6..f2592aa21 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -171,7 +171,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No } return; } - + case biTaiga: case biIcePlains: case biIceMountains: @@ -181,7 +181,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No GetConiferTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks); return; } - + case biSwamplandM: case biSwampland: { @@ -189,7 +189,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No GetSwampTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks); return; } - + case biJungle: case biJungleHills: case biJungleEdge: @@ -206,7 +206,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No } return; } - + case biBirchForest: case biBirchForestHills: { @@ -259,7 +259,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No GetDarkoakTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks); return; } - + case biMesa: case biMesaPlateauF: case biMesaPlateau: @@ -288,7 +288,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No return; } } - + ASSERT(!"Invalid biome type!"); } @@ -320,24 +320,24 @@ void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a - 2 layers of BigO2 + random corners (log) - 1 to 3 blocks of trunk */ - + int Random = a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) >> 3; - + HEIGHTTYPE Heights[] = {1, 2, 2, 3} ; HEIGHTTYPE Height = 1 + Heights[Random & 3]; Random >>= 2; - + // Pre-alloc so that we don't realloc too often later: a_LogBlocks.reserve(static_cast<size_t>(Height + 5)); a_OtherBlocks.reserve(ARRAYCOUNT(BigO2) * 2 + ARRAYCOUNT(BigO1) + ARRAYCOUNT(Corners) * 3 + 3 + 5); - + // Trunk: for (int i = 0; i < Height; i++) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); } int Hei = a_BlockY + Height; - + // 2 BigO2 + corners layers: for (int i = 0; i < 2; i++) { @@ -346,7 +346,7 @@ void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a a_LogBlocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); Hei++; } // for i - 2* - + // Optional BigO1 + corners layer: if ((Random & 1) == 0) { @@ -355,7 +355,7 @@ void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a a_LogBlocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); Hei++; } - + // Top plus: PushCoordBlocks(a_BlockX, Hei, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); a_OtherBlocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); @@ -479,28 +479,28 @@ NIBBLETYPE GetLogMetaFromDirection(NIBBLETYPE a_BlockMeta, Vector3d a_Direction) void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks) { HEIGHTTYPE Height = 5 + (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) % 3); - + // Prealloc, so that we don't realloc too often later: a_LogBlocks.reserve(static_cast<size_t>(Height)); a_OtherBlocks.reserve(80); - + // The entire trunk, out of logs: for (int i = Height - 1; i >= 0; --i) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_BIRCH)); } int h = a_BlockY + Height; - + // Top layer - just the Plus: PushCoordBlocks(a_BlockX, h, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); a_OtherBlocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH)); // There's no log at this layer h--; - + // Second layer - log, Plus and maybe Corners: PushCoordBlocks (a_BlockX, h, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); h--; - + // Third and fourth layers - BigO2 and maybe 2 * Corners: for (int Row = 0; Row < 2; Row++) { @@ -518,7 +518,7 @@ void GetAcaciaTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi { // Calculate a base height int Height = 2 + (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) / 11 % 3); - + // Create the trunk for (int i = 0; i < Height; i++) { @@ -653,28 +653,28 @@ void GetDarkoakTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No void GetTallBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks) { HEIGHTTYPE Height = 9 + (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) % 3); - + // Prealloc, so that we don't realloc too often later: a_LogBlocks.reserve(static_cast<size_t>(Height)); a_OtherBlocks.reserve(80); - + // The entire trunk, out of logs: for (int i = Height - 1; i >= 0; --i) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_BIRCH)); } int h = a_BlockY + Height; - + // Top layer - just the Plus: PushCoordBlocks(a_BlockX, h, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); a_OtherBlocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH)); // There's no log at this layer h--; - + // Second layer - log, Plus and maybe Corners: PushCoordBlocks (a_BlockX, h, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); h--; - + // Third and fourth layers - BigO2 and maybe 2 * Corners: for (int Row = 0; Row < 2; Row++) { @@ -710,11 +710,11 @@ void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi // Spruces have a top section with layer sizes of (0, 1, 0) or only (1, 0), // then 1 - 3 sections of ascending sizes (1, 2) [most often], (1, 3) or (1, 2, 3) // and an optional bottom section of size 1, followed by 1 - 3 clear trunk blocks - + // We'll use bits from this number as partial random numbers; but the noise function has mod8 irregularities // (each of the mod8 remainders has a very different chance of occurrence) - that's why we divide by 8 int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY + 32 * a_Seq, a_BlockZ) / 8; - + static const HEIGHTTYPE sHeights[] = {1, 2, 2, 3}; HEIGHTTYPE Height = sHeights[MyRandom & 3]; MyRandom >>= 2; @@ -722,14 +722,14 @@ void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi // Prealloc, so that we don't realloc too often later: a_LogBlocks.reserve(static_cast<size_t>(Height)); a_OtherBlocks.reserve(180); - + // Clear trunk blocks: for (int i = 0; i < Height; i++) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); } Height += a_BlockY; - + // Optional size-1 bottom leaves layer: if ((MyRandom & 1) == 0) { @@ -738,7 +738,7 @@ void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi Height++; } MyRandom >>= 1; - + // 1 to 3 sections of leaves layers: static const int sNumSections[] = {1, 2, 2, 3}; int NumSections = sNumSections[MyRandom & 3]; @@ -780,7 +780,7 @@ void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi } // switch (SectionType) MyRandom >>= 2; } // for i - Sections - + if ((MyRandom & 1) == 0) { // (0, 1, 0) top: @@ -806,7 +806,7 @@ void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise { // Tall, little leaves on top. The top leaves are arranged in a shape of two cones joined by their bases. // There can be one or two layers representing the cone bases (SameSizeMax) - + int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8; int TrunkHeight = 8 + (MyRandom % 3); int SameSizeMax = ((MyRandom & 8) == 0) ? 1 : 0; @@ -816,7 +816,7 @@ void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise { SameSizeMax = 0; } - + // Pre-allocate the vector: a_LogBlocks.reserve(static_cast<size_t>(TrunkHeight)); a_OtherBlocks.reserve(static_cast<size_t>(NumLeavesLayers * 25)); @@ -867,19 +867,19 @@ void GetSwampTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Nois } ; int Height = 3 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8) % 3; - + a_LogBlocks.reserve(static_cast<size_t>(Height)); a_OtherBlocks.reserve(2 * ARRAYCOUNT(BigO2) + 2 * ARRAYCOUNT(BigO3) + static_cast<size_t>(Height) * ARRAYCOUNT(Vines) + 20); - + for (int i = 0; i < Height; i++) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); } int hei = a_BlockY + Height - 2; - + // Put vines around the lowermost leaves layer: PushSomeColumns(a_BlockX, hei, a_BlockZ, Height, a_Seq, a_Noise, 0x3fffffff, a_OtherBlocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES); - + // The lower two leaves layers are BigO3 with log in the middle and possibly corners: for (int i = 0; i < 2; i++) { @@ -905,16 +905,16 @@ void GetSwampTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Nois void GetAppleBushImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks) { a_OtherBlocks.reserve(3 + ARRAYCOUNT(BigO2) + ARRAYCOUNT(BigO1)); - + int hei = a_BlockY; a_LogBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_JUNGLE)); PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); hei++; - + a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); hei++; - + a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); } @@ -951,12 +951,12 @@ void GetLargeJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & {-5, -2, 8}, {-5, -1, 8}, {-5, 0, 8}, {-5, 1, 8}, {-5, 2, 8}, // West face // TODO: vines around the trunk, proper metas and height } ; - + int Height = 24 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 11) % 24; - + a_LogBlocks.reserve(static_cast<size_t>(Height) * 4); a_OtherBlocks.reserve(2 * ARRAYCOUNT(BigO4) + ARRAYCOUNT(BigO3) + static_cast<size_t>(Height) * ARRAYCOUNT(Vines) + 50); - + for (int i = 0; i < Height; i++) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_JUNGLE)); @@ -965,10 +965,10 @@ void GetLargeJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_LogBlocks.push_back(sSetBlock(a_BlockX + 1, a_BlockY + i, a_BlockZ + 1, E_BLOCK_LOG, E_META_LOG_JUNGLE)); } int hei = a_BlockY + Height - 2; - + // Put vines around the lowermost leaves layer: PushSomeColumns(a_BlockX, hei, a_BlockZ, Height, a_Seq, a_Noise, 0x3fffffff, a_OtherBlocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES); - + // The lower two leaves layers are BigO4 with log in the middle and possibly corners: for (int i = 0; i < 2; i++) { @@ -1000,7 +1000,7 @@ void GetSmallJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & } ; int Height = 7 + (a_Noise.IntNoise3DInt(a_BlockX + 5 * a_Seq, a_BlockY, a_BlockZ + 5 * a_Seq) / 5) % 3; - + a_LogBlocks.reserve(static_cast<size_t>(Height)); a_OtherBlocks.reserve( 2 * ARRAYCOUNT(BigO3) + // O3 layer, 2x @@ -1009,16 +1009,16 @@ void GetSmallJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & static_cast<size_t>(Height) * ARRAYCOUNT(Vines) + // Vines 50 // some safety ); - + for (int i = 0; i < Height; i++) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_JUNGLE)); } int hei = a_BlockY + Height - 3; - + // Put vines around the lowermost leaves layer: PushSomeColumns(a_BlockX, hei, a_BlockZ, Height, a_Seq, a_Noise, 0x3fffffff, a_OtherBlocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES); - + // The lower two leaves layers are BigO3 with log in the middle and possibly corners: for (int i = 0; i < 2; i++) { @@ -1034,7 +1034,7 @@ void GetSmallJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE); hei++; } // for i - 2* - + // Top plus, all leaves: PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE); a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE)); diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index 6ee150209..e0804625a 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -67,14 +67,14 @@ public: RoadPiece->AddConnector(0, 0, 1, BLOCK_FACE_XM, -2); RoadPiece->AddConnector(len - 1, 0, 1, BLOCK_FACE_XP, -2); RoadPiece->SetDefaultWeight(100); - + // Add the road connectors: for (int x = 1; x < len; x += 12) { RoadPiece->AddConnector(x, 0, 0, BLOCK_FACE_ZM, 2); RoadPiece->AddConnector(x, 0, 2, BLOCK_FACE_ZP, 2); } - + // Add the buildings connectors: for (int x = 7; x < len; x += 12) { @@ -87,8 +87,8 @@ public: m_PiecesByConnector[2].push_back(RoadPiece); } // for len - roads of varying length } - - + + // cPrefabPiecePool overrides: virtual int GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece) override { @@ -97,7 +97,7 @@ public: { return 0; } - + return static_cast<const cPrefab &>(a_NewPiece).GetPieceWeight(a_PlacedPiece, a_ExistingConnector); } }; @@ -111,7 +111,7 @@ class cVillageGen::cVillage : protected cPiecePool { typedef cGridStructGen::cStructure super; - + public: cVillage( int a_Seed, @@ -140,38 +140,38 @@ public: return; } } - + ~cVillage() { cPieceGenerator::FreePieces(m_Pieces); } - + protected: /** Seed for the random functions */ int m_Seed; - + /** The noise used as a pseudo-random generator */ cNoise m_Noise; - + /** Maximum size, in X / Z blocks, of the village (radius from the origin) */ int m_MaxSize; - + /** The density for this village. Used to refrain from populating all house connectors. Range [0, 100] */ int m_Density; - + /** Borders of the village - no item may reach out of this cuboid. */ cCuboid m_Borders; - + /** Prefabs to use for buildings */ cVillagePiecePool & m_Prefabs; - + /** The underlying height generator, used for placing the structures on top of the terrain. */ cTerrainHeightGenPtr m_HeightGen; - + /** The village pieces, placed by the generator. */ cPlacedPieces m_Pieces; - - + + // cGridStructGen::cStructure overrides: virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override { @@ -213,8 +213,8 @@ protected: int TerrainHeight = cChunkDef::GetHeight(HeightMap, BlockX, BlockZ); a_Piece.MoveToGroundBy(TerrainHeight - FirstConnector.m_Pos.y + 1); } - - + + /** Draws the road into the chunk. The heightmap is not queried from the heightgen, but is given via parameter, so that it may be queried just once for all roads in a chunk. */ @@ -245,21 +245,21 @@ protected: } } } - - + + // cPiecePool overrides: virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override { return m_Prefabs.GetPiecesWithConnector(a_ConnectorType); } - - + + virtual cPieces GetStartingPieces(void) override { return m_Prefabs.GetStartingPieces(); } - - + + virtual int GetPieceWeight( const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, @@ -276,30 +276,30 @@ protected: return 0; } } - + // Density check passed, relay to m_Prefabs: return m_Prefabs.GetPieceWeight(a_PlacedPiece, a_ExistingConnector, a_NewPiece); } - - + + virtual int GetStartingPieceWeight(const cPiece & a_NewPiece) override { return m_Prefabs.GetStartingPieceWeight(a_NewPiece); } - - + + virtual void PiecePlaced(const cPiece & a_Piece) override { m_Prefabs.PiecePlaced(a_Piece); } - - + + virtual void Reset(void) override { m_Prefabs.Reset(); } - - + + void MoveAllDescendants(cPlacedPieces & a_PlacedPieces, size_t a_Pivot, int a_HeightDifference) { size_t num = a_PlacedPieces.size(); @@ -416,7 +416,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_GridX, int a_Gr { Density = pool->GetMinDensity(); } - + // Create a village based on the chosen prefabs: return cStructurePtr(new cVillage(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, Density, *pool.get(), m_HeightGen)); } diff --git a/src/Generating/VillageGen.h b/src/Generating/VillageGen.h index 6b7c4a3b4..df68d407d 100644 --- a/src/Generating/VillageGen.h +++ b/src/Generating/VillageGen.h @@ -48,22 +48,22 @@ protected: /** The noise used for generating random numbers */ cNoise m_Noise; - + /** Maximum depth of the generator tree */ int m_MaxDepth; - + /** Maximum size, in X / Z blocks, of the village (radius from the origin) */ int m_MaxSize; - + /** Minimum density - percentage of allowed house connections. Range [0, 100] */ int m_MinDensity; - + /** Maximum density - percentage of allowed house connections. Range [0, 100] */ int m_MaxDensity; /** The underlying biome generator that defines whether the village is created or not */ cBiomeGenPtr m_BiomeGen; - + /** The underlying height generator, used to position the prefabs crossing chunk borders */ cTerrainHeightGenPtr m_HeightGen; |