From 1c15f53318d49ccd148ec42b0a4345c4a8cd06bf Mon Sep 17 00:00:00 2001
From: Perttu Ahola <celeron55@gmail.com>
Date: Wed, 28 Dec 2011 18:18:08 +0200
Subject: [PATCH] Add EnvRef:get_objects_inside_radius(pos, radius)

---
 data/mods/default/init.lua      |  1 +
 data/mods/experimental/init.lua | 18 ++++++++++++------
 src/environment.cpp             | 17 +++++++++++++++++
 src/environment.h               | 12 +++++++++---
 src/scriptapi.cpp               | 31 +++++++++++++++++++++++++++++++
 5 files changed, 70 insertions(+), 9 deletions(-)

diff --git a/data/mods/default/init.lua b/data/mods/default/init.lua
index 1edbd3cbb..2ba42e0f4 100644
--- a/data/mods/default/init.lua
+++ b/data/mods/default/init.lua
@@ -155,6 +155,7 @@
 -- - 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()
diff --git a/data/mods/experimental/init.lua b/data/mods/experimental/init.lua
index 52a729a4a..dd0d60f4e 100644
--- a/data/mods/experimental/init.lua
+++ b/data/mods/experimental/init.lua
@@ -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)
diff --git a/src/environment.cpp b/src/environment.cpp
index aa2b45f8f..88f1527fc 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -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(): "
diff --git a/src/environment.h b/src/environment.h
index e14a9c485..3ebbee910 100644
--- a/src/environment.h
+++ b/src/environment.h
@@ -261,18 +261,24 @@ class ServerEnvironment : public Environment
 	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:
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index 23336e32d..1a50e1e34 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -2592,6 +2592,36 @@ class EnvRef
 		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}
 };
 
-- 
GitLab