ABMs: Make catch-up behaviour optional
authorparamat <mat.gregory@virginmedia.com>
Tue, 13 Oct 2015 04:17:33 +0000 (05:17 +0100)
committerparamat <mat.gregory@virginmedia.com>
Sun, 18 Oct 2015 15:42:59 +0000 (16:42 +0100)
Default is true for backwards compatibility
Update lua_api.txt

doc/lua_api.txt
src/environment.cpp
src/environment.h
src/script/cpp_api/s_env.cpp
src/script/lua_api/l_env.h

index f0f70d073e58cf70ab8e08ce22c841a33121b807..489154fb387559538da1e2e2f07e45b74de27b0d 100644 (file)
@@ -3063,10 +3063,14 @@ Definition tables
     {
     --  In the following two fields, also group:groupname will work.
         nodenames = {"default:lava_source"},
-        neighbors = {"default:water_source", "default:water_flowing"}, -- (any of these)
-    --  ^ If left out or empty, any neighbor will do
-        interval = 1.0, -- (operation interval)
-        chance = 1, -- (chance of trigger is 1.0/this)
+        neighbors = {"default:water_source", "default:water_flowing"}, -- Any of these --[[
+        ^ If left out or empty, any neighbor will do ]]
+        interval = 1.0, -- Operation interval in seconds
+        chance = 1, -- Chance of trigger per-node per-interval is 1.0 / this
+        catch_up = true, -- If true, catch-up behaviour is enabled --[[
+        ^ The chance value is temporarily reduced when returning to
+          an area to simulate time lost by the area being unattended.
+        ^ Note chance value can often be reduced to 1 ]]
         action = func(pos, node, active_object_count, active_object_count_wider),
     }
 
index 88f25536ffce8e9a1df1b117b8bc04d6475aa681..0b37212e5c1d6ddc49687e9a32e769349fceb03d 100644 (file)
@@ -577,17 +577,21 @@ public:
                                i->timer -= trigger_interval;
                                actual_interval = trigger_interval;
                        }
-                       float intervals = actual_interval / trigger_interval;
-                       if(intervals == 0)
-                               continue;
                        float chance = abm->getTriggerChance();
                        if(chance == 0)
                                chance = 1;
                        ActiveABM aabm;
                        aabm.abm = abm;
-                       aabm.chance = chance / intervals;
-                       if(aabm.chance == 0)
-                               aabm.chance = 1;
+                       if(abm->getSimpleCatchUp()) {
+                               float intervals = actual_interval / trigger_interval;
+                               if(intervals == 0)
+                                       continue;
+                               aabm.chance = chance / intervals;
+                               if(aabm.chance == 0)
+                                       aabm.chance = 1;
+                       } else {
+                               aabm.chance = chance;
+                       }
                        // Trigger neighbors
                        std::set<std::string> required_neighbors_s
                                        = abm->getRequiredNeighbors();
index 17d7ff19deecc447066590fcc1776ba4d6ab291d..42faf5f6daab16ce56944cc67ed3abb14ff2cf33 100644 (file)
@@ -155,6 +155,8 @@ public:
        virtual float getTriggerInterval() = 0;
        // Random chance of (1 / return value), 0 is disallowed
        virtual u32 getTriggerChance() = 0;
+       // Whether to modify chance to simulate time lost by an unnattended block
+       virtual bool getSimpleCatchUp() = 0;
        // This is called usually at interval for 1/chance of the nodes
        virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n){};
        virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
index 9c733773a6d14ed8ab11cf3e5663f5d08b0982d6..b8717597a8f46f207b519c54fc784910c428505b 100644 (file)
@@ -143,8 +143,11 @@ void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
                        int trigger_chance = 50;
                        getintfield(L, current_abm, "chance", trigger_chance);
 
-                       LuaABM *abm = new LuaABM(L, id, trigger_contents,
-                                       required_neighbors, trigger_interval, trigger_chance);
+                       bool simple_catch_up = true;
+                       getboolfield(L, current_abm, "catch_up", simple_catch_up);
+
+                       LuaABM *abm = new LuaABM(L, id, trigger_contents, required_neighbors,
+                               trigger_interval, trigger_chance, simple_catch_up);
 
                        env->addActiveBlockModifier(abm);
 
index 2e9fab777c642aefc8957ab5b1f766ba1791d975..4f204da81c4bc4440b3bd7d3ec29771324ef4815 100644 (file)
@@ -184,16 +184,18 @@ private:
        std::set<std::string> m_required_neighbors;
        float m_trigger_interval;
        u32 m_trigger_chance;
+       bool m_simple_catch_up;
 public:
        LuaABM(lua_State *L, int id,
                        const std::set<std::string> &trigger_contents,
                        const std::set<std::string> &required_neighbors,
-                       float trigger_interval, u32 trigger_chance):
+                       float trigger_interval, u32 trigger_chance, bool simple_catch_up):
                m_id(id),
                m_trigger_contents(trigger_contents),
                m_required_neighbors(required_neighbors),
                m_trigger_interval(trigger_interval),
-               m_trigger_chance(trigger_chance)
+               m_trigger_chance(trigger_chance),
+               m_simple_catch_up(simple_catch_up)
        {
        }
        virtual std::set<std::string> getTriggerContents()
@@ -212,6 +214,10 @@ public:
        {
                return m_trigger_chance;
        }
+       virtual bool getSimpleCatchUp()
+       {
+               return m_simple_catch_up;
+       }
        virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
                        u32 active_object_count, u32 active_object_count_wider);
 };