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:
parent
1c1bcf5c07
commit
b4697ab9db
@ -92,6 +92,70 @@ static void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, N
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Combinator used for cBlockArea::msLake merging
|
||||||
|
static void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||||
|
{
|
||||||
|
// Sponge is the NOP block
|
||||||
|
if (a_SrcType == E_BLOCK_SPONGE)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Air is always hollowed out
|
||||||
|
if (a_SrcType == E_BLOCK_AIR)
|
||||||
|
{
|
||||||
|
a_DstType = E_BLOCK_AIR;
|
||||||
|
a_DstMeta = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Water and lava are never overwritten
|
||||||
|
switch (a_DstType)
|
||||||
|
{
|
||||||
|
case E_BLOCK_WATER:
|
||||||
|
case E_BLOCK_STATIONARY_WATER:
|
||||||
|
case E_BLOCK_LAVA:
|
||||||
|
case E_BLOCK_STATIONARY_LAVA:
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Water and lava always overwrite
|
||||||
|
switch (a_SrcType)
|
||||||
|
{
|
||||||
|
case E_BLOCK_WATER:
|
||||||
|
case E_BLOCK_STATIONARY_WATER:
|
||||||
|
case E_BLOCK_LAVA:
|
||||||
|
case E_BLOCK_STATIONARY_LAVA:
|
||||||
|
{
|
||||||
|
a_DstType = a_SrcType;
|
||||||
|
a_DstMeta = a_DstMeta;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a_SrcType == E_BLOCK_STONE)
|
||||||
|
{
|
||||||
|
switch (a_DstType)
|
||||||
|
{
|
||||||
|
case E_BLOCK_DIRT:
|
||||||
|
case E_BLOCK_GRASS:
|
||||||
|
case E_BLOCK_MYCELIUM:
|
||||||
|
{
|
||||||
|
a_DstType = E_BLOCK_STONE;
|
||||||
|
a_DstMeta = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Everything else is left as it is
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// cBlockArea:
|
// cBlockArea:
|
||||||
|
|
||||||
@ -611,6 +675,21 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R
|
|||||||
break;
|
break;
|
||||||
} // case msImprint
|
} // case msImprint
|
||||||
|
|
||||||
|
case msLake:
|
||||||
|
{
|
||||||
|
InternalMergeBlocks(
|
||||||
|
m_BlockTypes, a_Src.GetBlockTypes(),
|
||||||
|
DstMetas, SrcMetas,
|
||||||
|
SizeX, SizeY, SizeZ,
|
||||||
|
SrcOffX, SrcOffY, SrcOffZ,
|
||||||
|
DstOffX, DstOffY, DstOffZ,
|
||||||
|
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
||||||
|
m_SizeX, m_SizeY, m_SizeZ,
|
||||||
|
MergeCombinatorLake
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
} // case msLake
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
LOGWARNING("Unknown block area merge strategy: %d", a_Strategy);
|
LOGWARNING("Unknown block area merge strategy: %d", a_Strategy);
|
||||||
|
@ -49,6 +49,7 @@ public:
|
|||||||
msOverwrite,
|
msOverwrite,
|
||||||
msFillAir,
|
msFillAir,
|
||||||
msImprint,
|
msImprint,
|
||||||
|
msLake,
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
cBlockArea(void);
|
cBlockArea(void);
|
||||||
@ -107,11 +108,29 @@ public:
|
|||||||
| A | air | air | A | A |
|
| A | air | air | A | A |
|
||||||
| air | B | B | B | B |
|
| air | B | B | B | B |
|
||||||
| A | B | B | A | B |
|
| A | B | B | A | B |
|
||||||
|
|
||||||
So to sum up:
|
So to sum up:
|
||||||
- msOverwrite completely overwrites all blocks with the Src's blocks
|
- msOverwrite completely overwrites all blocks with the Src's blocks
|
||||||
- msFillAir overwrites only those blocks that were air
|
- msFillAir overwrites only those blocks that were air
|
||||||
- msImprint overwrites with only those blocks that are non-air
|
- msImprint overwrites with only those blocks that are non-air
|
||||||
|
|
||||||
|
Special strategies:
|
||||||
|
msLake (evaluate top-down, first match wins):
|
||||||
|
| area block | |
|
||||||
|
| this | Src | result |
|
||||||
|
+----------+--------+--------+
|
||||||
|
| A | sponge | A | Sponge is the NOP block
|
||||||
|
| * | air | air | Air always gets hollowed out, even under the oceans
|
||||||
|
| water | * | water | Water is never overwritten
|
||||||
|
| lava | * | lava | Lava is never overwritten
|
||||||
|
| * | water | water | Water always overwrites anything
|
||||||
|
| * | lava | lava | Lava always overwrites anything
|
||||||
|
| dirt | stone | stone | Stone overwrites dirt
|
||||||
|
| grass | stone | stone | ... and grass
|
||||||
|
| mycelium | stone | stone | ... and mycelium
|
||||||
|
| A | stone | A | ... but nothing else
|
||||||
|
| A | * | A | Everything else is left as it is
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy);
|
void Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy);
|
||||||
|
|
||||||
|
@ -20,8 +20,11 @@ cChunkDesc::cChunkDesc(int a_ChunkX, int a_ChunkZ) :
|
|||||||
m_bUseDefaultStructures(true),
|
m_bUseDefaultStructures(true),
|
||||||
m_bUseDefaultFinish(true)
|
m_bUseDefaultFinish(true)
|
||||||
{
|
{
|
||||||
|
m_BlockArea.Create(cChunkDef::Width, cChunkDef::Height, cChunkDef::Width);
|
||||||
|
/*
|
||||||
memset(m_BlockTypes, 0, sizeof(cChunkDef::BlockTypes));
|
memset(m_BlockTypes, 0, sizeof(cChunkDef::BlockTypes));
|
||||||
memset(m_BlockMeta, 0, sizeof(cChunkDef::BlockNibbles));
|
memset(m_BlockMeta, 0, sizeof(cChunkDef::BlockNibbles));
|
||||||
|
*/
|
||||||
memset(m_BiomeMap, 0, sizeof(cChunkDef::BiomeMap));
|
memset(m_BiomeMap, 0, sizeof(cChunkDef::BiomeMap));
|
||||||
memset(m_HeightMap, 0, sizeof(cChunkDef::HeightMap));
|
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)
|
void cChunkDesc::FillBlocks(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
||||||
{
|
{
|
||||||
const NIBBLETYPE CompressedMeta = a_BlockMeta | (a_BlockMeta << 4);
|
m_BlockArea.Fill(cBlockArea::baTypes | cBlockArea::baMetas, a_BlockType, a_BlockMeta);
|
||||||
memset(m_BlockTypes, a_BlockType, sizeof(cChunkDef::BlockTypes));
|
|
||||||
memset(m_BlockMeta, CompressedMeta, sizeof(cChunkDef::BlockNibbles));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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)
|
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);
|
m_BlockArea.SetRelBlockTypeMeta(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta);
|
||||||
cChunkDef::SetBlock(m_BlockTypes, Index, a_BlockType);
|
|
||||||
cChunkDef::SetNibble(m_BlockMeta, Index, 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)
|
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);
|
m_BlockArea.GetRelBlockTypeMeta(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta);
|
||||||
a_BlockType = cChunkDef::GetBlock(m_BlockTypes, Index);
|
|
||||||
a_BlockMeta = cChunkDef::GetNibble(m_BlockMeta, Index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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)
|
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)
|
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)
|
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)
|
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())
|
m_BlockArea.Merge(a_BlockArea, a_RelX, a_RelY, a_RelZ, a_MergeStrategy);
|
||||||
{
|
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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
|
#pragma once
|
||||||
|
|
||||||
#include "../ChunkDef.h"
|
#include "../ChunkDef.h"
|
||||||
|
#include "../BlockArea.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ public:
|
|||||||
bool IsUsingDefaultFinish(void) const;
|
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.
|
/// 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
|
/// 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);
|
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:
|
// Accessors used by cChunkGenerator::Generator descendants:
|
||||||
inline cChunkDef::BiomeMap & GetBiomeMap (void) { return m_BiomeMap; }
|
inline cChunkDef::BiomeMap & GetBiomeMap (void) { return m_BiomeMap; }
|
||||||
inline cChunkDef::BlockTypes & GetBlockTypes (void) { return m_BlockTypes; }
|
inline cChunkDef::BlockTypes & GetBlockTypes (void) { return *((cChunkDef::BlockTypes *)m_BlockArea.GetBlockTypes()); }
|
||||||
inline cChunkDef::BlockNibbles & GetBlockMetas (void) { return m_BlockMeta; }
|
// CANNOT, different compression!
|
||||||
|
// inline cChunkDef::BlockNibbles & GetBlockMetas (void) { return *((cChunkDef::BlockNibbles *)m_BlockArea.GetBlockMetas()); }
|
||||||
inline cChunkDef::HeightMap & GetHeightMap (void) { return m_HeightMap; }
|
inline cChunkDef::HeightMap & GetHeightMap (void) { return m_HeightMap; }
|
||||||
inline cEntityList & GetEntities (void) { return m_Entities; }
|
inline cEntityList & GetEntities (void) { return m_Entities; }
|
||||||
inline cBlockEntityList & GetBlockEntities(void) { return m_BlockEntities; }
|
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:
|
private:
|
||||||
int m_ChunkX;
|
int m_ChunkX;
|
||||||
int m_ChunkZ;
|
int m_ChunkZ;
|
||||||
|
|
||||||
cChunkDef::BiomeMap m_BiomeMap;
|
cChunkDef::BiomeMap m_BiomeMap;
|
||||||
cChunkDef::BlockTypes m_BlockTypes;
|
cBlockArea m_BlockArea;
|
||||||
cChunkDef::BlockNibbles m_BlockMeta;
|
|
||||||
cChunkDef::HeightMap m_HeightMap;
|
cChunkDef::HeightMap m_HeightMap;
|
||||||
cEntityList m_Entities; // Individual entities are NOT owned by this object!
|
cEntityList m_Entities; // Individual entities are NOT owned by this object!
|
||||||
cBlockEntityList m_BlockEntities; // Individual block entities are NOT owned by this object!
|
cBlockEntityList m_BlockEntities; // Individual block entities are NOT owned by this object!
|
||||||
|
|
||||||
|
|
||||||
bool m_bUseDefaultBiomes;
|
bool m_bUseDefaultBiomes;
|
||||||
bool m_bUseDefaultHeight;
|
bool m_bUseDefaultHeight;
|
||||||
bool m_bUseDefaultComposition;
|
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);
|
m_Generator->DoGenerate(a_ChunkX, a_ChunkZ, ChunkDesc);
|
||||||
cRoot::Get()->GetPluginManager()->CallHookChunkGenerated(m_World, 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(
|
m_World->SetChunkData(
|
||||||
a_ChunkX, a_ChunkY, a_ChunkZ,
|
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
|
NULL, NULL, // We don't have lighting, chunk will be lighted when needed
|
||||||
&ChunkDesc.GetHeightMap(), &ChunkDesc.GetBiomeMap(),
|
&ChunkDesc.GetHeightMap(), &ChunkDesc.GetBiomeMap(),
|
||||||
ChunkDesc.GetEntities(), ChunkDesc.GetBlockEntities(),
|
ChunkDesc.GetEntities(), ChunkDesc.GetBlockEntities(),
|
||||||
|
@ -20,8 +20,7 @@
|
|||||||
|
|
||||||
void cCompoGenSameBlock::ComposeTerrain(cChunkDesc & a_ChunkDesc)
|
void cCompoGenSameBlock::ComposeTerrain(cChunkDesc & a_ChunkDesc)
|
||||||
{
|
{
|
||||||
memset(a_ChunkDesc.GetBlockTypes(), E_BLOCK_AIR, sizeof(a_ChunkDesc.GetBlockTypes()));
|
a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
|
||||||
memset(a_ChunkDesc.GetBlockMetas(), 0, sizeof(a_ChunkDesc.GetBlockMetas()));
|
|
||||||
for (int z = 0; z < cChunkDef::Width; z++)
|
for (int z = 0; z < cChunkDef::Width; z++)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < cChunkDef::Width; x++)
|
for (int x = 0; x < cChunkDef::Width; x++)
|
||||||
@ -80,8 +79,7 @@ void cCompoGenDebugBiomes::ComposeTerrain(cChunkDesc & a_ChunkDesc)
|
|||||||
E_BLOCK_BEDROCK,
|
E_BLOCK_BEDROCK,
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
memset(a_ChunkDesc.GetBlockTypes(), E_BLOCK_AIR, sizeof(a_ChunkDesc.GetBlockTypes()));
|
a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
|
||||||
memset(a_ChunkDesc.GetBlockMetas(), 0, sizeof(a_ChunkDesc.GetBlockMetas()));
|
|
||||||
|
|
||||||
for (int z = 0; z < cChunkDef::Width; z++)
|
for (int z = 0; z < cChunkDef::Width; z++)
|
||||||
{
|
{
|
||||||
@ -134,8 +132,7 @@ void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc)
|
|||||||
- bedrock at the bottom
|
- bedrock at the bottom
|
||||||
*/
|
*/
|
||||||
|
|
||||||
memset(a_ChunkDesc.GetBlockTypes(), E_BLOCK_AIR, sizeof(a_ChunkDesc.GetBlockTypes()));
|
a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
|
||||||
memset(a_ChunkDesc.GetBlockMetas(), 0, sizeof(a_ChunkDesc.GetBlockMetas()));
|
|
||||||
|
|
||||||
// The patterns to use for different situations, must be same length!
|
// The patterns to use for different situations, must be same length!
|
||||||
const BLOCKTYPE PatternGround[] = {m_BlockTop, m_BlockMiddle, m_BlockMiddle, m_BlockMiddle} ;
|
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)
|
void cCompoGenBiomal::ComposeTerrain(cChunkDesc & a_ChunkDesc)
|
||||||
{
|
{
|
||||||
memset(a_ChunkDesc.GetBlockTypes(), E_BLOCK_AIR, sizeof(a_ChunkDesc.GetBlockTypes()));
|
a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
|
||||||
memset(a_ChunkDesc.GetBlockMetas(), 0, sizeof(a_ChunkDesc.GetBlockMetas()));
|
|
||||||
|
|
||||||
int ChunkX = a_ChunkDesc.GetChunkX();
|
int ChunkX = a_ChunkDesc.GetChunkX();
|
||||||
int ChunkZ = a_ChunkDesc.GetChunkZ();
|
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)
|
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())
|
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())
|
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())
|
if (a_ChunkDesc.IsUsingDefaultComposition())
|
||||||
@ -336,13 +329,18 @@ void cComposableGenerator::InitStructureGens(cIniFile & a_IniFile)
|
|||||||
{
|
{
|
||||||
m_StructureGens.push_back(new cStructGenRavines(Seed, 128));
|
m_StructureGens.push_back(new cStructGenRavines(Seed, 128));
|
||||||
}
|
}
|
||||||
//*
|
|
||||||
// TODO: Not implemented yet; need a name
|
|
||||||
else if (NoCaseCompare(*itr, "wormnestcaves") == 0)
|
else if (NoCaseCompare(*itr, "wormnestcaves") == 0)
|
||||||
{
|
{
|
||||||
m_StructureGens.push_back(new cStructGenWormNestCaves(Seed));
|
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
|
else
|
||||||
{
|
{
|
||||||
LOGWARNING("Unknown structure generator: \"%s\". Ignoring.", itr->c_str());
|
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_NETHERRACK:
|
||||||
case E_BLOCK_STONE:
|
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
|
// Succeeded, bail out
|
||||||
return;
|
return;
|
||||||
@ -614,15 +614,11 @@ void cFinishGenFluidSprings::GenFinish(cChunkDesc & a_ChunkDesc)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cFinishGenFluidSprings::TryPlaceSpring(
|
bool cFinishGenFluidSprings::TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int y, int z)
|
||||||
cChunkDef::BlockTypes & a_BlockTypes,
|
|
||||||
cChunkDef::BlockNibbles & a_BlockMetas,
|
|
||||||
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
|
// 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
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
@ -641,7 +637,7 @@ bool cFinishGenFluidSprings::TryPlaceSpring(
|
|||||||
int NumAirNeighbors = 0;
|
int NumAirNeighbors = 0;
|
||||||
for (int i = 0; i < ARRAYCOUNT(Coords); i++)
|
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:
|
case E_BLOCK_AIR:
|
||||||
{
|
{
|
||||||
@ -659,8 +655,7 @@ bool cFinishGenFluidSprings::TryPlaceSpring(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Has exactly one air neighbor, place a spring:
|
// Has exactly one air neighbor, place a spring:
|
||||||
cChunkDef::SetBlock(a_BlockTypes, x, y, z, m_Fluid);
|
a_ChunkDesc.SetBlockTypeMeta(x, y, z, m_Fluid, 0);
|
||||||
cChunkDef::SetNibble(a_BlockMetas, x, y, z, 0);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,11 +177,7 @@ protected:
|
|||||||
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
|
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
|
||||||
|
|
||||||
/// Tries to place a spring at the specified coords, checks neighbors. Returns true if successful
|
/// Tries to place a spring at the specified coords, checks neighbors. Returns true if successful
|
||||||
bool TryPlaceSpring(
|
bool TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int y, int z);
|
||||||
cChunkDef::BlockTypes & a_BlockTypes,
|
|
||||||
cChunkDef::BlockNibbles & a_BlockMetas,
|
|
||||||
int x, int y, int z
|
|
||||||
);
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "StructGen.h"
|
#include "StructGen.h"
|
||||||
#include "../BlockID.h"
|
#include "../BlockID.h"
|
||||||
#include "Trees.h"
|
#include "Trees.h"
|
||||||
|
#include "../BlockArea.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -85,18 +86,11 @@ void cStructGenTrees::GenStructures(cChunkDesc & a_ChunkDesc)
|
|||||||
{
|
{
|
||||||
int BaseZ = ChunkZ + z - 1;
|
int BaseZ = ChunkZ + z - 1;
|
||||||
|
|
||||||
cChunkDef::BlockTypes * BlT;
|
cChunkDesc * Dest;
|
||||||
cChunkDef::BlockNibbles * BlM;
|
|
||||||
cChunkDef::HeightMap * Hei;
|
|
||||||
cChunkDef::BiomeMap * Bio;
|
|
||||||
|
|
||||||
|
|
||||||
if ((x != 1) || (z != 1))
|
if ((x != 1) || (z != 1))
|
||||||
{
|
{
|
||||||
BlT = &(WorkerDesc.GetBlockTypes());
|
Dest = &WorkerDesc;
|
||||||
BlM = &(WorkerDesc.GetBlockMetas());
|
|
||||||
Hei = &(WorkerDesc.GetHeightMap());
|
|
||||||
Bio = &(WorkerDesc.GetBiomeMap());
|
|
||||||
WorkerDesc.SetChunkCoords(BaseX, BaseZ);
|
WorkerDesc.SetChunkCoords(BaseX, BaseZ);
|
||||||
|
|
||||||
m_BiomeGen->GenBiomes (BaseX, BaseZ, WorkerDesc.GetBiomeMap());
|
m_BiomeGen->GenBiomes (BaseX, BaseZ, WorkerDesc.GetBiomeMap());
|
||||||
@ -106,26 +100,23 @@ void cStructGenTrees::GenStructures(cChunkDesc & a_ChunkDesc)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BlT = &(a_ChunkDesc.GetBlockTypes());
|
Dest = &a_ChunkDesc;
|
||||||
BlM = &(a_ChunkDesc.GetBlockMetas());
|
|
||||||
Hei = &(a_ChunkDesc.GetHeightMap());
|
|
||||||
Bio = &(a_ChunkDesc.GetBiomeMap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int NumTrees = GetNumTrees(BaseX, BaseZ, *Bio);
|
int NumTrees = GetNumTrees(BaseX, BaseZ, Dest->GetBiomeMap());
|
||||||
|
|
||||||
sSetBlockVector OutsideLogs, OutsideOther;
|
sSetBlockVector OutsideLogs, OutsideOther;
|
||||||
for (int i = 0; i < NumTrees; i++)
|
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;
|
sSetBlockVector IgnoredOverflow;
|
||||||
IgnoredOverflow.reserve(OutsideOther.size());
|
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.clear();
|
||||||
IgnoredOverflow.reserve(OutsideLogs.size());
|
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 z
|
||||||
} // for x
|
} // for x
|
||||||
|
|
||||||
@ -136,9 +127,9 @@ void cStructGenTrees::GenStructures(cChunkDesc & a_ChunkDesc)
|
|||||||
{
|
{
|
||||||
for (int y = cChunkDef::Height - 1; y >= 0; y--)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
} // for y
|
} // for y
|
||||||
@ -152,10 +143,7 @@ void cStructGenTrees::GenStructures(cChunkDesc & a_ChunkDesc)
|
|||||||
|
|
||||||
void cStructGenTrees::GenerateSingleTree(
|
void cStructGenTrees::GenerateSingleTree(
|
||||||
int a_ChunkX, int a_ChunkZ, int a_Seq,
|
int a_ChunkX, int a_ChunkZ, int a_Seq,
|
||||||
cChunkDef::BlockTypes & a_BlockTypes,
|
cChunkDesc & a_ChunkDesc,
|
||||||
cChunkDef::BlockNibbles & a_BlockMetas,
|
|
||||||
const cChunkDef::HeightMap & a_Height,
|
|
||||||
const cChunkDef::BiomeMap & a_Biomes,
|
|
||||||
sSetBlockVector & a_OutsideLogs,
|
sSetBlockVector & a_OutsideLogs,
|
||||||
sSetBlockVector & a_OutsideOther
|
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 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 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))
|
if ((Height <= 0) || (Height > 240))
|
||||||
{
|
{
|
||||||
@ -171,7 +159,7 @@ void cStructGenTrees::GenerateSingleTree(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check the block underneath the tree:
|
// 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))
|
if ((TopBlock != E_BLOCK_DIRT) && (TopBlock != E_BLOCK_GRASS) && (TopBlock != E_BLOCK_FARMLAND))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -181,7 +169,7 @@ void cStructGenTrees::GenerateSingleTree(
|
|||||||
GetTreeImageByBiome(
|
GetTreeImageByBiome(
|
||||||
a_ChunkX * cChunkDef::Width + x, Height + 1, a_ChunkZ * cChunkDef::Width + z,
|
a_ChunkX * cChunkDef::Width + x, Height + 1, a_ChunkZ * cChunkDef::Width + z,
|
||||||
m_Noise, a_Seq,
|
m_Noise, a_Seq,
|
||||||
cChunkDef::GetBiome(a_Biomes, x, z),
|
a_ChunkDesc.GetBiome(x, z),
|
||||||
TreeLogs, TreeOther
|
TreeLogs, TreeOther
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -194,7 +182,7 @@ void cStructGenTrees::GenerateSingleTree(
|
|||||||
continue;
|
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)
|
switch (Block)
|
||||||
{
|
{
|
||||||
CASE_TREE_ALLOWED_BLOCKS:
|
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_ChunkDesc, TreeOther, a_OutsideOther);
|
||||||
ApplyTreeImage(a_ChunkX, a_ChunkZ, a_BlockTypes, a_BlockMetas, TreeLogs, a_OutsideLogs);
|
ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeLogs, a_OutsideLogs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -219,19 +207,18 @@ void cStructGenTrees::GenerateSingleTree(
|
|||||||
|
|
||||||
void cStructGenTrees::ApplyTreeImage(
|
void cStructGenTrees::ApplyTreeImage(
|
||||||
int a_ChunkX, int a_ChunkZ,
|
int a_ChunkX, int a_ChunkZ,
|
||||||
cChunkDef::BlockTypes & a_BlockTypes,
|
cChunkDesc & a_ChunkDesc,
|
||||||
cChunkDef::BlockNibbles & a_BlockMetas,
|
|
||||||
const sSetBlockVector & a_Image,
|
const sSetBlockVector & a_Image,
|
||||||
sSetBlockVector & a_Overflow
|
sSetBlockVector & a_Overflow
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Put the generated image into a_BlockTypes, push things outside this chunk into a_Blocks
|
// 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))
|
if ((itr->ChunkX == a_ChunkX) && (itr->ChunkZ == a_ChunkZ))
|
||||||
{
|
{
|
||||||
// Inside this chunk, integrate into a_BlockTypes:
|
// Inside this chunk, integrate into a_ChunkDesc:
|
||||||
switch (cChunkDef::GetBlock(a_BlockTypes, itr->x, itr->y, itr->z))
|
switch (a_ChunkDesc.GetBlockType(itr->x, itr->y, itr->z))
|
||||||
{
|
{
|
||||||
case E_BLOCK_LEAVES:
|
case E_BLOCK_LEAVES:
|
||||||
{
|
{
|
||||||
@ -243,8 +230,7 @@ void cStructGenTrees::ApplyTreeImage(
|
|||||||
}
|
}
|
||||||
CASE_TREE_OVERWRITTEN_BLOCKS:
|
CASE_TREE_OVERWRITTEN_BLOCKS:
|
||||||
{
|
{
|
||||||
cChunkDef::SetBlock (a_BlockTypes, itr->x, itr->y, itr->z, itr->BlockType);
|
a_ChunkDesc.SetBlockTypeMeta(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta);
|
||||||
cChunkDef::SetNibble(a_BlockMetas, itr->x, itr->y, itr->z, itr->BlockMeta);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,22 +257,22 @@ int cStructGenTrees::GetNumTrees(
|
|||||||
for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++)
|
for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++)
|
||||||
{
|
{
|
||||||
int Add = 0;
|
int Add = 0;
|
||||||
switch (a_Biomes[x + cChunkDef::Width * z])
|
switch (cChunkDef::GetBiome(a_Biomes, x, z))
|
||||||
{
|
{
|
||||||
case biPlains: Add = 1; break;
|
case biPlains: Add = 1; break;
|
||||||
case biExtremeHills: Add = 3; break;
|
case biExtremeHills: Add = 3; break;
|
||||||
case biForest: Add = 30; break;
|
case biForest: Add = 30; break;
|
||||||
case biTaiga: Add = 30; break;
|
case biTaiga: Add = 30; break;
|
||||||
case biSwampland: Add = 8; break;
|
case biSwampland: Add = 8; break;
|
||||||
case biIcePlains: Add = 1; break;
|
case biIcePlains: Add = 1; break;
|
||||||
case biIceMountains: Add = 1; break;
|
case biIceMountains: Add = 1; break;
|
||||||
case biMushroomIsland: Add = 3; break;
|
case biMushroomIsland: Add = 3; break;
|
||||||
case biMushroomShore: Add = 3; break;
|
case biMushroomShore: Add = 3; break;
|
||||||
case biForestHills: Add = 20; break;
|
case biForestHills: Add = 20; break;
|
||||||
case biTaigaHills: Add = 20; break;
|
case biTaigaHills: Add = 20; break;
|
||||||
case biExtremeHillsEdge: Add = 5; break;
|
case biExtremeHillsEdge: Add = 5; break;
|
||||||
case biJungle: Add = 120; break;
|
case biJungle: Add = 120; break;
|
||||||
case biJungleHills: Add = 90; break;
|
case biJungleHills: Add = 90; break;
|
||||||
}
|
}
|
||||||
NumTrees += Add;
|
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(
|
void GenerateSingleTree(
|
||||||
int a_ChunkX, int a_ChunkZ, int a_Seq,
|
int a_ChunkX, int a_ChunkZ, int a_Seq,
|
||||||
cChunkDef::BlockTypes & a_BlockTypes,
|
cChunkDesc & a_ChunkDesc,
|
||||||
cChunkDef::BlockNibbles & a_BlockMetas,
|
|
||||||
const cChunkDef::HeightMap & a_Height,
|
|
||||||
const cChunkDef::BiomeMap & a_Biomes,
|
|
||||||
sSetBlockVector & a_OutsideLogs,
|
sSetBlockVector & a_OutsideLogs,
|
||||||
sSetBlockVector & a_OutsideOther
|
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
|
/// Applies an image into chunk blockdata; all blocks outside the chunk will be appended to a_Overflow
|
||||||
void ApplyTreeImage(
|
void ApplyTreeImage(
|
||||||
int a_ChunkX, int a_ChunkZ,
|
int a_ChunkX, int a_ChunkZ,
|
||||||
cChunkDef::BlockTypes & a_BlockTypes,
|
cChunkDesc & a_ChunkDesc,
|
||||||
cChunkDef::BlockNibbles & a_BlockMetas,
|
|
||||||
const sSetBlockVector & a_Image,
|
const sSetBlockVector & a_Image,
|
||||||
sSetBlockVector & a_Overflow
|
sSetBlockVector & a_Overflow
|
||||||
);
|
);
|
||||||
@ -100,15 +96,25 @@ class cStructGenLakes :
|
|||||||
public cStructureGen
|
public cStructureGen
|
||||||
{
|
{
|
||||||
public:
|
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:
|
protected:
|
||||||
cNoise m_Noise;
|
cNoise m_Noise;
|
||||||
int m_Seed;
|
int m_Seed;
|
||||||
BLOCKTYPE m_Fluid;
|
BLOCKTYPE m_Fluid;
|
||||||
|
cTerrainHeightGen & m_HeiGen;
|
||||||
|
|
||||||
// cStructureGen override:
|
// cStructureGen override:
|
||||||
virtual void GenStructures(cChunkDesc & a_ChunkDesc) 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);
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user