// Calculate distance by speed, add own extent and 1.5m of tolerance
f32 distance = speed_f->getLength() * dtime +
box_0.getExtent().getLength() + 1.5f * BS;
- std::vector<u16> s_objects;
- s_env->getObjectsInsideRadius(s_objects, *pos_f, distance);
- for (u16 obj_id : s_objects) {
- ServerActiveObject *current = s_env->getActiveObject(obj_id);
-
- if (!self || (self != current &&
- self != current->getParent())) {
- objects.push_back((ActiveObject*)current);
+ // search for objects which are not us, or we are not its parent
+ // we directly use the callback to populate the result to prevent
+ // a useless result loop here
+ auto include_obj_cb = [self, &objects] (ServerActiveObject *obj) {
+ if (!self || (self != obj && self != obj->getParent())) {
+ objects.push_back((ActiveObject *)obj);
}
- }
+ return false;
+ };
+
+ std::vector<ServerActiveObject *> s_objects;
+ s_env->getObjectsInsideRadius(s_objects, *pos_f, distance, include_obj_cb);
}
}
int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L)
{
GET_ENV_PTR;
+ ScriptApiBase *script = getScriptApiBase(L);
// Do it
v3f pos = checkFloatPos(L, 1);
float radius = readParam<float>(L, 2) * BS;
- std::vector<u16> ids;
- env->getObjectsInsideRadius(ids, pos, radius);
- ScriptApiBase *script = getScriptApiBase(L);
- lua_createtable(L, ids.size(), 0);
- std::vector<u16>::const_iterator iter = ids.begin();
- for(u32 i = 0; iter != ids.end(); ++iter) {
- ServerActiveObject *obj = env->getActiveObject(*iter);
- if (!obj->isGone()) {
- // Insert object reference into table
- script->objectrefGetOrCreate(L, obj);
- lua_rawseti(L, -2, ++i);
- }
+ std::vector<ServerActiveObject *> objs;
+
+ auto include_obj_cb = [](ServerActiveObject *obj){ return !obj->isGone(); };
+ env->getObjectsInsideRadius(objs, pos, radius, 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;
}
}
// clang-format on
-void ActiveObjectMgr::getObjectsInsideRadius(
- const v3f &pos, float radius, std::vector<u16> &result)
+void ActiveObjectMgr::getObjectsInsideRadius(const v3f &pos, float radius,
+ std::vector<ServerActiveObject *> &result,
+ std::function<bool(ServerActiveObject *obj)> include_obj_cb)
{
float r2 = radius * radius;
for (auto &activeObject : m_active_objects) {
ServerActiveObject *obj = activeObject.second;
- u16 id = activeObject.first;
const v3f &objectpos = obj->getBasePosition();
if (objectpos.getDistanceFromSQ(pos) > r2)
continue;
- result.push_back(id);
+
+ if (!include_obj_cb || include_obj_cb(obj))
+ result.push_back(obj);
}
}
bool registerObject(ServerActiveObject *obj) override;
void removeObject(u16 id) override;
- void getObjectsInsideRadius(
- const v3f &pos, float radius, std::vector<u16> &result);
+ void getObjectsInsideRadius(const v3f &pos, float radius,
+ 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> ¤t_objects,
const core::line3d<f32> &shootline_on_map,
std::vector<PointedThing> &objects)
{
- std::vector<u16> objectIds;
- getObjectsInsideRadius(objectIds, shootline_on_map.start,
- shootline_on_map.getLength() + 10.0f);
+ std::vector<ServerActiveObject *> objs;
+ getObjectsInsideRadius(objs, shootline_on_map.start,
+ shootline_on_map.getLength() + 10.0f, nullptr);
const v3f line_vector = shootline_on_map.getVector();
- for (u16 objectId : objectIds) {
- ServerActiveObject* obj = getActiveObject(objectId);
-
+ for (auto obj : objs) {
aabb3f selection_box;
if (!obj->getSelectionBox(&selection_box))
continue;
if (boxLineCollision(offsetted_box, shootline_on_map.start, line_vector,
¤t_intersection, ¤t_normal)) {
objects.emplace_back(
- (s16) objectId, current_intersection, current_normal,
+ (s16) obj->getId(), current_intersection, current_normal,
(current_intersection - shootline_on_map.start).getLengthSQ());
}
}
bool swapNode(v3s16 p, const MapNode &n);
// Find all active objects inside a radius around a point
- void getObjectsInsideRadius(std::vector<u16> &objects, const v3f &pos, float radius)
+ void getObjectsInsideRadius(std::vector<ServerActiveObject *> &objects, const v3f &pos, float radius,
+ std::function<bool(ServerActiveObject *obj)> include_obj_cb)
{
- return m_ao_manager.getObjectsInsideRadius(pos, radius, objects);
+ return m_ao_manager.getObjectsInsideRadius(pos, radius, objects, include_obj_cb);
}
// Clear objects, loading and going through every MapBlock
saomgr.registerObject(new TestServerActiveObject(p));
}
- std::vector<u16> result;
- saomgr.getObjectsInsideRadius(v3f(), 50, result);
+ std::vector<ServerActiveObject *> result;
+ saomgr.getObjectsInsideRadius(v3f(), 50, result, nullptr);
UASSERTCMP(int, ==, result.size(), 1);
result.clear();
- saomgr.getObjectsInsideRadius(v3f(), 750, result);
+ saomgr.getObjectsInsideRadius(v3f(), 750, result, nullptr);
UASSERTCMP(int, ==, result.size(), 2);
+ result.clear();
+ saomgr.getObjectsInsideRadius(v3f(), 750000, result, nullptr);
+ UASSERTCMP(int, ==, result.size(), 5);
+
+ result.clear();
+ auto include_obj_cb = [](ServerActiveObject *obj) {
+ return (obj->getBasePosition().X != 10);
+ };
+
+ saomgr.getObjectsInsideRadius(v3f(), 750000, result, include_obj_cb);
+ UASSERTCMP(int, ==, result.size(), 4);
+
clearSAOMgr(&saomgr);
}