Browse Source

Fix object duplication bug (at least in the most reproducible UFO case)

Perttu Ahola 10 years ago
parent
commit
b3591019ad
2 changed files with 42 additions and 1 deletions
  1. 41 0
      src/environment.cpp
  2. 1 1
      src/staticobject.h

+ 41 - 0
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;

+ 1 - 1
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)
 	{