From b55afc940b4a95ac0191cc24a40c5c3824ab2f0f Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Fri, 8 Feb 2013 20:57:42 +0000 Subject: cChunkDesc can now read and write cBlockAreas. A simple example is provided in the Debuggers plugin. git-svn-id: http://mc-server.googlecode.com/svn/trunk@1201 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Generating/ChunkDesc.cpp | 198 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 196 insertions(+), 2 deletions(-) (limited to 'source/Generating/ChunkDesc.cpp') 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 +} + + + + + -- cgit v1.2.3