Makes it possible to check the status of the mapblock in a future-extensible way.
* If `transient` is `false` or absent, frees a persistent forceload.
If `true`, frees a transient forceload.
+* `minetest.compare_block_status(pos, condition)`
+ * Checks whether the mapblock at positition `pos` is in the wanted condition.
+ * `condition` may be one of the following values:
+ * `"unknown"`: not in memory
+ * `"emerging"`: in the queue for loading from disk or generating
+ * `"loaded"`: in memory but inactive (no ABMs are executed)
+ * `"active"`: in memory and active
+ * Other values are reserved for future functionality extensions
+ * Return value, the comparison status:
+ * `false`: Mapblock does not fulfil the wanted condition
+ * `true`: Mapblock meets the requirement
+ * `nil`: Unsupported `condition` value
+
* `minetest.request_insecure_environment()`: returns an environment containing
insecure functions if the calling mod has been listed as trusted in the
`secure.trusted_mods` setting or security is disabled, otherwise returns
}
+bool EmergeManager::isBlockInQueue(v3s16 pos)
+{
+ MutexAutoLock queuelock(m_queue_mutex);
+ return m_blocks_enqueued.find(pos) != m_blocks_enqueued.end();
+}
+
+
//
// Mapgen-related helper functions
//
EmergeCompletionCallback callback,
void *callback_param);
+ bool isBlockInQueue(v3s16 pos);
+
v3s16 getContainingChunk(v3s16 blockpos);
Mapgen *getCurrentMapgen();
return block;
}
+bool ServerMap::isBlockInQueue(v3s16 pos)
+{
+ return m_emerge && m_emerge->isBlockInQueue(pos);
+}
+
// N.B. This requires no synchronization, since data will not be modified unless
// the VoxelManipulator being updated belongs to the same thread.
void ServerMap::updateVManip(v3s16 pos)
*/
MapBlock *getBlockOrEmerge(v3s16 p3d);
+ bool isBlockInQueue(v3s16 pos);
+
/*
Database functions
*/
//// Flags
////
- inline bool isDummy()
+ inline bool isDummy() const
{
return !data;
}
#include "client/client.h"
#endif
-struct EnumString ModApiEnvMod::es_ClearObjectsMode[] =
+const EnumString ModApiEnvMod::es_ClearObjectsMode[] =
{
{CLEAR_OBJECTS_MODE_FULL, "full"},
{CLEAR_OBJECTS_MODE_QUICK, "quick"},
{0, NULL},
};
+const EnumString ModApiEnvMod::es_BlockStatusType[] =
+{
+ {ServerEnvironment::BS_UNKNOWN, "unknown"},
+ {ServerEnvironment::BS_EMERGING, "emerging"},
+ {ServerEnvironment::BS_LOADED, "loaded"},
+ {ServerEnvironment::BS_ACTIVE, "active"},
+ {0, NULL},
+};
+
///////////////////////////////////////////////////////////////////////////////
return 0;
}
+// compare_block_status(nodepos)
+int ModApiEnvMod::l_compare_block_status(lua_State *L)
+{
+ GET_ENV_PTR;
+
+ v3s16 nodepos = check_v3s16(L, 1);
+ std::string condition_s = luaL_checkstring(L, 2);
+ auto status = env->getBlockStatus(getNodeBlockPos(nodepos));
+
+ int condition_i = -1;
+ if (!string_to_enum(es_BlockStatusType, condition_i, condition_s))
+ return 0; // Unsupported
+
+ lua_pushboolean(L, status >= condition_i);
+ return 1;
+}
+
+
// forceload_free_block(blockpos)
// blockpos = {x=num, y=num, z=num}
int ModApiEnvMod::l_forceload_free_block(lua_State *L)
API_FCT(transforming_liquid_add);
API_FCT(forceload_block);
API_FCT(forceload_free_block);
+ API_FCT(compare_block_status);
API_FCT(get_translated_string);
}
// stops forceloading a position
static int l_forceload_free_block(lua_State *L);
+ // compare_block_status(nodepos)
+ static int l_compare_block_status(lua_State *L);
+
// Get a string translated server side
static int l_get_translated_string(lua_State * L);
static void Initialize(lua_State *L, int top);
static void InitializeClient(lua_State *L, int top);
- static struct EnumString es_ClearObjectsMode[];
+ static const EnumString es_ClearObjectsMode[];
+ static const EnumString es_BlockStatusType[];
};
class LuaABM : public ActiveBlockModifier {
m_server->sendDetachedInventories(PEER_ID_INEXISTENT, true);
}
+ServerEnvironment::BlockStatus ServerEnvironment::getBlockStatus(v3s16 blockpos)
+{
+ if (m_active_blocks.contains(blockpos))
+ return BS_ACTIVE;
+
+ const MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
+ if (block && !block->isDummy())
+ return BS_LOADED;
+
+ if (m_map->isBlockInQueue(blockpos))
+ return BS_EMERGING;
+
+ return BS_UNKNOWN;
+}
+
u32 ServerEnvironment::addParticleSpawner(float exptime)
{
// Timers with lifetime 0 do not expire
void reportMaxLagEstimate(float f) { m_max_lag_estimate = f; }
float getMaxLagEstimate() { return m_max_lag_estimate; }
- std::set<v3s16>* getForceloadedBlocks() { return &m_active_blocks.m_forceloaded_list; };
+ std::set<v3s16>* getForceloadedBlocks() { return &m_active_blocks.m_forceloaded_list; }
+
+ // Sorted by how ready a mapblock is
+ enum BlockStatus {
+ BS_UNKNOWN,
+ BS_EMERGING,
+ BS_LOADED,
+ BS_ACTIVE // always highest value
+ };
+ BlockStatus getBlockStatus(v3s16 blockpos);
// Sets the static object status all the active objects in the specified block
// This is only really needed for deleting blocks from the map