diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 2c9b3290..aca1a446 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -4238,6 +4238,12 @@ Definition tables ^ 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 + + min_y = -32768, + max_y = 32767, + -- min and max height levels where ABM will be processed + -- can be used to reduce CPU usage + 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. diff --git a/src/script/cpp_api/s_env.cpp b/src/script/cpp_api/s_env.cpp index ab5c4deb..8d3fa853 100644 --- a/src/script/cpp_api/s_env.cpp +++ b/src/script/cpp_api/s_env.cpp @@ -151,8 +151,14 @@ void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env) bool simple_catch_up = true; getboolfield(L, current_abm, "catch_up", simple_catch_up); + int min_y = -32767; + getintfield(L, current_abm, "min_y", min_y); + + int max_y = 32767; + getintfield(L, current_abm, "max_y", max_y); + LuaABM *abm = new LuaABM(L, id, trigger_contents, required_neighbors, - trigger_interval, trigger_chance, simple_catch_up); + trigger_interval, trigger_chance, simple_catch_up, min_y, max_y); env->addActiveBlockModifier(abm); diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h index 8101f8eb..11a8ba0d 100644 --- a/src/script/lua_api/l_env.h +++ b/src/script/lua_api/l_env.h @@ -190,17 +190,21 @@ private: float m_trigger_interval; u32 m_trigger_chance; bool m_simple_catch_up; + s16 m_min_y; + s16 m_max_y; public: LuaABM(lua_State *L, int id, const std::set &trigger_contents, const std::set &required_neighbors, - float trigger_interval, u32 trigger_chance, bool simple_catch_up): + float trigger_interval, u32 trigger_chance, bool simple_catch_up, s16 min_y, s16 max_y): m_id(id), m_trigger_contents(trigger_contents), m_required_neighbors(required_neighbors), m_trigger_interval(trigger_interval), m_trigger_chance(trigger_chance), - m_simple_catch_up(simple_catch_up) + m_simple_catch_up(simple_catch_up), + m_min_y(min_y), + m_max_y(max_y) { } virtual const std::set &getTriggerContents() const @@ -223,6 +227,14 @@ public: { return m_simple_catch_up; } + virtual s16 getMinY() + { + return m_min_y; + } + virtual s16 getMaxY() + { + return m_max_y; + } virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n, u32 active_object_count, u32 active_object_count_wider); }; diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index a0ce1590..05de9e46 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -694,6 +694,9 @@ struct ActiveABM ActiveBlockModifier *abm; int chance; std::set required_neighbors; + bool check_required_neighbors; // false if required_neighbors is known to be empty + s16 min_y; + s16 max_y; }; class ABMHandler @@ -739,6 +742,9 @@ public: } else { aabm.chance = chance; } + // y limits + aabm.min_y = abm->getMinY(); + aabm.max_y = abm->getMaxY(); // Trigger neighbors const std::set &required_neighbors_s = @@ -826,7 +832,10 @@ public: v3s16 p = p0 + block->getPosRelative(); for(std::vector::iterator i = m_aabms[c]->begin(); i != m_aabms[c]->end(); ++i) { - if(myrand() % i->chance != 0) + if ((p.Y < i->min_y) || (p.Y > i->max_y)) + continue; + + if (myrand() % i->chance != 0) continue; // Check neighbors @@ -2169,8 +2178,8 @@ PlayerDatabase *ServerEnvironment::openPlayerDatabase(const std::string &name, { #ifdef _WIN32 if (name == "sqlite3") - return new PlayerDatabaseSQLite3(savedir); - else + return new PlayerDatabaseSQLite3(savedir); + else #endif if (name == "dummy") return new Database_Dummy(); diff --git a/src/serverenvironment.h b/src/serverenvironment.h index 99a1c593..4a4103fb 100644 --- a/src/serverenvironment.h +++ b/src/serverenvironment.h @@ -62,6 +62,10 @@ public: virtual u32 getTriggerChance() = 0; // Whether to modify chance to simulate time lost by an unnattended block virtual bool getSimpleCatchUp() = 0; + // get min Y for apply abm + virtual s16 getMinY() = 0; + // get max Y for apply abm + virtual s16 getMaxY() = 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,