Fix object duplication bug (at least in the most reproducible UFO case)
authorPerttu Ahola <celeron55@gmail.com>
Wed, 16 Oct 2013 21:10:16 +0000 (00:10 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Wed, 16 Oct 2013 21:10:16 +0000 (00:10 +0300)
src/environment.cpp
src/staticobject.h

index 03b436890b333d4c7fe8db968806889264da7ce1..dd160d1f7b17ddc16d082a444d7c60b846161f1e 100644 (file)
@@ -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;
index 640747e96dbe3152823d02cb0d6a16444a6582d7..575c15b18d9de747c9fbaf717cb30ce169d90a22 100644 (file)
@@ -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)
        {