diff options
author | Perttu Ahola <celeron55@gmail.com> | 2013-10-17 00:10:16 +0300 |
---|---|---|
committer | Perttu Ahola <celeron55@gmail.com> | 2013-10-17 00:10:16 +0300 |
commit | b3591019ad7e9bdce2a0a20cbbf64a769c1717c2 (patch) | |
tree | a323058cdc2de0ec33c53a410397af95d6d22ee1 | |
parent | 34e0a0ca0fbb6826ea0c583295f79307b1a754c6 (diff) | |
download | minetest-b3591019ad7e9bdce2a0a20cbbf64a769c1717c2.tar.gz minetest-b3591019ad7e9bdce2a0a20cbbf64a769c1717c2.tar.bz2 minetest-b3591019ad7e9bdce2a0a20cbbf64a769c1717c2.zip |
Fix object duplication bug (at least in the most reproducible UFO case)
-rw-r--r-- | src/environment.cpp | 41 | ||||
-rw-r--r-- | src/staticobject.h | 2 |
2 files changed, 42 insertions, 1 deletions
diff --git a/src/environment.cpp b/src/environment.cpp index 03b436890..dd160d1f7 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -1805,6 +1805,47 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) // The block in which the object resides in v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS)); + // If object's static data is stored in a deactivated block and object + // is actually located in an active block, re-save to the block in + // which the object is actually located in. + if(!force_delete && + obj->m_static_exists && + !m_active_blocks.contains(obj->m_static_block) && + m_active_blocks.contains(blockpos_o)) + { + v3s16 old_static_block = obj->m_static_block; + + // Save to block where object is located + MapBlock *block = m_map->emergeBlock(blockpos_o, false); + if(!block){ + errorstream<<"ServerEnvironment::deactivateFarObjects(): " + <<"Could not save object id="<<id + <<" to it's current block "<<PP(blockpos_o) + <<std::endl; + continue; + } + std::string staticdata_new = obj->getStaticData(); + StaticObject s_obj(obj->getType(), objectpos, staticdata_new); + block->m_static_objects.insert(id, s_obj); + obj->m_static_block = blockpos_o; + block->raiseModified(MOD_STATE_WRITE_NEEDED, + "deactivateFarObjects: Static data moved in"); + + // Delete from block where object was located + block = m_map->emergeBlock(old_static_block, false); + if(!block){ + errorstream<<"ServerEnvironment::deactivateFarObjects(): " + <<"Could not delete object id="<<id + <<" from it's previous block "<<PP(old_static_block) + <<std::endl; + continue; + } + block->m_static_objects.remove(id); + block->raiseModified(MOD_STATE_WRITE_NEEDED, + "deactivateFarObjects: Static data moved out"); + continue; + } + // If block is active, don't remove if(!force_delete && m_active_blocks.contains(blockpos_o)) continue; diff --git a/src/staticobject.h b/src/staticobject.h index 640747e96..575c15b18 100644 --- a/src/staticobject.h +++ b/src/staticobject.h @@ -54,7 +54,7 @@ class StaticObjectList public: /* Inserts an object to the container. - Id must be unique or 0. + Id must be unique (active) or 0 (stored). */ void insert(u16 id, StaticObject obj) { |