2012-01-29 11:28:19 -08:00
# include "Globals.h"
2011-12-25 04:55:20 -08:00
# include "cChunkGenerator.h"
# include "cWorld.h"
2012-05-25 00:18:52 -07:00
# include "../iniFile/iniFile.h"
# include "BioGen.h"
# include "HeiGen.h"
# include "CompoGen.h"
# include "StructGen.h"
# include "FinishGen.h"
2012-06-05 08:20:48 -07:00
# include "cRoot.h"
# include "cPluginManager.h"
2011-12-25 04:55:20 -08:00
2012-01-29 06:29:26 -08:00
/// If the generation queue size exceeds this number, a warning will be output
2012-02-13 13:47:03 -08:00
const int QUEUE_WARNING_LIMIT = 1000 ;
/// If the generation queue size exceeds this number, chunks with no clients will be skipped
2012-02-28 02:01:42 -08:00
const int QUEUE_SKIP_LIMIT = 500 ;
2012-01-29 06:29:26 -08:00
2011-12-25 04:55:20 -08:00
2012-06-09 08:26:52 -07:00
static BLOCKTYPE GetIniBlock ( cIniFile & a_IniFile , const AString & a_SectionName , const AString & a_ValueName , const AString & a_Default )
{
AString BlockType = a_IniFile . GetValueSet ( a_SectionName , a_ValueName , a_Default ) ;
BLOCKTYPE Block = BlockStringToType ( BlockType ) ;
if ( Block < 0 )
{
LOGWARN ( " [&s].%s Could not parse block value \" %s \" . Using default: \" %s \" . " , a_SectionName . c_str ( ) , a_ValueName . c_str ( ) , BlockType . c_str ( ) , a_Default . c_str ( ) ) ;
return BlockStringToType ( a_Default ) ;
}
return Block ;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cChunkGenerator:
2012-02-13 13:47:03 -08:00
cChunkGenerator : : cChunkGenerator ( void )
: super ( " cChunkGenerator " )
, m_World ( NULL )
2012-05-25 00:18:52 -07:00
, m_BiomeGen ( NULL )
, m_HeightGen ( NULL )
, m_CompositionGen ( NULL )
2011-12-25 04:55:20 -08:00
{
2012-02-13 13:47:03 -08:00
}
2012-01-29 06:29:26 -08:00
2012-02-13 13:47:03 -08:00
cChunkGenerator : : ~ cChunkGenerator ( )
{
Stop ( ) ;
}
2012-01-29 06:29:26 -08:00
2011-12-25 04:55:20 -08:00
2012-05-25 00:18:52 -07:00
bool cChunkGenerator : : Start ( cWorld * a_World , cIniFile & a_IniFile )
2011-12-25 04:55:20 -08:00
{
2012-05-25 00:18:52 -07:00
MTRand rnd ;
2012-02-13 13:47:03 -08:00
m_World = a_World ;
2012-06-09 08:26:52 -07:00
m_Seed = a_IniFile . GetValueSetI ( " Seed " , " Seed " , rnd . randInt ( ) ) ;
2012-05-25 00:18:52 -07:00
InitBiomeGen ( a_IniFile ) ;
InitHeightGen ( a_IniFile ) ;
InitCompositionGen ( a_IniFile ) ;
InitStructureGens ( a_IniFile ) ;
InitFinishGens ( a_IniFile ) ;
a_IniFile . WriteFile ( ) ;
2012-02-13 13:47:03 -08:00
return super : : Start ( ) ;
2011-12-25 04:55:20 -08:00
}
2012-01-29 06:29:26 -08:00
2012-02-13 13:47:03 -08:00
void cChunkGenerator : : Stop ( void )
2011-12-25 04:55:20 -08:00
{
2012-03-10 09:37:00 -08:00
m_ShouldTerminate = true ;
2012-02-13 13:47:03 -08:00
m_Event . Set ( ) ;
2012-02-18 09:53:22 -08:00
m_evtRemoved . Set ( ) ; // Wake up anybody waiting for empty queue
2012-02-13 13:47:03 -08:00
Wait ( ) ;
2012-05-25 00:18:52 -07:00
// Delete the generating composition:
for ( cFinishGenList : : const_iterator itr = m_FinishGens . begin ( ) ; itr ! = m_FinishGens . end ( ) ; + + itr )
{
delete * itr ;
}
m_FinishGens . clear ( ) ;
for ( cStructureGenList : : const_iterator itr = m_StructureGens . begin ( ) ; itr ! = m_StructureGens . end ( ) ; + + itr )
{
delete * itr ;
}
m_StructureGens . clear ( ) ;
delete m_CompositionGen ;
m_CompositionGen = NULL ;
delete m_HeightGen ;
m_HeightGen = NULL ;
delete m_BiomeGen ;
m_BiomeGen = NULL ;
}
void cChunkGenerator : : InitBiomeGen ( cIniFile & a_IniFile )
{
2012-06-09 08:26:52 -07:00
AString BiomeGenName = a_IniFile . GetValueSet ( " Generator " , " BiomeGen " , " " ) ;
2012-05-25 00:18:52 -07:00
if ( BiomeGenName . empty ( ) )
{
2012-06-09 08:26:52 -07:00
LOGWARN ( " [Generator]::BiomeGen value not found in world.ini, using \" DistortedVoronoi \" . " ) ;
BiomeGenName = " DistortedVoronoi " ;
2012-05-25 00:18:52 -07:00
}
2012-02-13 13:47:03 -08:00
2012-06-02 06:21:59 -07:00
bool CacheOffByDefault = false ;
2012-05-25 00:18:52 -07:00
if ( NoCaseCompare ( BiomeGenName , " constant " ) = = 0 )
{
2012-06-09 08:26:52 -07:00
AString Biome = a_IniFile . GetValueSet ( " Generator " , " ConstantBiome " , " Plains " ) ;
2012-05-27 03:57:36 -07:00
EMCSBiome b = StringToBiome ( Biome ) ;
if ( b = = - 1 )
{
2012-06-02 05:19:20 -07:00
LOGWARN ( " [Generator]::ConstantBiome value \" %s \" not recognized, using \" Plains \" . " , Biome . c_str ( ) ) ;
2012-05-27 03:57:36 -07:00
b = biPlains ;
}
m_BiomeGen = new cBioGenConstant ( b ) ;
2012-06-02 06:21:59 -07:00
CacheOffByDefault = true ; // we're generating faster than a cache would retrieve data :)
2012-05-25 00:18:52 -07:00
}
else if ( NoCaseCompare ( BiomeGenName , " checkerboard " ) = = 0 )
{
2012-06-09 08:26:52 -07:00
int BiomeSize = a_IniFile . GetValueSetI ( " Generator " , " CheckerboardBiomeSize " , 64 ) ;
AString Biomes = a_IniFile . GetValueSet ( " Generator " , " CheckerBoardBiomes " , " " ) ;
2012-05-27 03:51:04 -07:00
m_BiomeGen = new cBioGenCheckerboard ( BiomeSize , Biomes ) ;
2012-06-02 06:21:59 -07:00
CacheOffByDefault = true ; // we're (probably) generating faster than a cache would retrieve data
2012-05-25 00:18:52 -07:00
}
2012-05-27 07:17:47 -07:00
else if ( NoCaseCompare ( BiomeGenName , " voronoi " ) = = 0 )
{
2012-06-09 08:26:52 -07:00
int CellSize = a_IniFile . GetValueSetI ( " Generator " , " VoronoiCellSize " , 64 ) ;
AString Biomes = a_IniFile . GetValueSet ( " Generator " , " VoronoiBiomes " , " " ) ;
2012-05-27 07:17:47 -07:00
m_BiomeGen = new cBioGenVoronoi ( m_Seed , CellSize , Biomes ) ;
}
2012-05-25 00:18:52 -07:00
else
{
if ( NoCaseCompare ( BiomeGenName , " distortedvoronoi " ) ! = 0 )
{
2012-06-09 08:26:52 -07:00
LOGWARNING ( " Unknown BiomeGen \" %s \" , using \" DistortedVoronoi \" instead. " , BiomeGenName . c_str ( ) ) ;
2012-05-25 00:18:52 -07:00
}
2012-06-09 08:26:52 -07:00
int CellSize = a_IniFile . GetValueSetI ( " Generator " , " DistortedVoronoiCellSize " , 96 ) ;
AString Biomes = a_IniFile . GetValueSet ( " Generator " , " DistortedVoronoiBiomes " , " " ) ;
2012-05-31 13:34:58 -07:00
m_BiomeGen = new cBioGenDistortedVoronoi ( m_Seed , CellSize , Biomes ) ;
2012-05-25 00:18:52 -07:00
}
2012-06-02 06:21:59 -07:00
// Add a cache, if requested:
2012-06-09 08:26:52 -07:00
int CacheSize = a_IniFile . GetValueSetI ( " Generator " , " BiomeGenCacheSize " , CacheOffByDefault ? 0 : 64 ) ;
2012-06-02 06:21:59 -07:00
if ( CacheSize > 0 )
{
if ( CacheSize < 4 )
{
LOGWARNING ( " Biomegen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d " ,
CacheSize , 4
) ;
CacheSize = 4 ;
}
LOGINFO ( " Using a cache for biomegen of size %d. " , CacheSize ) ;
m_BiomeGen = new cBioGenCache ( m_BiomeGen , CacheSize ) ;
}
2012-05-25 00:18:52 -07:00
}
void cChunkGenerator : : InitHeightGen ( cIniFile & a_IniFile )
{
2012-06-09 08:26:52 -07:00
AString HeightGenName = a_IniFile . GetValueSet ( " Generator " , " HeightGen " , " " ) ;
2012-05-25 00:18:52 -07:00
if ( HeightGenName . empty ( ) )
{
2012-06-09 08:26:52 -07:00
LOGWARN ( " [Generator]::HeightGen value not found in world.ini, using \" Biomal \" . " ) ;
HeightGenName = " Biomal " ;
2012-05-25 00:18:52 -07:00
}
2012-06-02 06:45:57 -07:00
bool CacheOffByDefault = false ;
2012-05-25 00:18:52 -07:00
if ( NoCaseCompare ( HeightGenName , " flat " ) = = 0 )
{
2012-06-09 08:26:52 -07:00
int Height = a_IniFile . GetValueSetI ( " Generator " , " FlatHeight " , 5 ) ;
2012-05-25 00:18:52 -07:00
m_HeightGen = new cHeiGenFlat ( Height ) ;
2012-06-02 06:45:57 -07:00
CacheOffByDefault = true ; // We're generating faster than a cache would retrieve data
2012-05-25 00:18:52 -07:00
}
2012-06-02 05:19:20 -07:00
else if ( NoCaseCompare ( HeightGenName , " classic " ) = = 0 )
2012-05-25 00:18:52 -07:00
{
// These used to be in terrain.ini, but now they are in world.ini (so that multiple worlds can have different values):
2012-06-09 08:26:52 -07:00
float HeightFreq1 = ( float ) a_IniFile . GetValueSetF ( " Generator " , " ClassicHeightFreq1 " , 0.1 ) ;
float HeightFreq2 = ( float ) a_IniFile . GetValueSetF ( " Generator " , " ClassicHeightFreq2 " , 1.0 ) ;
float HeightFreq3 = ( float ) a_IniFile . GetValueSetF ( " Generator " , " ClassicHeightFreq3 " , 2.0 ) ;
float HeightAmp1 = ( float ) a_IniFile . GetValueSetF ( " Generator " , " ClassicHeightAmp1 " , 1.0 ) ;
float HeightAmp2 = ( float ) a_IniFile . GetValueSetF ( " Generator " , " ClassicHeightAmp2 " , 0.5 ) ;
float HeightAmp3 = ( float ) a_IniFile . GetValueSetF ( " Generator " , " ClassicHeightAmp3 " , 0.5 ) ;
2012-05-25 00:18:52 -07:00
m_HeightGen = new cHeiGenClassic ( m_Seed , HeightFreq1 , HeightAmp1 , HeightFreq2 , HeightAmp2 , HeightFreq3 , HeightAmp3 ) ;
}
2012-06-02 05:19:20 -07:00
else // "biomal" or <not found>
{
if ( NoCaseCompare ( HeightGenName , " biomal " ) ! = 0 )
{
LOGWARN ( " Unknown HeightGen \" %s \" , using \" Biomal \" instead. " , HeightGenName . c_str ( ) ) ;
}
m_HeightGen = new cHeiGenBiomal ( m_Seed , * m_BiomeGen ) ;
}
2012-06-02 06:45:57 -07:00
// Add a cache, if requested:
2012-06-09 08:26:52 -07:00
int CacheSize = a_IniFile . GetValueSetI ( " Generator " , " HeightGenCacheSize " , CacheOffByDefault ? 0 : 64 ) ;
2012-06-02 06:45:57 -07:00
if ( CacheSize > 0 )
{
if ( CacheSize < 4 )
{
LOGWARNING ( " Heightgen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d " ,
CacheSize , 4
) ;
CacheSize = 4 ;
}
LOGINFO ( " Using a cache for Heightgen of size %d. " , CacheSize ) ;
m_HeightGen = new cHeiGenCache ( m_HeightGen , CacheSize ) ;
}
2012-05-25 00:18:52 -07:00
}
2012-06-08 05:16:39 -07:00
2012-05-25 00:18:52 -07:00
void cChunkGenerator : : InitCompositionGen ( cIniFile & a_IniFile )
{
2012-06-09 08:26:52 -07:00
AString CompoGenName = a_IniFile . GetValueSet ( " Generator " , " CompositionGen " , " " ) ;
2012-05-25 00:18:52 -07:00
if ( CompoGenName . empty ( ) )
{
2012-06-09 08:26:52 -07:00
LOGWARN ( " [Generator]::CompositionGen value not found in world.ini, using \" Biomal \" . " ) ;
CompoGenName = " Biomal " ;
2012-05-25 00:18:52 -07:00
}
if ( NoCaseCompare ( CompoGenName , " sameblock " ) = = 0 )
{
2012-06-09 08:26:52 -07:00
AString BlockType = a_IniFile . GetValueSet ( " Generator " , " SameBlockType " , " " ) ;
2012-05-25 00:18:52 -07:00
if ( BlockType . empty ( ) )
{
LOGWARN ( " [Generator]::SameBlockType value not found in world.ini, using \" stone \" . " ) ;
BlockType = " stone " ;
}
2012-06-09 08:26:52 -07:00
int Block = GetIniBlock ( a_IniFile , " [Generator] " , " SameBlockType " , " stone " ) ;
2012-05-25 00:18:52 -07:00
bool Bedrocked = ( a_IniFile . GetValueI ( " Generator " , " SameBlockBedrocked " , 1 ) ! = 0 ) ;
m_CompositionGen = new cCompoGenSameBlock ( ( BLOCKTYPE ) Block , Bedrocked ) ;
}
else if ( NoCaseCompare ( CompoGenName , " debugbiomes " ) = = 0 )
{
2012-06-02 13:44:15 -07:00
m_CompositionGen = new cCompoGenDebugBiomes ;
2012-05-25 00:18:52 -07:00
}
2012-06-02 13:44:15 -07:00
else if ( NoCaseCompare ( CompoGenName , " classic " ) = = 0 )
2012-05-25 00:18:52 -07:00
{
int SeaLevel = a_IniFile . GetValueI ( " Generator " , " ClassicSeaLevel " , 60 ) ;
int BeachHeight = a_IniFile . GetValueI ( " Generator " , " ClassicBeachHeight " , 2 ) ;
int BeachDepth = a_IniFile . GetValueI ( " Generator " , " ClassicBeachDepth " , 4 ) ;
2012-06-09 08:26:52 -07:00
BLOCKTYPE BlockTop = GetIniBlock ( a_IniFile , " Generator " , " ClassicBlockTop " , " grass " ) ;
BLOCKTYPE BlockMiddle = GetIniBlock ( a_IniFile , " Generator " , " ClassicBlockMiddle " , " dirt " ) ;
BLOCKTYPE BlockBottom = GetIniBlock ( a_IniFile , " Generator " , " ClassicBlockBottom " , " stone " ) ;
BLOCKTYPE BlockBeach = GetIniBlock ( a_IniFile , " Generator " , " ClassicBlockBeach " , " sand " ) ;
BLOCKTYPE BlockBeachBottom = GetIniBlock ( a_IniFile , " Generator " , " ClassicBlockBeachBottom " , " sandstone " ) ;
BLOCKTYPE BlockSea = GetIniBlock ( a_IniFile , " Generator " , " ClassicBlockSea " , " 9 " ) ;
2012-06-08 05:16:39 -07:00
m_CompositionGen = new cCompoGenClassic (
SeaLevel , BeachHeight , BeachDepth , BlockTop , BlockMiddle , BlockBottom , BlockBeach ,
BlockBeachBottom , BlockSea
) ;
2012-05-25 00:18:52 -07:00
}
2012-06-02 13:44:15 -07:00
else
{
if ( NoCaseCompare ( CompoGenName , " biomal " ) ! = 0 )
{
LOGWARN ( " Unknown CompositionGen \" %s \" , using \" biomal \" instead. " , CompoGenName . c_str ( ) ) ;
}
2012-06-09 08:26:52 -07:00
int SeaLevel = a_IniFile . GetValueSetI ( " Generator " , " BiomalSeaLevel " , 62 ) ;
2012-06-02 13:44:15 -07:00
m_CompositionGen = new cCompoGenBiomal ( m_Seed , SeaLevel ) ;
}
2012-05-25 00:18:52 -07:00
}
void cChunkGenerator : : InitStructureGens ( cIniFile & a_IniFile )
{
2012-06-09 08:26:52 -07:00
AString Structures = a_IniFile . GetValueSet ( " Generator " , " Structures " , " Trees,MarbleCaves,OreNests " ) ;
2012-05-25 00:18:52 -07:00
AStringVector Str = StringSplit ( Structures , " , " ) ;
for ( AStringVector : : const_iterator itr = Str . begin ( ) ; itr ! = Str . end ( ) ; + + itr )
{
if ( NoCaseCompare ( * itr , " trees " ) = = 0 )
{
m_StructureGens . push_back ( new cStructGenTrees ( m_Seed , m_BiomeGen , m_HeightGen , m_CompositionGen ) ) ;
}
else if ( NoCaseCompare ( * itr , " marblecaves " ) = = 0 )
{
m_StructureGens . push_back ( new cStructGenMarbleCaves ( m_Seed ) ) ;
}
else if ( NoCaseCompare ( * itr , " orenests " ) = = 0 )
{
m_StructureGens . push_back ( new cStructGenOreNests ( m_Seed ) ) ;
}
else
{
LOGWARNING ( " Unknown structure generator: \" %s \" . Ignoring. " , itr - > c_str ( ) ) ;
}
} // for itr - Str[]
2011-12-25 04:55:20 -08:00
}
2012-01-29 06:29:26 -08:00
2012-05-25 00:18:52 -07:00
void cChunkGenerator : : InitFinishGens ( cIniFile & a_IniFile )
{
2012-06-09 08:26:52 -07:00
AString Structures = a_IniFile . GetValueSet ( " Generator " , " Finishers " , " SprinkleFoliage,Ice,Snow " ) ;
2012-05-25 00:18:52 -07:00
AStringVector Str = StringSplit ( Structures , " , " ) ;
for ( AStringVector : : const_iterator itr = Str . begin ( ) ; itr ! = Str . end ( ) ; + + itr )
{
if ( NoCaseCompare ( * itr , " SprinkleFoliage " ) = = 0 )
{
m_FinishGens . push_back ( new cFinishGenSprinkleFoliage ( m_Seed ) ) ;
}
else if ( NoCaseCompare ( * itr , " Snow " ) = = 0 )
{
m_FinishGens . push_back ( new cFinishGenSnow ) ;
}
else if ( NoCaseCompare ( * itr , " Ice " ) = = 0 )
{
m_FinishGens . push_back ( new cFinishGenIce ) ;
}
} // for itr - Str[]
}
void cChunkGenerator : : QueueGenerateChunk ( int a_ChunkX , int a_ChunkY , int a_ChunkZ )
2011-12-25 04:55:20 -08:00
{
{
2012-02-28 08:59:59 -08:00
cCSLock Lock ( m_CS ) ;
// Check if it is already in the queue:
for ( cChunkCoordsList : : iterator itr = m_Queue . begin ( ) ; itr ! = m_Queue . end ( ) ; + + itr )
{
if ( ( itr - > m_ChunkX = = a_ChunkX ) & & ( itr - > m_ChunkY = = a_ChunkY ) & & ( itr - > m_ChunkZ = = a_ChunkZ ) )
{
// Already in the queue, bail out
return ;
}
} // for itr - m_Queue[]
// Add to queue, issue a warning if too many:
if ( m_Queue . size ( ) > = QUEUE_WARNING_LIMIT )
2011-12-25 04:55:20 -08:00
{
2012-02-28 08:59:59 -08:00
LOGWARN ( " WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (%i) " , a_ChunkX , a_ChunkZ , m_Queue . size ( ) ) ;
2011-12-25 04:55:20 -08:00
}
2012-02-28 08:59:59 -08:00
m_Queue . push_back ( cChunkCoords ( a_ChunkX , a_ChunkY , a_ChunkZ ) ) ;
2011-12-25 04:55:20 -08:00
}
2012-01-29 06:29:26 -08:00
2012-02-13 13:47:03 -08:00
m_Event . Set ( ) ;
2011-12-25 04:55:20 -08:00
}
2012-01-29 06:29:26 -08:00
2012-05-25 00:18:52 -07:00
void cChunkGenerator : : GenerateBiomes ( int a_ChunkX , int a_ChunkZ , cChunkDef : : BiomeMap & a_BiomeMap )
{
m_BiomeGen - > GenBiomes ( a_ChunkX , a_ChunkZ , a_BiomeMap ) ;
}
2012-02-18 09:53:22 -08:00
void cChunkGenerator : : WaitForQueueEmpty ( void )
{
cCSLock Lock ( m_CS ) ;
2012-03-10 09:37:00 -08:00
while ( ! m_ShouldTerminate & & ! m_Queue . empty ( ) )
2012-02-18 09:53:22 -08:00
{
cCSUnlock Unlock ( Lock ) ;
m_evtRemoved . Wait ( ) ;
}
}
int cChunkGenerator : : GetQueueLength ( void )
{
cCSLock Lock ( m_CS ) ;
return ( int ) m_Queue . size ( ) ;
}
2012-05-25 00:18:52 -07:00
EMCSBiome cChunkGenerator : : GetBiomeAt ( int a_BlockX , int a_BlockZ )
{
cChunkDef : : BiomeMap Biomes ;
int Y = 0 ;
int ChunkX , ChunkZ ;
cWorld : : AbsoluteToRelative ( a_BlockX , Y , a_BlockZ , ChunkX , Y , ChunkZ ) ;
m_BiomeGen - > GenBiomes ( ChunkX , ChunkZ , Biomes ) ;
return cChunkDef : : GetBiome ( Biomes , a_BlockX , a_BlockZ ) ;
}
2012-02-13 13:47:03 -08:00
void cChunkGenerator : : Execute ( void )
2011-12-25 04:55:20 -08:00
{
2012-03-10 09:37:00 -08:00
while ( ! m_ShouldTerminate )
2011-12-25 04:55:20 -08:00
{
2012-02-13 13:47:03 -08:00
cCSLock Lock ( m_CS ) ;
while ( m_Queue . size ( ) = = 0 )
2011-12-25 04:55:20 -08:00
{
2012-01-29 06:29:26 -08:00
cCSUnlock Unlock ( Lock ) ;
2012-02-13 13:47:03 -08:00
m_Event . Wait ( ) ;
2012-03-10 09:37:00 -08:00
if ( m_ShouldTerminate )
2012-02-13 13:47:03 -08:00
{
return ;
}
2011-12-25 04:55:20 -08:00
}
2012-01-29 06:29:26 -08:00
2012-02-13 13:47:03 -08:00
cChunkCoords coords = m_Queue . front ( ) ; // Get next coord from queue
m_Queue . erase ( m_Queue . begin ( ) ) ; // Remove coordinate from queue
bool SkipEnabled = ( m_Queue . size ( ) > QUEUE_SKIP_LIMIT ) ;
2012-01-29 06:29:26 -08:00
Lock . Unlock ( ) ; // Unlock ASAP
2012-02-18 09:53:22 -08:00
m_evtRemoved . Set ( ) ;
2011-12-25 04:55:20 -08:00
2012-04-10 04:22:11 -07:00
// Hack for regenerating chunks: if Y != 0, the chunk is considered invalid, even if it has its data set
if ( ( coords . m_ChunkY = = 0 ) & & m_World - > IsChunkValid ( coords . m_ChunkX , coords . m_ChunkY , coords . m_ChunkZ ) )
2012-02-13 13:47:03 -08:00
{
2012-04-10 04:22:11 -07:00
LOGD ( " Chunk [%d, %d] already generated, skipping generation " , coords . m_ChunkX , coords . m_ChunkZ ) ;
2012-02-28 02:01:42 -08:00
// Already generated, ignore request
continue ;
}
if ( SkipEnabled & & ! m_World - > HasChunkAnyClients ( coords . m_ChunkX , coords . m_ChunkY , coords . m_ChunkZ ) )
{
2012-04-10 04:22:11 -07:00
LOGWARNING ( " Chunk generator overloaded, skipping chunk [%d, %d, %d] " , coords . m_ChunkX , coords . m_ChunkY , coords . m_ChunkZ ) ;
2011-12-25 04:55:20 -08:00
continue ;
}
2012-02-16 09:45:26 -08:00
2012-02-18 09:53:22 -08:00
LOGD ( " Generating chunk [%d, %d, %d] " , coords . m_ChunkX , coords . m_ChunkY , coords . m_ChunkZ ) ;
2012-02-17 09:56:25 -08:00
DoGenerate ( coords . m_ChunkX , coords . m_ChunkY , coords . m_ChunkZ ) ;
2012-02-13 13:47:03 -08:00
2012-02-16 09:45:26 -08:00
// Save the chunk right after generating, so that we don't have to generate it again on next run
2012-02-17 09:56:25 -08:00
m_World - > GetStorage ( ) . QueueSaveChunk ( coords . m_ChunkX , coords . m_ChunkY , coords . m_ChunkZ ) ;
2012-01-29 06:29:26 -08:00
} // while (!bStop)
2011-12-25 04:55:20 -08:00
}
2012-01-29 06:29:26 -08:00
2012-02-17 09:56:25 -08:00
void cChunkGenerator : : DoGenerate ( int a_ChunkX , int a_ChunkY , int a_ChunkZ )
{
2012-05-25 00:18:52 -07:00
cChunkDef : : BiomeMap BiomeMap ;
cChunkDef : : BlockTypes BlockTypes ;
cChunkDef : : BlockNibbles BlockMeta ;
cChunkDef : : HeightMap HeightMap ;
2012-02-18 09:53:22 -08:00
cEntityList Entities ;
cBlockEntityList BlockEntities ;
2012-03-14 13:56:09 -07:00
2012-05-25 00:18:52 -07:00
// Use the composed generator:
m_BiomeGen - > GenBiomes ( a_ChunkX , a_ChunkZ , BiomeMap ) ;
m_HeightGen - > GenHeightMap ( a_ChunkX , a_ChunkZ , HeightMap ) ;
2012-06-02 13:44:15 -07:00
m_CompositionGen - > ComposeTerrain ( a_ChunkX , a_ChunkZ , BlockTypes , BlockMeta , HeightMap , BiomeMap , Entities , BlockEntities ) ;
2012-05-25 00:18:52 -07:00
for ( cStructureGenList : : iterator itr = m_StructureGens . begin ( ) ; itr ! = m_StructureGens . end ( ) ; + + itr )
{
( * itr ) - > GenStructures ( a_ChunkX , a_ChunkZ , BlockTypes , BlockMeta , HeightMap , Entities , BlockEntities ) ;
} // for itr - m_StructureGens[]
for ( cFinishGenList : : iterator itr = m_FinishGens . begin ( ) ; itr ! = m_FinishGens . end ( ) ; + + itr )
{
( * itr ) - > GenFinish ( a_ChunkX , a_ChunkZ , BlockTypes , BlockMeta , HeightMap , BiomeMap , Entities , BlockEntities ) ;
} // for itr - m_FinishGens[]
m_World - > SetChunkData (
2012-03-14 13:56:09 -07:00
a_ChunkX , a_ChunkY , a_ChunkZ ,
2012-05-25 00:18:52 -07:00
BlockTypes , BlockMeta ,
NULL , NULL , // We don't have lighting, chunk will be lighted when needed
& HeightMap , & BiomeMap ,
Entities , BlockEntities ,
true
2012-03-14 13:56:09 -07:00
) ;
2012-06-05 08:20:48 -07:00
cRoot : : Get ( ) - > GetPluginManager ( ) - > CallHook ( cPluginManager : : E_PLUGIN_CHUNK_GENERATED , 3 , m_World , a_ChunkX , a_ChunkZ ) ;
2012-02-17 09:56:25 -08:00
}