|
|
@ -582,13 +582,10 @@ void ServerEnvironment::clearAllObjects()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
infostream<<"ServerEnvironment::clearAllObjects(): "
|
|
|
|
infostream<<"ServerEnvironment::clearAllObjects(): "
|
|
|
|
<<"Removing all active objects"<<std::endl;
|
|
|
|
<<"Removing all active objects"<<std::endl;
|
|
|
|
core::list<u16> objects_to_remove;
|
|
|
|
std::vector<u16> objects_to_remove;
|
|
|
|
for(core::map<u16, ServerActiveObject*>::Iterator
|
|
|
|
for (std::map<u16, ServerActiveObject*>::iterator i = m_active_objects.begin(); i != m_active_objects.end(); i++) {
|
|
|
|
i = m_active_objects.getIterator();
|
|
|
|
ServerActiveObject* obj = i->second;
|
|
|
|
i.atEnd()==false; i++)
|
|
|
|
u16 id = i->first;
|
|
|
|
{
|
|
|
|
|
|
|
|
ServerActiveObject* obj = i.getNode()->getValue();
|
|
|
|
|
|
|
|
u16 id = i.getNode()->getKey();
|
|
|
|
|
|
|
|
v3f objectpos = obj->getBasePosition();
|
|
|
|
v3f objectpos = obj->getBasePosition();
|
|
|
|
// Delete static object if block is loaded
|
|
|
|
// Delete static object if block is loaded
|
|
|
|
if(obj->m_static_exists){
|
|
|
|
if(obj->m_static_exists){
|
|
|
@ -611,10 +608,8 @@ void ServerEnvironment::clearAllObjects()
|
|
|
|
objects_to_remove.push_back(id);
|
|
|
|
objects_to_remove.push_back(id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Remove references from m_active_objects
|
|
|
|
// Remove references from m_active_objects
|
|
|
|
for(core::list<u16>::Iterator i = objects_to_remove.begin();
|
|
|
|
for (std::vector<u16>::iterator i = objects_to_remove.begin(); i != objects_to_remove.end(); i++) {
|
|
|
|
i != objects_to_remove.end(); i++)
|
|
|
|
m_active_objects.erase(*i);
|
|
|
|
{
|
|
|
|
|
|
|
|
m_active_objects.remove(*i);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
core::list<v3s16> loadable_blocks;
|
|
|
|
core::list<v3s16> loadable_blocks;
|
|
|
@ -2722,24 +2717,19 @@ void ServerEnvironment::step(float dtime)
|
|
|
|
send_recommended = true;
|
|
|
|
send_recommended = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for(core::map<u16, ServerActiveObject*>::Iterator
|
|
|
|
for (std::map<u16, ServerActiveObject*>::iterator i = m_active_objects.begin(); i != m_active_objects.end(); i++) {
|
|
|
|
i = m_active_objects.getIterator();
|
|
|
|
ServerActiveObject* obj = i->second;
|
|
|
|
i.atEnd()==false; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ServerActiveObject* obj = i.getNode()->getValue();
|
|
|
|
|
|
|
|
// Remove non-peaceful mobs on peaceful mode
|
|
|
|
// Remove non-peaceful mobs on peaceful mode
|
|
|
|
if(obj->level() > mob_level)
|
|
|
|
if (obj->level() > mob_level)
|
|
|
|
obj->m_removed = true;
|
|
|
|
obj->m_removed = true;
|
|
|
|
// Don't step if is to be removed or stored statically
|
|
|
|
// Don't step if is to be removed or stored statically
|
|
|
|
if(obj->m_removed || obj->m_pending_deactivation)
|
|
|
|
if (obj->m_removed || obj->m_pending_deactivation)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
// Step object
|
|
|
|
// Step object
|
|
|
|
obj->step(dtime, send_recommended);
|
|
|
|
obj->step(dtime, send_recommended);
|
|
|
|
// Read messages from object
|
|
|
|
// Read messages from object
|
|
|
|
while(obj->m_messages_out.size() > 0)
|
|
|
|
while (obj->m_messages_out.size() > 0) {
|
|
|
|
{
|
|
|
|
m_active_object_messages.push_back(obj->m_messages_out.pop_front());
|
|
|
|
m_active_object_messages.push_back(
|
|
|
|
|
|
|
|
obj->m_messages_out.pop_front());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -2759,11 +2749,10 @@ void ServerEnvironment::step(float dtime)
|
|
|
|
|
|
|
|
|
|
|
|
ServerActiveObject* ServerEnvironment::getActiveObject(u16 id)
|
|
|
|
ServerActiveObject* ServerEnvironment::getActiveObject(u16 id)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
core::map<u16, ServerActiveObject*>::Node *n;
|
|
|
|
std::map<u16, ServerActiveObject*>::iterator i = m_active_objects.find(id);
|
|
|
|
n = m_active_objects.find(id);
|
|
|
|
if (i == m_active_objects.end())
|
|
|
|
if(n == NULL)
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
return n->getValue();
|
|
|
|
return i->second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool ServerEnvironment::propogateEnergy(u8 level, v3s16 powersrc, v3s16 signalsrc, v3s16 pos)
|
|
|
|
bool ServerEnvironment::propogateEnergy(u8 level, v3s16 powersrc, v3s16 signalsrc, v3s16 pos)
|
|
|
@ -3037,24 +3026,18 @@ bool ServerEnvironment::propogateEnergy(u8 level, v3s16 powersrc, v3s16 signalsr
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool isFreeServerActiveObjectId(u16 id,
|
|
|
|
bool isFreeServerActiveObjectId(u16 id, std::map<u16, ServerActiveObject*> &objects)
|
|
|
|
core::map<u16, ServerActiveObject*> &objects)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(id == 0)
|
|
|
|
if (id == 0)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
for(core::map<u16, ServerActiveObject*>::Iterator
|
|
|
|
std::map<u16, ServerActiveObject*>::iterator i = objects.find(id);
|
|
|
|
i = objects.getIterator();
|
|
|
|
if (i == objects.end())
|
|
|
|
i.atEnd()==false; i++)
|
|
|
|
return true;
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
if(i.getNode()->getKey() == id)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
u16 getFreeServerActiveObjectId(
|
|
|
|
u16 getFreeServerActiveObjectId(std::map<u16, ServerActiveObject*> &objects)
|
|
|
|
core::map<u16, ServerActiveObject*> &objects)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//try to reuse id's as late as possible
|
|
|
|
//try to reuse id's as late as possible
|
|
|
|
static u16 last_used_id = 0;
|
|
|
|
static u16 last_used_id = 0;
|
|
|
@ -3137,26 +3120,23 @@ void ServerEnvironment::getAddedActiveObjects(v3s16 pos, s16 radius,
|
|
|
|
- discard objects that are found in current_objects.
|
|
|
|
- discard objects that are found in current_objects.
|
|
|
|
- add remaining objects to added_objects
|
|
|
|
- add remaining objects to added_objects
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
for(core::map<u16, ServerActiveObject*>::Iterator
|
|
|
|
for (std::map<u16, ServerActiveObject*>::iterator i = m_active_objects.begin(); i != m_active_objects.end(); i++) {
|
|
|
|
i = m_active_objects.getIterator();
|
|
|
|
u16 id = i->first;
|
|
|
|
i.atEnd()==false; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
u16 id = i.getNode()->getKey();
|
|
|
|
|
|
|
|
// Get object
|
|
|
|
// Get object
|
|
|
|
ServerActiveObject *object = i.getNode()->getValue();
|
|
|
|
ServerActiveObject *object = i->second;
|
|
|
|
if(object == NULL)
|
|
|
|
if (object == NULL)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
// Discard if removed
|
|
|
|
// Discard if removed
|
|
|
|
if(object->m_removed)
|
|
|
|
if (object->m_removed)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
// Discard if too far
|
|
|
|
// Discard if too far
|
|
|
|
f32 distance_f = object->getBasePosition().getDistanceFrom(pos_f);
|
|
|
|
f32 distance_f = object->getBasePosition().getDistanceFrom(pos_f);
|
|
|
|
if(distance_f > radius_f)
|
|
|
|
if (distance_f > radius_f)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
// Discard if already on current_objects
|
|
|
|
// Discard if already on current_objects
|
|
|
|
core::map<u16, bool>::Node *n;
|
|
|
|
core::map<u16, bool>::Node *n;
|
|
|
|
n = current_objects.find(id);
|
|
|
|
n = current_objects.find(id);
|
|
|
|
if(n != NULL)
|
|
|
|
if (n != NULL)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
// Add to added_objects
|
|
|
|
// Add to added_objects
|
|
|
|
added_objects.insert(id, false);
|
|
|
|
added_objects.insert(id, false);
|
|
|
@ -3248,7 +3228,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object, bool set_c
|
|
|
|
/*infostream<<"ServerEnvironment::addActiveObjectRaw(): "
|
|
|
|
/*infostream<<"ServerEnvironment::addActiveObjectRaw(): "
|
|
|
|
<<"added (id="<<object->getId()<<")"<<std::endl;*/
|
|
|
|
<<"added (id="<<object->getId()<<")"<<std::endl;*/
|
|
|
|
|
|
|
|
|
|
|
|
m_active_objects.insert(object->getId(), object);
|
|
|
|
m_active_objects[object->getId()] = object;
|
|
|
|
|
|
|
|
|
|
|
|
verbosestream<<"ServerEnvironment::addActiveObjectRaw(): "
|
|
|
|
verbosestream<<"ServerEnvironment::addActiveObjectRaw(): "
|
|
|
|
<<"Added id="<<object->getId()<<"; there are now "
|
|
|
|
<<"Added id="<<object->getId()<<"; there are now "
|
|
|
@ -3285,16 +3265,12 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object, bool set_c
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void ServerEnvironment::removeRemovedObjects()
|
|
|
|
void ServerEnvironment::removeRemovedObjects()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
core::list<u16> objects_to_remove;
|
|
|
|
std::vector<u16> objects_to_remove;
|
|
|
|
for(core::map<u16, ServerActiveObject*>::Iterator
|
|
|
|
for (std::map<u16, ServerActiveObject*>::iterator i = m_active_objects.begin(); i != m_active_objects.end(); i++) {
|
|
|
|
i = m_active_objects.getIterator();
|
|
|
|
u16 id = i->first;
|
|
|
|
i.atEnd()==false; i++)
|
|
|
|
ServerActiveObject* obj = i->second;
|
|
|
|
{
|
|
|
|
|
|
|
|
u16 id = i.getNode()->getKey();
|
|
|
|
|
|
|
|
ServerActiveObject* obj = i.getNode()->getValue();
|
|
|
|
|
|
|
|
// This shouldn't happen but check it
|
|
|
|
// This shouldn't happen but check it
|
|
|
|
if(obj == NULL)
|
|
|
|
if (obj == NULL) {
|
|
|
|
{
|
|
|
|
|
|
|
|
infostream<<"NULL object found in ServerEnvironment"
|
|
|
|
infostream<<"NULL object found in ServerEnvironment"
|
|
|
|
<<" while finding removed objects. id="<<id<<std::endl;
|
|
|
|
<<" while finding removed objects. id="<<id<<std::endl;
|
|
|
|
// Id to be removed from m_active_objects
|
|
|
|
// Id to be removed from m_active_objects
|
|
|
@ -3306,17 +3282,15 @@ void ServerEnvironment::removeRemovedObjects()
|
|
|
|
We will delete objects that are marked as removed or thatare
|
|
|
|
We will delete objects that are marked as removed or thatare
|
|
|
|
waiting for deletion after deactivation
|
|
|
|
waiting for deletion after deactivation
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
if(obj->m_removed == false && obj->m_pending_deactivation == false)
|
|
|
|
if (obj->m_removed == false && obj->m_pending_deactivation == false)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
Delete static data from block if is marked as removed
|
|
|
|
Delete static data from block if is marked as removed
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
if(obj->m_static_exists && obj->m_removed)
|
|
|
|
if (obj->m_static_exists && obj->m_removed) {
|
|
|
|
{
|
|
|
|
|
|
|
|
MapBlock *block = m_map->emergeBlock(obj->m_static_block);
|
|
|
|
MapBlock *block = m_map->emergeBlock(obj->m_static_block);
|
|
|
|
if(block)
|
|
|
|
if (block) {
|
|
|
|
{
|
|
|
|
|
|
|
|
block->m_static_objects.remove(id);
|
|
|
|
block->m_static_objects.remove(id);
|
|
|
|
block->raiseModified(MOD_STATE_WRITE_NEEDED);
|
|
|
|
block->raiseModified(MOD_STATE_WRITE_NEEDED);
|
|
|
|
obj->m_static_exists = false;
|
|
|
|
obj->m_static_exists = false;
|
|
|
@ -3324,7 +3298,7 @@ void ServerEnvironment::removeRemovedObjects()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If m_known_by_count > 0, don't actually remove.
|
|
|
|
// If m_known_by_count > 0, don't actually remove.
|
|
|
|
if(obj->m_known_by_count > 0)
|
|
|
|
if (obj->m_known_by_count > 0)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
// Delete
|
|
|
|
// Delete
|
|
|
@ -3333,10 +3307,8 @@ void ServerEnvironment::removeRemovedObjects()
|
|
|
|
objects_to_remove.push_back(id);
|
|
|
|
objects_to_remove.push_back(id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Remove references from m_active_objects
|
|
|
|
// Remove references from m_active_objects
|
|
|
|
for(core::list<u16>::Iterator i = objects_to_remove.begin();
|
|
|
|
for (std::vector<u16>::iterator i = objects_to_remove.begin(); i != objects_to_remove.end(); i++) {
|
|
|
|
i != objects_to_remove.end(); i++)
|
|
|
|
m_active_objects.erase(*i);
|
|
|
|
{
|
|
|
|
|
|
|
|
m_active_objects.remove(*i);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -3379,17 +3351,17 @@ static void print_hexdump(std::ostream &o, const std::string &data)
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void ServerEnvironment::activateObjects(MapBlock *block)
|
|
|
|
void ServerEnvironment::activateObjects(MapBlock *block)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(block==NULL)
|
|
|
|
if (block==NULL)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
// Ignore if no stored objects (to not set changed flag)
|
|
|
|
// Ignore if no stored objects (to not set changed flag)
|
|
|
|
if(block->m_static_objects.m_stored.size() == 0)
|
|
|
|
if (block->m_static_objects.m_stored.size() == 0)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
verbosestream<<"ServerEnvironment::activateObjects(): "
|
|
|
|
verbosestream<<"ServerEnvironment::activateObjects(): "
|
|
|
|
<<"activating objects of block "<<PP(block->getPos())
|
|
|
|
<<"activating objects of block "<<PP(block->getPos())
|
|
|
|
<<" ("<<block->m_static_objects.m_stored.size()
|
|
|
|
<<" ("<<block->m_static_objects.m_stored.size()
|
|
|
|
<<" objects)"<<std::endl;
|
|
|
|
<<" objects)"<<std::endl;
|
|
|
|
bool large_amount = (block->m_static_objects.m_stored.size() > 49);
|
|
|
|
bool large_amount = (block->m_static_objects.m_stored.size() > 49);
|
|
|
|
if(large_amount){
|
|
|
|
if (large_amount) {
|
|
|
|
errorstream<<"suspiciously large amount of objects detected: "
|
|
|
|
errorstream<<"suspiciously large amount of objects detected: "
|
|
|
|
<<block->m_static_objects.m_stored.size()<<" in "
|
|
|
|
<<block->m_static_objects.m_stored.size()<<" in "
|
|
|
|
<<PP(block->getPos())
|
|
|
|
<<PP(block->getPos())
|
|
|
@ -3401,9 +3373,9 @@ void ServerEnvironment::activateObjects(MapBlock *block)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// A list for objects that couldn't be converted to static for some
|
|
|
|
// A list for objects that couldn't be converted to static for some
|
|
|
|
// reason. They will be stored back.
|
|
|
|
// reason. They will be stored back.
|
|
|
|
core::list<StaticObject> new_stored;
|
|
|
|
std::vector<StaticObject> new_stored;
|
|
|
|
// Loop through stored static objects
|
|
|
|
// Loop through stored static objects
|
|
|
|
for(core::list<StaticObject>::Iterator
|
|
|
|
for (core::list<StaticObject>::Iterator
|
|
|
|
i = block->m_static_objects.m_stored.begin();
|
|
|
|
i = block->m_static_objects.m_stored.begin();
|
|
|
|
i != block->m_static_objects.m_stored.end(); i++)
|
|
|
|
i != block->m_static_objects.m_stored.end(); i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -3414,8 +3386,7 @@ void ServerEnvironment::activateObjects(MapBlock *block)
|
|
|
|
ServerActiveObject *obj = ServerActiveObject::create
|
|
|
|
ServerActiveObject *obj = ServerActiveObject::create
|
|
|
|
(s_obj.type, this, 0, s_obj.pos, s_obj.data);
|
|
|
|
(s_obj.type, this, 0, s_obj.pos, s_obj.data);
|
|
|
|
// If couldn't create object, store static data back.
|
|
|
|
// If couldn't create object, store static data back.
|
|
|
|
if(obj==NULL)
|
|
|
|
if (obj==NULL) {
|
|
|
|
{
|
|
|
|
|
|
|
|
errorstream<<"ServerEnvironment::activateObjects(): "
|
|
|
|
errorstream<<"ServerEnvironment::activateObjects(): "
|
|
|
|
<<"failed to create active object from static object "
|
|
|
|
<<"failed to create active object from static object "
|
|
|
|
<<"in block "<<PP(s_obj.pos/BS)
|
|
|
|
<<"in block "<<PP(s_obj.pos/BS)
|
|
|
@ -3434,10 +3405,7 @@ void ServerEnvironment::activateObjects(MapBlock *block)
|
|
|
|
// Clear stored list
|
|
|
|
// Clear stored list
|
|
|
|
block->m_static_objects.m_stored.clear();
|
|
|
|
block->m_static_objects.m_stored.clear();
|
|
|
|
// Add leftover failed stuff to stored list
|
|
|
|
// Add leftover failed stuff to stored list
|
|
|
|
for(core::list<StaticObject>::Iterator
|
|
|
|
for (std::vector<StaticObject>::iterator i = new_stored.begin(); i != new_stored.end(); i++) {
|
|
|
|
i = new_stored.begin();
|
|
|
|
|
|
|
|
i != new_stored.end(); i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
StaticObject &s_obj = *i;
|
|
|
|
StaticObject &s_obj = *i;
|
|
|
|
block->m_static_objects.m_stored.push_back(s_obj);
|
|
|
|
block->m_static_objects.m_stored.push_back(s_obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -3462,16 +3430,12 @@ void ServerEnvironment::activateObjects(MapBlock *block)
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
|
|
|
void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
core::list<u16> objects_to_remove;
|
|
|
|
std::vector<u16> objects_to_remove;
|
|
|
|
for(core::map<u16, ServerActiveObject*>::Iterator
|
|
|
|
for (std::map<u16, ServerActiveObject*>::iterator i = m_active_objects.begin(); i != m_active_objects.end(); i++) {
|
|
|
|
i = m_active_objects.getIterator();
|
|
|
|
ServerActiveObject* obj = i->second;
|
|
|
|
i.atEnd()==false; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ServerActiveObject* obj = i.getNode()->getValue();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This shouldn't happen but check it
|
|
|
|
// This shouldn't happen but check it
|
|
|
|
if(obj == NULL)
|
|
|
|
if (obj == NULL) {
|
|
|
|
{
|
|
|
|
|
|
|
|
errorstream<<"NULL object found in ServerEnvironment"
|
|
|
|
errorstream<<"NULL object found in ServerEnvironment"
|
|
|
|
<<std::endl;
|
|
|
|
<<std::endl;
|
|
|
|
assert(0);
|
|
|
|
assert(0);
|
|
|
@ -3479,26 +3443,52 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If pending deactivation, let removeRemovedObjects() do it
|
|
|
|
// If pending deactivation, let removeRemovedObjects() do it
|
|
|
|
if(obj->m_pending_deactivation)
|
|
|
|
if (obj->m_pending_deactivation)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
u16 id = i.getNode()->getKey();
|
|
|
|
u16 id = i->first;
|
|
|
|
v3f objectpos = obj->getBasePosition();
|
|
|
|
v3f objectpos = obj->getBasePosition();
|
|
|
|
|
|
|
|
|
|
|
|
// The block in which the object resides in
|
|
|
|
// The block in which the object resides in
|
|
|
|
v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS));
|
|
|
|
v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If known by some client, don't immediately delete.
|
|
|
|
|
|
|
|
bool pending_delete = (obj->m_known_by_count > 0 && !force_delete);
|
|
|
|
|
|
|
|
|
|
|
|
// If block is active, don't remove
|
|
|
|
// If block is active, don't remove
|
|
|
|
if(m_active_blocks.contains(blockpos_o))
|
|
|
|
if (m_active_blocks.contains(blockpos_o)) {
|
|
|
|
|
|
|
|
if (obj->m_static_exists && blockpos_o != obj->m_static_block) {
|
|
|
|
|
|
|
|
std::string staticdata_new = obj->getStaticData();
|
|
|
|
|
|
|
|
StaticObject s_obj(obj->getType(), objectpos, staticdata_new);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MapBlock *block = m_map->emergeBlock(obj->m_static_block, false);
|
|
|
|
|
|
|
|
if (block) {
|
|
|
|
|
|
|
|
block->m_static_objects.remove(id);
|
|
|
|
|
|
|
|
obj->m_static_exists = false;
|
|
|
|
|
|
|
|
block->raiseModified(MOD_STATE_WRITE_NEEDED);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
block = m_map->emergeBlock(blockpos_o);
|
|
|
|
|
|
|
|
if (block) {
|
|
|
|
|
|
|
|
if (block->m_static_objects.m_stored.size() < 50) {
|
|
|
|
|
|
|
|
u16 new_id = pending_delete ? id : 0;
|
|
|
|
|
|
|
|
block->m_static_objects.insert(new_id, s_obj);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
block->raiseModified(MOD_STATE_WRITE_NEEDED);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
obj->m_static_exists = true;
|
|
|
|
|
|
|
|
obj->m_static_block = block->getPos();
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
obj->m_removed = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
verbosestream<<"ServerEnvironment::deactivateFarObjects(): "
|
|
|
|
verbosestream<<"ServerEnvironment::deactivateFarObjects(): "
|
|
|
|
<<"deactivating object id="<<id<<" on inactive block "
|
|
|
|
<<"deactivating object id="<<id<<" on inactive block "
|
|
|
|
<<PP(blockpos_o)<<std::endl;
|
|
|
|
<<PP(blockpos_o)<<std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
// If known by some client, don't immediately delete.
|
|
|
|
|
|
|
|
bool pending_delete = (obj->m_known_by_count > 0 && !force_delete);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
Update the static data
|
|
|
|
Update the static data
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -3510,21 +3500,19 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
|
|
|
bool stays_in_same_block = false;
|
|
|
|
bool stays_in_same_block = false;
|
|
|
|
bool data_changed = true;
|
|
|
|
bool data_changed = true;
|
|
|
|
|
|
|
|
|
|
|
|
if(obj->m_static_exists){
|
|
|
|
if (obj->m_static_exists) {
|
|
|
|
if(obj->m_static_block == blockpos_o)
|
|
|
|
if (obj->m_static_block == blockpos_o)
|
|
|
|
stays_in_same_block = true;
|
|
|
|
stays_in_same_block = true;
|
|
|
|
|
|
|
|
|
|
|
|
MapBlock *block = m_map->emergeBlock(obj->m_static_block, false);
|
|
|
|
MapBlock *block = m_map->emergeBlock(obj->m_static_block, false);
|
|
|
|
|
|
|
|
|
|
|
|
core::map<u16, StaticObject>::Node *n =
|
|
|
|
core::map<u16, StaticObject>::Node *n = block->m_static_objects.m_active.find(id);
|
|
|
|
block->m_static_objects.m_active.find(id);
|
|
|
|
if (n) {
|
|
|
|
if(n){
|
|
|
|
|
|
|
|
StaticObject static_old = n->getValue();
|
|
|
|
StaticObject static_old = n->getValue();
|
|
|
|
|
|
|
|
|
|
|
|
if(static_old.data == staticdata_new &&
|
|
|
|
if (static_old.data == staticdata_new && (static_old.pos - objectpos).getLength() < 2*BS)
|
|
|
|
(static_old.pos - objectpos).getLength() < 2*BS)
|
|
|
|
|
|
|
|
data_changed = false;
|
|
|
|
data_changed = false;
|
|
|
|
} else {
|
|
|
|
}else{
|
|
|
|
errorstream<<"ServerEnvironment::deactivateFarObjects(): "
|
|
|
|
errorstream<<"ServerEnvironment::deactivateFarObjects(): "
|
|
|
|
<<"id="<<id<<" m_static_exists=true but "
|
|
|
|
<<"id="<<id<<" m_static_exists=true but "
|
|
|
|
<<"static data doesn't actually exist in "
|
|
|
|
<<"static data doesn't actually exist in "
|
|
|
@ -3533,15 +3521,13 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Delete old static object
|
|
|
|
// Delete old static object
|
|
|
|
if(obj->m_static_exists)
|
|
|
|
if (obj->m_static_exists) {
|
|
|
|
{
|
|
|
|
|
|
|
|
MapBlock *block = m_map->emergeBlock(obj->m_static_block, false);
|
|
|
|
MapBlock *block = m_map->emergeBlock(obj->m_static_block, false);
|
|
|
|
if(block)
|
|
|
|
if (block) {
|
|
|
|
{
|
|
|
|
|
|
|
|
block->m_static_objects.remove(id);
|
|
|
|
block->m_static_objects.remove(id);
|
|
|
|
obj->m_static_exists = false;
|
|
|
|
obj->m_static_exists = false;
|
|
|
|
// Only mark block as modified if data changed considerably
|
|
|
|
// Only mark block as modified if data changed considerably
|
|
|
|
if(!stays_in_same_block || data_changed)
|
|
|
|
if (!stays_in_same_block || data_changed)
|
|
|
|
block->raiseModified(MOD_STATE_WRITE_NEEDED);
|
|
|
|
block->raiseModified(MOD_STATE_WRITE_NEEDED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -3551,9 +3537,8 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
|
|
|
// Get or generate the block
|
|
|
|
// Get or generate the block
|
|
|
|
MapBlock *block = m_map->emergeBlock(blockpos);
|
|
|
|
MapBlock *block = m_map->emergeBlock(blockpos);
|
|
|
|
|
|
|
|
|
|
|
|
if(block)
|
|
|
|
if (block) {
|
|
|
|
{
|
|
|
|
if (block->m_static_objects.m_stored.size() >= 49) {
|
|
|
|
if(block->m_static_objects.m_stored.size() >= 49){
|
|
|
|
|
|
|
|
errorstream<<"ServerEnv: Trying to store id="<<obj->getId()
|
|
|
|
errorstream<<"ServerEnv: Trying to store id="<<obj->getId()
|
|
|
|
<<" statically but block "<<PP(blockpos)
|
|
|
|
<<" statically but block "<<PP(blockpos)
|
|
|
|
<<" already contains "
|
|
|
|
<<" already contains "
|
|
|
@ -3561,19 +3546,18 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
|
|
|
<<" (over 49) objects."
|
|
|
|
<<" (over 49) objects."
|
|
|
|
<<" Forcing delete."<<std::endl;
|
|
|
|
<<" Forcing delete."<<std::endl;
|
|
|
|
force_delete = true;
|
|
|
|
force_delete = true;
|
|
|
|
} else {
|
|
|
|
}else{
|
|
|
|
u16 new_id = pending_delete ? id : 0;
|
|
|
|
u16 new_id = pending_delete ? id : 0;
|
|
|
|
block->m_static_objects.insert(new_id, s_obj);
|
|
|
|
block->m_static_objects.insert(new_id, s_obj);
|
|
|
|
|
|
|
|
|
|
|
|
// Only mark block as modified if data changed considerably
|
|
|
|
// Only mark block as modified if data changed considerably
|
|
|
|
if(!stays_in_same_block || data_changed)
|
|
|
|
if (!stays_in_same_block || data_changed)
|
|
|
|
block->raiseModified(MOD_STATE_WRITE_NEEDED);
|
|
|
|
block->raiseModified(MOD_STATE_WRITE_NEEDED);
|
|
|
|
|
|
|
|
|
|
|
|
obj->m_static_exists = true;
|
|
|
|
obj->m_static_exists = true;
|
|
|
|
obj->m_static_block = block->getPos();
|
|
|
|
obj->m_static_block = block->getPos();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
else{
|
|
|
|
|
|
|
|
errorstream<<"ServerEnv: Could not find or generate "
|
|
|
|
errorstream<<"ServerEnv: Could not find or generate "
|
|
|
|
<<"a block for storing id="<<obj->getId()
|
|
|
|
<<"a block for storing id="<<obj->getId()
|
|
|
|
<<" statically"<<std::endl;
|
|
|
|
<<" statically"<<std::endl;
|
|
|
@ -3585,8 +3569,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
|
|
|
Otherwise delete it immediately.
|
|
|
|
Otherwise delete it immediately.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
if(pending_delete)
|
|
|
|
if (pending_delete) {
|
|
|
|
{
|
|
|
|
|
|
|
|
verbosestream<<"ServerEnvironment::deactivateFarObjects(): "
|
|
|
|
verbosestream<<"ServerEnvironment::deactivateFarObjects(): "
|
|
|
|
<<"object id="<<id<<" is known by clients"
|
|
|
|
<<"object id="<<id<<" is known by clients"
|
|
|
|
<<"; not deleting yet"<<std::endl;
|
|
|
|
<<"; not deleting yet"<<std::endl;
|
|
|
@ -3605,10 +3588,8 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Remove references from m_active_objects
|
|
|
|
// Remove references from m_active_objects
|
|
|
|
for(core::list<u16>::Iterator i = objects_to_remove.begin();
|
|
|
|
for (std::vector<u16>::iterator i = objects_to_remove.begin(); i != objects_to_remove.end(); i++) {
|
|
|
|
i != objects_to_remove.end(); i++)
|
|
|
|
m_active_objects.erase(*i);
|
|
|
|
{
|
|
|
|
|
|
|
|
m_active_objects.remove(*i);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -3631,11 +3612,8 @@ ClientEnvironment::ClientEnvironment(Client *client, ClientMap *map, scene::ISce
|
|
|
|
ClientEnvironment::~ClientEnvironment()
|
|
|
|
ClientEnvironment::~ClientEnvironment()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// delete active objects
|
|
|
|
// delete active objects
|
|
|
|
for(core::map<u16, ClientActiveObject*>::Iterator
|
|
|
|
for (std::map<u16, ClientActiveObject*>::iterator i = m_active_objects.begin(); i != m_active_objects.end(); i++) {
|
|
|
|
i = m_active_objects.getIterator();
|
|
|
|
delete i->second;
|
|
|
|
i.atEnd()==false; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
delete i.getNode()->getValue();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Drop/delete map
|
|
|
|
// Drop/delete map
|
|
|
@ -3943,16 +3921,12 @@ void ClientEnvironment::step(float dtime)
|
|
|
|
Step active objects and update lighting of them
|
|
|
|
Step active objects and update lighting of them
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
for(core::map<u16, ClientActiveObject*>::Iterator
|
|
|
|
for (std::map<u16, ClientActiveObject*>::iterator i = m_active_objects.begin(); i != m_active_objects.end(); i++) {
|
|
|
|
i = m_active_objects.getIterator();
|
|
|
|
ClientActiveObject* obj = i->second;
|
|
|
|
i.atEnd()==false; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ClientActiveObject* obj = i.getNode()->getValue();
|
|
|
|
|
|
|
|
// Step object
|
|
|
|
// Step object
|
|
|
|
obj->step(dtime, this);
|
|
|
|
obj->step(dtime, this);
|
|
|
|
|
|
|
|
|
|
|
|
if(m_active_object_light_update_interval.step(dtime, 0.21))
|
|
|
|
if (m_active_object_light_update_interval.step(dtime, 0.21)) {
|
|
|
|
{
|
|
|
|
|
|
|
|
// Update lighting
|
|
|
|
// Update lighting
|
|
|
|
//u8 light = LIGHT_MAX;
|
|
|
|
//u8 light = LIGHT_MAX;
|
|
|
|
u8 light = 0;
|
|
|
|
u8 light = 0;
|
|
|
@ -3980,31 +3954,24 @@ void ClientEnvironment::expireMeshes(bool only_daynight_diffed)
|
|
|
|
|
|
|
|
|
|
|
|
ClientActiveObject* ClientEnvironment::getActiveObject(u16 id)
|
|
|
|
ClientActiveObject* ClientEnvironment::getActiveObject(u16 id)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
core::map<u16, ClientActiveObject*>::Node *n;
|
|
|
|
std::map<u16, ClientActiveObject*>::iterator i = m_active_objects.find(id);
|
|
|
|
n = m_active_objects.find(id);
|
|
|
|
if (i == m_active_objects.end())
|
|
|
|
if(n == NULL)
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
return n->getValue();
|
|
|
|
return i->second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool isFreeClientActiveObjectId(u16 id,
|
|
|
|
bool isFreeClientActiveObjectId(u16 id, std::map<u16, ClientActiveObject*> &objects)
|
|
|
|
core::map<u16, ClientActiveObject*> &objects)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(id == 0)
|
|
|
|
if (id == 0)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
for(core::map<u16, ClientActiveObject*>::Iterator
|
|
|
|
std::map<u16, ClientActiveObject*>::iterator i = objects.find(id);
|
|
|
|
i = objects.getIterator();
|
|
|
|
if (i == objects.end())
|
|
|
|
i.atEnd()==false; i++)
|
|
|
|
return true;
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
if(i.getNode()->getKey() == id)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
u16 getFreeClientActiveObjectId(
|
|
|
|
u16 getFreeClientActiveObjectId(std::map<u16, ClientActiveObject*> &objects)
|
|
|
|
core::map<u16, ClientActiveObject*> &objects)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//try to reuse id's as late as possible
|
|
|
|
//try to reuse id's as late as possible
|
|
|
|
static u16 last_used_id = 0;
|
|
|
|
static u16 last_used_id = 0;
|
|
|
@ -4045,7 +4012,7 @@ u16 ClientEnvironment::addActiveObject(ClientActiveObject *object)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
infostream<<"ClientEnvironment::addActiveObject(): "
|
|
|
|
infostream<<"ClientEnvironment::addActiveObject(): "
|
|
|
|
<<"added (id="<<object->getId()<<")"<<std::endl;
|
|
|
|
<<"added (id="<<object->getId()<<")"<<std::endl;
|
|
|
|
m_active_objects.insert(object->getId(), object);
|
|
|
|
m_active_objects[object->getId()] = object;
|
|
|
|
object->addToScene(m_smgr);
|
|
|
|
object->addToScene(m_smgr);
|
|
|
|
{ // Update lighting immediately
|
|
|
|
{ // Update lighting immediately
|
|
|
|
u8 light = 0;
|
|
|
|
u8 light = 0;
|
|
|
@ -4091,7 +4058,7 @@ void ClientEnvironment::removeActiveObject(u16 id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
obj->removeFromScene();
|
|
|
|
obj->removeFromScene();
|
|
|
|
delete obj;
|
|
|
|
delete obj;
|
|
|
|
m_active_objects.remove(id);
|
|
|
|
m_active_objects.erase(id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ClientEnvironment::processActiveObjectMessage(u16 id,
|
|
|
|
void ClientEnvironment::processActiveObjectMessage(u16 id,
|
|
|
@ -4132,14 +4099,10 @@ void ClientEnvironment::damageLocalPlayer(u8 damage)
|
|
|
|
Client likes to call these
|
|
|
|
Client likes to call these
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
void ClientEnvironment::getActiveObjects(v3f origin, f32 max_d,
|
|
|
|
void ClientEnvironment::getActiveObjects(v3f origin, f32 max_d, core::array<DistanceSortedActiveObject> &dest)
|
|
|
|
core::array<DistanceSortedActiveObject> &dest)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for(core::map<u16, ClientActiveObject*>::Iterator
|
|
|
|
for (std::map<u16, ClientActiveObject*>::iterator i = m_active_objects.begin(); i != m_active_objects.end(); i++) {
|
|
|
|
i = m_active_objects.getIterator();
|
|
|
|
ClientActiveObject* obj = i->second;
|
|
|
|
i.atEnd()==false; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ClientActiveObject* obj = i.getNode()->getValue();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
f32 d = (obj->getPosition() - origin).getLength();
|
|
|
|
f32 d = (obj->getPosition() - origin).getLength();
|
|
|
|
|
|
|
|
|
|
|
@ -4241,14 +4204,12 @@ bool ClientEnvironment::searchNearInv(v3s16 pos, v3s16 radius_min, v3s16 radius_
|
|
|
|
|
|
|
|
|
|
|
|
void ClientEnvironment::updateObjectsCameraOffset(v3s16 camera_offset)
|
|
|
|
void ClientEnvironment::updateObjectsCameraOffset(v3s16 camera_offset)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for(core::map<u16, ClientActiveObject*>::Iterator
|
|
|
|
for (std::map<u16, ClientActiveObject*>::iterator i = m_active_objects.begin(); i != m_active_objects.end(); i++) {
|
|
|
|
i = m_active_objects.getIterator();
|
|
|
|
ClientActiveObject* obj = i->second;
|
|
|
|
i.atEnd()==false; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ClientActiveObject* obj = i.getNode()->getValue();
|
|
|
|
|
|
|
|
obj->updateCameraOffset(camera_offset);
|
|
|
|
obj->updateCameraOffset(camera_offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(core::list<Player*>::Iterator i = m_players.begin();
|
|
|
|
|
|
|
|
|
|
|
|
for (core::list<Player*>::Iterator i = m_players.begin();
|
|
|
|
i != m_players.end(); i++)
|
|
|
|
i != m_players.end(); i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Player *player = *i;
|
|
|
|
Player *player = *i;
|
|
|
|