diff --git a/src/environment.cpp b/src/environment.cpp index 9f7207b8d..3593c94f0 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -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.Xabm->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; } diff --git a/src/environment.h b/src/environment.h index 8cc0bcd7e..d99e27ba4 100644 --- a/src/environment.h +++ b/src/environment.h @@ -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 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; + }; /*