aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2013-10-17 00:10:16 +0300
committerPerttu Ahola <celeron55@gmail.com>2013-10-17 00:10:16 +0300
commitb3591019ad7e9bdce2a0a20cbbf64a769c1717c2 (patch)
treea323058cdc2de0ec33c53a410397af95d6d22ee1
parent34e0a0ca0fbb6826ea0c583295f79307b1a754c6 (diff)
downloadminetest-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.cpp41
-rw-r--r--src/staticobject.h2
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)
{