summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Bindings/ManualBindings_World.cpp54
-rw-r--r--src/ChunkMap.cpp28
-rw-r--r--src/ChunkMap.h3
-rw-r--r--src/World.cpp9
-rw-r--r--src/World.h5
5 files changed, 98 insertions, 1 deletions
diff --git a/src/Bindings/ManualBindings_World.cpp b/src/Bindings/ManualBindings_World.cpp
index e2902b81a..e007a9689 100644
--- a/src/Bindings/ManualBindings_World.cpp
+++ b/src/Bindings/ManualBindings_World.cpp
@@ -110,6 +110,59 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S)
+static int tolua_cWorld_ForEachLoadedChunk(lua_State * tolua_S)
+{
+ // Exported manually, because tolua doesn't support converting functions to functor types.
+ // Function signature: ForEachLoadedChunk(callback) -> bool
+
+ cLuaState L(tolua_S);
+ if (
+ !L.CheckParamUserType(1, "cWorld") ||
+ !L.CheckParamFunction(2)
+ )
+ {
+ return 0;
+ }
+
+ cPluginLua * Plugin = cManualBindings::GetLuaPlugin(tolua_S);
+ if (Plugin == nullptr)
+ {
+ return 0;
+ }
+
+ // Read the params:
+ cWorld * World = (cWorld *)tolua_tousertype(tolua_S, 1, nullptr);
+ if (World == nullptr)
+ {
+ LOGWARNING("World:ForEachLoadedChunk(): invalid world parameter");
+ L.LogStackTrace();
+ return 0;
+ }
+ cLuaState::cRef FnRef;
+ L.GetStackValues(2, FnRef);
+ if (!FnRef.IsValid())
+ {
+ return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #2");
+ }
+
+ // Call the enumeration:
+ bool ret = World->ForEachLoadedChunk(
+ [&L, &FnRef](int a_ChunkX, int a_ChunkZ) -> bool
+ {
+ bool res = false; // By default continue the enumeration
+ L.Call(FnRef, a_ChunkX, a_ChunkZ, cLuaState::Return, res);
+ return res;
+ }
+ );
+
+ // Push the return value:
+ L.Push(ret);
+ return 1;
+}
+
+
+
+
static int tolua_cWorld_GetBlockInfo(lua_State * tolua_S)
{
@@ -580,6 +633,7 @@ void cManualBindings::BindWorld(lua_State * tolua_S)
tolua_function(tolua_S, "ForEachEntityInChunk", ForEachInChunk<cWorld, cEntity, &cWorld::ForEachEntityInChunk>);
tolua_function(tolua_S, "ForEachFurnaceInChunk", ForEachInChunk<cWorld, cFurnaceEntity, &cWorld::ForEachFurnaceInChunk>);
tolua_function(tolua_S, "ForEachPlayer", ForEach< cWorld, cPlayer, &cWorld::ForEachPlayer>);
+ tolua_function(tolua_S, "ForEachLoadedChunk", tolua_cWorld_ForEachLoadedChunk);
tolua_function(tolua_S, "GetBlockInfo", tolua_cWorld_GetBlockInfo);
tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cWorld_GetBlockTypeMeta);
tolua_function(tolua_S, "GetSignLines", tolua_cWorld_GetSignLines);
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp
index aeae8f350..a11ceb060 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -2576,6 +2576,34 @@ bool cChunkMap::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinCh
+bool cChunkMap::ForEachLoadedChunk(std::function<bool(int, int)> a_Callback)
+{
+ cCSLock Lock(m_CSLayers);
+ for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) // iterate over ALL loaded layers
+ {
+ cChunkLayer * layer = *itr;
+ for (int x = 0; x < LAYER_SIZE; x++)
+ {
+ for (int z = 0; z < LAYER_SIZE; z++)
+ {
+ cChunkPtr p = layer->FindChunk(layer->GetX() * LAYER_SIZE + x, layer->GetZ() * LAYER_SIZE + z);
+ if ((p != nullptr) && p->IsValid()) // if chunk is loaded
+ {
+ if (a_Callback(p->GetPosX(), p->GetPosZ()))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+
+
+
+
bool cChunkMap::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes)
{
// Convert block coords to chunks coords:
diff --git a/src/ChunkMap.h b/src/ChunkMap.h
index 4974671da..e9309dbd8 100644
--- a/src/ChunkMap.h
+++ b/src/ChunkMap.h
@@ -344,6 +344,9 @@ public:
/** Calls the callback for each chunk in the coords specified (all cords are inclusive). Returns true if all chunks have been processed successfully */
bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback);
+
+ /** Calls the callback for each loaded chunk. Returns true if all chunks have been processed successfully */
+ bool ForEachLoadedChunk(std::function<bool(int, int)> a_Callback);
/** Writes the block area into the specified coords. Returns true if all chunks have been processed. Prefer cBlockArea::Write() instead. */
bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes);
diff --git a/src/World.cpp b/src/World.cpp
index eb96eb57a..5920b83fe 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -3140,6 +3140,15 @@ bool cWorld::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunk
+bool cWorld::ForEachLoadedChunk(std::function<bool(int, int)> a_Callback)
+{
+ return m_ChunkMap->ForEachLoadedChunk(a_Callback);
+}
+
+
+
+
+
void cWorld::SaveAllChunks(void)
{
m_LastSave = std::chrono::duration_cast<cTickTimeLong>(m_WorldAge);
diff --git a/src/World.h b/src/World.h
index 1ee473970..1902296be 100644
--- a/src/World.h
+++ b/src/World.h
@@ -27,7 +27,7 @@
#include "Blocks/BroadcastInterface.h"
#include "FastRandom.h"
#include "ClientHandle.h"
-
+#include <functional>
@@ -434,6 +434,9 @@ public:
/** Calls the callback for each chunk in the coords specified (all cords are inclusive). Returns true if all chunks have been processed successfully */
virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) override;
+ /** Calls the callback for each loaded chunk. Returns true if all chunks have been processed successfully */
+ bool ForEachLoadedChunk(std::function<bool(int, int)> a_Callback);
+
// tolua_begin
/** Sets the block at the specified coords to the specified value.