diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/AllToLua.pkg | 1 | ||||
-rw-r--r-- | source/Bindings.cpp | 189 | ||||
-rw-r--r-- | source/Bindings.h | 2 | ||||
-rw-r--r-- | source/BlockEntities/DropSpenserEntity.h | 8 | ||||
-rw-r--r-- | source/BlockEntities/HopperEntity.h | 9 | ||||
-rw-r--r-- | source/Chunk.cpp | 359 | ||||
-rw-r--r-- | source/Chunk.h | 23 | ||||
-rw-r--r-- | source/ChunkDef.h | 55 | ||||
-rw-r--r-- | source/LuaWindow.h | 9 | ||||
-rw-r--r-- | source/ManualBindings.cpp | 44 | ||||
-rw-r--r-- | source/Mobs/Monster.cpp | 4 | ||||
-rw-r--r-- | source/Protocol/ProtocolRecognizer.cpp | 6 | ||||
-rw-r--r-- | source/Root.h | 10 | ||||
-rw-r--r-- | source/World.cpp | 3 |
14 files changed, 340 insertions, 382 deletions
diff --git a/source/AllToLua.pkg b/source/AllToLua.pkg index 00257e460..6d4a4083a 100644 --- a/source/AllToLua.pkg +++ b/source/AllToLua.pkg @@ -47,6 +47,7 @@ $cfile "BlockEntities/DropSpenserEntity.h" $cfile "BlockEntities/DispenserEntity.h" $cfile "BlockEntities/DropperEntity.h" $cfile "BlockEntities/FurnaceEntity.h" +$cfile "BlockEntities/HopperEntity.h" $cfile "WebAdmin.h" $cfile "WebPlugin.h" $cfile "Root.h" diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 69b70c9f4..54a3e161b 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 10/21/13 13:17:19. +** Generated automatically by tolua++-1.0.92 on 10/23/13 13:30:23. */ #ifndef __cplusplus @@ -46,6 +46,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); #include "BlockEntities/DispenserEntity.h" #include "BlockEntities/DropperEntity.h" #include "BlockEntities/FurnaceEntity.h" +#include "BlockEntities/HopperEntity.h" #include "WebAdmin.h" #include "WebPlugin.h" #include "Root.h" @@ -74,9 +75,9 @@ static int tolua_collect_cItem (lua_State* tolua_S) return 0; } -static int tolua_collect_cFurnaceEntity (lua_State* tolua_S) +static int tolua_collect_Vector3f (lua_State* tolua_S) { - cFurnaceEntity* self = (cFurnaceEntity*) tolua_tousertype(tolua_S,1,0); + Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); Mtolua_delete(self); return 0; } @@ -144,9 +145,9 @@ static int tolua_collect_cPickup (lua_State* tolua_S) return 0; } -static int tolua_collect_sWebAdminPage (lua_State* tolua_S) +static int tolua_collect_cItems (lua_State* tolua_S) { - sWebAdminPage* self = (sWebAdminPage*) tolua_tousertype(tolua_S,1,0); + cItems* self = (cItems*) tolua_tousertype(tolua_S,1,0); Mtolua_delete(self); return 0; } @@ -172,9 +173,16 @@ static int tolua_collect_cBoundingBox (lua_State* tolua_S) return 0; } -static int tolua_collect_Vector3f (lua_State* tolua_S) +static int tolua_collect_sWebAdminPage (lua_State* tolua_S) { - Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); + sWebAdminPage* self = (sWebAdminPage*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + +static int tolua_collect_cHopperEntity (lua_State* tolua_S) +{ + cHopperEntity* self = (cHopperEntity*) tolua_tousertype(tolua_S,1,0); Mtolua_delete(self); return 0; } @@ -186,16 +194,16 @@ static int tolua_collect_Vector3i (lua_State* tolua_S) return 0; } -static int tolua_collect_cIniFile (lua_State* tolua_S) +static int tolua_collect_cFurnaceEntity (lua_State* tolua_S) { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + cFurnaceEntity* self = (cFurnaceEntity*) tolua_tousertype(tolua_S,1,0); Mtolua_delete(self); return 0; } -static int tolua_collect_cItems (lua_State* tolua_S) +static int tolua_collect_cIniFile (lua_State* tolua_S) { - cItems* self = (cItems*) tolua_tousertype(tolua_S,1,0); + cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); Mtolua_delete(self); return 0; } @@ -244,7 +252,7 @@ static void tolua_reg_types (lua_State* tolua_S) tolua_usertype(tolua_S,"cHTTPServer::cCallbacks"); tolua_usertype(tolua_S,"cLuaWindow"); tolua_usertype(tolua_S,"cInventory"); - tolua_usertype(tolua_S,"cBoundingBox"); + tolua_usertype(tolua_S,"cHopperEntity"); tolua_usertype(tolua_S,"cBlockEntityWithItems"); tolua_usertype(tolua_S,"cWindow"); tolua_usertype(tolua_S,"cGroup"); @@ -255,24 +263,24 @@ static void tolua_reg_types (lua_State* tolua_S) tolua_usertype(tolua_S,"cBlockArea"); tolua_usertype(tolua_S,"cTracer"); tolua_usertype(tolua_S,"cStringMap"); + tolua_usertype(tolua_S,"cBoundingBox"); tolua_usertype(tolua_S,"cServer"); - tolua_usertype(tolua_S,"Vector3i"); tolua_usertype(tolua_S,"cBlockEntity"); tolua_usertype(tolua_S,"cCriticalSection"); tolua_usertype(tolua_S,"HTTPTemplateRequest"); + tolua_usertype(tolua_S,"Vector3i"); tolua_usertype(tolua_S,"cFile"); tolua_usertype(tolua_S,"std::vector<std::string>"); tolua_usertype(tolua_S,"cClientHandle"); tolua_usertype(tolua_S,"cChatColor"); tolua_usertype(tolua_S,"cWebPlugin"); - tolua_usertype(tolua_S,"cWebAdmin"); tolua_usertype(tolua_S,"cIniFile"); + tolua_usertype(tolua_S,"cWebAdmin"); tolua_usertype(tolua_S,"sWebAdminPage"); - tolua_usertype(tolua_S,"cItem"); tolua_usertype(tolua_S,"cPawn"); tolua_usertype(tolua_S,"cPlayer"); tolua_usertype(tolua_S,"cGroupManager"); - tolua_usertype(tolua_S,"cBlockEntityWindowOwner"); + tolua_usertype(tolua_S,"cItem"); tolua_usertype(tolua_S,"HTTPRequest"); tolua_usertype(tolua_S,"cProjectileEntity"); tolua_usertype(tolua_S,"cItemGrid::cListener"); @@ -18309,23 +18317,6 @@ static int tolua_AllToLua_cDropSpenserEntity_SetRedstonePower00(lua_State* tolua } #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) -{ - cDropSpenserEntity* self = (cDropSpenserEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable '__cBlockEntityWindowOwner__'",NULL); -#endif -#ifdef __cplusplus - tolua_pushusertype(tolua_S,(void*)static_cast<cBlockEntityWindowOwner*>(self), "cBlockEntityWindowOwner"); -#else - tolua_pushusertype(tolua_S,(void*)((cBlockEntityWindowOwner*)self), "cBlockEntityWindowOwner"); -#endif - return 1; -} -#endif //#ifndef TOLUA_DISABLE - /* method: new of class cDispenserEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cDispenserEntity_new00 static int tolua_AllToLua_cDispenserEntity_new00(lua_State* tolua_S) @@ -18864,6 +18855,75 @@ static int tolua_AllToLua_cFurnaceEntity_HasFuelTimeLeft00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: new of class cHopperEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cHopperEntity_new00 +static int tolua_AllToLua_cHopperEntity_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cHopperEntity",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_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + 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)); + { + cHopperEntity* tolua_ret = (cHopperEntity*) Mtolua_new((cHopperEntity)(a_BlockX,a_BlockY,a_BlockZ)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cHopperEntity"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cHopperEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cHopperEntity_new00_local +static int tolua_AllToLua_cHopperEntity_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cHopperEntity",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_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + 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)); + { + cHopperEntity* tolua_ret = (cHopperEntity*) Mtolua_new((cHopperEntity)(a_BlockX,a_BlockY,a_BlockZ)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cHopperEntity"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* get function: Name of class HTTPFormData */ #ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Name static int tolua_get_HTTPFormData_Name(lua_State* tolua_S) @@ -19403,36 +19463,6 @@ static int tolua_AllToLua_cWebPlugin_SafeString00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* get function: m_PrimaryServerVersion of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_get_cRoot_m_PrimaryServerVersion -static int tolua_get_cRoot_m_PrimaryServerVersion(lua_State* tolua_S) -{ - cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PrimaryServerVersion'",NULL); -#endif - tolua_pushnumber(tolua_S,(lua_Number)self->m_PrimaryServerVersion); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: m_PrimaryServerVersion of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_set_cRoot_m_PrimaryServerVersion -static int tolua_set_cRoot_m_PrimaryServerVersion(lua_State* tolua_S) -{ - cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'm_PrimaryServerVersion'",NULL); - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->m_PrimaryServerVersion = ((int) tolua_tonumber(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - /* method: Get of class cRoot */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_Get00 static int tolua_AllToLua_cRoot_Get00(lua_State* tolua_S) @@ -29148,23 +29178,6 @@ static int tolua_AllToLua_cLuaWindow_GetContents00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* get function: __cItemGrid of class cLuaWindow */ -#ifndef TOLUA_DISABLE_tolua_get_cLuaWindow___cItemGrid__cListener__ -static int tolua_get_cLuaWindow___cItemGrid__cListener__(lua_State* tolua_S) -{ - cLuaWindow* self = (cLuaWindow*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable '__cItemGrid'",NULL); -#endif -#ifdef __cplusplus - tolua_pushusertype(tolua_S,(void*)static_cast<cItemGrid::cListener*>(self), "cItemGrid::cListener"); -#else - tolua_pushusertype(tolua_S,(void*)((cItemGrid::cListener*)self), "cItemGrid::cListener"); -#endif - return 1; -} -#endif //#ifndef TOLUA_DISABLE - /* method: GetMobType of class cMonster */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cMonster_GetMobType00 static int tolua_AllToLua_cMonster_GetMobType00(lua_State* tolua_S) @@ -30903,7 +30916,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) 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 tolua_cclass(tolua_S,"cDispenserEntity","cDispenserEntity","cDropSpenserEntity",tolua_collect_cDispenserEntity); @@ -30950,6 +30962,19 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetFuelBurnTimeLeft",tolua_AllToLua_cFurnaceEntity_GetFuelBurnTimeLeft00); tolua_function(tolua_S,"HasFuelTimeLeft",tolua_AllToLua_cFurnaceEntity_HasFuelTimeLeft00); tolua_endmodule(tolua_S); + #ifdef __cplusplus + tolua_cclass(tolua_S,"cHopperEntity","cHopperEntity","cBlockEntityWithItems",tolua_collect_cHopperEntity); + #else + tolua_cclass(tolua_S,"cHopperEntity","cHopperEntity","cBlockEntityWithItems",NULL); + #endif + tolua_beginmodule(tolua_S,"cHopperEntity"); + tolua_constant(tolua_S,"ContentsHeight",cHopperEntity::ContentsHeight); + tolua_constant(tolua_S,"ContentsWidth",cHopperEntity::ContentsWidth); + tolua_constant(tolua_S,"TICKS_PER_TRANSFER",cHopperEntity::TICKS_PER_TRANSFER); + tolua_function(tolua_S,"new",tolua_AllToLua_cHopperEntity_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cHopperEntity_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cHopperEntity_new00_local); + tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"HTTPFormData","HTTPFormData","",NULL); tolua_beginmodule(tolua_S,"HTTPFormData"); tolua_variable(tolua_S,"Name",tolua_get_HTTPFormData_Name,tolua_set_HTTPFormData_Name); @@ -30991,7 +31016,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cRoot","cRoot","",NULL); tolua_beginmodule(tolua_S,"cRoot"); - tolua_variable(tolua_S,"m_PrimaryServerVersion",tolua_get_cRoot_m_PrimaryServerVersion,tolua_set_cRoot_m_PrimaryServerVersion); tolua_function(tolua_S,"Get",tolua_AllToLua_cRoot_Get00); tolua_function(tolua_S,"GetServer",tolua_AllToLua_cRoot_GetServer00); tolua_function(tolua_S,"GetDefaultWorld",tolua_AllToLua_cRoot_GetDefaultWorld00); @@ -31400,7 +31424,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,".call",tolua_AllToLua_cLuaWindow_new00_local); tolua_function(tolua_S,"delete",tolua_AllToLua_cLuaWindow_delete00); tolua_function(tolua_S,"GetContents",tolua_AllToLua_cLuaWindow_GetContents00); - tolua_variable(tolua_S,"__cItemGrid__cListener__",tolua_get_cLuaWindow___cItemGrid__cListener__,NULL); tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cMonster","cMonster","cPawn",NULL); tolua_beginmodule(tolua_S,"cMonster"); diff --git a/source/Bindings.h b/source/Bindings.h index 510091198..620dbea84 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /*
** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on 10/21/13 13:17:20.
+** Generated automatically by tolua++-1.0.92 on 10/23/13 13:30:24.
*/
/* Exported function */
diff --git a/source/BlockEntities/DropSpenserEntity.h b/source/BlockEntities/DropSpenserEntity.h index f2f1eba36..0e9039915 100644 --- a/source/BlockEntities/DropSpenserEntity.h +++ b/source/BlockEntities/DropSpenserEntity.h @@ -29,10 +29,10 @@ class cServer; -// tolua_begin -class cDropSpenserEntity : - public cBlockEntityWithItems, - public cBlockEntityWindowOwner +class cDropSpenserEntity : // tolua_export + public cBlockEntityWindowOwner, + // tolua_begin + public cBlockEntityWithItems { typedef cBlockEntityWithItems super; diff --git a/source/BlockEntities/HopperEntity.h b/source/BlockEntities/HopperEntity.h index a49868660..1a7650581 100644 --- a/source/BlockEntities/HopperEntity.h +++ b/source/BlockEntities/HopperEntity.h @@ -38,15 +38,12 @@ public: /// Constructor used for normal operation cHopperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); - // tolua_begin - /** Returns the block coords of the block receiving the output items, based on the meta - Returns false if unattached + Returns false if unattached. + Exported in ManualBindings.cpp */ bool GetOutputBlockPos(NIBBLETYPE a_BlockMeta, int & a_OutputX, int & a_OutputY, int & a_OutputZ); - // tolua_end - static const char * GetClassStatic(void) { return "cHopperEntity"; } protected: @@ -95,7 +92,7 @@ protected: /// Moves one piece to the specified entity's contents' slot. Returns true if contents have changed. bool MoveItemsToSlot(cBlockEntityWithItems & a_Entity, int a_DstSlotNum); -} ; +} ; // tolua_export diff --git a/source/Chunk.cpp b/source/Chunk.cpp index 2e81bf852..e4e5a7ca1 100644 --- a/source/Chunk.cpp +++ b/source/Chunk.cpp @@ -1065,45 +1065,14 @@ bool cChunk::UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE 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); - 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->UnboundedRelGetBlock(a_RelX + cChunkDef::Width, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - } - if ((a_RelX >= cChunkDef::Width) && (m_NeighborXP != NULL)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - return m_NeighborXP->UnboundedRelGetBlock(a_RelX - cChunkDef::Width, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - } - if ((a_RelZ < 0) && (m_NeighborZM != NULL)) - { - return m_NeighborZM->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ + cChunkDef::Width, a_BlockType, a_BlockMeta); - } - if ((a_RelZ >= cChunkDef::Width) && (m_NeighborZP != NULL)) - { - return m_NeighborZP->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ - cChunkDef::Width, a_BlockType, a_BlockMeta); + // The chunk is not available, bail out + return false; } - - // Neighbors not available, use the chunkmap to locate the chunk: - return m_ChunkMap->LockedGetBlock( - m_PosX * cChunkDef::Width + a_RelX, - ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, - m_PosZ * cChunkDef::Width + a_RelZ, - a_BlockType, a_BlockMeta - ); + Chunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); + return true; } @@ -1117,44 +1086,14 @@ bool cChunk::UnboundedRelGetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKT 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)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - return m_NeighborZP->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ - cChunkDef::Width, a_BlockType); + // The chunk is not available, bail out + return false; } - - // 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 - ); + a_BlockType = Chunk->GetBlock(a_RelX, a_RelY, a_RelZ); + return true; } @@ -1168,44 +1107,56 @@ bool cChunk::UnboundedRelGetBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLE 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)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - if (!IsValid()) - { - return false; - } - int BlockIdx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); - a_BlockMeta = GetMeta(BlockIdx); - return true; + // The chunk is not available, bail out + return false; } + a_BlockMeta = Chunk->GetMeta(a_RelX, a_RelY, a_RelZ); + return true; +} + + + - // Not in this chunk, try walking the neighbors first: - if ((a_RelX < 0) && (m_NeighborXM != NULL)) + +bool cChunk::UnboundedRelGetBlockBlockLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockBlockLight) const +{ + if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height)) { - return m_NeighborXM->UnboundedRelGetBlockMeta(a_RelX + cChunkDef::Width, a_RelY, a_RelZ, a_BlockMeta); + LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelY); + return false; } - if ((a_RelX >= cChunkDef::Width) && (m_NeighborXP != NULL)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - return m_NeighborXP->UnboundedRelGetBlockMeta(a_RelX - cChunkDef::Width, a_RelY, a_RelZ, a_BlockMeta); + // The chunk is not available, bail out + return false; } - if ((a_RelZ < 0) && (m_NeighborZM != NULL)) + a_BlockBlockLight = Chunk->GetBlockLight(a_RelX, a_RelY, a_RelZ); + return true; +} + + + + + +bool cChunk::UnboundedRelGetBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockSkyLight) const +{ + if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height)) { - return m_NeighborZM->UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ + cChunkDef::Width, a_BlockMeta); + LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelY); + return false; } - if ((a_RelZ >= cChunkDef::Width) && (m_NeighborZP != NULL)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - return m_NeighborZP->UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ - cChunkDef::Width, a_BlockMeta); + // The chunk is not available, bail out + return false; } - - // 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 - ); + a_BlockSkyLight = Chunk->GetSkyLight(a_RelX, a_RelY, a_RelZ); + return true; } @@ -1219,44 +1170,15 @@ bool cChunk::UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE LOGWARNING("UnboundedRelSetBlock(): requesting a block with a_RelY out of range: %d", 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; - } - SetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - return true; - } - - // Not in this chunk, try walking the neighbors first: - if ((a_RelX < 0) && (m_NeighborXM != NULL)) - { - return m_NeighborXM->UnboundedRelSetBlock(a_RelX + cChunkDef::Width, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - } - if ((a_RelX >= cChunkDef::Width) && (m_NeighborXP != NULL)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - return m_NeighborXP->UnboundedRelSetBlock(a_RelX - cChunkDef::Width, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - } - if ((a_RelZ < 0) && (m_NeighborZM != NULL)) - { - return m_NeighborZM->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ + cChunkDef::Width, a_BlockType, a_BlockMeta); - } - if ((a_RelZ >= cChunkDef::Width) && (m_NeighborZP != NULL)) - { - return m_NeighborZP->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ - cChunkDef::Width, a_BlockType, a_BlockMeta); + // The chunk is not available, bail out + return false; } - - // Neighbors not available, use the chunkmap to locate the chunk: - return m_ChunkMap->LockedSetBlock( - m_PosX * cChunkDef::Width + a_RelX, - ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, - m_PosZ * cChunkDef::Width + a_RelZ, - a_BlockType, a_BlockMeta - ); -} + Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); + return true; +} @@ -1269,43 +1191,14 @@ bool cChunk::UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKT LOGWARNING("UnboundedRelFastSetBlock(): requesting a block with a_RelY out of range: %d", 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; - } - FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - return true; - } - - // Not in this chunk, try walking the neighbors first: - if ((a_RelX < 0) && (m_NeighborXM != NULL)) - { - return m_NeighborXM->UnboundedRelFastSetBlock(a_RelX + cChunkDef::Width, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - } - if ((a_RelX >= cChunkDef::Width) && (m_NeighborXP != NULL)) - { - return m_NeighborXP->UnboundedRelFastSetBlock(a_RelX - cChunkDef::Width, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - } - if ((a_RelZ < 0) && (m_NeighborZM != NULL)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - return m_NeighborZM->UnboundedRelFastSetBlock(a_RelX, a_RelY, a_RelZ + cChunkDef::Width, a_BlockType, a_BlockMeta); - } - if ((a_RelZ >= cChunkDef::Width) && (m_NeighborZP != NULL)) - { - return m_NeighborZP->UnboundedRelFastSetBlock(a_RelX, a_RelY, a_RelZ - cChunkDef::Width, a_BlockType, a_BlockMeta); + // The chunk is not available, bail out + return false; } - - // Neighbors not available, use the chunkmap to locate the chunk: - return m_ChunkMap->LockedFastSetBlock( - m_PosX * cChunkDef::Width + a_RelX, - ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, - m_PosZ * cChunkDef::Width + a_RelZ, - a_BlockType, a_BlockMeta - ); + Chunk->FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); + return true; } @@ -1319,44 +1212,18 @@ void cChunk::UnboundedQueueTickBlock(int a_RelX, int a_RelY, int a_RelZ) // Outside of chunkmap return; } - - // Is it in this chunk? - if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) - { - QueueTickBlock(a_RelX, a_RelY, a_RelZ); - return; - } - - // Not in this chunk, try walking the neighbors first: - if ((a_RelX < 0) && (m_NeighborXM != NULL)) - { - m_NeighborXM->UnboundedQueueTickBlock(a_RelX + cChunkDef::Width, a_RelY, a_RelZ); - return; - } - if ((a_RelX >= cChunkDef::Width) && (m_NeighborXP != NULL)) - { - m_NeighborXP->UnboundedQueueTickBlock(a_RelX - cChunkDef::Width, a_RelY, a_RelZ); - return; - } - if ((a_RelZ < 0) && (m_NeighborZM != NULL)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk != NULL) && Chunk->IsValid()) { - m_NeighborZM->UnboundedQueueTickBlock(a_RelX, a_RelY, a_RelZ + cChunkDef::Width); - return; - } - if ((a_RelZ >= cChunkDef::Width) && (m_NeighborZP != NULL)) - { - m_NeighborZP->UnboundedQueueTickBlock(a_RelX, a_RelY, a_RelZ - cChunkDef::Width); - return; + Chunk->QueueTickBlock(a_RelX, a_RelY, a_RelZ); } - - // Neighbors not available, ignore altogether } -int cChunk::GetHeight( int a_X, int a_Z ) +int cChunk::GetHeight(int a_X, int a_Z) { ASSERT((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width)); @@ -2482,66 +2349,58 @@ cChunk * cChunk::GetRelNeighborChunk(int a_RelX, int a_RelZ) -cChunk * cChunk::GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ) +cChunk * cChunk::GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ) const { - bool ReturnThis = true; - int RelX = a_RelX; + cChunk * ToReturn = const_cast<cChunk *>(this); + + // The most common case: inside this chunk: + if ( + (a_RelX >= 0) && (a_RelX < Width) && + (a_RelZ >= 0) && (a_RelZ < Width) + ) + { + return ToReturn; + } + + // Request for a different chunk, calculate chunk offset: + int RelX = a_RelX; // Make a local copy of the coords (faster access) int RelZ = a_RelZ; - if (a_RelX < 0) + while ((RelX >= Width) && (ToReturn != NULL)) { - if (m_NeighborXM != NULL) - { - RelX = a_RelX + cChunkDef::Width; - cChunk * Candidate = m_NeighborXM->GetRelNeighborChunkAdjustCoords(RelX, RelZ); - if (Candidate != NULL) - { - a_RelX = RelX; - a_RelZ = RelZ; - return Candidate; - } - } - // Going X-first failed, but if the request is crossing Z as well, let's try the Z-first later on. - ReturnThis = false; + RelX -= Width; + ToReturn = ToReturn->m_NeighborXP; } - else if (a_RelX >= cChunkDef::Width) + while ((RelX < 0) && (ToReturn != NULL)) { - if (m_NeighborXP != NULL) - { - RelX = a_RelX - cChunkDef::Width; - cChunk * Candidate = m_NeighborXP->GetRelNeighborChunkAdjustCoords(RelX, RelZ); - if (Candidate != NULL) - { - a_RelX = RelX; - a_RelZ = RelZ; - return Candidate; - } - } - // Going X-first failed, but if the request is crossing Z as well, let's try the Z-first later on. - ReturnThis = false; + RelX += Width; + ToReturn = ToReturn->m_NeighborXM; } - - if (a_RelZ < 0) + while ((RelZ >= Width) && (ToReturn != NULL)) { - if (m_NeighborZM != NULL) - { - a_RelZ += cChunkDef::Width; - return m_NeighborZM->GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - // For requests crossing both X and Z, the X-first way has been already tried - } - return NULL; + RelZ -= Width; + ToReturn = ToReturn->m_NeighborZP; } - else if (a_RelZ >= cChunkDef::Width) + while ((RelZ < 0) && (ToReturn != NULL)) { - if (m_NeighborZP != NULL) - { - a_RelZ -= cChunkDef::Width; - return m_NeighborZP->GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - // For requests crossing both X and Z, the X-first way has been already tried - } - return NULL; + RelZ += Width; + ToReturn = ToReturn->m_NeighborZM; + } + if (ToReturn != NULL) + { + a_RelX = RelX; + a_RelZ = RelZ; + return ToReturn; } - return (ReturnThis ? this : NULL); + // The chunk cannot be walked through neighbors, find it through the chunkmap: + int AbsX = a_RelX + m_PosX * Width; + int AbsZ = a_RelZ + m_PosZ * Width; + int DstChunkX, DstChunkZ; + BlockToChunk(AbsX, AbsZ, DstChunkX, DstChunkZ); + ToReturn = m_ChunkMap->FindChunk(DstChunkX, DstChunkZ); + a_RelX = AbsX - DstChunkX * Width; + a_RelZ = AbsZ - DstChunkZ * Width; + return ToReturn; } diff --git a/source/Chunk.h b/source/Chunk.h index 2fa4a7a67..2aac78354 100644 --- a/source/Chunk.h +++ b/source/Chunk.h @@ -171,11 +171,12 @@ public: cChunk * GetRelNeighborChunk(int a_RelX, int a_RelZ); /** - Returns the chunk into which the relatively-specified block belongs, by walking the neighbors. + Returns the chunk into which the relatively-specified block belongs. Also modifies the relative coords from this-relative to return-relative. - Will return self if appropriate. Returns NULL if not reachable through neighbors. + Will return self if appropriate. + Will try walking the neighbors first; if that fails, will query the chunkmap */ - cChunk * GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ); + cChunk * GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ) const; EMCSBiome GetBiomeAt(int a_RelX, int a_RelZ) const {return cChunkDef::GetBiome(m_BiomeMap, a_RelX, a_RelZ); } @@ -299,19 +300,25 @@ public: inline NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const {return cChunkDef::GetNibble(m_BlockLight, a_RelX, a_RelY, a_RelZ); } inline NIBBLETYPE GetSkyLight (int a_RelX, int a_RelY, int a_RelZ) const {return cChunkDef::GetNibble(m_BlockSkyLight, a_RelX, a_RelY, a_RelZ); } - /// 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() + /// 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 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() + /// 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 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() + /// 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 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() + /// Same as GetBlockBlockLight(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success + bool UnboundedRelGetBlockBlockLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockLight) const; + + /// Same as GetBlockSkyLight(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success + bool UnboundedRelGetBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_SkyLight) 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 bool UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - /// Same as FastSetBlock(), 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() + /// Same as FastSetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success bool UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); /// Same as QueueTickBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s in such a case), ignores unsuccessful attempts diff --git a/source/ChunkDef.h b/source/ChunkDef.h index 9db88f293..d6630df7e 100644 --- a/source/ChunkDef.h +++ b/source/ChunkDef.h @@ -208,10 +208,15 @@ public: inline static unsigned int MakeIndex(int x, int y, int z ) { - if( x < cChunkDef::Width && x > -1 && y < cChunkDef::Height && y > -1 && z < cChunkDef::Width && z > -1 ) + if ( + (x < Width) && (x > -1) && + (y < Height) && (y > -1) && + (z < Width) && (z > -1) + ) { return MakeIndexNoCheck(x, y, z); } + ASSERT(!"cChunkDef::MakeIndex(): coords out of chunk range!"); return INDEX_OUT_OF_RANGE; } @@ -256,6 +261,7 @@ public: inline static void SetBlock(BLOCKTYPE * a_BlockTypes, int a_Index, BLOCKTYPE a_Type) { + ASSERT((a_Index >= 0) && (a_Index <= NumBlocks)); a_BlockTypes[a_Index] = a_Type; } @@ -271,41 +277,50 @@ public: inline static BLOCKTYPE GetBlock(const BLOCKTYPE * a_BlockTypes, int a_Idx) { - ASSERT((a_Idx >= 0) && (a_Idx < Width * Width * Height)); + ASSERT((a_Idx >= 0) && (a_Idx < NumBlocks)); return a_BlockTypes[a_Idx]; } inline static int GetHeight(const HeightMap & a_HeightMap, int a_X, int a_Z) { + ASSERT((a_X >= 0) && (a_X <= Width)); + ASSERT((a_Z >= 0) && (a_Z <= Width)); return a_HeightMap[a_X + Width * a_Z]; } inline static void SetHeight(HeightMap & a_HeightMap, int a_X, int a_Z, unsigned char a_Height) { + ASSERT((a_X >= 0) && (a_X <= Width)); + ASSERT((a_Z >= 0) && (a_Z <= Width)); a_HeightMap[a_X + Width * a_Z] = a_Height; } inline static EMCSBiome GetBiome(const BiomeMap & a_BiomeMap, int a_X, int a_Z) { + ASSERT((a_X >= 0) && (a_X <= Width)); + ASSERT((a_Z >= 0) && (a_Z <= Width)); return a_BiomeMap[a_X + Width * a_Z]; } inline static void SetBiome(BiomeMap & a_BiomeMap, int a_X, int a_Z, EMCSBiome a_Biome) { + ASSERT((a_X >= 0) && (a_X <= Width)); + ASSERT((a_Z >= 0) && (a_Z <= Width)); a_BiomeMap[a_X + Width * a_Z] = a_Biome; } static NIBBLETYPE GetNibble(const NIBBLETYPE * a_Buffer, int a_BlockIdx) { - if ((a_BlockIdx > -1) && (a_BlockIdx < cChunkDef::NumBlocks)) + if ((a_BlockIdx > -1) && (a_BlockIdx < NumBlocks)) { return (a_Buffer[a_BlockIdx / 2] >> ((a_BlockIdx & 1) * 4)) & 0x0f; } + ASSERT(!"cChunkDef::GetNibble(): index out of chunk range!"); return 0; } @@ -317,38 +332,48 @@ public: int Index = MakeIndexNoCheck(x, y, z); return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f; } + ASSERT(!"cChunkDef::GetNibble(): coords out of chunk range!"); return 0; } static void SetNibble(NIBBLETYPE * a_Buffer, int a_BlockIdx, NIBBLETYPE a_Nibble) { - if ((a_BlockIdx > -1) && (a_BlockIdx < cChunkDef::NumBlocks)) + if ((a_BlockIdx < 0) || (a_BlockIdx >= NumBlocks)) { - a_Buffer[a_BlockIdx / 2] = ( - (a_Buffer[a_BlockIdx / 2] & (0xf0 >> ((a_BlockIdx & 1) * 4))) | // The untouched nibble - ((a_Nibble & 0x0f) << ((a_BlockIdx & 1) * 4)) // The nibble being set - ); + ASSERT(!"cChunkDef::SetNibble(): index out of range!"); + return; } + a_Buffer[a_BlockIdx / 2] = ( + (a_Buffer[a_BlockIdx / 2] & (0xf0 >> ((a_BlockIdx & 1) * 4))) | // The untouched nibble + ((a_Nibble & 0x0f) << ((a_BlockIdx & 1) * 4)) // The nibble being set + ); } static void SetNibble(NIBBLETYPE * a_Buffer, int x, int y, int z, NIBBLETYPE a_Nibble) { - if ((x < cChunkDef::Width) && (x > -1) && (y < cChunkDef::Height) && (y > -1) && (z < cChunkDef::Width) && (z > -1)) + if ( + (x >= Width) || (x < 0) || + (y >= Height) || (y < 0) || + (z >= Width) || (z < 0) + ) { - int Index = MakeIndexNoCheck(x, y, z); - a_Buffer[Index / 2] = ( - (a_Buffer[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble - ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set - ); + ASSERT(!"cChunkDef::SetNibble(): index out of range!"); + return; } + + int Index = MakeIndexNoCheck(x, y, z); + a_Buffer[Index / 2] = ( + (a_Buffer[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble + ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set + ); } inline static char GetNibble(const NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos ) { - return GetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); + return GetNibble(a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); } diff --git a/source/LuaWindow.h b/source/LuaWindow.h index 5a0685ebb..4c32c263e 100644 --- a/source/LuaWindow.h +++ b/source/LuaWindow.h @@ -23,8 +23,6 @@ class cPluginLua; -// tolua_begin - /** A window that has been created by a Lua plugin and is handled entirely by that plugin This object needs extra care with its lifetime management: - It is created by Lua, so Lua expects to garbage-collect it later @@ -35,9 +33,10 @@ Additionally, to forbid Lua from deleting this object while it is used by player cPlayer:OpenWindow check if the window is of this class, and if so, make a global Lua reference for this object. This reference needs to be unreferenced in the Destroy() function. */ -class cLuaWindow : - public cWindow, - public cItemGrid::cListener +class cLuaWindow : // tolua_export + public cItemGrid::cListener, + // tolua_begin + public cWindow { typedef cWindow super; diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index e6605ddb0..466701bf8 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -17,6 +17,7 @@ #include "BlockEntities/DispenserEntity.h" #include "BlockEntities/DropperEntity.h" #include "BlockEntities/FurnaceEntity.h" +#include "BlockEntities/HopperEntity.h" #include "md5/md5.h" #include "LuaWindow.h" #include "LineBlockTracer.h" @@ -2059,6 +2060,45 @@ static int tolua_cLineBlockTracer_Trace(lua_State * tolua_S) +static int tolua_cHopperEntity_GetOutputBlockPos(lua_State * tolua_S) +{ + // function cHopperEntity::GetOutputBlockPos() + // Exported manually because tolua would require meaningless params + + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cHopperEntity") || + !L.CheckParamNumber (2) || + !L.CheckParamEnd (3) + ) + { + return 0; + } + cHopperEntity * self = (cHopperEntity *)tolua_tousertype(tolua_S, 1, 0); + if (self == NULL) + { + tolua_error(tolua_S, "invalid 'self' in function 'cHopperEntity::GetOutputBlockPos()'", NULL); + return 0; + } + + NIBBLETYPE a_BlockMeta = ((NIBBLETYPE)tolua_tonumber(tolua_S, 2, 0)); + int a_OutputX, a_OutputY, a_OutputZ; + bool res = self->GetOutputBlockPos(a_BlockMeta, a_OutputX, a_OutputY, a_OutputZ); + tolua_pushboolean(tolua_S, res); + if (res) + { + tolua_pushnumber(tolua_S, (lua_Number)a_OutputX); + tolua_pushnumber(tolua_S, (lua_Number)a_OutputY); + tolua_pushnumber(tolua_S, (lua_Number)a_OutputZ); + return 4; + } + return 1; +} + + + + + void ManualBindings::Bind(lua_State * tolua_S) { tolua_beginmodule(tolua_S, NULL); @@ -2070,6 +2110,10 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "LOGWARNING", tolua_LOGWARN); tolua_function(tolua_S, "LOGERROR", tolua_LOGERROR); + tolua_beginmodule(tolua_S, "cHopperEntity"); + tolua_function(tolua_S, "GetOutputBlockPos", tolua_cHopperEntity_GetOutputBlockPos); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S, "cLineBlockTracer"); tolua_function(tolua_S, "Trace", tolua_cLineBlockTracer_Trace); tolua_endmodule(tolua_S); diff --git a/source/Mobs/Monster.cpp b/source/Mobs/Monster.cpp index 599aa9cfc..7e35b97f1 100644 --- a/source/Mobs/Monster.cpp +++ b/source/Mobs/Monster.cpp @@ -718,8 +718,8 @@ void cMonster::HandleDaylightBurning(cChunk & a_Chunk) return; } - int RelX = (int)floor(GetPosX()) - a_Chunk.GetPosX() * cChunkDef::Width; - int RelZ = (int)floor(GetPosZ()) - a_Chunk.GetPosZ() * cChunkDef::Width; + int RelX = (int)floor(GetPosX()) - GetChunkX() * cChunkDef::Width; + int RelZ = (int)floor(GetPosZ()) - GetChunkZ() * cChunkDef::Width; if ( (a_Chunk.GetSkyLight(RelX, RelY, RelZ) == 15) && // In the daylight (a_Chunk.GetBlock(RelX, RelY, RelZ) != E_BLOCK_SOULSAND) && // Not on soulsand diff --git a/source/Protocol/ProtocolRecognizer.cpp b/source/Protocol/ProtocolRecognizer.cpp index fe99b22e1..ceada1944 100644 --- a/source/Protocol/ProtocolRecognizer.cpp +++ b/source/Protocol/ProtocolRecognizer.cpp @@ -727,7 +727,7 @@ bool cProtocolRecognizer::TryRecognizeProtocol(void) void cProtocolRecognizer::HandleServerPing(void) { AString Reply; - switch (cRoot::Get()->m_PrimaryServerVersion) + switch (cRoot::Get()->GetPrimaryServerVersion()) { case PROTO_VERSION_1_2_5: case PROTO_VERSION_1_3_2: @@ -771,8 +771,8 @@ void cProtocolRecognizer::HandleServerPing(void) Printf(MaxPlayers, "%d", cRoot::Get()->GetServer()->GetMaxPlayers()); AString ProtocolVersionNum; - Printf(ProtocolVersionNum, "%d", cRoot::Get()->m_PrimaryServerVersion); - AString ProtocolVersionTxt(GetVersionTextFromInt(cRoot::Get()->m_PrimaryServerVersion)); + Printf(ProtocolVersionNum, "%d", cRoot::Get()->GetPrimaryServerVersion()); + AString ProtocolVersionTxt(GetVersionTextFromInt(cRoot::Get()->GetPrimaryServerVersion())); // Cannot use Printf() because of in-string NUL bytes. Reply = cChatColor::Delimiter; diff --git a/source/Root.h b/source/Root.h index 2b15d3461..c05b29d14 100644 --- a/source/Root.h +++ b/source/Root.h @@ -32,10 +32,7 @@ typedef cItemCallback<cWorld> cWorldListCallback; class cRoot // tolua_export { // tolua_export public: - /// The version of the protocol that is primary for the server (reported in the server list). All versions are still supported. - int m_PrimaryServerVersion; // tolua_export - - static cRoot* Get() { return s_Root; } // tolua_export + static cRoot * Get() { return s_Root; } // tolua_export cRoot(void); ~cRoot(); @@ -55,7 +52,7 @@ public: int GetPrimaryServerVersion(void) const { return m_PrimaryServerVersion; } // tolua_export void SetPrimaryServerVersion(int a_Version) { m_PrimaryServerVersion = a_Version; } // tolua_export - cMonsterConfig * GetMonsterConfig() { return m_MonsterConfig; } + cMonsterConfig * GetMonsterConfig(void) { return m_MonsterConfig; } cGroupManager * GetGroupManager (void) { return m_GroupManager; } // tolua_export cCraftingRecipes * GetCraftingRecipes(void) { return m_CraftingRecipes; } // tolua_export @@ -135,6 +132,9 @@ private: typedef std::map<AString, cWorld *> WorldMap; typedef std::vector<cCommand> cCommandQueue; + /// The version of the protocol that is primary for the server (reported in the server list). All versions are still supported. + int m_PrimaryServerVersion; + cWorld * m_pDefaultWorld; WorldMap m_WorldsByName; diff --git a/source/World.cpp b/source/World.cpp index d1ddb0e6e..a61c19d63 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -736,6 +736,9 @@ void cWorld::TickWeather(float a_Dt) void cWorld::TickMobs(float a_Dt) { + // _X 2013_10_22: This is a quick fix for #283 - the world needs to be locked while ticking mobs + cWorld::cLock Lock(*this); + // before every Mob action, we have to count them depending on the distance to players, on their family ... cMobCensus MobCensus; m_ChunkMap->CollectMobCensus(MobCensus); |