]> git.lizzy.rs Git - minetest.git/commitdiff
Add minetest.get_objects_in_area (#10668)
authorElias Fleckenstein <54945686+EliasFleckenstein03@users.noreply.github.com>
Tue, 29 Dec 2020 15:50:09 +0000 (16:50 +0100)
committerGitHub <noreply@github.com>
Tue, 29 Dec 2020 15:50:09 +0000 (16:50 +0100)
doc/lua_api.txt
src/script/lua_api/l_env.cpp
src/script/lua_api/l_env.h
src/server/activeobjectmgr.cpp
src/server/activeobjectmgr.h
src/serverenvironment.h

index 708d6b0bc0c5b343a35e9e8f631192e383dc3574..800fc0c248d9b4472568906593e273f900178051 100644 (file)
@@ -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()`
index 021ef2ea7cd0ab6f4540394ebe8a2e1fa78c0b70..c75fc8dc7b66111a78274ff8a3c3eb706b2dbfa5 100644 (file)
@@ -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<ServerActiveObject *> 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);
index 7f212b5fcd1be05b28a222ce738ecf833e10197c..42c2d64f86179d51105d2df4afc0ba6eb6e128f2 100644 (file)
@@ -114,6 +114,9 @@ class ModApiEnvMod : public ModApiBase {
 
        // 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
index 1b8e31409fb8389d3ce6a0bfad36e6b21dc0a403..acd6611f4ec99ce1b25b00b641d5d8b5e42bf907 100644 (file)
@@ -127,6 +127,21 @@ void ActiveObjectMgr::getObjectsInsideRadius(const v3f &pos, float radius,
        }
 }
 
+void ActiveObjectMgr::getObjectsInArea(const aabb3f &box,
+               std::vector<ServerActiveObject *> &result,
+               std::function<bool(ServerActiveObject *obj)> 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<u16> &current_objects,
                std::queue<u16> &added_objects)
index bc208549929446fc7789cbab0d6c986465de251a..d43f5643c2797129de890e3b3a7259a794deabc2 100644 (file)
@@ -38,6 +38,9 @@ class ActiveObjectMgr : public ::ActiveObjectMgr<ServerActiveObject>
        void getObjectsInsideRadius(const v3f &pos, float radius,
                        std::vector<ServerActiveObject *> &result,
                        std::function<bool(ServerActiveObject *obj)> include_obj_cb);
+       void getObjectsInArea(const aabb3f &box,
+                       std::vector<ServerActiveObject *> &result,
+                       std::function<bool(ServerActiveObject *obj)> include_obj_cb);
 
        void getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius,
                        f32 player_radius, std::set<u16> &current_objects,
index cfd5b8f3eb7e3b6f5426ea0de4aa7a6b0bcaacde..c76d34a3744c088d5def2009870c764c8e6032cb 100644 (file)
@@ -331,6 +331,13 @@ class ServerEnvironment : public Environment
        {
                return m_ao_manager.getObjectsInsideRadius(pos, radius, objects, include_obj_cb);
        }
+       
+       // Find all active objects inside a box
+       void getObjectsInArea(std::vector<ServerActiveObject *> &objects, const aabb3f &box,
+                       std::function<bool(ServerActiveObject *obj)> 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);