diff options
Diffstat (limited to 'source/Generating/ChunkGenerator.cpp')
-rw-r--r-- | source/Generating/ChunkGenerator.cpp | 450 |
1 files changed, 85 insertions, 365 deletions
diff --git a/source/Generating/ChunkGenerator.cpp b/source/Generating/ChunkGenerator.cpp index 8af4f7be7..b4781fbda 100644 --- a/source/Generating/ChunkGenerator.cpp +++ b/source/Generating/ChunkGenerator.cpp @@ -4,16 +4,10 @@ #include "ChunkGenerator.h" #include "../World.h" #include "../../iniFile/iniFile.h" -#include "BioGen.h" -#include "HeiGen.h" -#include "CompoGen.h" -#include "StructGen.h" -#include "FinishGen.h" #include "../Root.h" #include "../PluginManager.h" -#include "../LuaChunk.h" -#include "Ravines.h" -#include "Caves.h" +#include "ChunkDesc.h" +#include "ComposableGenerator.h" @@ -29,31 +23,13 @@ const int QUEUE_SKIP_LIMIT = 500; -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: -cChunkGenerator::cChunkGenerator(void) - : super("cChunkGenerator") - , m_World(NULL) - , m_BiomeGen(NULL) - , m_HeightGen(NULL) - , m_CompositionGen(NULL) +cChunkGenerator::cChunkGenerator(void) : + super("cChunkGenerator"), + m_World(NULL), + m_Generator(NULL) { } @@ -75,312 +51,47 @@ bool cChunkGenerator::Start(cWorld * a_World, cIniFile & a_IniFile) MTRand rnd; m_World = a_World; m_Seed = a_IniFile.GetValueSetI("Seed", "Seed", rnd.randInt()); - - InitBiomeGen(a_IniFile); - InitHeightGen(a_IniFile); - InitCompositionGen(a_IniFile); - InitStructureGens(a_IniFile); - InitFinishGens(a_IniFile); - - a_IniFile.WriteFile(); + AString GeneratorName = a_IniFile.GetValueSet("Generator", "Generator", "Composable"); - return super::Start(); -} - - - - - -void cChunkGenerator::Stop(void) -{ - m_ShouldTerminate = true; - m_Event.Set(); - m_evtRemoved.Set(); // Wake up anybody waiting for empty queue - Wait(); - - // 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) -{ - AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", ""); - if (BiomeGenName.empty()) - { - LOGWARN("[Generator]::BiomeGen value not found in world.ini, using \"DistortedVoronoi\"."); - BiomeGenName = "DistortedVoronoi"; - } - - bool CacheOffByDefault = false; - if (NoCaseCompare(BiomeGenName, "constant") == 0) - { - AString Biome = a_IniFile.GetValueSet("Generator", "ConstantBiome", "Plains"); - EMCSBiome b = StringToBiome(Biome); - if (b == -1) - { - LOGWARN("[Generator]::ConstantBiome value \"%s\" not recognized, using \"Plains\".", Biome.c_str()); - b = biPlains; - } - m_BiomeGen = new cBioGenConstant(b); - CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :) - } - else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0) - { - int BiomeSize = a_IniFile.GetValueSetI("Generator", "CheckerboardBiomeSize", 64); - AString Biomes = a_IniFile.GetValueSet ("Generator", "CheckerBoardBiomes", ""); - m_BiomeGen = new cBioGenCheckerboard(BiomeSize, Biomes); - CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data - } - else if (NoCaseCompare(BiomeGenName, "voronoi") == 0) - { - int CellSize = a_IniFile.GetValueSetI("Generator", "VoronoiCellSize", 64); - AString Biomes = a_IniFile.GetValueSet ("Generator", "VoronoiBiomes", ""); - m_BiomeGen = new cBioGenVoronoi(m_Seed, CellSize, Biomes); - } - else if (NoCaseCompare(BiomeGenName, "multistepmap") == 0) + if (NoCaseCompare(GeneratorName, "RoughHills") == 0) { - m_BiomeGen = new cBioGenMultiStepMap(m_Seed); - ((cBioGenMultiStepMap *)m_BiomeGen)->Init(a_IniFile); + // TODO } else { - if (NoCaseCompare(BiomeGenName, "distortedvoronoi") != 0) + if (NoCaseCompare(GeneratorName, "composable") != 0) { - LOGWARNING("Unknown BiomeGen \"%s\", using \"DistortedVoronoi\" instead.", BiomeGenName.c_str()); - } - int CellSize = a_IniFile.GetValueSetI("Generator", "DistortedVoronoiCellSize", 96); - AString Biomes = a_IniFile.GetValueSet ("Generator", "DistortedVoronoiBiomes", ""); - m_BiomeGen = new cBioGenDistortedVoronoi(m_Seed, CellSize, Biomes); - } - - // Add a cache, if requested: - int CacheSize = a_IniFile.GetValueSetI("Generator", "BiomeGenCacheSize", CacheOffByDefault ? 0 : 64); - 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; + LOGWARN("[Generator]::Generator value \"%s\" not recognized, using \"Composable\".", GeneratorName.c_str()); } - LOGINFO("Using a cache for biomegen of size %d.", CacheSize); - m_BiomeGen = new cBioGenCache(m_BiomeGen, CacheSize); + m_Generator = new cComposableGenerator(*this); } -} - - - - -void cChunkGenerator::InitHeightGen(cIniFile & a_IniFile) -{ - AString HeightGenName = a_IniFile.GetValueSet("Generator", "HeightGen", ""); - if (HeightGenName.empty()) + if (m_Generator == NULL) { - LOGWARN("[Generator]::HeightGen value not found in world.ini, using \"Biomal\"."); - HeightGenName = "Biomal"; + LOGERROR("Generator could not start, aborting the server"); + return false; } - bool CacheOffByDefault = false; - if (NoCaseCompare(HeightGenName, "flat") == 0) - { - int Height = a_IniFile.GetValueSetI("Generator", "FlatHeight", 5); - m_HeightGen = new cHeiGenFlat(Height); - CacheOffByDefault = true; // We're generating faster than a cache would retrieve data - } - else if (NoCaseCompare(HeightGenName, "classic") == 0) - { - // These used to be in terrain.ini, but now they are in world.ini (so that multiple worlds can have different values): - 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); - m_HeightGen = new cHeiGenClassic(m_Seed, HeightFreq1, HeightAmp1, HeightFreq2, HeightAmp2, HeightFreq3, HeightAmp3); - } - 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); - } + m_Generator->Initialize(a_World, a_IniFile); - // Add a cache, if requested: - int CacheSize = a_IniFile.GetValueSetI("Generator", "HeightGenCacheSize", CacheOffByDefault ? 0 : 64); - 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); - } -} - - - - - -void cChunkGenerator::InitCompositionGen(cIniFile & a_IniFile) -{ - AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", ""); - if (CompoGenName.empty()) - { - LOGWARN("[Generator]::CompositionGen value not found in world.ini, using \"Biomal\"."); - CompoGenName = "Biomal"; - } - if (NoCaseCompare(CompoGenName, "sameblock") == 0) - { - int Block = GetIniBlock(a_IniFile, "Generator", "SameBlockType", "stone"); - bool Bedrocked = (a_IniFile.GetValueSetI("Generator", "SameBlockBedrocked", 1) != 0); - m_CompositionGen = new cCompoGenSameBlock((BLOCKTYPE)Block, Bedrocked); - } - else if (NoCaseCompare(CompoGenName, "debugbiomes") == 0) - { - m_CompositionGen = new cCompoGenDebugBiomes; - } - else if (NoCaseCompare(CompoGenName, "classic") == 0) - { - int SeaLevel = a_IniFile.GetValueSetI("Generator", "ClassicSeaLevel", 60); - int BeachHeight = a_IniFile.GetValueSetI("Generator", "ClassicBeachHeight", 2); - int BeachDepth = a_IniFile.GetValueSetI("Generator", "ClassicBeachDepth", 4); - 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", "stationarywater"); - m_CompositionGen = new cCompoGenClassic( - SeaLevel, BeachHeight, BeachDepth, BlockTop, BlockMiddle, BlockBottom, BlockBeach, - BlockBeachBottom, BlockSea - ); - } - else - { - if (NoCaseCompare(CompoGenName, "biomal") != 0) - { - LOGWARN("Unknown CompositionGen \"%s\", using \"biomal\" instead.", CompoGenName.c_str()); - } - int SeaLevel = a_IniFile.GetValueSetI("Generator", "BiomalSeaLevel", 62); - m_CompositionGen = new cCompoGenBiomal(m_Seed, SeaLevel); - } -} - - - - - -void cChunkGenerator::InitStructureGens(cIniFile & a_IniFile) -{ - AString Structures = a_IniFile.GetValueSet("Generator", "Structures", "Ravines,WormNestCaves,OreNests,Trees"); - - 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, "dualridgecaves") == 0) - { - float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3); - m_StructureGens.push_back(new cStructGenDualRidgeCaves(m_Seed, Threshold)); - } - else if (NoCaseCompare(*itr, "orenests") == 0) - { - m_StructureGens.push_back(new cStructGenOreNests(m_Seed)); - } - else if (NoCaseCompare(*itr, "ravines") == 0) - { - m_StructureGens.push_back(new cStructGenRavines(m_Seed, 128)); - } - //* - // TODO: Not implemented yet; need a name - else if (NoCaseCompare(*itr, "wormnestcaves") == 0) - { - m_StructureGens.push_back(new cStructGenWormNestCaves(m_Seed)); - } - //*/ - else - { - LOGWARNING("Unknown structure generator: \"%s\". Ignoring.", itr->c_str()); - } - } // for itr - Str[] + a_IniFile.WriteFile(); + + return super::Start(); } -void cChunkGenerator::InitFinishGens(cIniFile & a_IniFile) +void cChunkGenerator::Stop(void) { - AString Structures = a_IniFile.GetValueSet("Generator", "Finishers", "SprinkleFoliage,Ice,Snow,Lilypads,BottomLava,DeadBushes,PreSimulator"); + m_ShouldTerminate = true; + m_Event.Set(); + m_evtRemoved.Set(); // Wake up anybody waiting for empty queue + Wait(); - AStringVector Str = StringSplit(Structures, ","); - for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) - { - // Finishers, alpha-sorted: - if (NoCaseCompare(*itr, "BottomLava") == 0) - { - int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", 10); - m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel)); - } - else if (NoCaseCompare(*itr, "DeadBushes") == 0) - { - m_FinishGens.push_back(new cFinishGenDeadBushes(m_Seed)); - } - else if (NoCaseCompare(*itr, "Ice") == 0) - { - m_FinishGens.push_back(new cFinishGenIce); - } - else if (NoCaseCompare(*itr, "Lilypads") == 0) - { - m_FinishGens.push_back(new cFinishGenLilypads(m_Seed)); - } - else if (NoCaseCompare(*itr, "PreSimulator") == 0) - { - m_FinishGens.push_back(new cFinishGenPreSimulator); - } - else if (NoCaseCompare(*itr, "Snow") == 0) - { - m_FinishGens.push_back(new cFinishGenSnow); - } - else if (NoCaseCompare(*itr, "SprinkleFoliage") == 0) - { - m_FinishGens.push_back(new cFinishGenSprinkleFoliage(m_Seed)); - } - } // for itr - Str[] + delete m_Generator; + m_Generator = NULL; } @@ -419,9 +130,9 @@ void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_Chunk void cChunkGenerator::GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) { - if (m_BiomeGen != NULL) // Quick fix for generator deinitializing before the world storage finishes loading + if (m_Generator != NULL) { - m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); + m_Generator->GenerateBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); } } @@ -455,12 +166,24 @@ int cChunkGenerator::GetQueueLength(void) 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); + ASSERT(m_Generator != NULL); + return m_Generator->GetBiomeAt(a_BlockX, a_BlockZ); +} + + + + + +BLOCKTYPE cChunkGenerator::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; } @@ -550,48 +273,9 @@ void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ) cEntityList Entities; cBlockEntityList BlockEntities; - cLuaChunk LuaChunk( BlockTypes, BlockMeta, HeightMap, BiomeMap ); - if( cRoot::Get()->GetPluginManager()->CallHookChunkGenerating(m_World, a_ChunkX, a_ChunkZ, &LuaChunk ) ) - { - // A plugin interrupted generation, handle something plugin specific - if( LuaChunk.IsUsingDefaultBiomes() ) - { - m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, BiomeMap); - } - if( LuaChunk.IsUsingDefaultComposition() ) - { - m_CompositionGen->ComposeTerrain(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); - } - if( LuaChunk.IsUsingDefaultStructures() ) - { - 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[] - } - if( LuaChunk.IsUsingDefaultFinish() ) - { - 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[] - } - } - else - { - // Use the composed generator: - m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, BiomeMap); - m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, HeightMap); - m_CompositionGen->ComposeTerrain(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); - 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[] - } + cChunkDesc LuaChunk(BlockTypes, BlockMeta, HeightMap, BiomeMap); + cRoot::Get()->GetPluginManager()->CallHookChunkGenerating(m_World, a_ChunkX, a_ChunkZ, &LuaChunk); + m_Generator->DoGenerate(a_ChunkX, a_ChunkZ, LuaChunk, Entities, BlockEntities); m_World->SetChunkData( a_ChunkX, a_ChunkY, a_ChunkZ, @@ -608,3 +292,39 @@ void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ) + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cChunkGenerator::cGenerator: + +cChunkGenerator::cGenerator::cGenerator(cChunkGenerator & a_ChunkGenerator) : + m_ChunkGenerator(a_ChunkGenerator) +{ +} + + + + + +void cChunkGenerator::cGenerator::Initialize(cWorld * a_World, cIniFile & a_IniFile) +{ + m_World = a_World; + UNUSED(a_IniFile); +} + + + + + +EMCSBiome cChunkGenerator::cGenerator::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); + GenerateBiomes(ChunkX, ChunkZ, Biomes); + return cChunkDef::GetBiome(Biomes, a_BlockX, a_BlockZ); +} + + + + |