summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-06-17 21:58:39 +0200
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-06-17 21:58:39 +0200
commite5fdc133bc6e03c4e8e1f1707ff13f4c836d2b8d (patch)
treed13286487b7d74dc3c56cf3c529909e31f00b8ff
parentLogs completion of chunk saving (FS #215) (diff)
downloadcuberite-e5fdc133bc6e03c4e8e1f1707ff13f4c836d2b8d.tar
cuberite-e5fdc133bc6e03c4e8e1f1707ff13f4c836d2b8d.tar.gz
cuberite-e5fdc133bc6e03c4e8e1f1707ff13f4c836d2b8d.tar.bz2
cuberite-e5fdc133bc6e03c4e8e1f1707ff13f4c836d2b8d.tar.lz
cuberite-e5fdc133bc6e03c4e8e1f1707ff13f4c836d2b8d.tar.xz
cuberite-e5fdc133bc6e03c4e8e1f1707ff13f4c836d2b8d.tar.zst
cuberite-e5fdc133bc6e03c4e8e1f1707ff13f4c836d2b8d.zip
-rw-r--r--source/Bindings.cpp67
-rw-r--r--source/Bindings.h2
-rw-r--r--source/ManualBindings.cpp16
-rw-r--r--source/cChunk.cpp154
-rw-r--r--source/cChunk.h21
-rw-r--r--source/cChunkMap.cpp84
-rw-r--r--source/cChunkMap.h21
-rw-r--r--source/cWorld.cpp55
-rw-r--r--source/cWorld.h28
9 files changed, 396 insertions, 52 deletions
diff --git a/source/Bindings.cpp b/source/Bindings.cpp
index 643be25ce..f7aca5c8f 100644
--- a/source/Bindings.cpp
+++ b/source/Bindings.cpp
@@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on 06/16/12 20:12:04.
+** Generated automatically by tolua++-1.0.92 on 06/17/12 20:43:06.
*/
#ifndef __cplusplus
@@ -174,24 +174,23 @@ static int tolua_collect_Vector3d (lua_State* tolua_S)
static void tolua_reg_types (lua_State* tolua_S)
{
tolua_usertype(tolua_S,"BLOCKTYPE");
- tolua_usertype(tolua_S,"cLuaItems");
tolua_usertype(tolua_S,"TakeDamageInfo");
- tolua_usertype(tolua_S,"HTTPFormData");
- tolua_usertype(tolua_S,"cCraftingGrid");
+ tolua_usertype(tolua_S,"cLuaItems");
tolua_usertype(tolua_S,"cLuaChunk");
+ tolua_usertype(tolua_S,"cCraftingGrid");
tolua_usertype(tolua_S,"cCraftingRecipe");
tolua_usertype(tolua_S,"cPlugin");
- tolua_usertype(tolua_S,"Lua__cPacket_BlockDig");
+ tolua_usertype(tolua_S,"cPluginManager");
tolua_usertype(tolua_S,"NIBBLETYPE");
- tolua_usertype(tolua_S,"cCraftingRecipes");
+ tolua_usertype(tolua_S,"Lua__cPacket_BlockDig");
tolua_usertype(tolua_S,"cTCPLink");
- tolua_usertype(tolua_S,"cCuboid");
+ tolua_usertype(tolua_S,"Lua__cTCPLink");
tolua_usertype(tolua_S,"Json::Value");
tolua_usertype(tolua_S,"cServer");
tolua_usertype(tolua_S,"cRoot");
+ tolua_usertype(tolua_S,"cMCLogger");
tolua_usertype(tolua_S,"cGroup");
tolua_usertype(tolua_S,"cTracer");
- tolua_usertype(tolua_S,"cMCLogger");
tolua_usertype(tolua_S,"cPlugin::CommandStruct");
tolua_usertype(tolua_S,"cPickup");
tolua_usertype(tolua_S,"cItems");
@@ -199,13 +198,13 @@ static void tolua_reg_types (lua_State* tolua_S)
tolua_usertype(tolua_S,"cClientHandle");
tolua_usertype(tolua_S,"cStep");
tolua_usertype(tolua_S,"cFurnaceRecipe");
- tolua_usertype(tolua_S,"Vector3i");
+ tolua_usertype(tolua_S,"cCuboid");
tolua_usertype(tolua_S,"cChatColor");
- tolua_usertype(tolua_S,"cStairs");
+ tolua_usertype(tolua_S,"Vector3i");
tolua_usertype(tolua_S,"cPacket_PickupSpawn");
tolua_usertype(tolua_S,"Lua__cWebPlugin");
tolua_usertype(tolua_S,"Lua__cPawn");
- tolua_usertype(tolua_S,"Lua__cTCPLink");
+ tolua_usertype(tolua_S,"cStairs");
tolua_usertype(tolua_S,"cItem");
tolua_usertype(tolua_S,"Vector3f");
tolua_usertype(tolua_S,"cPlugin_Lua");
@@ -214,15 +213,15 @@ static void tolua_reg_types (lua_State* tolua_S)
tolua_usertype(tolua_S,"cPacket");
tolua_usertype(tolua_S,"cPacket_BlockDig");
tolua_usertype(tolua_S,"cWebAdmin");
+ tolua_usertype(tolua_S,"cCraftingRecipes");
tolua_usertype(tolua_S,"cGroupManager");
- tolua_usertype(tolua_S,"cBlockEntity");
tolua_usertype(tolua_S,"Lua__cPickup");
tolua_usertype(tolua_S,"cWebPlugin");
tolua_usertype(tolua_S,"Lua__cPlugin");
- tolua_usertype(tolua_S,"cInventory");
+ tolua_usertype(tolua_S,"cStringMap");
tolua_usertype(tolua_S,"cPacket_BlockPlace");
tolua_usertype(tolua_S,"cLadder");
- tolua_usertype(tolua_S,"cPluginManager");
+ tolua_usertype(tolua_S,"HTTPFormData");
tolua_usertype(tolua_S,"Lua__cPlayer");
tolua_usertype(tolua_S,"cIniFile");
tolua_usertype(tolua_S,"cEntity");
@@ -230,7 +229,7 @@ static void tolua_reg_types (lua_State* tolua_S)
tolua_usertype(tolua_S,"cPawn");
tolua_usertype(tolua_S,"cPlayer");
tolua_usertype(tolua_S,"cTorch");
- tolua_usertype(tolua_S,"cStringMap");
+ tolua_usertype(tolua_S,"cInventory");
tolua_usertype(tolua_S,"cWorld");
tolua_usertype(tolua_S,"cPlugin_NewLua");
tolua_usertype(tolua_S,"cVine");
@@ -11468,9 +11467,9 @@ static int tolua_AllToLua_cWorld_GetSpawnZ00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
-/* method: GetBlockEntity of class cWorld */
-#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockEntity00
-static int tolua_AllToLua_cWorld_GetBlockEntity00(lua_State* tolua_S)
+/* method: GetSignLines of class cWorld */
+#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSignLines00
+static int tolua_AllToLua_cWorld_GetSignLines00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
@@ -11479,28 +11478,40 @@ static int tolua_AllToLua_cWorld_GetBlockEntity00(lua_State* tolua_S)
!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)
+ !tolua_iscppstring(tolua_S,5,0,&tolua_err) ||
+ !tolua_iscppstring(tolua_S,6,0,&tolua_err) ||
+ !tolua_iscppstring(tolua_S,7,0,&tolua_err) ||
+ !tolua_iscppstring(tolua_S,8,0,&tolua_err) ||
+ !tolua_isnoobj(tolua_S,9,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
- int a_X = ((int) tolua_tonumber(tolua_S,2,0));
- int a_Y = ((int) tolua_tonumber(tolua_S,3,0));
- int a_Z = ((int) tolua_tonumber(tolua_S,4,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));
+ AString a_Line1 = ((AString) tolua_tocppstring(tolua_S,5,0));
+ AString a_Line2 = ((AString) tolua_tocppstring(tolua_S,6,0));
+ AString a_Line3 = ((AString) tolua_tocppstring(tolua_S,7,0));
+ AString a_Line4 = ((AString) tolua_tocppstring(tolua_S,8,0));
#ifndef TOLUA_RELEASE
- if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockEntity'", NULL);
+ if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSignLines'", NULL);
#endif
{
- OBSOLETE cBlockEntity* tolua_ret = (OBSOLETE cBlockEntity*) self->GetBlockEntity(a_X,a_Y,a_Z);
- tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBlockEntity");
+ bool tolua_ret = (bool) self->GetSignLines(a_BlockX,a_BlockY,a_BlockZ,a_Line1,a_Line2,a_Line3,a_Line4);
+ tolua_pushboolean(tolua_S,(bool)tolua_ret);
+ tolua_pushcppstring(tolua_S,(const char*)a_Line1);
+ tolua_pushcppstring(tolua_S,(const char*)a_Line2);
+ tolua_pushcppstring(tolua_S,(const char*)a_Line3);
+ tolua_pushcppstring(tolua_S,(const char*)a_Line4);
}
}
- return 1;
+ return 5;
#ifndef TOLUA_RELEASE
tolua_lerror:
- tolua_error(tolua_S,"#ferror in function 'GetBlockEntity'.",&tolua_err);
+ tolua_error(tolua_S,"#ferror in function 'GetSignLines'.",&tolua_err);
return 0;
#endif
}
@@ -21324,7 +21335,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"GetSpawnX",tolua_AllToLua_cWorld_GetSpawnX00);
tolua_function(tolua_S,"GetSpawnY",tolua_AllToLua_cWorld_GetSpawnY00);
tolua_function(tolua_S,"GetSpawnZ",tolua_AllToLua_cWorld_GetSpawnZ00);
- tolua_function(tolua_S,"GetBlockEntity",tolua_AllToLua_cWorld_GetBlockEntity00);
+ tolua_function(tolua_S,"GetSignLines",tolua_AllToLua_cWorld_GetSignLines00);
tolua_function(tolua_S,"GrowTree",tolua_AllToLua_cWorld_GrowTree00);
tolua_function(tolua_S,"GrowTreeFromSapling",tolua_AllToLua_cWorld_GrowTreeFromSapling00);
tolua_function(tolua_S,"GrowTreeByBiome",tolua_AllToLua_cWorld_GrowTreeByBiome00);
diff --git a/source/Bindings.h b/source/Bindings.h
index a9be7791c..d1ed4b132 100644
--- a/source/Bindings.h
+++ b/source/Bindings.h
@@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on 06/16/12 20:12:05.
+** Generated automatically by tolua++-1.0.92 on 06/17/12 20:43:06.
*/
/* Exported function */
diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp
index f01fea278..92414d897 100644
--- a/source/ManualBindings.cpp
+++ b/source/ManualBindings.cpp
@@ -158,10 +158,10 @@ static int FNNAME(lua_State * tolua_S) \
{} \
\
private: \
- virtual bool Item(cEntity * a_Item) override \
+ virtual bool Item(ITEM * a_Item) override \
{ \
lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */ \
- tolua_pushusertype(LuaState, a_Item, "cEntity"); \
+ tolua_pushusertype(LuaState, a_Item, #ITEM); \
if (TableRef != LUA_REFNIL) \
{ \
lua_rawgeti( LuaState, LUA_REGISTRYINDEX, TableRef); /* Push table reference */ \
@@ -292,7 +292,9 @@ DEFINE_LUA_FOREACH(cWorld, cPlayer, ForEachPlayer, tolua_cWorld_ForEachPlayer);
DEFINE_LUA_FOREACH(cRoot, cWorld, ForEachWorld, tolua_cRoot_ForEachWorld);
DEFINE_LUA_FOREACH(cWorld, cEntity, ForEachEntity, tolua_cWorld_ForEachEntity);
-DEFINE_LUA_FOREACHINCHUNK(cWorld, cEntity, ForEachEntityInChunk, tolua_cWorld_ForEachEntityInChunk);
+DEFINE_LUA_FOREACHINCHUNK(cWorld, cEntity, ForEachEntityInChunk, tolua_cWorld_ForEachEntityInChunk);
+DEFINE_LUA_FOREACHINCHUNK(cWorld, cChestEntity, ForEachChestInChunk, tolua_cWorld_ForEachChestInChunk);
+DEFINE_LUA_FOREACHINCHUNK(cWorld, cFurnaceEntity, ForEachFurnaceInChunk, tolua_cWorld_ForEachFurnaceInChunk);
@@ -594,9 +596,11 @@ void ManualBindings::Bind( lua_State* tolua_S )
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cWorld");
- tolua_function(tolua_S, "ForEachPlayer", tolua_cWorld_ForEachPlayer);
- tolua_function(tolua_S, "ForEachEntity", tolua_cWorld_ForEachEntity);
- tolua_function(tolua_S, "ForEachEntityInChunk", tolua_cWorld_ForEachEntityInChunk);
+ tolua_function(tolua_S, "ForEachPlayer", tolua_cWorld_ForEachPlayer);
+ tolua_function(tolua_S, "ForEachEntity", tolua_cWorld_ForEachEntity);
+ tolua_function(tolua_S, "ForEachEntityInChunk", tolua_cWorld_ForEachEntityInChunk);
+ tolua_function(tolua_S, "ForEachChestInChunk", tolua_cWorld_ForEachChestInChunk);
+ tolua_function(tolua_S, "ForEachFurnaceInChunk", tolua_cWorld_ForEachFurnaceInChunk);
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cPlugin");
diff --git a/source/cChunk.cpp b/source/cChunk.cpp
index 647478339..9d7bc60ac 100644
--- a/source/cChunk.cpp
+++ b/source/cChunk.cpp
@@ -1540,6 +1540,160 @@ bool cChunk::ForEachEntity(cEntityCallback & a_Callback)
+bool cChunk::ForEachChest(cChestCallback & a_Callback)
+{
+ // The blockentity list is locked by the parent chunkmap's CS
+ for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
+ {
+ if ((*itr)->GetBlockType() != E_BLOCK_CHEST)
+ {
+ continue;
+ }
+ if (a_Callback.Item((cChestEntity *)*itr))
+ {
+ return false;
+ }
+ } // for itr - m_BlockEntitites[]
+ return true;
+}
+
+
+
+
+
+bool cChunk::ForEachFurnace(cFurnaceCallback & a_Callback)
+{
+ // The blockentity list is locked by the parent chunkmap's CS
+ for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
+ {
+ switch ((*itr)->GetBlockType())
+ {
+ case E_BLOCK_FURNACE:
+ case E_BLOCK_LIT_FURNACE:
+ {
+ break;
+ }
+ default:
+ {
+ continue;
+ }
+ }
+ if (a_Callback.Item((cFurnaceEntity *)*itr))
+ {
+ return false;
+ }
+ } // for itr - m_BlockEntitites[]
+ return true;
+}
+
+
+
+
+
+bool cChunk::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback)
+{
+ // The blockentity list is locked by the parent chunkmap's CS
+ for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
+ {
+ if (((*itr)->GetPosX() != a_BlockX) || ((*itr)->GetPosY() != a_BlockY) || ((*itr)->GetPosZ() != a_BlockZ))
+ {
+ continue;
+ }
+ if ((*itr)->GetBlockType() != E_BLOCK_CHEST)
+ {
+ // There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
+ return false;
+ }
+
+ // The correct block entity is here
+ if (a_Callback.Item((cChestEntity *)*itr))
+ {
+ return false;
+ }
+ return true;
+ } // for itr - m_BlockEntitites[]
+
+ // Not found:
+ return false;
+}
+
+
+
+
+
+bool cChunk::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback)
+{
+ // The blockentity list is locked by the parent chunkmap's CS
+ for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
+ {
+ if (((*itr)->GetPosX() != a_BlockX) || ((*itr)->GetPosY() != a_BlockY) || ((*itr)->GetPosZ() != a_BlockZ))
+ {
+ continue;
+ }
+ switch ((*itr)->GetBlockType())
+ {
+ case E_BLOCK_FURNACE:
+ case E_BLOCK_LIT_FURNACE:
+ {
+ break;
+ }
+ default:
+ {
+ // There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
+ return false;
+ }
+ } // switch (BlockType)
+
+ // The correct block entity is here,
+ if (a_Callback.Item((cFurnaceEntity *)*itr))
+ {
+ return false;
+ }
+ return true;
+ } // for itr - m_BlockEntitites[]
+
+ // Not found:
+ return false;
+}
+
+
+
+
+
+bool cChunk::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4)
+{
+ // The blockentity list is locked by the parent chunkmap's CS
+ for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
+ {
+ if (((*itr)->GetPosX() != a_BlockX) || ((*itr)->GetPosY() != a_BlockY) || ((*itr)->GetPosZ() != a_BlockZ))
+ {
+ continue;
+ }
+ switch ((*itr)->GetBlockType())
+ {
+ case E_BLOCK_WALLSIGN:
+ case E_BLOCK_SIGN_POST:
+ {
+ a_Line1 = ((cSignEntity *)*itr)->GetLine(0);
+ a_Line2 = ((cSignEntity *)*itr)->GetLine(1);
+ a_Line3 = ((cSignEntity *)*itr)->GetLine(2);
+ a_Line4 = ((cSignEntity *)*itr)->GetLine(3);
+ return true;
+ }
+ } // switch (BlockType)
+
+ // There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
+ return false;
+ } // for itr - m_BlockEntitites[]
+
+ // Not found:
+ return false;
+}
+
+
+
+
+
BLOCKTYPE cChunk::GetBlock( int a_X, int a_Y, int a_Z )
{
if ((a_X < 0) || (a_X >= Width) || (a_Y < 0) || (a_Y >= Height) || (a_Z < 0) || (a_Z >= Width)) return 0; // Clip
diff --git a/source/cChunk.h b/source/cChunk.h
index 9ecbe89b8..5aff98962 100644
--- a/source/cChunk.h
+++ b/source/cChunk.h
@@ -38,9 +38,13 @@ class cServer;
class MTRand;
class cPlayer;
class cChunkMap;
+class cChestEntity;
+class cFurnaceEntity;
typedef std::list<cClientHandle *> cClientHandleList;
-typedef cItemCallback<cEntity> cEntityCallback;
+typedef cItemCallback<cEntity> cEntityCallback;
+typedef cItemCallback<cChestEntity> cChestCallback;
+typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
@@ -146,6 +150,21 @@ public:
/// Calls the callback for each entity; returns true if all entities processed, false if the callback aborted by returning true
bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible
+ /// Calls the callback for each chest; returns true if all chests processed, false if the callback aborted by returning true
+ bool ForEachChest(cChestCallback & a_Callback); // Lua-accessible
+
+ /// Calls the callback for each furnace; returns true if all furnaces processed, false if the callback aborted by returning true
+ bool ForEachFurnace(cFurnaceCallback & a_Callback); // Lua-accessible
+
+ /// Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found
+ bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Lua-acessible
+
+ /// Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords, true if found
+ bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Lua-accessible
+
+ /// Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found
+ bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible
+
void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); // [x, y, z] in world block coords
void CalculateLighting(); // Recalculate right now
diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp
index 515741a62..47474f9a4 100644
--- a/source/cChunkMap.cpp
+++ b/source/cChunkMap.cpp
@@ -947,6 +947,90 @@ bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback
+bool cChunkMap::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback)
+{
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
+ if ((Chunk == NULL) && !Chunk->IsValid())
+ {
+ return false;
+ }
+ return Chunk->ForEachChest(a_Callback);
+}
+
+
+
+
+
+bool cChunkMap::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback)
+{
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
+ if ((Chunk == NULL) && !Chunk->IsValid())
+ {
+ return false;
+ }
+ return Chunk->ForEachFurnace(a_Callback);
+}
+
+
+
+
+
+bool cChunkMap::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback)
+{
+ int ChunkX, ChunkZ;
+ int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
+ cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
+ if ((Chunk == NULL) && !Chunk->IsValid())
+ {
+ return false;
+ }
+ return Chunk->DoWithChestAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
+}
+
+
+
+
+
+bool cChunkMap::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback)
+{
+ int ChunkX, ChunkZ;
+ int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
+ cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
+ if ((Chunk == NULL) && !Chunk->IsValid())
+ {
+ return false;
+ }
+ return Chunk->DoWithFurnaceAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
+}
+
+
+
+
+
+bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4)
+{
+ int ChunkX, ChunkZ;
+ int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
+ cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
+ if ((Chunk == NULL) && !Chunk->IsValid())
+ {
+ return false;
+ }
+ return Chunk->GetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4);
+}
+
+
+
+
+
void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
{
cCSLock Lock(m_CSLayers);
diff --git a/source/cChunkMap.h b/source/cChunkMap.h
index df5cb5814..e00ed80c1 100644
--- a/source/cChunkMap.h
+++ b/source/cChunkMap.h
@@ -18,10 +18,14 @@ class cChunkStay;
class cChunk;
class cPacket;
class cPlayer;
+class cChestEntity;
+class cFurnaceEntity;
typedef std::list<cClientHandle *> cClientHandleList;
typedef cChunk * cChunkPtr;
-typedef cItemCallback<cEntity> cEntityCallback;
+typedef cItemCallback<cEntity> cEntityCallback;
+typedef cItemCallback<cChestEntity> cChestCallback;
+typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
@@ -130,6 +134,21 @@ public:
/// Calls the callback for each entity in the specified chunk; returns true if all entities processed, false if the callback aborted by returning true
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Lua-accessible
+ /// Calls the callback for each chest in the specified chunk; returns true if all chests processed, false if the callback aborted by returning true
+ bool ForEachChestInChunk (int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback); // Lua-accessible
+
+ /// Calls the callback for each furnace in the specified chunk; returns true if all furnaces processed, false if the callback aborted by returning true
+ bool ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback); // Lua-accessible
+
+ /// Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found
+ bool DoWithChestAt (int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Lua-acessible
+
+ /// Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords, true if found
+ bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Lua-accessible
+
+ /// Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found
+ bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible
+
/// Touches the chunk, causing it to be loaded or generated
void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
diff --git a/source/cWorld.cpp b/source/cWorld.cpp
index 235e7c983..b9731d96c 100644
--- a/source/cWorld.cpp
+++ b/source/cWorld.cpp
@@ -804,6 +804,51 @@ void cWorld::TickSpawnMobs(float a_Dt)
+bool cWorld::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback)
+{
+ return m_ChunkMap->ForEachChestInChunk(a_ChunkX, a_ChunkZ, a_Callback);
+}
+
+
+
+
+
+bool cWorld::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback)
+{
+ return m_ChunkMap->ForEachFurnaceInChunk(a_ChunkX, a_ChunkZ, a_Callback);
+}
+
+
+
+
+
+bool cWorld::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback)
+{
+ return m_ChunkMap->DoWithChestAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
+}
+
+
+
+
+
+bool cWorld::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback)
+{
+ return m_ChunkMap->DoWithFurnaceAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
+}
+
+
+
+
+
+bool cWorld::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4)
+{
+ return m_ChunkMap->GetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4);
+}
+
+
+
+
+
void cWorld::GrowTree( int a_X, int a_Y, int a_Z )
{
if (GetBlock(a_X, a_Y, a_Z) == E_BLOCK_SAPLING)
@@ -1227,16 +1272,6 @@ void cWorld::SendBlockTo( int a_X, int a_Y, int a_Z, cPlayer * a_Player )
-// TODO: This interface is dangerous!
-cBlockEntity * cWorld::GetBlockEntity( int a_X, int a_Y, int a_Z )
-{
- return NULL;
-}
-
-
-
-
-
int cWorld::GetHeight( int a_X, int a_Z )
{
return m_ChunkMap->GetHeight(a_X, a_Z);
diff --git a/source/cWorld.h b/source/cWorld.h
index c4ce91474..b356bdf0a 100644
--- a/source/cWorld.h
+++ b/source/cWorld.h
@@ -39,9 +39,16 @@ class cEntity;
class cBlockEntity;
class cWorldGenerator; // The generator that actually generates the chunks for a single world
class cChunkGenerator; // The thread responsible for generating chunks
+class cChestEntity;
+class cFurnaceEntity;
+
typedef std::list< cPlayer * > cPlayerList;
-typedef cItemCallback<cPlayer> cPlayerListCallback;
-typedef cItemCallback<cEntity> cEntityCallback;
+
+typedef cItemCallback<cPlayer> cPlayerListCallback;
+typedef cItemCallback<cEntity> cEntityCallback;
+typedef cItemCallback<cChestEntity> cChestCallback;
+typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
+
@@ -238,9 +245,20 @@ public:
inline cWaterSimulator *GetWaterSimulator() { return m_WaterSimulator; }
inline cLavaSimulator *GetLavaSimulator() { return m_LavaSimulator; }
- // TODO: This interface is dangerous! Export as a set of specific action functions for Lua: GetChestItem, GetFurnaceItem, SetFurnaceItem, SetSignLines etc.
- // _X 2012_02_21: This function always returns NULL
- OBSOLETE cBlockEntity * GetBlockEntity( int a_X, int a_Y, int a_Z ); //tolua_export
+ /// Calls the callback for each chest in the specified chunk; returns true if all chests processed, false if the callback aborted by returning true
+ bool ForEachChestInChunk (int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp
+
+ /// Calls the callback for each furnace in the specified chunk; returns true if all furnaces processed, false if the callback aborted by returning true
+ bool ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback); // Exported in ManualBindings.cpp
+
+ /// Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found
+ bool DoWithChestAt (int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp
+
+ /// Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords, true if found
+ bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Exported in ManualBindings.cpp
+
+ /// Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found
+ bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // tolua_export
/// a_Player is using block entity at [x, y, z], handle that:
void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) {m_ChunkMap->UseBlockEntity(a_Player, a_X, a_Y, a_Z); }