ABMs: Make catch-up behaviour optional

Default is true for backwards compatibility
Update lua_api.txt
This commit is contained in:
paramat 2015-10-13 05:17:33 +01:00
parent 2364449d7a
commit 3b9f99e0d6
5 changed files with 33 additions and 14 deletions

@ -3063,10 +3063,14 @@ Definition tables
{ {
-- In the following two fields, also group:groupname will work. -- In the following two fields, also group:groupname will work.
nodenames = {"default:lava_source"}, nodenames = {"default:lava_source"},
neighbors = {"default:water_source", "default:water_flowing"}, -- (any of these) neighbors = {"default:water_source", "default:water_flowing"}, -- Any of these --[[
-- ^ If left out or empty, any neighbor will do ^ If left out or empty, any neighbor will do ]]
interval = 1.0, -- (operation interval) interval = 1.0, -- Operation interval in seconds
chance = 1, -- (chance of trigger is 1.0/this) 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), action = func(pos, node, active_object_count, active_object_count_wider),
} }

@ -577,17 +577,21 @@ public:
i->timer -= trigger_interval; i->timer -= trigger_interval;
actual_interval = trigger_interval; actual_interval = trigger_interval;
} }
float intervals = actual_interval / trigger_interval;
if(intervals == 0)
continue;
float chance = abm->getTriggerChance(); float chance = abm->getTriggerChance();
if(chance == 0) if(chance == 0)
chance = 1; chance = 1;
ActiveABM aabm; ActiveABM aabm;
aabm.abm = abm; aabm.abm = abm;
if(abm->getSimpleCatchUp()) {
float intervals = actual_interval / trigger_interval;
if(intervals == 0)
continue;
aabm.chance = chance / intervals; aabm.chance = chance / intervals;
if(aabm.chance == 0) if(aabm.chance == 0)
aabm.chance = 1; aabm.chance = 1;
} else {
aabm.chance = chance;
}
// Trigger neighbors // Trigger neighbors
std::set<std::string> required_neighbors_s std::set<std::string> required_neighbors_s
= abm->getRequiredNeighbors(); = abm->getRequiredNeighbors();

@ -155,6 +155,8 @@ public:
virtual float getTriggerInterval() = 0; virtual float getTriggerInterval() = 0;
// Random chance of (1 / return value), 0 is disallowed // Random chance of (1 / return value), 0 is disallowed
virtual u32 getTriggerChance() = 0; 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 // 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){};
virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n, virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,

@ -143,8 +143,11 @@ void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
int trigger_chance = 50; int trigger_chance = 50;
getintfield(L, current_abm, "chance", trigger_chance); getintfield(L, current_abm, "chance", trigger_chance);
LuaABM *abm = new LuaABM(L, id, trigger_contents, bool simple_catch_up = true;
required_neighbors, trigger_interval, trigger_chance); 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); env->addActiveBlockModifier(abm);

@ -184,16 +184,18 @@ private:
std::set<std::string> m_required_neighbors; std::set<std::string> m_required_neighbors;
float m_trigger_interval; float m_trigger_interval;
u32 m_trigger_chance; u32 m_trigger_chance;
bool m_simple_catch_up;
public: public:
LuaABM(lua_State *L, int id, LuaABM(lua_State *L, int id,
const std::set<std::string> &trigger_contents, const std::set<std::string> &trigger_contents,
const std::set<std::string> &required_neighbors, 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_id(id),
m_trigger_contents(trigger_contents), m_trigger_contents(trigger_contents),
m_required_neighbors(required_neighbors), m_required_neighbors(required_neighbors),
m_trigger_interval(trigger_interval), 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() virtual std::set<std::string> getTriggerContents()
@ -212,6 +214,10 @@ public:
{ {
return m_trigger_chance; return m_trigger_chance;
} }
virtual bool getSimpleCatchUp()
{
return m_simple_catch_up;
}
virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n, virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
u32 active_object_count, u32 active_object_count_wider); u32 active_object_count, u32 active_object_count_wider);
}; };