From 537e1afcb1134a3b49fbc5483243e46b46b42f22 Mon Sep 17 00:00:00 2001 From: faketruth Date: Mon, 26 Dec 2011 02:39:43 +0000 Subject: [PATCH] Moved the actual world generation from cChunk.cpp to a more isolated file cWorldGenerator.cpp New generators should inherit cWorldGenerator and implement their own generation algorithms git-svn-id: http://mc-server.googlecode.com/svn/trunk@117 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- VC2010/MCServer.vcxproj | 2 + VC2010/MCServer.vcxproj.filters | 9 ++ source/cChunk.cpp | 239 +----------------------------- source/cChunk.h | 22 +-- source/cWorldGenerator.cpp | 247 ++++++++++++++++++++++++++++++++ source/cWorldGenerator.h | 17 +++ 6 files changed, 285 insertions(+), 251 deletions(-) create mode 100644 source/cWorldGenerator.cpp create mode 100644 source/cWorldGenerator.h diff --git a/VC2010/MCServer.vcxproj b/VC2010/MCServer.vcxproj index 42fd90443..2317408a1 100644 --- a/VC2010/MCServer.vcxproj +++ b/VC2010/MCServer.vcxproj @@ -278,6 +278,7 @@ + @@ -425,6 +426,7 @@ + diff --git a/VC2010/MCServer.vcxproj.filters b/VC2010/MCServer.vcxproj.filters index f2a5cedae..1b3cb6ab9 100644 --- a/VC2010/MCServer.vcxproj.filters +++ b/VC2010/MCServer.vcxproj.filters @@ -421,6 +421,9 @@ {b690d7b6-3697-4d91-bab3-21fd652986be} + + {72727ea7-779f-439e-8f30-53bd6985c9e7} + @@ -841,6 +844,9 @@ Packets\cPacket_PlayerListItem + + cWorldGenerator + @@ -1296,6 +1302,9 @@ Packets\cPacket_PlayerListItem + + cWorldGenerator + diff --git a/source/cChunk.cpp b/source/cChunk.cpp index f30602010..30f6d839f 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -28,10 +28,9 @@ #include "cNoise.h" #include "cRoot.h" #include "cCriticalSection.h" +#include "cWorldGenerator.h" #include "cBlockToPickup.h" -#include "cGenSettings.h" - #include "packets/cPacket_DestroyEntity.h" #include "packets/cPacket_PreChunk.h" #include "packets/cPacket_BlockChange.h" @@ -133,8 +132,8 @@ void cChunk::Initialize() // Clear memory memset( m_BlockData, 0x00, c_BlockDataSize ); - GenerateTerrain(); - GenerateFoliage(); + cWorldGenerator Generator; + Generator.GenerateChunk( this ); CalculateHeightmap(); CalculateLighting(); @@ -718,238 +717,6 @@ void cChunk::SpreadLight(char* a_LightBuffer) if( bCalcBack ) m_World->ReSpreadLighting( BackChunk ); } -float GetNoise( float x, float y, cNoise & a_Noise ) -{ - float oct1 = a_Noise.CubicNoise2D( x*cGenSettings::HeightFreq1, y*cGenSettings::HeightFreq1 )*cGenSettings::HeightAmp1; - float oct2 = a_Noise.CubicNoise2D( x*cGenSettings::HeightFreq2, y*cGenSettings::HeightFreq2 )*cGenSettings::HeightAmp2; - float oct3 = a_Noise.CubicNoise2D( x*cGenSettings::HeightFreq3, y*cGenSettings::HeightFreq3 )*cGenSettings::HeightAmp3; - - float height = a_Noise.CubicNoise2D( x*0.1f, y*0.1f )*2; - - float flatness = ((a_Noise.CubicNoise2D( x*0.5f, y*0.5f ) + 1.f ) * 0.5f) * 1.1f; // 0 ... 1.5 - flatness *= flatness * flatness; - - return (oct1 + oct2 + oct3) * flatness + height; -} - -#define PI_2 (1.57079633f) -float GetMarbleNoise( float x, float y, float z, cNoise & a_Noise ) -{ - float oct1 = (a_Noise.CubicNoise3D( x*0.1f, y*0.1f, z*0.1f ))*4; - - oct1 = oct1 * oct1 * oct1; - if( oct1 < 0.f ) oct1 = PI_2; - if( oct1 > PI_2 ) oct1 = PI_2; - - return oct1; -} - -float GetOreNoise( float x, float y, float z, cNoise & a_Noise ) -{ - float oct1 = a_Noise.CubicNoise3D( x*0.1f, y*0.1f, z*0.1f ); - float oct2 = a_Noise.CubicNoise3D( x*0.05f, y*0.5f, z*0.05f ); - - oct2 *= oct2; - oct1 = (1 - (oct1 * oct1 *100)) * oct2; - //if( oct1 < 0.5f ) oct1 = 0; - //else oct1 = 1.f; - - return oct1; -} - -void cChunk::GenerateTerrain() -{ - - - //const ENUM_BLOCK_ID GrassID = E_BLOCK_GRASS; - const ENUM_BLOCK_ID DirtID = E_BLOCK_DIRT; - const ENUM_BLOCK_ID StoneID = E_BLOCK_STONE; - const ENUM_BLOCK_ID SandID = E_BLOCK_SAND; - const ENUM_BLOCK_ID SandStoneID = E_BLOCK_SANDSTONE; - const ENUM_BLOCK_ID CaveID = E_BLOCK_AIR; - const ENUM_BLOCK_ID LavaID = E_BLOCK_STATIONARY_LAVA; - const ENUM_BLOCK_ID CoalID = E_BLOCK_COAL_ORE; - const ENUM_BLOCK_ID IronID = E_BLOCK_IRON_ORE; - const ENUM_BLOCK_ID GoldID = E_BLOCK_GOLD_ORE; - const ENUM_BLOCK_ID DiamondID = E_BLOCK_DIAMOND_ORE; - const ENUM_BLOCK_ID RedID = E_BLOCK_REDSTONE_ORE; - - /* - const ENUM_BLOCK_ID GrassID = E_BLOCK_AIR; - const ENUM_BLOCK_ID DirtID = E_BLOCK_AIR; - const ENUM_BLOCK_ID StoneID = E_BLOCK_AIR; - const ENUM_BLOCK_ID SandID = E_BLOCK_AIR; - const ENUM_BLOCK_ID CaveID = E_BLOCK_AIR; - const ENUM_BLOCK_ID LavaID = E_BLOCK_AIR; - const ENUM_BLOCK_ID CoalID = E_BLOCK_COAL_ORE; - const ENUM_BLOCK_ID IronID = E_BLOCK_IRON_ORE; - const ENUM_BLOCK_ID GoldID = E_BLOCK_GOLD_ORE; - const ENUM_BLOCK_ID DiamondID = E_BLOCK_DIAMOND_ORE; - const ENUM_BLOCK_ID RedID = E_BLOCK_REDSTONE_ORE; - */ - - cNoise m_Noise( m_World->GetWorldSeed() ); - for(int z = 0; z < 16; z++) - { - const float zz = (float)(m_PosZ*16 + z); - for(int x = 0; x < 16; x++) - { - // Place bedrock on bottom layer - m_BlockType[ MakeIndex(x, 0, z) ] = E_BLOCK_BEDROCK; - - const float xx = (float)(m_PosX*16 + x); - - int Height = (int)(GetNoise( xx*0.05f, zz*0.05f, m_Noise )*16); - const int Lower = 64; - if( Height+Lower > 127 ) Height = 127-Lower; - const int Top = Lower+Height; - const float WaveNoise = 1;//m_Noise.CubicNoise2D( xx*0.01f, zz*0.01f ) + 0.5f; - for( int y = 1; y < Top; ++y ) - { - const float yy = (float)y; - // V prevent caves from getting too close to the surface - if( (Top - y > (WaveNoise*2) ) && cosf(GetMarbleNoise( xx, yy*0.5f, zz, m_Noise )) * fabs( cosf( yy*0.2f + WaveNoise*2 )*0.75f + WaveNoise ) > 0.5f ) - { - if( y > 4 ) - { - m_BlockType[ MakeIndex(x, y, z) ] = CaveID; - if( z > 0 ) m_BlockType[ MakeIndex(x, y, z-1) ] = CaveID; - if( z < 15 ) m_BlockType[ MakeIndex(x, y, z+1) ] = CaveID; - if( x > 0 ) m_BlockType[ MakeIndex(x-1, y, z) ] = CaveID; - if( x < 15 ) m_BlockType[ MakeIndex(x+1, y, z) ] = CaveID; - } - else - { - m_BlockType[ MakeIndex(x, y, z) ] = LavaID; - } - } - else if( y < 61 && Top - y < 3 ) - m_BlockType[ MakeIndex(x, y, z) ] = SandID; - else if( y < 61 && Top - y < 4 ) - m_BlockType[ MakeIndex(x, y, z) ] = SandStoneID; - else if( Top - y > ((WaveNoise+1.5f)*1.5f) ) // rock and ores between 1.5 .. 4.5 deep - { - if( GetOreNoise( xx, yy, zz, m_Noise ) > 0.5f ) - m_BlockType[ MakeIndex(x, y, z) ] = CoalID; - else if( GetOreNoise( xx, yy+100.f, zz, m_Noise ) > 0.6f ) - m_BlockType[ MakeIndex(x, y, z) ] = IronID; - else if( yy < 20 && GetOreNoise( xx*1.5f, yy+300.f, zz*1.5f, m_Noise ) > 0.6f ) - m_BlockType[ MakeIndex(x, y, z) ] = RedID; - else if( yy < 30 && GetOreNoise( xx*2, yy+200.f, zz*2, m_Noise ) > 0.75f ) - m_BlockType[ MakeIndex(x, y, z) ] = DiamondID; - else if( yy < 40 && GetOreNoise( xx*2, yy+100.f, zz*2, m_Noise ) > 0.75f ) - m_BlockType[ MakeIndex(x, y, z) ] = GoldID; - else - m_BlockType[ MakeIndex(x, y, z) ] = StoneID; - } - else - m_BlockType[ MakeIndex(x, y, z) ] = DirtID; - } - for( int y = Lower+Height; y < 60; ++y ) - { - m_BlockType[ MakeIndex(x, y, z) ] = E_BLOCK_STATIONARY_WATER; - } - } - } -} - -void cChunk::GenerateFoliage() -{ - const ENUM_BLOCK_ID GrassID = E_BLOCK_GRASS; - const ENUM_BLOCK_ID DirtID = E_BLOCK_DIRT; - const ENUM_BLOCK_ID SandID = E_BLOCK_SAND; - const ENUM_BLOCK_ID SandStoneID = E_BLOCK_SANDSTONE; - const ENUM_BLOCK_ID CaveID = E_BLOCK_AIR; - - cNoise m_Noise( m_World->GetWorldSeed() ); - - for(int z = 0; z < 16; z++) for(int x = 0; x < 16; x++) - { - // Find top most Y - int TopY = -1; - for(int y = 127; y > 0; y--) - { - int index = MakeIndex( x, y, z ); - if( m_BlockType[index] != E_BLOCK_AIR ) - { - TopY = y; - break; - } - } - if( TopY > 0 ) - { - // Change top dirt into grass and prevent sand from floating over caves - int index = MakeIndex( x, TopY, z ); - int index1 = MakeIndex( x, TopY-1, z ); - int index2 = MakeIndex( x, TopY-2, z ); - int index3 = MakeIndex( x, TopY-3, z ); - int index4 = MakeIndex( x, TopY-4, z ); - int index5 = MakeIndex( x, TopY-5, z ); - - if( m_BlockType[index] == SandID ) { - - if( m_BlockType[index1] == CaveID ) { - m_BlockType[ index ] = (char)SandStoneID; - } else if( m_BlockType[index2] == CaveID ) { - m_BlockType[ index1 ] = (char)SandStoneID; - } else if( m_BlockType[index3] == CaveID ) { - m_BlockType[ index2 ] = (char)SandStoneID; - } else if( m_BlockType[index4] == CaveID ) { - m_BlockType[ index3 ] = (char)SandStoneID; - } else if( m_BlockType[index5] == CaveID ) { - m_BlockType[ index4 ] = (char)SandStoneID; - } - - } - - if( m_BlockType[index] == DirtID ) - { - m_BlockType[ index ] = (char)GrassID; - } - - - // Plant sum trees - { - int xx = x + m_PosX*16; - // int yy = TopY; - int zz = z + m_PosZ*16; - - float val1 = m_Noise.CubicNoise2D( xx*0.1f, zz*0.1f ); - float val2 = m_Noise.CubicNoise2D( xx*0.01f, zz*0.01f ); - if( m_BlockType[index] == SandID ) - { - if( (val1 + val2 > 0.f) && (rand()%128) > 124 && m_BlockType[index] == E_BLOCK_SAND ) - { - m_BlockType[ MakeIndex(x, TopY+1, z) ] = E_BLOCK_CACTUS; - if( (rand() & 3) == 3 ) - { - m_BlockType[ MakeIndex(x, TopY+2, z) ] = E_BLOCK_CACTUS; - } - continue; - } - } - else if( m_BlockType[index] == GrassID ) - { - float val3 = m_Noise.CubicNoise2D( xx*0.01f+10, zz*0.01f+10 ); - float val4 = m_Noise.CubicNoise2D( xx*0.05f+20, zz*0.05f+20 ); - if( val1 + val2 > 0.2f && (rand()%128) > 124 ) - m_World->GrowTree( xx, TopY, zz ); - else if( val3 > 0.2f && (rand()%128) > 124 ) - m_BlockType[ MakeIndex(x, TopY+1, z) ] = E_BLOCK_YELLOW_FLOWER; - else if( val4 > 0.2f && (rand()%128) > 124 ) - m_BlockType[ MakeIndex(x, TopY+1, z) ] = E_BLOCK_RED_ROSE; - else if( val1+val2+val3+val4 > 0.2f && (rand()%128) > 124 ) - m_BlockType[ MakeIndex(x, TopY+1, z) ] = E_BLOCK_RED_MUSHROOM; - else if( val1+val2+val3+val4 > 0.2f && (rand()%128) > 124 ) - m_BlockType[ MakeIndex(x, TopY+1, z) ] = E_BLOCK_BROWN_MUSHROOM; - } - } - - } - } -} - - void cChunk::AsyncUnload( cClientHandle* a_Client ) { m_pState->m_UnloadQuery.remove( a_Client ); // Make sure this client is only in the list once diff --git a/source/cChunk.h b/source/cChunk.h index b18a763b2..b794f4153 100644 --- a/source/cChunk.h +++ b/source/cChunk.h @@ -80,15 +80,14 @@ public: void PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z); void AddTickBlockEntity( cFurnaceEntity* a_Entity ); - //{ - // m_TickBlockEntities.remove( a_Entity ); - // m_TickBlockEntities.push_back( a_Entity ); - //} - void RemoveTickBlockEntity( cFurnaceEntity* a_Entity ); - //{ - // m_TickBlockEntities.remove( a_Entity ); - //} + + inline static unsigned int cChunk::MakeIndex(int x, int y, int z ) + { + if( x < 16 && x > -1 && y < 128 && y > -1 && z < 16 && z > -1 ) + return y + (z * 128) + (x * 128 * 16); + return 0; + } static const int c_NumBlocks = 16*128*16; static const int c_BlockDataSize = c_NumBlocks * 2 + (c_NumBlocks/2); // 2.5 * numblocks @@ -111,13 +110,6 @@ private: void CreateBlockEntities(); - inline unsigned int cChunk::MakeIndex(int x, int y, int z ) - { - if( x < 16 && x > -1 && y < 128 && y > -1 && z < 16 && z > -1 ) - return y + (z * 128) + (x * 128 * 16); - return 0; - } - bool m_bCalculateLighting; bool m_bCalculateHeightmap; diff --git a/source/cWorldGenerator.cpp b/source/cWorldGenerator.cpp new file mode 100644 index 000000000..f07f5f791 --- /dev/null +++ b/source/cWorldGenerator.cpp @@ -0,0 +1,247 @@ +#include "cWorldGenerator.h" +#include "cNoise.h" +#include "cWorld.h" +#include "cChunk.h" +#include "cGenSettings.h" + +#include "BlockID.h" +#include "Vector3i.h" + +cWorldGenerator::cWorldGenerator() +{ +} + +cWorldGenerator::~cWorldGenerator() +{ +} + + +void cWorldGenerator::GenerateChunk( cChunk* a_Chunk ) +{ + GenerateTerrain( a_Chunk ); + GenerateFoliage( a_Chunk ); +} + +static float GetNoise( float x, float y, cNoise & a_Noise ) +{ + float oct1 = a_Noise.CubicNoise2D( x*cGenSettings::HeightFreq1, y*cGenSettings::HeightFreq1 )*cGenSettings::HeightAmp1; + float oct2 = a_Noise.CubicNoise2D( x*cGenSettings::HeightFreq2, y*cGenSettings::HeightFreq2 )*cGenSettings::HeightAmp2; + float oct3 = a_Noise.CubicNoise2D( x*cGenSettings::HeightFreq3, y*cGenSettings::HeightFreq3 )*cGenSettings::HeightAmp3; + + float height = a_Noise.CubicNoise2D( x*0.1f, y*0.1f )*2; + + float flatness = ((a_Noise.CubicNoise2D( x*0.5f, y*0.5f ) + 1.f ) * 0.5f) * 1.1f; // 0 ... 1.5 + flatness *= flatness * flatness; + + return (oct1 + oct2 + oct3) * flatness + height; +} + +#define PI_2 (1.57079633f) +static float GetMarbleNoise( float x, float y, float z, cNoise & a_Noise ) +{ + float oct1 = (a_Noise.CubicNoise3D( x*0.1f, y*0.1f, z*0.1f ))*4; + + oct1 = oct1 * oct1 * oct1; + if( oct1 < 0.f ) oct1 = PI_2; + if( oct1 > PI_2 ) oct1 = PI_2; + + return oct1; +} + +static float GetOreNoise( float x, float y, float z, cNoise & a_Noise ) +{ + float oct1 = a_Noise.CubicNoise3D( x*0.1f, y*0.1f, z*0.1f ); + float oct2 = a_Noise.CubicNoise3D( x*0.05f, y*0.5f, z*0.05f ); + + oct2 *= oct2; + oct1 = (1 - (oct1 * oct1 *100)) * oct2; + //if( oct1 < 0.5f ) oct1 = 0; + //else oct1 = 1.f; + + return oct1; +} + +void cWorldGenerator::GenerateTerrain( cChunk* a_Chunk ) +{ + Vector3i ChunkPos( a_Chunk->GetPosX(), a_Chunk->GetPosY(), a_Chunk->GetPosZ() ); + char* BlockType = a_Chunk->pGetType(); + + //const ENUM_BLOCK_ID GrassID = E_BLOCK_GRASS; + const ENUM_BLOCK_ID DirtID = E_BLOCK_DIRT; + const ENUM_BLOCK_ID StoneID = E_BLOCK_STONE; + const ENUM_BLOCK_ID SandID = E_BLOCK_SAND; + const ENUM_BLOCK_ID SandStoneID = E_BLOCK_SANDSTONE; + const ENUM_BLOCK_ID CaveID = E_BLOCK_AIR; + const ENUM_BLOCK_ID LavaID = E_BLOCK_STATIONARY_LAVA; + const ENUM_BLOCK_ID CoalID = E_BLOCK_COAL_ORE; + const ENUM_BLOCK_ID IronID = E_BLOCK_IRON_ORE; + const ENUM_BLOCK_ID GoldID = E_BLOCK_GOLD_ORE; + const ENUM_BLOCK_ID DiamondID = E_BLOCK_DIAMOND_ORE; + const ENUM_BLOCK_ID RedID = E_BLOCK_REDSTONE_ORE; + + cNoise Noise( a_Chunk->GetWorld()->GetWorldSeed() ); + for(int z = 0; z < 16; z++) + { + const float zz = (float)(ChunkPos.z*16 + z); + for(int x = 0; x < 16; x++) + { + // Place bedrock on bottom layer + BlockType[ cChunk::MakeIndex(x, 0, z) ] = E_BLOCK_BEDROCK; + + const float xx = (float)(ChunkPos.x*16 + x); + + int Height = (int)(GetNoise( xx*0.05f, zz*0.05f, Noise )*16); + const int Lower = 64; + if( Height+Lower > 127 ) Height = 127-Lower; + const int Top = Lower+Height; + const float WaveNoise = 1;//m_Noise.CubicNoise2D( xx*0.01f, zz*0.01f ) + 0.5f; + for( int y = 1; y < Top; ++y ) + { + const float yy = (float)y; + // V prevent caves from getting too close to the surface + if( (Top - y > (WaveNoise*2) ) && cosf(GetMarbleNoise( xx, yy*0.5f, zz, Noise )) * fabs( cosf( yy*0.2f + WaveNoise*2 )*0.75f + WaveNoise ) > 0.5f ) + { + if( y > 4 ) + { + BlockType[ cChunk::MakeIndex(x, y, z) ] = CaveID; + if( z > 0 ) BlockType[ cChunk::MakeIndex(x, y, z-1) ] = CaveID; + if( z < 15 ) BlockType[ cChunk::MakeIndex(x, y, z+1) ] = CaveID; + if( x > 0 ) BlockType[ cChunk::MakeIndex(x-1, y, z) ] = CaveID; + if( x < 15 ) BlockType[ cChunk::MakeIndex(x+1, y, z) ] = CaveID; + } + else + { + BlockType[ cChunk::MakeIndex(x, y, z) ] = LavaID; + } + } + else if( y < 61 && Top - y < 3 ) + BlockType[ cChunk::MakeIndex(x, y, z) ] = SandID; + else if( y < 61 && Top - y < 4 ) + BlockType[ cChunk::MakeIndex(x, y, z) ] = SandStoneID; + else if( Top - y > ((WaveNoise+1.5f)*1.5f) ) // rock and ores between 1.5 .. 4.5 deep + { + if( GetOreNoise( xx, yy, zz, Noise ) > 0.5f ) + BlockType[ cChunk::MakeIndex(x, y, z) ] = CoalID; + else if( GetOreNoise( xx, yy+100.f, zz, Noise ) > 0.6f ) + BlockType[ cChunk::MakeIndex(x, y, z) ] = IronID; + else if( yy < 20 && GetOreNoise( xx*1.5f, yy+300.f, zz*1.5f, Noise ) > 0.6f ) + BlockType[ cChunk::MakeIndex(x, y, z) ] = RedID; + else if( yy < 30 && GetOreNoise( xx*2, yy+200.f, zz*2, Noise ) > 0.75f ) + BlockType[ cChunk::MakeIndex(x, y, z) ] = DiamondID; + else if( yy < 40 && GetOreNoise( xx*2, yy+100.f, zz*2, Noise ) > 0.75f ) + BlockType[ cChunk::MakeIndex(x, y, z) ] = GoldID; + else + BlockType[ cChunk::MakeIndex(x, y, z) ] = StoneID; + } + else + BlockType[ cChunk::MakeIndex(x, y, z) ] = DirtID; + } + for( int y = Lower+Height; y < 60; ++y ) + { + BlockType[ cChunk::MakeIndex(x, y, z) ] = E_BLOCK_STATIONARY_WATER; + } + } + } +} + + + +void cWorldGenerator::GenerateFoliage( cChunk* a_Chunk ) +{ + const ENUM_BLOCK_ID GrassID = E_BLOCK_GRASS; + const ENUM_BLOCK_ID DirtID = E_BLOCK_DIRT; + const ENUM_BLOCK_ID SandID = E_BLOCK_SAND; + const ENUM_BLOCK_ID SandStoneID = E_BLOCK_SANDSTONE; + const ENUM_BLOCK_ID CaveID = E_BLOCK_AIR; + + int PosX = a_Chunk->GetPosX(); + int PosZ = a_Chunk->GetPosZ(); + + cWorld* World = a_Chunk->GetWorld(); + cNoise m_Noise( World->GetWorldSeed() ); + char* BlockType = a_Chunk->pGetType(); + + for(int z = 0; z < 16; z++) for(int x = 0; x < 16; x++) + { + // Find top most Y + int TopY = -1; + for(int y = 127; y > 0; y--) + { + int index = cChunk::MakeIndex( x, y, z ); + if( BlockType[index] != E_BLOCK_AIR ) + { + TopY = y; + break; + } + } + if( TopY > 0 ) + { + // Change top dirt into grass and prevent sand from floating over caves + int index = cChunk::MakeIndex( x, TopY, z ); + int index1 = cChunk::MakeIndex( x, TopY-1, z ); + int index2 = cChunk::MakeIndex( x, TopY-2, z ); + int index3 = cChunk::MakeIndex( x, TopY-3, z ); + int index4 = cChunk::MakeIndex( x, TopY-4, z ); + int index5 = cChunk::MakeIndex( x, TopY-5, z ); + + if( BlockType[index] == SandID ) { + + if( BlockType[index1] == CaveID ) { + BlockType[ index ] = (char)SandStoneID; + } else if( BlockType[index2] == CaveID ) { + BlockType[ index1 ] = (char)SandStoneID; + } else if( BlockType[index3] == CaveID ) { + BlockType[ index2 ] = (char)SandStoneID; + } else if( BlockType[index4] == CaveID ) { + BlockType[ index3 ] = (char)SandStoneID; + } else if( BlockType[index5] == CaveID ) { + BlockType[ index4 ] = (char)SandStoneID; + } + + } + + if( BlockType[index] == DirtID ) + { + BlockType[ index ] = (char)GrassID; + } + + + // Plant sum trees + { + int xx = x + PosX*16; + int zz = z + PosZ*16; + + float val1 = m_Noise.CubicNoise2D( xx*0.1f, zz*0.1f ); + float val2 = m_Noise.CubicNoise2D( xx*0.01f, zz*0.01f ); + if( BlockType[index] == SandID ) + { + if( (val1 + val2 > 0.f) && (rand()%128) > 124 && BlockType[index] == E_BLOCK_SAND ) + { + BlockType[ cChunk::MakeIndex(x, TopY+1, z) ] = E_BLOCK_CACTUS; + if( (rand() & 3) == 3 ) + { + BlockType[ cChunk::MakeIndex(x, TopY+2, z) ] = E_BLOCK_CACTUS; + } + continue; + } + } + else if( BlockType[index] == GrassID ) + { + float val3 = m_Noise.CubicNoise2D( xx*0.01f+10, zz*0.01f+10 ); + float val4 = m_Noise.CubicNoise2D( xx*0.05f+20, zz*0.05f+20 ); + if( val1 + val2 > 0.2f && (rand()%128) > 124 ) + World->GrowTree( xx, TopY, zz ); + else if( val3 > 0.2f && (rand()%128) > 124 ) + BlockType[ cChunk::MakeIndex(x, TopY+1, z) ] = E_BLOCK_YELLOW_FLOWER; + else if( val4 > 0.2f && (rand()%128) > 124 ) + BlockType[ cChunk::MakeIndex(x, TopY+1, z) ] = E_BLOCK_RED_ROSE; + else if( val1+val2+val3+val4 > 0.2f && (rand()%128) > 124 ) + BlockType[ cChunk::MakeIndex(x, TopY+1, z) ] = E_BLOCK_RED_MUSHROOM; + else if( val1+val2+val3+val4 > 0.2f && (rand()%128) > 124 ) + BlockType[ cChunk::MakeIndex(x, TopY+1, z) ] = E_BLOCK_BROWN_MUSHROOM; + } + } + + } + } +} diff --git a/source/cWorldGenerator.h b/source/cWorldGenerator.h new file mode 100644 index 000000000..01a086612 --- /dev/null +++ b/source/cWorldGenerator.h @@ -0,0 +1,17 @@ +#pragma once + +class cChunk; +class cWorldGenerator +{ +public: + cWorldGenerator(); + ~cWorldGenerator(); + + virtual void GenerateChunk( cChunk* a_Chunk ); + +protected: + + virtual void GenerateTerrain( cChunk* a_Chunk ); + virtual void GenerateFoliage( cChunk* a_Chunk ); + +}; \ No newline at end of file