Add EnvRef:get_objects_inside_radius(pos, radius)
authorPerttu Ahola <celeron55@gmail.com>
Wed, 28 Dec 2011 16:18:08 +0000 (18:18 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Wed, 28 Dec 2011 16:18:08 +0000 (18:18 +0200)
data/mods/default/init.lua
data/mods/experimental/init.lua
src/environment.cpp
src/environment.h
src/scriptapi.cpp

index 1edbd3cbbca5d9d56ab2333528eca542e8b83f17..2ba42e0f4ebcd092d816b825e0056ea38045cebd 100644 (file)
 -- - add_firefly(pos)
 -- - get_meta(pos) -- Get a NodeMetaRef at that position
 -- - get_player_by_name(name) -- Get an ObjectRef to a player
+-- - get_objects_inside_radius(pos, radius)
 --
 -- NodeMetaRef
 -- - get_type()
index 52a729a4a0eb492a7c0498effa7ed122b22421b7..dd0d60f4e373499a29d3ddfc846aa26f0428a30f 100644 (file)
@@ -7,12 +7,18 @@
 function on_step(dtime)
        -- print("experimental on_step")
        --[[
-       print("celeron55 dir: "..dump(
-                       minetest.env:get_player_by_name("celeron55"):get_look_dir()))
-       print("celeron55 pitch: "..dump(
-                       minetest.env:get_player_by_name("celeron55"):get_look_pitch()))
-       print("celeron55 yaw: "..dump(
-                       minetest.env:get_player_by_name("celeron55"):get_look_yaw()))
+       objs = minetest.env:get_objects_inside_radius({x=0,y=0,z=0}, 10)
+       for k, obj in pairs(objs) do
+               name = obj:get_player_name()
+               if name then
+                       print(name.." at "..dump(obj:getpos()))
+                       print(name.." dir: "..dump(obj:get_look_dir()))
+                       print(name.." pitch: "..dump(obj:get_look_pitch()))
+                       print(name.." yaw: "..dump(obj:get_look_yaw()))
+               else
+                       print("Some object at "..dump(obj:getpos()))
+               end
+       end
        --]]
 end
 minetest.register_globalstep(on_step)
index aa2b45f8f5c95b77d571d03af747a55920278a6f..88f1527fcc4233fe5823f8b61af87a3a0eebe4a7 100644 (file)
@@ -752,6 +752,23 @@ void ServerEnvironment::addActiveBlockModifier(ActiveBlockModifier *abm)
        m_abms.push_back(ABMWithState(abm));
 }
 
+std::set<u16> ServerEnvironment::getObjectsInsideRadius(v3f pos, float radius)
+{
+       std::set<u16> objects;
+       for(core::map<u16, ServerActiveObject*>::Iterator
+                       i = m_active_objects.getIterator();
+                       i.atEnd()==false; i++)
+       {
+               ServerActiveObject* obj = i.getNode()->getValue();
+               u16 id = i.getNode()->getKey();
+               v3f objectpos = obj->getBasePosition();
+               if(objectpos.getDistanceFrom(pos) > radius)
+                       continue;
+               objects.insert(id);
+       }
+       return objects;
+}
+
 void ServerEnvironment::clearAllObjects()
 {
        infostream<<"ServerEnvironment::clearAllObjects(): "
index e14a9c48589a6109a3229efbf54ba70f3f58f59b..3ebbee9108cb9679913dd9d0363ef5748e9e7631 100644 (file)
@@ -261,18 +261,24 @@ public:
        void activateBlock(MapBlock *block, u32 additional_dtime=0);
 
        /*
-               ActiveBlockModifiers (TODO)
+               ActiveBlockModifiers
                -------------------------------------------
-               NOTE: Not used currently (TODO: Use or remove)
        */
 
        void addActiveBlockModifier(ActiveBlockModifier *abm);
 
-       /* Other stuff */
+       /*
+               Other stuff
+               -------------------------------------------
+       */
+       
+       // Find all active objects inside a radius around a point
+       std::set<u16> getObjectsInsideRadius(v3f pos, float radius);
        
        // Clear all objects, loading and going through every MapBlock
        void clearAllObjects();
        
+       // This makes stuff happen
        void step(f32 dtime);
        
 private:
index 23336e32dc0e22124a362b703636978ca4140fd1..1a50e1e34e1571854c11323e229a2f5066d1a07b 100644 (file)
@@ -2592,6 +2592,36 @@ private:
                return 1;
        }
 
+       // EnvRef:get_objects_inside_radius(pos, radius)
+       static int l_get_objects_inside_radius(lua_State *L)
+       {
+               // Get the table insert function
+               lua_getglobal(L, "table");
+               lua_getfield(L, -1, "insert");
+               int table_insert = lua_gettop(L);
+               // Get environemnt
+               EnvRef *o = checkobject(L, 1);
+               ServerEnvironment *env = o->m_env;
+               if(env == NULL) return 0;
+               // Do it
+               v3f pos = readFloatPos(L, 2);
+               float radius = luaL_checknumber(L, 3) * BS;
+               std::set<u16> ids = env->getObjectsInsideRadius(pos, radius);
+               lua_newtable(L);
+               int table = lua_gettop(L);
+               for(std::set<u16>::const_iterator
+                               i = ids.begin(); i != ids.end(); i++){
+                       ServerActiveObject *obj = env->getActiveObject(*i);
+                       // Insert object reference into table
+                       lua_pushvalue(L, table_insert);
+                       lua_pushvalue(L, table);
+                       objectref_get_or_create(L, obj);
+                       if(lua_pcall(L, 2, 0, 0))
+                               script_error(L, "error: %s", lua_tostring(L, -1));
+               }
+               return 1;
+       }
+
        static int gc_object(lua_State *L) {
                EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
                delete o;
@@ -2668,6 +2698,7 @@ const luaL_reg EnvRef::methods[] = {
        method(EnvRef, add_firefly),
        method(EnvRef, get_meta),
        method(EnvRef, get_player_by_name),
+       method(EnvRef, get_objects_inside_radius),
        {0,0}
 };