diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 708d6b0bc..800fc0c24 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -4891,6 +4891,9 @@ Environment access * `minetest.get_objects_inside_radius(pos, radius)`: returns a list of ObjectRefs. * `radius`: using an euclidean metric +* `minetest.get_objects_in_area(pos1, pos2)`: returns a list of + ObjectRefs. + * `pos1` and `pos2` are the min and max positions of the area to search. * `minetest.set_timeofday(val)` * `val` is between `0` and `1`; `0` for midnight, `0.5` for midday * `minetest.get_timeofday()` diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 021ef2ea7..c75fc8dc7 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -743,6 +743,31 @@ int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L) return 1; } +// get_objects_in_area(pos, minp, maxp) +int ModApiEnvMod::l_get_objects_in_area(lua_State *L) +{ + GET_ENV_PTR; + ScriptApiBase *script = getScriptApiBase(L); + + v3f minp = read_v3f(L, 1) * BS; + v3f maxp = read_v3f(L, 2) * BS; + aabb3f box(minp, maxp); + box.repair(); + std::vector objs; + + auto include_obj_cb = [](ServerActiveObject *obj){ return !obj->isGone(); }; + env->getObjectsInArea(objs, box, include_obj_cb); + + int i = 0; + lua_createtable(L, objs.size(), 0); + for (const auto obj : objs) { + // Insert object reference into table + script->objectrefGetOrCreate(L, obj); + lua_rawseti(L, -2, ++i); + } + return 1; +} + // set_timeofday(val) // val = 0...1 int ModApiEnvMod::l_set_timeofday(lua_State *L) @@ -1413,6 +1438,7 @@ void ModApiEnvMod::Initialize(lua_State *L, int top) API_FCT(get_node_timer); API_FCT(get_connected_players); API_FCT(get_player_by_name); + API_FCT(get_objects_in_area); API_FCT(get_objects_inside_radius); API_FCT(set_timeofday); API_FCT(get_timeofday); diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h index 7f212b5fc..42c2d64f8 100644 --- a/src/script/lua_api/l_env.h +++ b/src/script/lua_api/l_env.h @@ -114,6 +114,9 @@ private: // get_objects_inside_radius(pos, radius) static int l_get_objects_inside_radius(lua_State *L); + + // get_objects_in_area(pos, minp, maxp) + static int l_get_objects_in_area(lua_State *L); // set_timeofday(val) // val = 0...1 diff --git a/src/server/activeobjectmgr.cpp b/src/server/activeobjectmgr.cpp index 1b8e31409..acd6611f4 100644 --- a/src/server/activeobjectmgr.cpp +++ b/src/server/activeobjectmgr.cpp @@ -127,6 +127,21 @@ void ActiveObjectMgr::getObjectsInsideRadius(const v3f &pos, float radius, } } +void ActiveObjectMgr::getObjectsInArea(const aabb3f &box, + std::vector &result, + std::function include_obj_cb) +{ + for (auto &activeObject : m_active_objects) { + ServerActiveObject *obj = activeObject.second; + const v3f &objectpos = obj->getBasePosition(); + if (!box.isPointInside(objectpos)) + continue; + + if (!include_obj_cb || include_obj_cb(obj)) + result.push_back(obj); + } +} + void ActiveObjectMgr::getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius, f32 player_radius, std::set ¤t_objects, std::queue &added_objects) diff --git a/src/server/activeobjectmgr.h b/src/server/activeobjectmgr.h index bc2085499..d43f5643c 100644 --- a/src/server/activeobjectmgr.h +++ b/src/server/activeobjectmgr.h @@ -38,6 +38,9 @@ public: void getObjectsInsideRadius(const v3f &pos, float radius, std::vector &result, std::function include_obj_cb); + void getObjectsInArea(const aabb3f &box, + std::vector &result, + std::function include_obj_cb); void getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius, f32 player_radius, std::set ¤t_objects, diff --git a/src/serverenvironment.h b/src/serverenvironment.h index cfd5b8f3e..c76d34a37 100644 --- a/src/serverenvironment.h +++ b/src/serverenvironment.h @@ -331,6 +331,13 @@ public: { return m_ao_manager.getObjectsInsideRadius(pos, radius, objects, include_obj_cb); } + + // Find all active objects inside a box + void getObjectsInArea(std::vector &objects, const aabb3f &box, + std::function include_obj_cb) + { + return m_ao_manager.getObjectsInArea(box, objects, include_obj_cb); + } // Clear objects, loading and going through every MapBlock void clearObjects(ClearObjectsMode mode);