The subgenerators use cChunkDesc instead of raw arrays. cChunkDesc is based on cBlockArea. Initial version of Lakes generator.
git-svn-id: http://mc-server.googlecode.com/svn/trunk@1286 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
@@ -20,8 +20,11 @@ cChunkDesc::cChunkDesc(int a_ChunkX, int a_ChunkZ) :
|
||||
m_bUseDefaultStructures(true),
|
||||
m_bUseDefaultFinish(true)
|
||||
{
|
||||
m_BlockArea.Create(cChunkDef::Width, cChunkDef::Height, cChunkDef::Width);
|
||||
/*
|
||||
memset(m_BlockTypes, 0, sizeof(cChunkDef::BlockTypes));
|
||||
memset(m_BlockMeta, 0, sizeof(cChunkDef::BlockNibbles));
|
||||
*/
|
||||
memset(m_BiomeMap, 0, sizeof(cChunkDef::BiomeMap));
|
||||
memset(m_HeightMap, 0, sizeof(cChunkDef::HeightMap));
|
||||
}
|
||||
@@ -51,9 +54,7 @@ void cChunkDesc::SetChunkCoords(int a_ChunkX, int a_ChunkZ)
|
||||
|
||||
void cChunkDesc::FillBlocks(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
||||
{
|
||||
const NIBBLETYPE CompressedMeta = a_BlockMeta | (a_BlockMeta << 4);
|
||||
memset(m_BlockTypes, a_BlockType, sizeof(cChunkDef::BlockTypes));
|
||||
memset(m_BlockMeta, CompressedMeta, sizeof(cChunkDef::BlockNibbles));
|
||||
m_BlockArea.Fill(cBlockArea::baTypes | cBlockArea::baMetas, a_BlockType, a_BlockMeta);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,9 +63,7 @@ void cChunkDesc::FillBlocks(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
||||
|
||||
void cChunkDesc::SetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
||||
{
|
||||
int Index = cChunkDef::MakeIndex(a_RelX, a_RelY, a_RelZ);
|
||||
cChunkDef::SetBlock(m_BlockTypes, Index, a_BlockType);
|
||||
cChunkDef::SetNibble(m_BlockMeta, Index, a_BlockMeta);
|
||||
m_BlockArea.SetRelBlockTypeMeta(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta);
|
||||
}
|
||||
|
||||
|
||||
@@ -73,9 +72,7 @@ void cChunkDesc::SetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE
|
||||
|
||||
void cChunkDesc::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
|
||||
{
|
||||
int Index = cChunkDef::MakeIndex(a_RelX, a_RelY, a_RelZ);
|
||||
a_BlockType = cChunkDef::GetBlock(m_BlockTypes, Index);
|
||||
a_BlockMeta = cChunkDef::GetNibble(m_BlockMeta, Index);
|
||||
m_BlockArea.GetRelBlockTypeMeta(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta);
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +81,7 @@ void cChunkDesc::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE
|
||||
|
||||
void cChunkDesc::SetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType)
|
||||
{
|
||||
cChunkDef::SetBlock(m_BlockTypes, a_RelX, a_RelY, a_RelZ, a_BlockType);
|
||||
cChunkDef::SetBlock(m_BlockArea.GetBlockTypes(), a_RelX, a_RelY, a_RelZ, a_BlockType);
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +90,7 @@ void cChunkDesc::SetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Bl
|
||||
|
||||
BLOCKTYPE cChunkDesc::GetBlockType(int a_RelX, int a_RelY, int a_RelZ)
|
||||
{
|
||||
return cChunkDef::GetBlock(m_BlockTypes, a_RelX, a_RelY, a_RelZ);
|
||||
return cChunkDef::GetBlock(m_BlockArea.GetBlockTypes(), a_RelX, a_RelY, a_RelZ);
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +99,7 @@ BLOCKTYPE cChunkDesc::GetBlockType(int a_RelX, int a_RelY, int a_RelZ)
|
||||
|
||||
NIBBLETYPE cChunkDesc::GetBlockMeta(int a_RelX, int a_RelY, int a_RelZ)
|
||||
{
|
||||
return cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ);
|
||||
return m_BlockArea.GetRelBlockMeta(a_RelX, a_RelY, a_RelZ);
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +108,7 @@ NIBBLETYPE cChunkDesc::GetBlockMeta(int a_RelX, int a_RelY, int a_RelZ)
|
||||
|
||||
void cChunkDesc::SetBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockMeta)
|
||||
{
|
||||
cChunkDef::SetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ, a_BlockMeta);
|
||||
m_BlockArea.SetRelBlockMeta(a_RelX, a_RelY, a_RelZ, a_BlockMeta);
|
||||
}
|
||||
|
||||
|
||||
@@ -242,62 +239,9 @@ bool cChunkDesc::IsUsingDefaultFinish(void) const
|
||||
|
||||
|
||||
|
||||
void cChunkDesc::WriteBlockArea(const cBlockArea & a_BlockArea, int a_RelX, int a_RelY, int a_RelZ)
|
||||
void cChunkDesc::WriteBlockArea(const cBlockArea & a_BlockArea, int a_RelX, int a_RelY, int a_RelZ, cBlockArea::eMergeStrategy a_MergeStrategy)
|
||||
{
|
||||
if (!a_BlockArea.HasBlockTypes() && !a_BlockArea.HasBlockMetas())
|
||||
{
|
||||
LOGWARNING("Request was made to write a block area without BlockTypes nor BlockMetas into cChunkDesc. Ignoring.");
|
||||
return;
|
||||
}
|
||||
int BAOffX = std::max(0, -a_RelX); // Offset in BA where to start reading
|
||||
int CDOffX = std::max(0, a_RelX); // Offset in CD where to start writing
|
||||
int SizeX = std::min(a_BlockArea.GetSizeX() - BAOffX, cChunkDef::Width - CDOffX); // Number of slices to write
|
||||
int BAOffY = std::max(0, -a_RelY); // Offset in BA where to start reading
|
||||
int CDOffY = std::max(0, a_RelY); // Offset in CD where to start writing
|
||||
int SizeY = std::min(a_BlockArea.GetSizeY() - BAOffY, cChunkDef::Height - CDOffY); // Number of layers to write
|
||||
int BAOffZ = std::max(0, -a_RelZ); // Offset in BA where to start reading
|
||||
int CDOffZ = std::max(0, a_RelZ); // Offset in CD where to start writing
|
||||
int SizeZ = std::min(a_BlockArea.GetSizeZ() - BAOffZ, cChunkDef::Width - CDOffZ); // Number of slices to write
|
||||
|
||||
if (a_BlockArea.HasBlockTypes())
|
||||
{
|
||||
for (int y = 0; y < SizeY; y++)
|
||||
{
|
||||
int BAY = BAOffY + y;
|
||||
int CDY = CDOffY + y;
|
||||
for (int z = 0; z < SizeZ; z++)
|
||||
{
|
||||
int BAZ = BAOffZ + z;
|
||||
int CDZ = CDOffZ + z;
|
||||
for (int x = 0; x < SizeX; x++)
|
||||
{
|
||||
int BAX = BAOffX + x;
|
||||
int CDX = CDOffX + x;
|
||||
cChunkDef::SetBlock(m_BlockTypes, CDX, CDY, CDZ, a_BlockArea.GetRelBlockType(BAX, BAY, BAZ));
|
||||
} // for x
|
||||
} // for z
|
||||
} // for y
|
||||
} // HasBlockTypes()
|
||||
|
||||
if (a_BlockArea.HasBlockMetas())
|
||||
{
|
||||
for (int y = 0; y < SizeY; y++)
|
||||
{
|
||||
int BAY = BAOffY + y;
|
||||
int CDY = CDOffY + y;
|
||||
for (int z = 0; z < SizeZ; z++)
|
||||
{
|
||||
int BAZ = BAOffZ + z;
|
||||
int CDZ = CDOffZ + z;
|
||||
for (int x = 0; x < SizeX; x++)
|
||||
{
|
||||
int BAX = BAOffX + x;
|
||||
int CDX = CDOffX + x;
|
||||
cChunkDef::SetNibble(m_BlockMeta, CDX, CDY, CDZ, a_BlockArea.GetRelBlockMeta(BAX, BAY, BAZ));
|
||||
} // for x
|
||||
} // for z
|
||||
} // for y
|
||||
} // HasBlockMetas()
|
||||
m_BlockArea.Merge(a_BlockArea, a_RelX, a_RelY, a_RelZ, a_MergeStrategy);
|
||||
}
|
||||
|
||||
|
||||
@@ -437,3 +381,16 @@ HEIGHTTYPE cChunkDesc::GetMaxHeight(void) const
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkDesc::CompressBlockMetas(cChunkDef::BlockNibbles & a_DestMetas)
|
||||
{
|
||||
const NIBBLETYPE * AreaMetas = m_BlockArea.GetBlockMetas();
|
||||
for (int i = 0; i < ARRAYCOUNT(a_DestMetas); i++)
|
||||
{
|
||||
a_DestMetas[i] = AreaMetas[2 * i] | (AreaMetas[2 * i + 1] << 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ChunkDef.h"
|
||||
#include "../BlockArea.h"
|
||||
|
||||
|
||||
|
||||
@@ -67,7 +68,7 @@ public:
|
||||
bool IsUsingDefaultFinish(void) const;
|
||||
|
||||
/// Writes the block area into the chunk, with its origin set at the specified relative coords. Area's data overwrite everything in the chunk.
|
||||
void WriteBlockArea(const cBlockArea & a_BlockArea, int a_RelX, int a_RelY, int a_RelZ);
|
||||
void WriteBlockArea(const cBlockArea & a_BlockArea, int a_RelX, int a_RelY, int a_RelZ, cBlockArea::eMergeStrategy a_MergeStrategy = cBlockArea::msOverwrite);
|
||||
|
||||
/// Reads an area from the chunk into a cBlockArea
|
||||
void ReadBlockArea(cBlockArea & a_Dest, int a_MinRelX, int a_MaxRelX, int a_MinRelY, int a_MaxRelY, int a_MinRelZ, int a_MaxRelZ);
|
||||
@@ -80,24 +81,26 @@ public:
|
||||
|
||||
// Accessors used by cChunkGenerator::Generator descendants:
|
||||
inline cChunkDef::BiomeMap & GetBiomeMap (void) { return m_BiomeMap; }
|
||||
inline cChunkDef::BlockTypes & GetBlockTypes (void) { return m_BlockTypes; }
|
||||
inline cChunkDef::BlockNibbles & GetBlockMetas (void) { return m_BlockMeta; }
|
||||
inline cChunkDef::BlockTypes & GetBlockTypes (void) { return *((cChunkDef::BlockTypes *)m_BlockArea.GetBlockTypes()); }
|
||||
// CANNOT, different compression!
|
||||
// inline cChunkDef::BlockNibbles & GetBlockMetas (void) { return *((cChunkDef::BlockNibbles *)m_BlockArea.GetBlockMetas()); }
|
||||
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);
|
||||
|
||||
private:
|
||||
int m_ChunkX;
|
||||
int m_ChunkZ;
|
||||
|
||||
cChunkDef::BiomeMap m_BiomeMap;
|
||||
cChunkDef::BlockTypes m_BlockTypes;
|
||||
cChunkDef::BlockNibbles m_BlockMeta;
|
||||
cBlockArea m_BlockArea;
|
||||
cChunkDef::HeightMap m_HeightMap;
|
||||
cEntityList m_Entities; // Individual entities are NOT owned by this object!
|
||||
cBlockEntityList m_BlockEntities; // Individual block entities are NOT owned by this object!
|
||||
|
||||
|
||||
bool m_bUseDefaultBiomes;
|
||||
bool m_bUseDefaultHeight;
|
||||
bool m_bUseDefaultComposition;
|
||||
|
||||
@@ -271,9 +271,12 @@ void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||
m_Generator->DoGenerate(a_ChunkX, a_ChunkZ, ChunkDesc);
|
||||
cRoot::Get()->GetPluginManager()->CallHookChunkGenerated(m_World, a_ChunkX, a_ChunkZ, &ChunkDesc);
|
||||
|
||||
cChunkDef::BlockNibbles BlockMetas;
|
||||
ChunkDesc.CompressBlockMetas(BlockMetas);
|
||||
|
||||
m_World->SetChunkData(
|
||||
a_ChunkX, a_ChunkY, a_ChunkZ,
|
||||
ChunkDesc.GetBlockTypes(), ChunkDesc.GetBlockMetas(),
|
||||
ChunkDesc.GetBlockTypes(), BlockMetas,
|
||||
NULL, NULL, // We don't have lighting, chunk will be lighted when needed
|
||||
&ChunkDesc.GetHeightMap(), &ChunkDesc.GetBiomeMap(),
|
||||
ChunkDesc.GetEntities(), ChunkDesc.GetBlockEntities(),
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
|
||||
void cCompoGenSameBlock::ComposeTerrain(cChunkDesc & a_ChunkDesc)
|
||||
{
|
||||
memset(a_ChunkDesc.GetBlockTypes(), E_BLOCK_AIR, sizeof(a_ChunkDesc.GetBlockTypes()));
|
||||
memset(a_ChunkDesc.GetBlockMetas(), 0, sizeof(a_ChunkDesc.GetBlockMetas()));
|
||||
a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
|
||||
for (int z = 0; z < cChunkDef::Width; z++)
|
||||
{
|
||||
for (int x = 0; x < cChunkDef::Width; x++)
|
||||
@@ -80,8 +79,7 @@ void cCompoGenDebugBiomes::ComposeTerrain(cChunkDesc & a_ChunkDesc)
|
||||
E_BLOCK_BEDROCK,
|
||||
} ;
|
||||
|
||||
memset(a_ChunkDesc.GetBlockTypes(), E_BLOCK_AIR, sizeof(a_ChunkDesc.GetBlockTypes()));
|
||||
memset(a_ChunkDesc.GetBlockMetas(), 0, sizeof(a_ChunkDesc.GetBlockMetas()));
|
||||
a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
|
||||
|
||||
for (int z = 0; z < cChunkDef::Width; z++)
|
||||
{
|
||||
@@ -134,8 +132,7 @@ void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc)
|
||||
- bedrock at the bottom
|
||||
*/
|
||||
|
||||
memset(a_ChunkDesc.GetBlockTypes(), E_BLOCK_AIR, sizeof(a_ChunkDesc.GetBlockTypes()));
|
||||
memset(a_ChunkDesc.GetBlockMetas(), 0, sizeof(a_ChunkDesc.GetBlockMetas()));
|
||||
a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
|
||||
|
||||
// The patterns to use for different situations, must be same length!
|
||||
const BLOCKTYPE PatternGround[] = {m_BlockTop, m_BlockMiddle, m_BlockMiddle, m_BlockMiddle} ;
|
||||
@@ -191,8 +188,7 @@ void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc)
|
||||
|
||||
void cCompoGenBiomal::ComposeTerrain(cChunkDesc & a_ChunkDesc)
|
||||
{
|
||||
memset(a_ChunkDesc.GetBlockTypes(), E_BLOCK_AIR, sizeof(a_ChunkDesc.GetBlockTypes()));
|
||||
memset(a_ChunkDesc.GetBlockMetas(), 0, sizeof(a_ChunkDesc.GetBlockMetas()));
|
||||
a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
|
||||
|
||||
int ChunkX = a_ChunkDesc.GetChunkX();
|
||||
int ChunkZ = a_ChunkDesc.GetChunkZ();
|
||||
|
||||
@@ -94,21 +94,14 @@ void cComposableGenerator::GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef:
|
||||
|
||||
void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a_ChunkDesc)
|
||||
{
|
||||
cChunkDef::BiomeMap & BiomeMap = a_ChunkDesc.GetBiomeMap();
|
||||
cChunkDef::BlockTypes & BlockTypes = a_ChunkDesc.GetBlockTypes();
|
||||
cChunkDef::BlockNibbles & BlockMeta = a_ChunkDesc.GetBlockMetas();
|
||||
cChunkDef::HeightMap & HeightMap = a_ChunkDesc.GetHeightMap();
|
||||
cEntityList & Entities = a_ChunkDesc.GetEntities();
|
||||
cBlockEntityList & BlockEntities = a_ChunkDesc.GetBlockEntities();
|
||||
|
||||
if (a_ChunkDesc.IsUsingDefaultBiomes())
|
||||
{
|
||||
m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, BiomeMap);
|
||||
m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, a_ChunkDesc.GetBiomeMap());
|
||||
}
|
||||
|
||||
if (a_ChunkDesc.IsUsingDefaultHeight())
|
||||
{
|
||||
m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, HeightMap);
|
||||
m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, a_ChunkDesc.GetHeightMap());
|
||||
}
|
||||
|
||||
if (a_ChunkDesc.IsUsingDefaultComposition())
|
||||
@@ -336,13 +329,18 @@ void cComposableGenerator::InitStructureGens(cIniFile & a_IniFile)
|
||||
{
|
||||
m_StructureGens.push_back(new cStructGenRavines(Seed, 128));
|
||||
}
|
||||
//*
|
||||
// TODO: Not implemented yet; need a name
|
||||
else if (NoCaseCompare(*itr, "wormnestcaves") == 0)
|
||||
{
|
||||
m_StructureGens.push_back(new cStructGenWormNestCaves(Seed));
|
||||
}
|
||||
//*/
|
||||
else if (NoCaseCompare(*itr, "waterlakes") == 0)
|
||||
{
|
||||
m_StructureGens.push_back(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, *m_HeightGen));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "lavalakes") == 0)
|
||||
{
|
||||
m_StructureGens.push_back(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, *m_HeightGen));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGWARNING("Unknown structure generator: \"%s\". Ignoring.", itr->c_str());
|
||||
|
||||
@@ -598,7 +598,7 @@ void cFinishGenFluidSprings::GenFinish(cChunkDesc & a_ChunkDesc)
|
||||
case E_BLOCK_NETHERRACK:
|
||||
case E_BLOCK_STONE:
|
||||
{
|
||||
if (TryPlaceSpring(a_ChunkDesc.GetBlockTypes(), a_ChunkDesc.GetBlockMetas(), x, y, z))
|
||||
if (TryPlaceSpring(a_ChunkDesc, x, y, z))
|
||||
{
|
||||
// Succeeded, bail out
|
||||
return;
|
||||
@@ -614,15 +614,11 @@ void cFinishGenFluidSprings::GenFinish(cChunkDesc & a_ChunkDesc)
|
||||
|
||||
|
||||
|
||||
bool cFinishGenFluidSprings::TryPlaceSpring(
|
||||
cChunkDef::BlockTypes & a_BlockTypes,
|
||||
cChunkDef::BlockNibbles & a_BlockMetas,
|
||||
int x, int y, int z
|
||||
)
|
||||
bool cFinishGenFluidSprings::TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int y, int z)
|
||||
{
|
||||
// In order to place a spring, it needs exactly one of the XZ neighbors or a below neighbor to be air
|
||||
// Also, its neighbor on top of it must be non-air
|
||||
if (cChunkDef::GetBlock(a_BlockTypes, x, y + 1, z) == E_BLOCK_AIR)
|
||||
if (a_ChunkDesc.GetBlockType(x, y + 1, z) == E_BLOCK_AIR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -641,7 +637,7 @@ bool cFinishGenFluidSprings::TryPlaceSpring(
|
||||
int NumAirNeighbors = 0;
|
||||
for (int i = 0; i < ARRAYCOUNT(Coords); i++)
|
||||
{
|
||||
switch (cChunkDef::GetBlock(a_BlockTypes, x + Coords[i].x, y + Coords[i].y, z + Coords[i].z))
|
||||
switch (a_ChunkDesc.GetBlockType(x + Coords[i].x, y + Coords[i].y, z + Coords[i].z))
|
||||
{
|
||||
case E_BLOCK_AIR:
|
||||
{
|
||||
@@ -659,8 +655,7 @@ bool cFinishGenFluidSprings::TryPlaceSpring(
|
||||
}
|
||||
|
||||
// Has exactly one air neighbor, place a spring:
|
||||
cChunkDef::SetBlock(a_BlockTypes, x, y, z, m_Fluid);
|
||||
cChunkDef::SetNibble(a_BlockMetas, x, y, z, 0);
|
||||
a_ChunkDesc.SetBlockTypeMeta(x, y, z, m_Fluid, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -177,11 +177,7 @@ protected:
|
||||
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
|
||||
|
||||
/// Tries to place a spring at the specified coords, checks neighbors. Returns true if successful
|
||||
bool TryPlaceSpring(
|
||||
cChunkDef::BlockTypes & a_BlockTypes,
|
||||
cChunkDef::BlockNibbles & a_BlockMetas,
|
||||
int x, int y, int z
|
||||
);
|
||||
bool TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int y, int z);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "StructGen.h"
|
||||
#include "../BlockID.h"
|
||||
#include "Trees.h"
|
||||
#include "../BlockArea.h"
|
||||
|
||||
|
||||
|
||||
@@ -85,18 +86,11 @@ void cStructGenTrees::GenStructures(cChunkDesc & a_ChunkDesc)
|
||||
{
|
||||
int BaseZ = ChunkZ + z - 1;
|
||||
|
||||
cChunkDef::BlockTypes * BlT;
|
||||
cChunkDef::BlockNibbles * BlM;
|
||||
cChunkDef::HeightMap * Hei;
|
||||
cChunkDef::BiomeMap * Bio;
|
||||
|
||||
cChunkDesc * Dest;
|
||||
|
||||
if ((x != 1) || (z != 1))
|
||||
{
|
||||
BlT = &(WorkerDesc.GetBlockTypes());
|
||||
BlM = &(WorkerDesc.GetBlockMetas());
|
||||
Hei = &(WorkerDesc.GetHeightMap());
|
||||
Bio = &(WorkerDesc.GetBiomeMap());
|
||||
Dest = &WorkerDesc;
|
||||
WorkerDesc.SetChunkCoords(BaseX, BaseZ);
|
||||
|
||||
m_BiomeGen->GenBiomes (BaseX, BaseZ, WorkerDesc.GetBiomeMap());
|
||||
@@ -106,26 +100,23 @@ void cStructGenTrees::GenStructures(cChunkDesc & a_ChunkDesc)
|
||||
}
|
||||
else
|
||||
{
|
||||
BlT = &(a_ChunkDesc.GetBlockTypes());
|
||||
BlM = &(a_ChunkDesc.GetBlockMetas());
|
||||
Hei = &(a_ChunkDesc.GetHeightMap());
|
||||
Bio = &(a_ChunkDesc.GetBiomeMap());
|
||||
Dest = &a_ChunkDesc;
|
||||
}
|
||||
|
||||
int NumTrees = GetNumTrees(BaseX, BaseZ, *Bio);
|
||||
int NumTrees = GetNumTrees(BaseX, BaseZ, Dest->GetBiomeMap());
|
||||
|
||||
sSetBlockVector OutsideLogs, OutsideOther;
|
||||
for (int i = 0; i < NumTrees; i++)
|
||||
{
|
||||
GenerateSingleTree(BaseX, BaseZ, i, *BlT, *BlM, *Hei, *Bio, OutsideLogs, OutsideOther);
|
||||
GenerateSingleTree(BaseX, BaseZ, i, *Dest, OutsideLogs, OutsideOther);
|
||||
}
|
||||
|
||||
sSetBlockVector IgnoredOverflow;
|
||||
IgnoredOverflow.reserve(OutsideOther.size());
|
||||
ApplyTreeImage(ChunkX, ChunkZ, a_ChunkDesc.GetBlockTypes(), a_ChunkDesc.GetBlockMetas(), OutsideOther, IgnoredOverflow);
|
||||
ApplyTreeImage(ChunkX, ChunkZ, a_ChunkDesc, OutsideOther, IgnoredOverflow);
|
||||
IgnoredOverflow.clear();
|
||||
IgnoredOverflow.reserve(OutsideLogs.size());
|
||||
ApplyTreeImage(ChunkX, ChunkZ, a_ChunkDesc.GetBlockTypes(), a_ChunkDesc.GetBlockMetas(), OutsideLogs, IgnoredOverflow);
|
||||
ApplyTreeImage(ChunkX, ChunkZ, a_ChunkDesc, OutsideLogs, IgnoredOverflow);
|
||||
} // for z
|
||||
} // for x
|
||||
|
||||
@@ -136,9 +127,9 @@ void cStructGenTrees::GenStructures(cChunkDesc & a_ChunkDesc)
|
||||
{
|
||||
for (int y = cChunkDef::Height - 1; y >= 0; y--)
|
||||
{
|
||||
if (cChunkDef::GetBlock(a_ChunkDesc.GetBlockTypes(), x, y, z) != E_BLOCK_AIR)
|
||||
if (a_ChunkDesc.GetBlockType(x, y, z) != E_BLOCK_AIR)
|
||||
{
|
||||
cChunkDef::SetHeight(a_ChunkDesc.GetHeightMap(), x, z, y);
|
||||
a_ChunkDesc.SetHeight(x, z, y);
|
||||
break;
|
||||
}
|
||||
} // for y
|
||||
@@ -152,10 +143,7 @@ void cStructGenTrees::GenStructures(cChunkDesc & a_ChunkDesc)
|
||||
|
||||
void cStructGenTrees::GenerateSingleTree(
|
||||
int a_ChunkX, int a_ChunkZ, int a_Seq,
|
||||
cChunkDef::BlockTypes & a_BlockTypes,
|
||||
cChunkDef::BlockNibbles & a_BlockMetas,
|
||||
const cChunkDef::HeightMap & a_Height,
|
||||
const cChunkDef::BiomeMap & a_Biomes,
|
||||
cChunkDesc & a_ChunkDesc,
|
||||
sSetBlockVector & a_OutsideLogs,
|
||||
sSetBlockVector & a_OutsideOther
|
||||
)
|
||||
@@ -163,7 +151,7 @@ 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 = cChunkDef::GetHeight(a_Height, x, z);
|
||||
int Height = a_ChunkDesc.GetHeight(x, z);
|
||||
|
||||
if ((Height <= 0) || (Height > 240))
|
||||
{
|
||||
@@ -171,7 +159,7 @@ void cStructGenTrees::GenerateSingleTree(
|
||||
}
|
||||
|
||||
// Check the block underneath the tree:
|
||||
BLOCKTYPE TopBlock = cChunkDef::GetBlock(a_BlockTypes, x, Height, z);
|
||||
BLOCKTYPE TopBlock = a_ChunkDesc.GetBlockType(x, Height, z);
|
||||
if ((TopBlock != E_BLOCK_DIRT) && (TopBlock != E_BLOCK_GRASS) && (TopBlock != E_BLOCK_FARMLAND))
|
||||
{
|
||||
return;
|
||||
@@ -181,7 +169,7 @@ void cStructGenTrees::GenerateSingleTree(
|
||||
GetTreeImageByBiome(
|
||||
a_ChunkX * cChunkDef::Width + x, Height + 1, a_ChunkZ * cChunkDef::Width + z,
|
||||
m_Noise, a_Seq,
|
||||
cChunkDef::GetBiome(a_Biomes, x, z),
|
||||
a_ChunkDesc.GetBiome(x, z),
|
||||
TreeLogs, TreeOther
|
||||
);
|
||||
|
||||
@@ -194,7 +182,7 @@ void cStructGenTrees::GenerateSingleTree(
|
||||
continue;
|
||||
}
|
||||
|
||||
BLOCKTYPE Block = cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z);
|
||||
BLOCKTYPE Block = a_ChunkDesc.GetBlockType(itr->x, itr->y, itr->z);
|
||||
switch (Block)
|
||||
{
|
||||
CASE_TREE_ALLOWED_BLOCKS:
|
||||
@@ -209,8 +197,8 @@ void cStructGenTrees::GenerateSingleTree(
|
||||
}
|
||||
}
|
||||
|
||||
ApplyTreeImage(a_ChunkX, a_ChunkZ, a_BlockTypes, a_BlockMetas, TreeOther, a_OutsideOther);
|
||||
ApplyTreeImage(a_ChunkX, a_ChunkZ, a_BlockTypes, a_BlockMetas, TreeLogs, a_OutsideLogs);
|
||||
ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeOther, a_OutsideOther);
|
||||
ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeLogs, a_OutsideLogs);
|
||||
}
|
||||
|
||||
|
||||
@@ -219,19 +207,18 @@ void cStructGenTrees::GenerateSingleTree(
|
||||
|
||||
void cStructGenTrees::ApplyTreeImage(
|
||||
int a_ChunkX, int a_ChunkZ,
|
||||
cChunkDef::BlockTypes & a_BlockTypes,
|
||||
cChunkDef::BlockNibbles & a_BlockMetas,
|
||||
cChunkDesc & a_ChunkDesc,
|
||||
const sSetBlockVector & a_Image,
|
||||
sSetBlockVector & a_Overflow
|
||||
)
|
||||
{
|
||||
// Put the generated image into a_BlockTypes, push things outside this chunk into a_Blocks
|
||||
for (sSetBlockVector::const_iterator itr = a_Image.begin(); itr != a_Image.end(); ++itr)
|
||||
for (sSetBlockVector::const_iterator itr = a_Image.begin(), end = a_Image.end(); itr != end; ++itr)
|
||||
{
|
||||
if ((itr->ChunkX == a_ChunkX) && (itr->ChunkZ == a_ChunkZ))
|
||||
{
|
||||
// Inside this chunk, integrate into a_BlockTypes:
|
||||
switch (cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z))
|
||||
// Inside this chunk, integrate into a_ChunkDesc:
|
||||
switch (a_ChunkDesc.GetBlockType(itr->x, itr->y, itr->z))
|
||||
{
|
||||
case E_BLOCK_LEAVES:
|
||||
{
|
||||
@@ -243,8 +230,7 @@ void cStructGenTrees::ApplyTreeImage(
|
||||
}
|
||||
CASE_TREE_OVERWRITTEN_BLOCKS:
|
||||
{
|
||||
cChunkDef::SetBlock (a_BlockTypes, itr->x, itr->y, itr->z, itr->BlockType);
|
||||
cChunkDef::SetNibble(a_BlockMetas, itr->x, itr->y, itr->z, itr->BlockMeta);
|
||||
a_ChunkDesc.SetBlockTypeMeta(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -271,22 +257,22 @@ int cStructGenTrees::GetNumTrees(
|
||||
for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++)
|
||||
{
|
||||
int Add = 0;
|
||||
switch (a_Biomes[x + cChunkDef::Width * z])
|
||||
switch (cChunkDef::GetBiome(a_Biomes, x, z))
|
||||
{
|
||||
case biPlains: Add = 1; break;
|
||||
case biExtremeHills: Add = 3; break;
|
||||
case biForest: Add = 30; break;
|
||||
case biTaiga: Add = 30; break;
|
||||
case biSwampland: Add = 8; break;
|
||||
case biIcePlains: Add = 1; break;
|
||||
case biIceMountains: Add = 1; break;
|
||||
case biMushroomIsland: Add = 3; break;
|
||||
case biMushroomShore: Add = 3; break;
|
||||
case biForestHills: Add = 20; break;
|
||||
case biTaigaHills: Add = 20; break;
|
||||
case biExtremeHillsEdge: Add = 5; break;
|
||||
case biPlains: Add = 1; break;
|
||||
case biExtremeHills: Add = 3; break;
|
||||
case biForest: Add = 30; break;
|
||||
case biTaiga: Add = 30; break;
|
||||
case biSwampland: Add = 8; break;
|
||||
case biIcePlains: Add = 1; break;
|
||||
case biIceMountains: Add = 1; break;
|
||||
case biMushroomIsland: Add = 3; break;
|
||||
case biMushroomShore: Add = 3; break;
|
||||
case biForestHills: Add = 20; break;
|
||||
case biTaigaHills: Add = 20; break;
|
||||
case biExtremeHillsEdge: Add = 5; break;
|
||||
case biJungle: Add = 120; break;
|
||||
case biJungleHills: Add = 90; break;
|
||||
case biJungleHills: Add = 90; break;
|
||||
}
|
||||
NumTrees += Add;
|
||||
}
|
||||
@@ -403,3 +389,118 @@ void cStructGenOreNests::GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_Ore
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cStructGenLakes:
|
||||
|
||||
void cStructGenLakes::GenStructures(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++)
|
||||
{
|
||||
cBlockArea Lake;
|
||||
CreateLakeImage(ChunkX + x, ChunkZ + z, 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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, cBlockArea & a_Lake)
|
||||
{
|
||||
a_Lake.Create(16, 8, 16);
|
||||
a_Lake.Fill(cBlockArea::baTypes, E_BLOCK_SPONGE); // Sponge is the NOP blocktype for lake merging strategy
|
||||
|
||||
// Find the maximum height in this chunk:
|
||||
cChunkDef::HeightMap HeightMap;
|
||||
m_HeiGen.GenHeightMap(a_ChunkX, a_ChunkZ, HeightMap);
|
||||
HEIGHTTYPE MaxHeight = HeightMap[0];
|
||||
for (int i = 1; i < ARRAYCOUNT(HeightMap); i++)
|
||||
{
|
||||
if (HeightMap[i] > MaxHeight)
|
||||
{
|
||||
MaxHeight = HeightMap[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Make a random position in the chunk by using a random 16 block XZ offset and random height up to chunk's max height
|
||||
int Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 128, a_ChunkZ) / 11;
|
||||
// Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide and subtract to get range
|
||||
int OffsetX = 4 * ((Rnd & 0x07) + ((Rnd & 0x38) >> 3) + ((Rnd & 0x1c0) >> 6) + ((Rnd & 0xe00) >> 9)) / 7 - 8;
|
||||
Rnd >>= 12;
|
||||
// Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide and subtract to get range
|
||||
int OffsetZ = 4 * ((Rnd & 0x07) + ((Rnd & 0x38) >> 3) + ((Rnd & 0x1c0) >> 6) + ((Rnd & 0xe00) >> 9)) / 7 - 8;
|
||||
Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 512, a_ChunkZ) / 13;
|
||||
// Random height [0 .. MaxHeight] with preference to center heights
|
||||
int HeightY = (((Rnd & 0x1ff) % (MaxHeight + 1)) + (((Rnd >> 9) & 0x1ff) % (MaxHeight + 1))) / 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();
|
||||
for (int i = 0; i < NumBubbles; i++)
|
||||
{
|
||||
int Rnd = m_Noise.IntNoise3DInt(a_ChunkX, i, a_ChunkZ) / 13;
|
||||
const int BubbleR = 2 + (Rnd & 0x03); // 2 .. 5
|
||||
const int Range = 16 - 2 * BubbleR;
|
||||
const int BubbleX = BubbleR + (Rnd % Range);
|
||||
Rnd >>= 4;
|
||||
const int BubbleY = 4 + (Rnd & 0x01); // 4 .. 5
|
||||
Rnd >>= 1;
|
||||
const int BubbleZ = BubbleR + (Rnd % Range);
|
||||
Rnd >>= 4;
|
||||
const int HalfR = BubbleR / 2; // 1 .. 2
|
||||
const int RSquared = BubbleR * BubbleR;
|
||||
for (int y = -HalfR; y <= HalfR; y++)
|
||||
{
|
||||
// BubbleY + y is in the [0, 7] bounds
|
||||
int DistY = 4 * y * y / 3;
|
||||
int IdxY = (BubbleY + y) * 16 * 16;
|
||||
for (int z = -BubbleR; z <= BubbleR; z++)
|
||||
{
|
||||
int DistYZ = DistY + z * z;
|
||||
if (DistYZ >= RSquared)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int IdxYZ = BubbleX + IdxY + (BubbleZ + z) * 16;
|
||||
for (int x = -BubbleR; x <= BubbleR; x++)
|
||||
{
|
||||
if (x * x + DistYZ < RSquared)
|
||||
{
|
||||
BlockTypes[x + IdxYZ] = E_BLOCK_AIR;
|
||||
}
|
||||
} // for x
|
||||
} // for z
|
||||
} // for y
|
||||
} // for i - bubbles
|
||||
|
||||
// Turn air in the bottom half into liquid:
|
||||
for (int y = 0; y < 4; y++)
|
||||
{
|
||||
for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++)
|
||||
{
|
||||
if (BlockTypes[x + z * 16 + y * 16 * 16] == E_BLOCK_AIR)
|
||||
{
|
||||
BlockTypes[x + z * 16 + y * 16 * 16] = m_Fluid;
|
||||
}
|
||||
} // 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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -46,10 +46,7 @@ protected:
|
||||
*/
|
||||
void GenerateSingleTree(
|
||||
int a_ChunkX, int a_ChunkZ, int a_Seq,
|
||||
cChunkDef::BlockTypes & a_BlockTypes,
|
||||
cChunkDef::BlockNibbles & a_BlockMetas,
|
||||
const cChunkDef::HeightMap & a_Height,
|
||||
const cChunkDef::BiomeMap & a_Biomes,
|
||||
cChunkDesc & a_ChunkDesc,
|
||||
sSetBlockVector & a_OutsideLogs,
|
||||
sSetBlockVector & a_OutsideOther
|
||||
) ;
|
||||
@@ -57,8 +54,7 @@ protected:
|
||||
/// 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,
|
||||
cChunkDef::BlockTypes & a_BlockTypes,
|
||||
cChunkDef::BlockNibbles & a_BlockMetas,
|
||||
cChunkDesc & a_ChunkDesc,
|
||||
const sSetBlockVector & a_Image,
|
||||
sSetBlockVector & a_Overflow
|
||||
);
|
||||
@@ -100,15 +96,25 @@ class cStructGenLakes :
|
||||
public cStructureGen
|
||||
{
|
||||
public:
|
||||
cStructGenLakes(int a_Seed, BLOCKTYPE a_Fluid) : m_Noise(a_Seed), m_Seed(a_Seed), m_Fluid(a_Fluid) {}
|
||||
cStructGenLakes(int a_Seed, BLOCKTYPE a_Fluid, cTerrainHeightGen & a_HeiGen) :
|
||||
m_Noise(a_Seed),
|
||||
m_Seed(a_Seed),
|
||||
m_Fluid(a_Fluid),
|
||||
m_HeiGen(a_HeiGen)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
cNoise m_Noise;
|
||||
int m_Seed;
|
||||
BLOCKTYPE m_Fluid;
|
||||
cNoise m_Noise;
|
||||
int m_Seed;
|
||||
BLOCKTYPE m_Fluid;
|
||||
cTerrainHeightGen & m_HeiGen;
|
||||
|
||||
// cStructureGen override:
|
||||
virtual void GenStructures(cChunkDesc & a_ChunkDesc) override;
|
||||
|
||||
/// Creates a lake image for the specified chunk into a_Lake
|
||||
void CreateLakeImage(int a_ChunkX, int a_ChunkZ, cBlockArea & a_Lake);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user