Handle ActiveBlockModifier intervals properly, down to 1s
authorPerttu Ahola <celeron55@gmail.com>
Mon, 28 Nov 2011 08:33:47 +0000 (10:33 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Tue, 29 Nov 2011 17:13:57 +0000 (19:13 +0200)
src/environment.cpp
src/environment.h

index 4166571422b85cbf1853d2bf97113d0c01a5461f..3a11b4acf469e81b082201ecc4d18564b8c45b34 100644 (file)
@@ -301,9 +301,9 @@ ServerEnvironment::~ServerEnvironment()
        m_map->drop();
 
        // Delete ActiveBlockModifiers
-       for(core::list<ActiveBlockModifier*>::Iterator
+       for(core::list<ABMWithState>::Iterator
                        i = m_abms.begin(); i != m_abms.end(); i++){
-               delete (*i);
+               delete i->abm;
        }
 }
 
@@ -566,20 +566,29 @@ private:
        ServerEnvironment *m_env;
        std::map<content_t, std::list<ActiveABM> > m_aabms;
 public:
-       ABMHandler(core::list<ActiveBlockModifier*> &abms,
-                       float dtime_s, ServerEnvironment *env):
+       ABMHandler(core::list<ABMWithState> &abms,
+                       float dtime_s, ServerEnvironment *env,
+                       bool use_timers):
                m_env(env)
        {
-               infostream<<"ABMHandler: dtime_s="<<dtime_s<<std::endl;
                if(dtime_s < 0.001)
                        return;
                INodeDefManager *ndef = env->getGameDef()->ndef();
-               for(core::list<ActiveBlockModifier*>::Iterator
+               for(core::list<ABMWithState>::Iterator
                                i = abms.begin(); i != abms.end(); i++){
-                       ActiveBlockModifier *abm = *i;
+                       ActiveBlockModifier *abm = i->abm;
+                       float trigger_interval = abm->getTriggerInterval();
+                       if(trigger_interval < 0.001)
+                               trigger_interval = 0.001;
+                       if(use_timers){
+                               i->timer += dtime_s;
+                               if(i->timer < trigger_interval)
+                                       continue;
+                               i->timer -= trigger_interval;
+                       }
                        ActiveABM aabm;
                        aabm.abm = abm;
-                       float intervals = dtime_s / abm->getTriggerInterval();
+                       float intervals = dtime_s / trigger_interval;
                        float chance = abm->getTriggerChance();
                        if(chance == 0)
                                chance = 1;
@@ -605,6 +614,9 @@ public:
        }
        void apply(MapBlock *block)
        {
+               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();
@@ -685,13 +697,13 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
        }
 
        /* Handle ActiveBlockModifiers */
-       ABMHandler abmhandler(m_abms, dtime_s, this);
+       ABMHandler abmhandler(m_abms, dtime_s, this, false);
        abmhandler.apply(block);
 }
 
 void ServerEnvironment::addActiveBlockModifier(ActiveBlockModifier *abm)
 {
-       m_abms.push_back(abm);
+       m_abms.push_back(ABMWithState(abm));
 }
 
 void ServerEnvironment::clearAllObjects()
@@ -973,14 +985,14 @@ void ServerEnvironment::step(float dtime)
                }
        }
        
-       const float abm_interval = 10.0;
+       const float abm_interval = 1.0;
        if(m_active_block_modifier_interval.step(dtime, abm_interval))
        {
-               ScopeProfiler sp(g_profiler, "SEnv: modify in blocks avg /10s", SPT_AVG);
+               ScopeProfiler sp(g_profiler, "SEnv: modify in blocks avg /1s", SPT_AVG);
                TimeTaker timer("modify in active blocks");
                
                // Initialize handling of ActiveBlockModifiers
-               ABMHandler abmhandler(m_abms, abm_interval, this);
+               ABMHandler abmhandler(m_abms, abm_interval, this, true);
 
                for(core::map<v3s16, bool>::Iterator
                                i = m_active_blocks.m_list.getIterator();
index a3418dbd4fe97426bda26c007072a21c87b282b0..a8b51ae3f4d531b9be34d7bb1a1caab24f8e42ab 100644 (file)
@@ -118,6 +118,16 @@ public:
                        u32 active_object_count, u32 active_object_count_wider){};
 };
 
+struct ABMWithState
+{
+       ActiveBlockModifier *abm;
+       float timer;
+
+       ABMWithState(ActiveBlockModifier *abm_):
+               abm(abm_)
+       {}
+};
+
 /*
        List of active blocks, used by ServerEnvironment
 */
@@ -329,7 +339,7 @@ private:
        u32 m_game_time;
        // A helper variable for incrementing the latter
        float m_game_time_fraction_counter;
-       core::list<ActiveBlockModifier*> m_abms;
+       core::list<ABMWithState> m_abms;
 };
 
 #ifndef SERVER