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 --- MCServer/Plugins/Debuggers/Debuggers.lua | 20 ++- source/Bindings.cpp | 230 +++++++++++++++++++++++++++++-- source/Bindings.h | 2 +- source/BlockArea.cpp | 34 +++++ source/BlockArea.h | 6 +- source/Generating/ChunkDesc.cpp | 198 +++++++++++++++++++++++++- source/Generating/ChunkDesc.h | 21 ++- source/Generating/ChunkGenerator.cpp | 2 +- 8 files changed, 496 insertions(+), 17 deletions(-) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index 04f7af3c9..ae639f6a6 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -14,8 +14,9 @@ function Initialize(Plugin) Plugin:SetVersion(1) PluginManager = cRoot:Get():GetPluginManager() - PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_USING_ITEM) - PluginManager:AddHook(Plugin, cPluginManager.HOOK_TAKE_DAMAGE) + PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_USING_ITEM); + PluginManager:AddHook(Plugin, cPluginManager.HOOK_TAKE_DAMAGE); + PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATED); LOG("Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion()) @@ -186,3 +187,18 @@ end + + +function OnChunkGenerated(World, ChunkX, ChunkZ, ChunkDesc) + -- Test ChunkDesc / BlockArea interaction + local BlockArea = cBlockArea(); + ChunkDesc:ReadBlockArea(BlockArea, 0, 15, 50, 70, 0, 15); + BlockArea:SaveToSchematicFile("ChunkBlocks_" .. ChunkX .. "_" .. ChunkZ .. ".schematic"); + + ChunkDesc:WriteBlockArea(BlockArea, 5, 115, 5); + return false; +end + + + + diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 0dad837ba..84d964af7 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 02/08/13 16:56:54. +** Generated automatically by tolua++-1.0.92 on 02/08/13 21:06:19. */ #ifndef __cplusplus @@ -18654,6 +18654,88 @@ static int tolua_AllToLua_cBlockArea_GetBlockSkyLight00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: SetBlockTypeMeta of class cBlockArea */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_SetBlockTypeMeta00 +static int tolua_AllToLua_cBlockArea_SetBlockTypeMeta00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cBlockArea",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cBlockArea* self = (cBlockArea*) tolua_tousertype(tolua_S,1,0); + int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0)); + unsigned char a_BlockType = (( unsigned char) tolua_tonumber(tolua_S,5,0)); + unsigned char a_BlockMeta = (( unsigned char) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlockTypeMeta'", NULL); +#endif + { + self->SetBlockTypeMeta(a_BlockX,a_BlockY,a_BlockZ,a_BlockType,a_BlockMeta); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetBlockTypeMeta'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetRelBlockTypeMeta of class cBlockArea */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_SetRelBlockTypeMeta00 +static int tolua_AllToLua_cBlockArea_SetRelBlockTypeMeta00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cBlockArea",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cBlockArea* self = (cBlockArea*) tolua_tousertype(tolua_S,1,0); + int a_RelX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_RelY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_RelZ = ((int) tolua_tonumber(tolua_S,4,0)); + unsigned char a_BlockType = (( unsigned char) tolua_tonumber(tolua_S,5,0)); + unsigned char a_BlockMeta = (( unsigned char) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRelBlockTypeMeta'", NULL); +#endif + { + self->SetRelBlockTypeMeta(a_RelX,a_RelY,a_RelZ,a_BlockType,a_BlockMeta); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetRelBlockTypeMeta'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetBlockTypeMeta of class cBlockArea */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_GetBlockTypeMeta00 static int tolua_AllToLua_cBlockArea_GetBlockTypeMeta00(lua_State* tolua_S) @@ -19127,9 +19209,9 @@ static int tolua_AllToLua_cChunkDesc_FillBlocks00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: SetBlock of class cChunkDesc */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cChunkDesc_SetBlock00 -static int tolua_AllToLua_cChunkDesc_SetBlock00(lua_State* tolua_S) +/* method: SetBlockTypeMeta of class cChunkDesc */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cChunkDesc_SetBlockTypeMeta00 +static int tolua_AllToLua_cChunkDesc_SetBlockTypeMeta00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; @@ -19153,16 +19235,59 @@ static int tolua_AllToLua_cChunkDesc_SetBlock00(lua_State* tolua_S) unsigned char a_BlockType = (( unsigned char) tolua_tonumber(tolua_S,5,0)); unsigned char a_BlockMeta = (( unsigned char) tolua_tonumber(tolua_S,6,0)); #ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlock'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetBlockTypeMeta'", NULL); #endif { - self->SetBlock(a_RelX,a_RelY,a_RelZ,a_BlockType,a_BlockMeta); + self->SetBlockTypeMeta(a_RelX,a_RelY,a_RelZ,a_BlockType,a_BlockMeta); } } return 0; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetBlock'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'SetBlockTypeMeta'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetBlockTypeMeta of class cChunkDesc */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cChunkDesc_GetBlockTypeMeta00 +static int tolua_AllToLua_cChunkDesc_GetBlockTypeMeta00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cChunkDesc",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cChunkDesc* self = (cChunkDesc*) tolua_tousertype(tolua_S,1,0); + int a_RelX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_RelY = ((int) tolua_tonumber(tolua_S,3,0)); + int a_RelZ = ((int) tolua_tonumber(tolua_S,4,0)); + unsigned char a_BlockType = (( unsigned char) tolua_tonumber(tolua_S,5,0)); + unsigned char a_BlockMeta = (( unsigned char) tolua_tonumber(tolua_S,6,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockTypeMeta'", NULL); +#endif + { + self->GetBlockTypeMeta(a_RelX,a_RelY,a_RelZ,a_BlockType,a_BlockMeta); + tolua_pushnumber(tolua_S,(lua_Number)a_BlockType); + tolua_pushnumber(tolua_S,(lua_Number)a_BlockMeta); + } + } + return 2; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetBlockTypeMeta'.",&tolua_err); return 0; #endif } @@ -19793,6 +19918,90 @@ static int tolua_AllToLua_cChunkDesc_IsUsingDefaultFinish00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: WriteBlockArea of class cChunkDesc */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cChunkDesc_WriteBlockArea00 +static int tolua_AllToLua_cChunkDesc_WriteBlockArea00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cChunkDesc",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cBlockArea",0,&tolua_err)) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cChunkDesc* self = (cChunkDesc*) tolua_tousertype(tolua_S,1,0); + const cBlockArea* a_BlockArea = ((const cBlockArea*) tolua_tousertype(tolua_S,2,0)); + int a_RelX = ((int) tolua_tonumber(tolua_S,3,0)); + int a_RelY = ((int) tolua_tonumber(tolua_S,4,0)); + int a_RelZ = ((int) tolua_tonumber(tolua_S,5,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'WriteBlockArea'", NULL); +#endif + { + self->WriteBlockArea(*a_BlockArea,a_RelX,a_RelY,a_RelZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'WriteBlockArea'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: ReadBlockArea of class cChunkDesc */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cChunkDesc_ReadBlockArea00 +static int tolua_AllToLua_cChunkDesc_ReadBlockArea00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cChunkDesc",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cBlockArea",0,&tolua_err)) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnumber(tolua_S,7,0,&tolua_err) || + !tolua_isnumber(tolua_S,8,0,&tolua_err) || + !tolua_isnoobj(tolua_S,9,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cChunkDesc* self = (cChunkDesc*) tolua_tousertype(tolua_S,1,0); + cBlockArea* a_Dest = ((cBlockArea*) tolua_tousertype(tolua_S,2,0)); + int a_MinRelX = ((int) tolua_tonumber(tolua_S,3,0)); + int a_MaxRelX = ((int) tolua_tonumber(tolua_S,4,0)); + int a_MinRelY = ((int) tolua_tonumber(tolua_S,5,0)); + int a_MaxRelY = ((int) tolua_tonumber(tolua_S,6,0)); + int a_MinRelZ = ((int) tolua_tonumber(tolua_S,7,0)); + int a_MaxRelZ = ((int) tolua_tonumber(tolua_S,8,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ReadBlockArea'", NULL); +#endif + { + self->ReadBlockArea(*a_Dest,a_MinRelX,a_MaxRelX,a_MinRelY,a_MaxRelY,a_MinRelZ,a_MaxRelZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ReadBlockArea'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: new of class cCraftingGrid */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cCraftingGrid_new00 static int tolua_AllToLua_cCraftingGrid_new00(lua_State* tolua_S) @@ -21975,6 +22184,8 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetBlockLight",tolua_AllToLua_cBlockArea_GetBlockLight00); tolua_function(tolua_S,"GetRelBlockSkyLight",tolua_AllToLua_cBlockArea_GetRelBlockSkyLight00); tolua_function(tolua_S,"GetBlockSkyLight",tolua_AllToLua_cBlockArea_GetBlockSkyLight00); + tolua_function(tolua_S,"SetBlockTypeMeta",tolua_AllToLua_cBlockArea_SetBlockTypeMeta00); + tolua_function(tolua_S,"SetRelBlockTypeMeta",tolua_AllToLua_cBlockArea_SetRelBlockTypeMeta00); tolua_function(tolua_S,"GetBlockTypeMeta",tolua_AllToLua_cBlockArea_GetBlockTypeMeta00); tolua_function(tolua_S,"GetRelBlockTypeMeta",tolua_AllToLua_cBlockArea_GetRelBlockTypeMeta00); tolua_function(tolua_S,"GetSizeX",tolua_AllToLua_cBlockArea_GetSizeX00); @@ -21992,7 +22203,8 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_cclass(tolua_S,"cChunkDesc","cChunkDesc","",NULL); tolua_beginmodule(tolua_S,"cChunkDesc"); tolua_function(tolua_S,"FillBlocks",tolua_AllToLua_cChunkDesc_FillBlocks00); - tolua_function(tolua_S,"SetBlock",tolua_AllToLua_cChunkDesc_SetBlock00); + tolua_function(tolua_S,"SetBlockTypeMeta",tolua_AllToLua_cChunkDesc_SetBlockTypeMeta00); + tolua_function(tolua_S,"GetBlockTypeMeta",tolua_AllToLua_cChunkDesc_GetBlockTypeMeta00); tolua_function(tolua_S,"SetBlockType",tolua_AllToLua_cChunkDesc_SetBlockType00); tolua_function(tolua_S,"GetBlockType",tolua_AllToLua_cChunkDesc_GetBlockType00); tolua_function(tolua_S,"SetBlockMeta",tolua_AllToLua_cChunkDesc_SetBlockMeta00); @@ -22011,6 +22223,8 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"IsUsingDefaultStructures",tolua_AllToLua_cChunkDesc_IsUsingDefaultStructures00); tolua_function(tolua_S,"SetUseDefaultFinish",tolua_AllToLua_cChunkDesc_SetUseDefaultFinish00); tolua_function(tolua_S,"IsUsingDefaultFinish",tolua_AllToLua_cChunkDesc_IsUsingDefaultFinish00); + tolua_function(tolua_S,"WriteBlockArea",tolua_AllToLua_cChunkDesc_WriteBlockArea00); + tolua_function(tolua_S,"ReadBlockArea",tolua_AllToLua_cChunkDesc_ReadBlockArea00); tolua_endmodule(tolua_S); #ifdef __cplusplus tolua_cclass(tolua_S,"cCraftingGrid","cCraftingGrid","",tolua_collect_cCraftingGrid); diff --git a/source/Bindings.h b/source/Bindings.h index 121189ed4..2d39e3a46 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 02/08/13 16:56:55. +** Generated automatically by tolua++-1.0.92 on 02/08/13 21:06:20. */ /* Exported function */ diff --git a/source/BlockArea.cpp b/source/BlockArea.cpp index 11878edeb..a5cefb430 100644 --- a/source/BlockArea.cpp +++ b/source/BlockArea.cpp @@ -511,6 +511,40 @@ NIBBLETYPE cBlockArea::GetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ +void cBlockArea::SetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + SetRelBlockTypeMeta(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_BlockType, a_BlockMeta); +} + + + + + +void cBlockArea::SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + int idx = MakeIndex(a_RelX, a_RelY, a_RelZ); + if (m_BlockTypes == NULL) + { + LOGWARNING("%s: BlockTypes not available but requested to be written to.", __FUNCTION__); + } + else + { + m_BlockTypes[idx] = a_BlockType; + } + if (m_BlockMetas == NULL) + { + LOGWARNING("%s: BlockMetas not available but requested to be written to.", __FUNCTION__); + } + else + { + m_BlockMetas[idx] = a_BlockMeta; + } +} + + + + + void cBlockArea::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const { return GetRelBlockTypeMeta(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_BlockType, a_BlockMeta); diff --git a/source/BlockArea.h b/source/BlockArea.h index ace596be6..e01eade69 100644 --- a/source/BlockArea.h +++ b/source/BlockArea.h @@ -96,7 +96,9 @@ public: NIBBLETYPE GetBlockLight (int a_BlockX, int a_BlockY, int a_BlockZ) const; NIBBLETYPE GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ) const; NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ) const; - + + void SetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + void SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); void GetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const; void GetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const; @@ -128,6 +130,7 @@ public: int MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const; protected: + friend class cChunkDesc; class cChunkReader : public cChunkDataCallback @@ -168,6 +171,7 @@ protected: NIBBLETYPE * m_BlockLight; // Each light value is stored as a separate byte for faster access NIBBLETYPE * m_BlockSkyLight; // Each light value is stored as a separate byte for faster access + /// Clears the data stored and prepares a fresh new block area with the specified dimensions bool SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes); // Basic Setters: 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 +} + + + + + diff --git a/source/Generating/ChunkDesc.h b/source/Generating/ChunkDesc.h index e8d4aa17a..afe3df331 100644 --- a/source/Generating/ChunkDesc.h +++ b/source/Generating/ChunkDesc.h @@ -15,19 +15,27 @@ +// fwd: ../BlockArea.h +class cBlockArea; + + + + + // tolua_begin class cChunkDesc { public: // tolua_end - cChunkDesc(void); + cChunkDesc(int a_ChunkX, int a_ChunkZ); ~cChunkDesc(); // tolua_begin void FillBlocks(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + void SetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); void SetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType); BLOCKTYPE GetBlockType(int a_RelX, int a_RelY, int a_RelZ); @@ -53,6 +61,12 @@ public: void SetUseDefaultFinish(bool a_bUseDefaultFinish); 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); + + /// 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); + // tolua_end @@ -65,6 +79,9 @@ public: cBlockEntityList & GetBlockEntities(void) { return m_BlockEntities; } private: + int m_ChunkX; + int m_ChunkZ; + cChunkDef::BiomeMap m_BiomeMap; cChunkDef::BlockTypes m_BlockTypes; cChunkDef::BlockNibbles m_BlockMeta; diff --git a/source/Generating/ChunkGenerator.cpp b/source/Generating/ChunkGenerator.cpp index 0285fa7af..f235215da 100644 --- a/source/Generating/ChunkGenerator.cpp +++ b/source/Generating/ChunkGenerator.cpp @@ -266,7 +266,7 @@ void cChunkGenerator::Execute(void) void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ) { - cChunkDesc ChunkDesc; + cChunkDesc ChunkDesc(a_ChunkX, a_ChunkZ); cRoot::Get()->GetPluginManager()->CallHookChunkGenerating(m_World, a_ChunkX, a_ChunkZ, &ChunkDesc); m_Generator->DoGenerate(a_ChunkX, a_ChunkZ, ChunkDesc); cRoot::Get()->GetPluginManager()->CallHookChunkGenerated(m_World, a_ChunkX, a_ChunkZ, &ChunkDesc); -- cgit v1.2.3