Update ABM object counts when triggers add objects
authorCiaran Gultnieks <ciaran@ciarang.com>
Thu, 6 Mar 2014 19:20:06 +0000 (19:20 +0000)
committersapier <Sapier at GMX dot net>
Sun, 9 Mar 2014 10:13:44 +0000 (11:13 +0100)
Also fixes long-standing accuracy issue due to unknown wider
object count not being incremented.

src/environment.cpp
src/environment.h

index 9f7207b8d8533fa5c90d3466b36dad26c1912b9c..3593c94f05e740fb916d12c074c19e1c107cc516 100644 (file)
@@ -712,17 +712,13 @@ public:
                        }
                }
        }
-       void apply(MapBlock *block)
+       // Find out how many objects the given block and its neighbours contain.
+       // Returns the number of objects in the block, and also in 'wider' the
+       // number of objects in the block and all its neighbours. The latter
+       // may an estimate if any neighbours are unloaded.
+       u32 countObjects(MapBlock *block, ServerMap * map, u32 &wider)
        {
-               if(m_aabms.empty())
-                       return;
-
-               ServerMap *map = &m_env->getServerMap();
-
-               // Find out how many objects the block contains
-               u32 active_object_count = block->m_static_objects.m_active.size();
-               // Find out how many objects this and all the neighbors contain
-               u32 active_object_count_wider = 0;
+               wider = 0;
                u32 wider_unknown_count = 0;
                for(s16 x=-1; x<=1; x++)
                for(s16 y=-1; y<=1; y++)
@@ -731,17 +727,30 @@ public:
                        MapBlock *block2 = map->getBlockNoCreateNoEx(
                                        block->getPos() + v3s16(x,y,z));
                        if(block2==NULL){
-                               wider_unknown_count = 0;
+                               wider_unknown_count++;
                                continue;
                        }
-                       active_object_count_wider +=
-                                       block2->m_static_objects.m_active.size()
+                       wider += block2->m_static_objects.m_active.size()
                                        + block2->m_static_objects.m_stored.size();
                }
                // Extrapolate
+               u32 active_object_count = block->m_static_objects.m_active.size();
                u32 wider_known_count = 3*3*3 - wider_unknown_count;
-               active_object_count_wider += wider_unknown_count * active_object_count_wider / wider_known_count;
-                               
+               wider += wider_unknown_count * wider / wider_known_count;
+               return active_object_count;
+
+       }
+       void apply(MapBlock *block)
+       {
+               if(m_aabms.empty())
+                       return;
+
+               ServerMap *map = &m_env->getServerMap();
+
+               u32 active_object_count_wider;
+               u32 active_object_count = this->countObjects(block, map, active_object_count_wider);
+               m_env->m_added_objects = 0;
+
                v3s16 p0;
                for(p0.X=0; p0.X<MAP_BLOCKSIZE; p0.X++)
                for(p0.Y=0; p0.Y<MAP_BLOCKSIZE; p0.Y++)
@@ -788,7 +797,14 @@ neighbor_found:
                                // Call all the trigger variations
                                i->abm->trigger(m_env, p, n);
                                i->abm->trigger(m_env, p, n,
-                                               active_object_count, active_object_count_wider);
+                                               active_object_count,
+                                               active_object_count_wider + active_object_count);
+
+                               // Count surrounding objects again if the abms added any
+                               if(m_env->m_added_objects > 0) {
+                                       active_object_count = countObjects(block, map, active_object_count_wider);
+                                       m_env->m_added_objects = 0;
+                               }
                        }
                }
        }
@@ -1358,6 +1374,7 @@ u16 getFreeServerActiveObjectId(
 u16 ServerEnvironment::addActiveObject(ServerActiveObject *object)
 {
        assert(object);
+       m_added_objects++;
        u16 id = addActiveObjectRaw(object, true, 0);
        return id;
 }
index 8cc0bcd7e732e9e666253395431e5403e541f9cf..d99e27ba4606f1b8875a93c93bd236a0d32f1fad 100644 (file)
@@ -105,6 +105,9 @@ public:
                m_day_night_ratio_override = value;
        }
 
+       // counter used internally when triggering ABMs
+       u32 m_added_objects;
+
 protected:
        // peer_ids in here should be unique, except that there may be many 0s
        std::list<Player*> m_players;
@@ -118,6 +121,7 @@ protected:
        // Overriding the day-night ratio is useful for custom sky visuals
        bool m_enable_day_night_ratio_override;
        u32 m_day_night_ratio_override;
+
 };
 
 /*