summaryrefslogtreecommitdiffstats
path: root/source/Generating/ChunkDesc.cpp
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2013-02-08 21:57:42 +0100
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2013-02-08 21:57:42 +0100
commitb55afc940b4a95ac0191cc24a40c5c3824ab2f0f (patch)
tree83fe5517c9685d43986b87a28a4dfdcb141d381d /source/Generating/ChunkDesc.cpp
parentPrepared cChunkDesc for further API extension; used it as the sole container for generated chunk data, including entities / block entities. (diff)
downloadcuberite-b55afc940b4a95ac0191cc24a40c5c3824ab2f0f.tar
cuberite-b55afc940b4a95ac0191cc24a40c5c3824ab2f0f.tar.gz
cuberite-b55afc940b4a95ac0191cc24a40c5c3824ab2f0f.tar.bz2
cuberite-b55afc940b4a95ac0191cc24a40c5c3824ab2f0f.tar.lz
cuberite-b55afc940b4a95ac0191cc24a40c5c3824ab2f0f.tar.xz
cuberite-b55afc940b4a95ac0191cc24a40c5c3824ab2f0f.tar.zst
cuberite-b55afc940b4a95ac0191cc24a40c5c3824ab2f0f.zip
Diffstat (limited to '')
-rw-r--r--source/Generating/ChunkDesc.cpp198
1 files changed, 196 insertions, 2 deletions
diff --git a/source/Generating/ChunkDesc.cpp b/source/Generating/ChunkDesc.cpp
index 29eb80be7..f19c0ae1e 100644
--- a/source/Generating/ChunkDesc.cpp
+++ b/source/Generating/ChunkDesc.cpp
@@ -5,12 +5,15 @@
#include "Globals.h"
#include "ChunkDesc.h"
+#include "../BlockArea.h"
-cChunkDesc::cChunkDesc(void) :
+cChunkDesc::cChunkDesc(int a_ChunkX, int a_ChunkZ) :
+ m_ChunkX(a_ChunkX),
+ m_ChunkZ(a_ChunkZ),
m_bUseDefaultBiomes(true),
m_bUseDefaultHeight(true),
m_bUseDefaultComposition(true),
@@ -47,7 +50,7 @@ void cChunkDesc::FillBlocks(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
-void cChunkDesc::SetBlock(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);
cChunkDef::SetBlock(m_BlockTypes, Index, a_BlockType);
@@ -58,6 +61,17 @@ void cChunkDesc::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT
+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);
+}
+
+
+
+
+
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);
@@ -217,3 +231,183 @@ bool cChunkDesc::IsUsingDefaultFinish(void) const
+
+void cChunkDesc::WriteBlockArea(const cBlockArea & a_BlockArea, int a_RelX, int a_RelY, int a_RelZ)
+{
+ 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 = BAOffX + 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 = BAOffX + x;
+ cChunkDef::SetNibble(m_BlockMeta, CDX, CDY, CDZ, a_BlockArea.GetRelBlockMeta(BAX, BAY, BAZ));
+ } // for x
+ } // for z
+ } // for y
+ } // HasBlockMetas()
+}
+
+
+
+
+
+void cChunkDesc::ReadBlockArea(cBlockArea & a_Dest, int a_MinRelX, int a_MaxRelX, int a_MinRelY, int a_MaxRelY, int a_MinRelZ, int a_MaxRelZ)
+{
+ // Normalize the coords:
+ if (a_MinRelX > a_MaxRelX)
+ {
+ std::swap(a_MinRelX, a_MaxRelX);
+ }
+ if (a_MinRelY > a_MaxRelY)
+ {
+ std::swap(a_MinRelY, a_MaxRelY);
+ }
+ if (a_MinRelZ > a_MaxRelZ)
+ {
+ std::swap(a_MinRelZ, a_MaxRelZ);
+ }
+
+ // Include the Max coords:
+ a_MaxRelX += 1;
+ a_MaxRelY += 1;
+ a_MaxRelZ += 1;
+
+ // Check coords validity:
+ if (a_MinRelX < 0)
+ {
+ LOGWARNING("%s: MinRelX less than zero, adjusting to zero", __FUNCTION__);
+ a_MinRelX = 0;
+ }
+ else if (a_MinRelX >= cChunkDef::Width)
+ {
+ LOGWARNING("%s: MinRelX more than chunk width, adjusting to chunk width", __FUNCTION__);
+ a_MinRelX = cChunkDef::Width - 1;
+ }
+ if (a_MaxRelX < 0)
+ {
+ LOGWARNING("%s: MaxRelX less than zero, adjusting to zero", __FUNCTION__);
+ a_MaxRelX = 0;
+ }
+ else if (a_MinRelX >= cChunkDef::Width)
+ {
+ LOGWARNING("%s: MaxRelX more than chunk width, adjusting to chunk width", __FUNCTION__);
+ a_MaxRelX = cChunkDef::Width - 1;
+ }
+
+ if (a_MinRelY < 0)
+ {
+ LOGWARNING("%s: MinRelY less than zero, adjusting to zero", __FUNCTION__);
+ a_MinRelY = 0;
+ }
+ else if (a_MinRelY >= cChunkDef::Height)
+ {
+ LOGWARNING("%s: MinRelY more than chunk height, adjusting to chunk height", __FUNCTION__);
+ a_MinRelY = cChunkDef::Height - 1;
+ }
+ if (a_MaxRelY < 0)
+ {
+ LOGWARNING("%s: MaxRelY less than zero, adjusting to zero", __FUNCTION__);
+ a_MaxRelY = 0;
+ }
+ else if (a_MinRelY >= cChunkDef::Height)
+ {
+ LOGWARNING("%s: MaxRelY more than chunk height, adjusting to chunk height", __FUNCTION__);
+ a_MaxRelY = cChunkDef::Height - 1;
+ }
+
+ if (a_MinRelZ < 0)
+ {
+ LOGWARNING("%s: MinRelZ less than zero, adjusting to zero", __FUNCTION__);
+ a_MinRelZ = 0;
+ }
+ else if (a_MinRelZ >= cChunkDef::Width)
+ {
+ LOGWARNING("%s: MinRelZ more than chunk width, adjusting to chunk width", __FUNCTION__);
+ a_MinRelZ = cChunkDef::Width - 1;
+ }
+ if (a_MaxRelZ < 0)
+ {
+ LOGWARNING("%s: MaxRelZ less than zero, adjusting to zero", __FUNCTION__);
+ a_MaxRelZ = 0;
+ }
+ else if (a_MinRelZ >= cChunkDef::Width)
+ {
+ LOGWARNING("%s: MaxRelZ more than chunk width, adjusting to chunk width", __FUNCTION__);
+ a_MaxRelZ = cChunkDef::Width - 1;
+ }
+
+ // Prepare the block area:
+ int SizeX = a_MaxRelX - a_MinRelX;
+ int SizeY = a_MaxRelY - a_MinRelY;
+ int SizeZ = a_MaxRelZ - a_MinRelZ;
+ a_Dest.Clear();
+ a_Dest.m_OriginX = m_ChunkX * cChunkDef::Width + a_MinRelX;
+ a_Dest.m_OriginY = a_MinRelY;
+ a_Dest.m_OriginZ = m_ChunkZ * cChunkDef::Width + a_MinRelZ;
+ a_Dest.SetSize(SizeX, SizeY, SizeZ, cBlockArea::baTypes | cBlockArea::baMetas);
+
+ for (int y = 0; y < SizeY; y++)
+ {
+ int CDY = a_MinRelY + y;
+ for (int z = 0; z < SizeZ; z++)
+ {
+ int CDZ = a_MinRelZ + z;
+ for (int x = 0; x < SizeX; x++)
+ {
+ int CDX = a_MinRelX + x;
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ GetBlockTypeMeta(CDX, CDY, CDZ, BlockType, BlockMeta);
+ a_Dest.SetRelBlockTypeMeta(x, y, z, BlockType, BlockMeta);
+ } // for x
+ } // for z
+ } // for y
+}
+
+
+
+
+