From 22b07bdb30f602d9c469d97b138cf09ee131de62 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Tue, 18 Oct 2011 02:58:15 +0300 Subject: Fix object duplication bug --- src/environment.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/environment.cpp b/src/environment.cpp index 142271849..80e9d5c78 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -1695,6 +1695,10 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) continue; } + // If pending deactivation, let removeRemovedObjects() do it + if(obj->m_pending_deactivation) + continue; + u16 id = i.getNode()->getKey(); v3f objectpos = obj->getBasePosition(); @@ -1709,10 +1713,42 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) <<"deactivating object id="<m_known_by_count > 0 && !force_delete); + /* Update the static data */ + // Create new static object + std::string staticdata_new = obj->getStaticData(); + StaticObject s_obj(obj->getType(), objectpos, staticdata_new); + + bool stays_in_same_block = false; + bool data_changed = true; + + if(obj->m_static_exists){ + if(obj->m_static_block == blockpos_o) + stays_in_same_block = true; + + MapBlock *block = m_map->emergeBlock(obj->m_static_block, false); + + core::map::Node *n = + block->m_static_objects.m_active.find(id); + if(n){ + StaticObject static_old = n->getValue(); + + if(static_old.data == staticdata_new && + (static_old.pos - objectpos).getLength() < 2*BS) + data_changed = false; + } else { + errorstream<<"ServerEnvironment::deactivateFarObjects(): " + <<"id="<m_static_block)<m_static_exists) { @@ -1720,14 +1756,13 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) if(block) { block->m_static_objects.remove(id); - block->raiseModified(MOD_STATE_WRITE_AT_UNLOAD); obj->m_static_exists = false; + // Only mark block as modified if data changed considerably + if(!stays_in_same_block || data_changed) + block->raiseModified(MOD_STATE_WRITE_NEEDED); } } - // Create new static object - std::string staticdata = obj->getStaticData(); - StaticObject s_obj(obj->getType(), objectpos, staticdata); // Add to the block where the object is located in v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS)); // Get or generate the block @@ -1744,8 +1779,13 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) <<" Forcing delete."<m_static_objects.insert(0, s_obj); - block->raiseModified(MOD_STATE_WRITE_AT_UNLOAD); + u16 new_id = pending_delete ? id : 0; + block->m_static_objects.insert(new_id, s_obj); + + // Only mark block as modified if data changed considerably + if(!stays_in_same_block || data_changed) + block->raiseModified(MOD_STATE_WRITE_NEEDED); + obj->m_static_exists = true; obj->m_static_block = block->getPos(); } @@ -1758,12 +1798,11 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) } /* - Delete active object if not known by some client, - else set pending deactivation + If known by some client, set pending deactivation. + Otherwise delete it immediately. */ - // If known by some client, don't delete. - if(obj->m_known_by_count > 0 && force_delete == false) + if(pending_delete) { verbosestream<<"ServerEnvironment::deactivateFarObjects(): " <<"object id="<