From 5f208f30ac5f72dc0e7a6f5a658902ce9d1c57c1 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Tue, 28 May 2013 12:05:23 +0000 Subject: [PATCH] Chunk / ChunkMap: Added support for unbounded querying blocktype-only or blockmeta-only git-svn-id: http://mc-server.googlecode.com/svn/trunk@1522 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Bindings.cpp | 36 ++++++++++++++- source/Bindings.h | 2 +- source/Chunk.cpp | 104 +++++++++++++++++++++++++++++++++++++++++++- source/Chunk.h | 6 +++ source/ChunkMap.cpp | 46 ++++++++++++++++++++ source/ChunkMap.h | 10 ++++- 6 files changed, 199 insertions(+), 5 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index a3a23acce..0bbe126f6 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 05/26/13 22:51:07. +** Generated automatically by tolua++-1.0.92 on 05/28/13 14:04:23. */ #ifndef __cplusplus @@ -16168,6 +16168,39 @@ static int tolua_AllToLua_cDropSpenserEntity_Activate00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: SetRedstonePower of class cDropSpenserEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cDropSpenserEntity_SetRedstonePower00 +static int tolua_AllToLua_cDropSpenserEntity_SetRedstonePower00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cDropSpenserEntity",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cDropSpenserEntity* self = (cDropSpenserEntity*) tolua_tousertype(tolua_S,1,0); + bool a_IsPowered = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRedstonePower'", NULL); +#endif + { + self->SetRedstonePower(a_IsPowered); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetRedstonePower'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* get function: __cBlockEntityWindowOwner__ of class cDropSpenserEntity */ #ifndef TOLUA_DISABLE_tolua_get_cDropSpenserEntity___cBlockEntityWindowOwner__ static int tolua_get_cDropSpenserEntity___cBlockEntityWindowOwner__(lua_State* tolua_S) @@ -26654,6 +26687,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"ContentsWidth",cDropSpenserEntity::ContentsWidth); tolua_function(tolua_S,"AddDropSpenserDir",tolua_AllToLua_cDropSpenserEntity_AddDropSpenserDir00); tolua_function(tolua_S,"Activate",tolua_AllToLua_cDropSpenserEntity_Activate00); + tolua_function(tolua_S,"SetRedstonePower",tolua_AllToLua_cDropSpenserEntity_SetRedstonePower00); tolua_variable(tolua_S,"__cBlockEntityWindowOwner__",tolua_get_cDropSpenserEntity___cBlockEntityWindowOwner__,NULL); tolua_endmodule(tolua_S); #ifdef __cplusplus diff --git a/source/Bindings.h b/source/Bindings.h index 2b47c8dd7..90ed4fcc0 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 05/26/13 22:51:07. +** Generated automatically by tolua++-1.0.92 on 05/28/13 14:04:23. */ /* Exported function */ diff --git a/source/Chunk.cpp b/source/Chunk.cpp index d52092e74..14b4acba7 100644 --- a/source/Chunk.cpp +++ b/source/Chunk.cpp @@ -900,7 +900,7 @@ bool cChunk::UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE { if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height)) { - LOGWARNING("UnboundedRelGetBlock(): requesting a block with a_RelY out of range: %d", a_RelY); + LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelY); return false; } @@ -948,6 +948,108 @@ bool cChunk::UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE +bool cChunk::UnboundedRelGetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType) const +{ + if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height)) + { + LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelY); + return false; + } + + // Is it in this chunk? + if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) + { + if (!IsValid()) + { + return false; + } + int BlockIdx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); + a_BlockType = GetBlock(BlockIdx); + return true; + } + + // Not in this chunk, try walking the neighbors first: + if ((a_RelX < 0) && (m_NeighborXM != NULL)) + { + return m_NeighborXM->UnboundedRelGetBlockType(a_RelX + cChunkDef::Width, a_RelY, a_RelZ, a_BlockType); + } + if ((a_RelX >= cChunkDef::Width) && (m_NeighborXP != NULL)) + { + return m_NeighborXP->UnboundedRelGetBlockType(a_RelX - cChunkDef::Width, a_RelY, a_RelZ, a_BlockType); + } + if ((a_RelZ < 0) && (m_NeighborZM != NULL)) + { + return m_NeighborZM->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ + cChunkDef::Width, a_BlockType); + } + if ((a_RelZ >= cChunkDef::Width) && (m_NeighborZP != NULL)) + { + return m_NeighborZP->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ - cChunkDef::Width, a_BlockType); + } + + // Neighbors not available, use the chunkmap to locate the chunk: + return m_ChunkMap->LockedGetBlockType( + m_PosX * cChunkDef::Width + a_RelX, + ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, + m_PosZ * cChunkDef::Width + a_RelZ, + a_BlockType + ); +} + + + + + +bool cChunk::UnboundedRelGetBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockMeta) const +{ + if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height)) + { + LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelY); + return false; + } + + // Is it in this chunk? + if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) + { + if (!IsValid()) + { + return false; + } + int BlockIdx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); + a_BlockMeta = GetMeta(BlockIdx); + return true; + } + + // Not in this chunk, try walking the neighbors first: + if ((a_RelX < 0) && (m_NeighborXM != NULL)) + { + return m_NeighborXM->UnboundedRelGetBlockMeta(a_RelX + cChunkDef::Width, a_RelY, a_RelZ, a_BlockMeta); + } + if ((a_RelX >= cChunkDef::Width) && (m_NeighborXP != NULL)) + { + return m_NeighborXP->UnboundedRelGetBlockMeta(a_RelX - cChunkDef::Width, a_RelY, a_RelZ, a_BlockMeta); + } + if ((a_RelZ < 0) && (m_NeighborZM != NULL)) + { + return m_NeighborZM->UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ + cChunkDef::Width, a_BlockMeta); + } + if ((a_RelZ >= cChunkDef::Width) && (m_NeighborZP != NULL)) + { + return m_NeighborZP->UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ - cChunkDef::Width, a_BlockMeta); + } + + // Neighbors not available, use the chunkmap to locate the chunk: + return m_ChunkMap->LockedGetBlockMeta( + m_PosX * cChunkDef::Width + a_RelX, + ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, + m_PosZ * cChunkDef::Width + a_RelZ, + a_BlockMeta + ); +} + + + + + bool cChunk::UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { if ((a_RelY < 0) || (a_RelY > cChunkDef::Height)) diff --git a/source/Chunk.h b/source/Chunk.h index f6a8a082c..506d0cd0f 100644 --- a/source/Chunk.h +++ b/source/Chunk.h @@ -280,6 +280,12 @@ public: /// Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success; only usable in Tick() bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const; + /// Same as GetBlockType(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success; only usable in Tick() + bool UnboundedRelGetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType) const; + + /// Same as GetBlockMeta(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success; only usable in Tick() + bool UnboundedRelGetBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockMeta) const; + /// Same as SetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success; only usable in Tick() bool UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp index 438d23c9c..785238d1d 100644 --- a/source/ChunkMap.cpp +++ b/source/ChunkMap.cpp @@ -203,6 +203,8 @@ cChunkPtr cChunkMap::GetChunkNoLoad( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) { // We already have m_CSLayers locked since this can be called only from within the tick thread + ASSERT(m_CSLayers.IsLockedByCurrentThread()); + int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); @@ -221,6 +223,50 @@ bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY +bool cChunkMap::LockedGetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType) +{ + // We already have m_CSLayers locked since this can be called only from within the tick thread + ASSERT(m_CSLayers.IsLockedByCurrentThread()); + + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk == NULL) + { + return false; + } + + int Index = cChunkDef::MakeIndexNoCheck(a_BlockX, a_BlockY, a_BlockZ); + a_BlockType = Chunk->GetBlock(Index); + return true; +} + + + + + +bool cChunkMap::LockedGetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE & a_BlockMeta) +{ + // We already have m_CSLayers locked since this can be called only from within the tick thread + ASSERT(m_CSLayers.IsLockedByCurrentThread()); + + int ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk == NULL) + { + return false; + } + + int Index = cChunkDef::MakeIndexNoCheck(a_BlockX, a_BlockY, a_BlockZ); + a_BlockMeta = Chunk->GetMeta(Index); + return true; +} + + + + + bool cChunkMap::LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { // We already have m_CSLayers locked since this can be called only from within the tick thread diff --git a/source/ChunkMap.h b/source/ChunkMap.h index 204bbf662..4a25abd4b 100644 --- a/source/ChunkMap.h +++ b/source/ChunkMap.h @@ -375,11 +375,17 @@ private: /// Gets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) bool LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); + /// Gets a block type in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) + bool LockedGetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType); + + /// Gets a block meta in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) + bool LockedGetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE & a_BlockMeta); + /// Sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) - bool LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + bool LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); /// Fast-sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) - bool LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + bool LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); /// Locates a chunk ptr in the chunkmap; doesn't create it when not found; assumes m_CSLayers is locked. To be called only from cChunkMap. cChunk * FindChunk(int a_ChunkX, int a_ChunkZ);