Decoupled cChunkGenerator from cWorld and cRoot.
Now the chunk generator can be used by other projects without depending on the two hugest structures in MCS.
This commit is contained in:
parent
712e6e0bb2
commit
cea997426b
@ -2,13 +2,11 @@
|
|||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
|
||||||
#include "ChunkGenerator.h"
|
#include "ChunkGenerator.h"
|
||||||
#include "../World.h"
|
|
||||||
#include "inifile/iniFile.h"
|
#include "inifile/iniFile.h"
|
||||||
#include "../Root.h"
|
|
||||||
#include "../Bindings/PluginManager.h"
|
|
||||||
#include "ChunkDesc.h"
|
#include "ChunkDesc.h"
|
||||||
#include "ComposableGenerator.h"
|
#include "ComposableGenerator.h"
|
||||||
#include "Noise3DGenerator.h"
|
#include "Noise3DGenerator.h"
|
||||||
|
#include "../MersenneTwister.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -29,8 +27,9 @@ const unsigned int QUEUE_SKIP_LIMIT = 500;
|
|||||||
|
|
||||||
cChunkGenerator::cChunkGenerator(void) :
|
cChunkGenerator::cChunkGenerator(void) :
|
||||||
super("cChunkGenerator"),
|
super("cChunkGenerator"),
|
||||||
m_World(NULL),
|
m_Generator(NULL),
|
||||||
m_Generator(NULL)
|
m_PluginInterface(NULL),
|
||||||
|
m_ChunkSink(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,10 +46,12 @@ cChunkGenerator::~cChunkGenerator()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkGenerator::Start(cWorld * a_World, cIniFile & a_IniFile)
|
bool cChunkGenerator::Start(cPluginInterface & a_PluginInterface, cChunkSink & a_ChunkSink, cIniFile & a_IniFile)
|
||||||
{
|
{
|
||||||
|
m_PluginInterface = &a_PluginInterface;
|
||||||
|
m_ChunkSink = &a_ChunkSink;
|
||||||
|
|
||||||
MTRand rnd;
|
MTRand rnd;
|
||||||
m_World = a_World;
|
|
||||||
m_Seed = a_IniFile.GetValueSetI("Seed", "Seed", rnd.randInt());
|
m_Seed = a_IniFile.GetValueSetI("Seed", "Seed", rnd.randInt());
|
||||||
AString GeneratorName = a_IniFile.GetValueSet("Generator", "Generator", "Composable");
|
AString GeneratorName = a_IniFile.GetValueSet("Generator", "Generator", "Composable");
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ bool cChunkGenerator::Start(cWorld * a_World, cIniFile & a_IniFile)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Generator->Initialize(a_World, a_IniFile);
|
m_Generator->Initialize(a_IniFile);
|
||||||
|
|
||||||
return super::Start();
|
return super::Start();
|
||||||
}
|
}
|
||||||
@ -237,14 +238,14 @@ void cChunkGenerator::Execute(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hack for regenerating chunks: if Y != 0, the chunk is considered invalid, even if it has its data set
|
// 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_ChunkZ))
|
if ((coords.m_ChunkY == 0) && m_ChunkSink->IsChunkValid(coords.m_ChunkX, coords.m_ChunkZ))
|
||||||
{
|
{
|
||||||
LOGD("Chunk [%d, %d] already generated, skipping generation", coords.m_ChunkX, coords.m_ChunkZ);
|
LOGD("Chunk [%d, %d] already generated, skipping generation", coords.m_ChunkX, coords.m_ChunkZ);
|
||||||
// Already generated, ignore request
|
// Already generated, ignore request
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SkipEnabled && !m_World->HasChunkAnyClients(coords.m_ChunkX, coords.m_ChunkZ))
|
if (SkipEnabled && !m_ChunkSink->HasChunkAnyClients(coords.m_ChunkX, coords.m_ChunkZ))
|
||||||
{
|
{
|
||||||
LOGWARNING("Chunk generator overloaded, skipping chunk [%d, %d]", coords.m_ChunkX, coords.m_ChunkZ);
|
LOGWARNING("Chunk generator overloaded, skipping chunk [%d, %d]", coords.m_ChunkX, coords.m_ChunkZ);
|
||||||
continue;
|
continue;
|
||||||
@ -253,9 +254,6 @@ void cChunkGenerator::Execute(void)
|
|||||||
LOGD("Generating chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
|
LOGD("Generating chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
|
||||||
DoGenerate(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
|
DoGenerate(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
|
||||||
|
|
||||||
// Save the chunk right after generating, so that we don't have to generate it again on next run
|
|
||||||
m_World->GetStorage().QueueSaveChunk(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
|
|
||||||
|
|
||||||
NumChunksGenerated++;
|
NumChunksGenerated++;
|
||||||
} // while (!bStop)
|
} // while (!bStop)
|
||||||
}
|
}
|
||||||
@ -265,27 +263,20 @@ void cChunkGenerator::Execute(void)
|
|||||||
|
|
||||||
void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
|
ASSERT(m_PluginInterface != NULL);
|
||||||
|
ASSERT(m_ChunkSink != NULL);
|
||||||
|
|
||||||
cChunkDesc ChunkDesc(a_ChunkX, a_ChunkZ);
|
cChunkDesc ChunkDesc(a_ChunkX, a_ChunkZ);
|
||||||
cRoot::Get()->GetPluginManager()->CallHookChunkGenerating(m_World, a_ChunkX, a_ChunkZ, &ChunkDesc);
|
m_PluginInterface->CallHookChunkGenerating(ChunkDesc);
|
||||||
m_Generator->DoGenerate(a_ChunkX, a_ChunkZ, ChunkDesc);
|
m_Generator->DoGenerate(a_ChunkX, a_ChunkZ, ChunkDesc);
|
||||||
cRoot::Get()->GetPluginManager()->CallHookChunkGenerated(m_World, a_ChunkX, a_ChunkZ, &ChunkDesc);
|
m_PluginInterface->CallHookChunkGenerated(ChunkDesc);
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
// Verify that the generator has produced valid data:
|
// Verify that the generator has produced valid data:
|
||||||
ChunkDesc.VerifyHeightmap();
|
ChunkDesc.VerifyHeightmap();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cChunkDef::BlockNibbles BlockMetas;
|
m_ChunkSink->OnChunkGenerated(ChunkDesc);
|
||||||
ChunkDesc.CompressBlockMetas(BlockMetas);
|
|
||||||
|
|
||||||
m_World->SetChunkData(
|
|
||||||
a_ChunkX, a_ChunkZ,
|
|
||||||
ChunkDesc.GetBlockTypes(), BlockMetas,
|
|
||||||
NULL, NULL, // We don't have lighting, chunk will be lighted when needed
|
|
||||||
&ChunkDesc.GetHeightMap(), &ChunkDesc.GetBiomeMap(),
|
|
||||||
ChunkDesc.GetEntities(), ChunkDesc.GetBlockEntities(),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -304,9 +295,8 @@ cChunkGenerator::cGenerator::cGenerator(cChunkGenerator & a_ChunkGenerator) :
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkGenerator::cGenerator::Initialize(cWorld * a_World, cIniFile & a_IniFile)
|
void cChunkGenerator::cGenerator::Initialize(cIniFile & a_IniFile)
|
||||||
{
|
{
|
||||||
m_World = a_World;
|
|
||||||
UNUSED(a_IniFile);
|
UNUSED(a_IniFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,7 +309,7 @@ EMCSBiome cChunkGenerator::cGenerator::GetBiomeAt(int a_BlockX, int a_BlockZ)
|
|||||||
cChunkDef::BiomeMap Biomes;
|
cChunkDef::BiomeMap Biomes;
|
||||||
int Y = 0;
|
int Y = 0;
|
||||||
int ChunkX, ChunkZ;
|
int ChunkX, ChunkZ;
|
||||||
cWorld::AbsoluteToRelative(a_BlockX, Y, a_BlockZ, ChunkX, Y, ChunkZ);
|
cChunkDef::AbsoluteToRelative(a_BlockX, Y, a_BlockZ, ChunkX, ChunkZ);
|
||||||
GenerateBiomes(ChunkX, ChunkZ, Biomes);
|
GenerateBiomes(ChunkX, ChunkZ, Biomes);
|
||||||
return cChunkDef::GetBiome(Biomes, a_BlockX, a_BlockZ);
|
return cChunkDef::GetBiome(Biomes, a_BlockX, a_BlockZ);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ If the generator queue is overloaded, the generator skips chunks with no clients
|
|||||||
|
|
||||||
|
|
||||||
// fwd:
|
// fwd:
|
||||||
class cWorld;
|
|
||||||
class cIniFile;
|
class cIniFile;
|
||||||
class cChunkDesc;
|
class cChunkDesc;
|
||||||
|
|
||||||
@ -40,7 +39,7 @@ class cChunkGenerator :
|
|||||||
typedef cIsThread super;
|
typedef cIsThread super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// The interface that a class has to implement to become a generator
|
/** The interface that a class has to implement to become a generator */
|
||||||
class cGenerator
|
class cGenerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -48,7 +47,7 @@ public:
|
|||||||
virtual ~cGenerator() {} ; // Force a virtual destructor
|
virtual ~cGenerator() {} ; // Force a virtual destructor
|
||||||
|
|
||||||
/// Called to initialize the generator on server startup.
|
/// Called to initialize the generator on server startup.
|
||||||
virtual void Initialize(cWorld * a_World, cIniFile & a_IniFile);
|
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.
|
/// 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;
|
virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) = 0;
|
||||||
@ -61,14 +60,59 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
cChunkGenerator & m_ChunkGenerator;
|
cChunkGenerator & m_ChunkGenerator;
|
||||||
cWorld * m_World;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
/** 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;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
cChunkGenerator (void);
|
cChunkGenerator (void);
|
||||||
~cChunkGenerator();
|
~cChunkGenerator();
|
||||||
|
|
||||||
bool Start(cWorld * a_World, cIniFile & a_IniFile);
|
bool Start(cPluginInterface & a_PluginInterface, cChunkSink & a_ChunkSink, cIniFile & a_IniFile);
|
||||||
void Stop(void);
|
void Stop(void);
|
||||||
|
|
||||||
/// Queues the chunk for generation; removes duplicate requests
|
/// Queues the chunk for generation; removes duplicate requests
|
||||||
@ -91,8 +135,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
cWorld * m_World;
|
|
||||||
|
|
||||||
int m_Seed;
|
int m_Seed;
|
||||||
|
|
||||||
cCriticalSection m_CS;
|
cCriticalSection m_CS;
|
||||||
@ -101,6 +143,13 @@ private:
|
|||||||
cEvent m_evtRemoved; ///< Set when an item is removed from the queue
|
cEvent m_evtRemoved; ///< Set when an item is removed from the queue
|
||||||
|
|
||||||
cGenerator * m_Generator; ///< The actual generator engine used to generate chunks
|
cGenerator * m_Generator; ///< The actual generator engine used to generate chunks
|
||||||
|
|
||||||
|
/** 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:
|
// cIsThread override:
|
||||||
virtual void Execute(void) override;
|
virtual void Execute(void) override;
|
||||||
|
@ -157,9 +157,9 @@ cComposableGenerator::~cComposableGenerator()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cComposableGenerator::Initialize(cWorld * a_World, cIniFile & a_IniFile)
|
void cComposableGenerator::Initialize(cIniFile & a_IniFile)
|
||||||
{
|
{
|
||||||
super::Initialize(a_World, a_IniFile);
|
super::Initialize(a_IniFile);
|
||||||
|
|
||||||
InitBiomeGen(a_IniFile);
|
InitBiomeGen(a_IniFile);
|
||||||
InitHeightGen(a_IniFile);
|
InitHeightGen(a_IniFile);
|
||||||
@ -369,13 +369,14 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
|
|||||||
int Seed = m_ChunkGenerator.GetSeed();
|
int Seed = m_ChunkGenerator.GetSeed();
|
||||||
AString Structures = a_IniFile.GetValueSet("Generator", "Finishers", "SprinkleFoliage,Ice,Snow,Lilypads,BottomLava,DeadBushes,PreSimulator");
|
AString Structures = a_IniFile.GetValueSet("Generator", "Finishers", "SprinkleFoliage,Ice,Snow,Lilypads,BottomLava,DeadBushes,PreSimulator");
|
||||||
|
|
||||||
|
eDimension Dimension = StringToDimension(a_IniFile.GetValue("General", "Dimension", "Overworld"));
|
||||||
AStringVector Str = StringSplitAndTrim(Structures, ",");
|
AStringVector Str = StringSplitAndTrim(Structures, ",");
|
||||||
for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr)
|
for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr)
|
||||||
{
|
{
|
||||||
// Finishers, alpha-sorted:
|
// Finishers, alpha-sorted:
|
||||||
if (NoCaseCompare(*itr, "BottomLava") == 0)
|
if (NoCaseCompare(*itr, "BottomLava") == 0)
|
||||||
{
|
{
|
||||||
int DefaultBottomLavaLevel = (m_World->GetDimension() == dimNether) ? 30 : 10;
|
int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10;
|
||||||
int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel);
|
int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel);
|
||||||
m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel));
|
m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel));
|
||||||
}
|
}
|
||||||
@ -389,7 +390,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
|
|||||||
}
|
}
|
||||||
else if (NoCaseCompare(*itr, "LavaSprings") == 0)
|
else if (NoCaseCompare(*itr, "LavaSprings") == 0)
|
||||||
{
|
{
|
||||||
m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, *m_World));
|
m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension));
|
||||||
}
|
}
|
||||||
else if (NoCaseCompare(*itr, "Lilypads") == 0)
|
else if (NoCaseCompare(*itr, "Lilypads") == 0)
|
||||||
{
|
{
|
||||||
@ -409,7 +410,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
|
|||||||
}
|
}
|
||||||
else if (NoCaseCompare(*itr, "WaterSprings") == 0)
|
else if (NoCaseCompare(*itr, "WaterSprings") == 0)
|
||||||
{
|
{
|
||||||
m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, *m_World));
|
m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, Dimension));
|
||||||
}
|
}
|
||||||
} // for itr - Str[]
|
} // for itr - Str[]
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ public:
|
|||||||
cComposableGenerator(cChunkGenerator & a_ChunkGenerator);
|
cComposableGenerator(cChunkGenerator & a_ChunkGenerator);
|
||||||
virtual ~cComposableGenerator();
|
virtual ~cComposableGenerator();
|
||||||
|
|
||||||
virtual void Initialize(cWorld * a_World, cIniFile & a_IniFile) override;
|
virtual void Initialize(cIniFile & a_IniFile) override;
|
||||||
virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) 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;
|
virtual void DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a_ChunkDesc) override;
|
||||||
|
|
||||||
|
@ -520,7 +520,7 @@ void cFinishGenPreSimulator::StationarizeFluid(
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// cFinishGenFluidSprings:
|
// cFinishGenFluidSprings:
|
||||||
|
|
||||||
cFinishGenFluidSprings::cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cIniFile & a_IniFile, const cWorld & a_World) :
|
cFinishGenFluidSprings::cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cIniFile & a_IniFile, eDimension a_Dimension) :
|
||||||
m_Noise(a_Seed + a_Fluid * 100), // Need to take fluid into account, otherwise water and lava springs generate next to each other
|
m_Noise(a_Seed + a_Fluid * 100), // Need to take fluid into account, otherwise water and lava springs generate next to each other
|
||||||
m_HeightDistribution(255),
|
m_HeightDistribution(255),
|
||||||
m_Fluid(a_Fluid)
|
m_Fluid(a_Fluid)
|
||||||
@ -529,7 +529,7 @@ cFinishGenFluidSprings::cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cI
|
|||||||
AString SectionName = IsWater ? "WaterSprings" : "LavaSprings";
|
AString SectionName = IsWater ? "WaterSprings" : "LavaSprings";
|
||||||
AString DefaultHeightDistribution;
|
AString DefaultHeightDistribution;
|
||||||
int DefaultChance = 0;
|
int DefaultChance = 0;
|
||||||
switch (a_World.GetDimension())
|
switch (a_Dimension)
|
||||||
{
|
{
|
||||||
case dimNether:
|
case dimNether:
|
||||||
{
|
{
|
||||||
|
@ -164,7 +164,7 @@ class cFinishGenFluidSprings :
|
|||||||
public cFinishGen
|
public cFinishGen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cIniFile & a_IniFile, const cWorld & a_World);
|
cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cIniFile & a_IniFile, eDimension a_Dimension);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -150,10 +150,8 @@ cNoise3DGenerator::~cNoise3DGenerator()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cNoise3DGenerator::Initialize(cWorld * a_World, cIniFile & a_IniFile)
|
void cNoise3DGenerator::Initialize(cIniFile & a_IniFile)
|
||||||
{
|
{
|
||||||
m_World = a_World;
|
|
||||||
|
|
||||||
// Params:
|
// Params:
|
||||||
m_SeaLevel = a_IniFile.GetValueSetI("Generator", "Noise3DSeaLevel", 62);
|
m_SeaLevel = a_IniFile.GetValueSetI("Generator", "Noise3DSeaLevel", 62);
|
||||||
m_HeightAmplification = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DHeightAmplification", 0);
|
m_HeightAmplification = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "Noise3DHeightAmplification", 0);
|
||||||
|
@ -24,7 +24,7 @@ public:
|
|||||||
cNoise3DGenerator(cChunkGenerator & a_ChunkGenerator);
|
cNoise3DGenerator(cChunkGenerator & a_ChunkGenerator);
|
||||||
virtual ~cNoise3DGenerator();
|
virtual ~cNoise3DGenerator();
|
||||||
|
|
||||||
virtual void Initialize(cWorld * a_World, cIniFile & a_IniFile) override;
|
virtual void Initialize(cIniFile & a_IniFile) override;
|
||||||
virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) 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;
|
virtual void DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a_ChunkDesc) override;
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "Root.h"
|
#include "Root.h"
|
||||||
#include "inifile/iniFile.h"
|
#include "inifile/iniFile.h"
|
||||||
#include "ChunkMap.h"
|
#include "ChunkMap.h"
|
||||||
|
#include "Generating/ChunkDesc.h"
|
||||||
#include "OSSupport/Timer.h"
|
#include "OSSupport/Timer.h"
|
||||||
|
|
||||||
// Entities (except mobs):
|
// Entities (except mobs):
|
||||||
@ -238,6 +239,7 @@ cWorld::cWorld(const AString & a_WorldName) :
|
|||||||
m_SkyDarkness(0),
|
m_SkyDarkness(0),
|
||||||
m_Weather(eWeather_Sunny),
|
m_Weather(eWeather_Sunny),
|
||||||
m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :)
|
m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :)
|
||||||
|
m_GeneratorCallbacks(*this),
|
||||||
m_TickThread(*this)
|
m_TickThread(*this)
|
||||||
{
|
{
|
||||||
LOGD("cWorld::cWorld(\"%s\")", a_WorldName.c_str());
|
LOGD("cWorld::cWorld(\"%s\")", a_WorldName.c_str());
|
||||||
@ -583,7 +585,7 @@ void cWorld::Start(void)
|
|||||||
|
|
||||||
m_Lighting.Start(this);
|
m_Lighting.Start(this);
|
||||||
m_Storage.Start(this, m_StorageSchema);
|
m_Storage.Start(this, m_StorageSchema);
|
||||||
m_Generator.Start(this, IniFile);
|
m_Generator.Start(m_GeneratorCallbacks, m_GeneratorCallbacks, IniFile);
|
||||||
m_ChunkSender.Start(this);
|
m_ChunkSender.Start(this);
|
||||||
m_TickThread.Start();
|
m_TickThread.Start();
|
||||||
|
|
||||||
@ -2843,3 +2845,77 @@ void cWorld::cTaskSaveAllChunks::Run(cWorld & a_World)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cWorld::cChunkGeneratorCallbacks:
|
||||||
|
|
||||||
|
cWorld::cChunkGeneratorCallbacks::cChunkGeneratorCallbacks(cWorld & a_World) :
|
||||||
|
m_World(&a_World)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cWorld::cChunkGeneratorCallbacks::OnChunkGenerated(cChunkDesc & a_ChunkDesc)
|
||||||
|
{
|
||||||
|
cChunkDef::BlockNibbles BlockMetas;
|
||||||
|
a_ChunkDesc.CompressBlockMetas(BlockMetas);
|
||||||
|
|
||||||
|
m_World->SetChunkData(
|
||||||
|
a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(),
|
||||||
|
a_ChunkDesc.GetBlockTypes(), BlockMetas,
|
||||||
|
NULL, NULL, // We don't have lighting, chunk will be lighted when needed
|
||||||
|
&a_ChunkDesc.GetHeightMap(), &a_ChunkDesc.GetBiomeMap(),
|
||||||
|
a_ChunkDesc.GetEntities(), a_ChunkDesc.GetBlockEntities(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
// Save the chunk right after generating, so that we don't have to generate it again on next run
|
||||||
|
m_World->GetStorage().QueueSaveChunk(a_ChunkDesc.GetChunkX(), 0, a_ChunkDesc.GetChunkZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cWorld::cChunkGeneratorCallbacks::IsChunkValid(int a_ChunkX, int a_ChunkZ)
|
||||||
|
{
|
||||||
|
return m_World->IsChunkValid(a_ChunkX, a_ChunkZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cWorld::cChunkGeneratorCallbacks::HasChunkAnyClients(int a_ChunkX, int a_ChunkZ)
|
||||||
|
{
|
||||||
|
return m_World->HasChunkAnyClients(a_ChunkX, a_ChunkZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerating(cChunkDesc & a_ChunkDesc)
|
||||||
|
{
|
||||||
|
cPluginManager::Get()->CallHookChunkGenerating(
|
||||||
|
m_World, a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), &a_ChunkDesc
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerated (cChunkDesc & a_ChunkDesc)
|
||||||
|
{
|
||||||
|
cPluginManager::Get()->CallHookChunkGenerated(
|
||||||
|
m_World, a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), &a_ChunkDesc
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
24
src/World.h
24
src/World.h
@ -636,6 +636,27 @@ private:
|
|||||||
virtual void Execute(void) override;
|
virtual void Execute(void) override;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
/** Implementation of the callbacks that the ChunkGenerator uses to store new chunks and interface to plugins */
|
||||||
|
class cChunkGeneratorCallbacks :
|
||||||
|
public cChunkGenerator::cChunkSink,
|
||||||
|
public cChunkGenerator::cPluginInterface
|
||||||
|
{
|
||||||
|
cWorld * m_World;
|
||||||
|
|
||||||
|
// cChunkSink overrides:
|
||||||
|
virtual void OnChunkGenerated (cChunkDesc & a_ChunkDesc) override;
|
||||||
|
virtual bool IsChunkValid (int a_ChunkX, int a_ChunkZ) override;
|
||||||
|
virtual bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) override;
|
||||||
|
|
||||||
|
// cPluginInterface overrides:
|
||||||
|
virtual void CallHookChunkGenerating(cChunkDesc & a_ChunkDesc) override;
|
||||||
|
virtual void CallHookChunkGenerated (cChunkDesc & a_ChunkDesc) override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
cChunkGeneratorCallbacks(cWorld & a_World);
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
AString m_WorldName;
|
AString m_WorldName;
|
||||||
AString m_IniFileName;
|
AString m_IniFileName;
|
||||||
@ -714,6 +735,9 @@ private:
|
|||||||
|
|
||||||
cChunkGenerator m_Generator;
|
cChunkGenerator m_Generator;
|
||||||
|
|
||||||
|
/** The callbacks that the ChunkGenerator uses to store new chunks and interface to plugins */
|
||||||
|
cChunkGeneratorCallbacks m_GeneratorCallbacks;
|
||||||
|
|
||||||
cChunkSender m_ChunkSender;
|
cChunkSender m_ChunkSender;
|
||||||
cLightingThread m_Lighting;
|
cLightingThread m_Lighting;
|
||||||
cTickThread m_TickThread;
|
cTickThread m_TickThread;
|
||||||
|
Loading…
Reference in New Issue
Block a user