3 Copyright (C) 2010-2018 nerzhul, Loic BLOT <loic.blot@unix-experience.fr>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "activeobjectmgr.h"
28 void ActiveObjectMgr::clear(const std::function<bool(ServerActiveObject *, u16)> &cb)
30 std::vector<u16> objects_to_remove;
31 for (auto &it : m_active_objects) {
32 if (cb(it.second, it.first)) {
33 // Id to be removed from m_active_objects
34 objects_to_remove.push_back(it.first);
38 // Remove references from m_active_objects
39 for (u16 i : objects_to_remove) {
40 m_active_objects.erase(i);
44 void ActiveObjectMgr::step(
45 float dtime, const std::function<void(ServerActiveObject *)> &f)
47 g_profiler->avg("ActiveObjectMgr: SAO count [#]", m_active_objects.size());
48 for (auto &ao_it : m_active_objects) {
54 bool ActiveObjectMgr::registerObject(ServerActiveObject *obj)
56 assert(obj); // Pre-condition
57 if (obj->getId() == 0) {
58 u16 new_id = getFreeId();
60 errorstream << "Server::ActiveObjectMgr::addActiveObjectRaw(): "
61 << "no free id available" << std::endl;
62 if (obj->environmentDeletes())
68 verbosestream << "Server::ActiveObjectMgr::addActiveObjectRaw(): "
69 << "supplied with id " << obj->getId() << std::endl;
72 if (!isFreeId(obj->getId())) {
73 errorstream << "Server::ActiveObjectMgr::addActiveObjectRaw(): "
74 << "id is not free (" << obj->getId() << ")" << std::endl;
75 if (obj->environmentDeletes())
80 if (objectpos_over_limit(obj->getBasePosition())) {
81 v3f p = obj->getBasePosition();
82 warningstream << "Server::ActiveObjectMgr::addActiveObjectRaw(): "
83 << "object position (" << p.X << "," << p.Y << "," << p.Z
84 << ") outside maximum range" << std::endl;
85 if (obj->environmentDeletes())
90 m_active_objects[obj->getId()] = obj;
92 verbosestream << "Server::ActiveObjectMgr::addActiveObjectRaw(): "
93 << "Added id=" << obj->getId() << "; there are now "
94 << m_active_objects.size() << " active objects." << std::endl;
98 void ActiveObjectMgr::removeObject(u16 id)
100 verbosestream << "Server::ActiveObjectMgr::removeObject(): "
101 << "id=" << id << std::endl;
102 ServerActiveObject *obj = getActiveObject(id);
104 infostream << "Server::ActiveObjectMgr::removeObject(): "
105 << "id=" << id << " not found" << std::endl;
109 m_active_objects.erase(id);
114 void ActiveObjectMgr::getObjectsInsideRadius(const v3f &pos, float radius,
115 std::vector<ServerActiveObject *> &result,
116 std::function<bool(ServerActiveObject *obj)> include_obj_cb)
118 float r2 = radius * radius;
119 for (auto &activeObject : m_active_objects) {
120 ServerActiveObject *obj = activeObject.second;
121 const v3f &objectpos = obj->getBasePosition();
122 if (objectpos.getDistanceFromSQ(pos) > r2)
125 if (!include_obj_cb || include_obj_cb(obj))
126 result.push_back(obj);
130 void ActiveObjectMgr::getObjectsInArea(const aabb3f &box,
131 std::vector<ServerActiveObject *> &result,
132 std::function<bool(ServerActiveObject *obj)> include_obj_cb)
134 for (auto &activeObject : m_active_objects) {
135 ServerActiveObject *obj = activeObject.second;
136 const v3f &objectpos = obj->getBasePosition();
137 if (!box.isPointInside(objectpos))
140 if (!include_obj_cb || include_obj_cb(obj))
141 result.push_back(obj);
145 void ActiveObjectMgr::getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius,
146 f32 player_radius, std::set<u16> ¤t_objects,
147 std::queue<u16> &added_objects)
150 Go through the object list,
151 - discard removed/deactivated objects,
152 - discard objects that are too far away,
153 - discard objects that are found in current_objects.
154 - add remaining objects to added_objects
156 for (auto &ao_it : m_active_objects) {
157 u16 id = ao_it.first;
160 ServerActiveObject *object = ao_it.second;
164 if (object->isGone())
167 f32 distance_f = object->getBasePosition().getDistanceFrom(player_pos);
168 if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
169 // Discard if too far
170 if (distance_f > player_radius && player_radius != 0)
172 } else if (distance_f > radius)
175 // Discard if already on current_objects
176 auto n = current_objects.find(id);
177 if (n != current_objects.end())
179 // Add to added_objects
180 added_objects.push(id);
184 } // namespace server