diff --git a/builtin/game/features.lua b/builtin/game/features.lua index 8f0604448..b50a05989 100644 --- a/builtin/game/features.lua +++ b/builtin/game/features.lua @@ -20,6 +20,7 @@ core.features = { direct_velocity_on_players = true, use_texture_alpha_string_modes = true, degrotate_240_steps = true, + abm_min_max_y = true, } function core.has_feature(arg) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 0c81ca911..ded416333 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -4484,6 +4484,8 @@ Utilities -- degrotate param2 rotates in units of 1.5° instead of 2° -- thus changing the range of values from 0-179 to 0-240 (5.5.0) degrotate_240_steps = true, + -- ABM supports min_y and max_y fields in definition (5.5.0) + abm_min_max_y = true, } * `minetest.has_feature(arg)`: returns `boolean, missing_features` @@ -7187,6 +7189,11 @@ Used by `minetest.register_abm`. chance = 1, -- Chance of triggering `action` per-node per-interval is 1.0 / this -- value + + 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 diff --git a/src/script/cpp_api/s_env.cpp b/src/script/cpp_api/s_env.cpp index 8da5debaa..c4a39a869 100644 --- a/src/script/cpp_api/s_env.cpp +++ b/src/script/cpp_api/s_env.cpp @@ -150,13 +150,19 @@ void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env) bool simple_catch_up = true; getboolfield(L, current_abm, "catch_up", simple_catch_up); + + s16 min_y = INT16_MIN; + getintfield(L, current_abm, "min_y", min_y); + + s16 max_y = INT16_MAX; + getintfield(L, current_abm, "max_y", max_y); lua_getfield(L, current_abm, "action"); luaL_checktype(L, current_abm + 1, LUA_TFUNCTION); lua_pop(L, 1); 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 979b13c40..67c76faae 100644 --- a/src/script/lua_api/l_env.h +++ b/src/script/lua_api/l_env.h @@ -223,17 +223,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::vector &trigger_contents, const std::vector &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::vector &getTriggerContents() const @@ -256,6 +260,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 413a785e6..f3711652c 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -729,6 +729,8 @@ struct ActiveABM int chance; std::vector required_neighbors; bool check_required_neighbors; // false if required_neighbors is known to be empty + s16 min_y; + s16 max_y; }; class ABMHandler @@ -773,6 +775,9 @@ public: } else { aabm.chance = chance; } + // y limits + aabm.min_y = abm->getMinY(); + aabm.max_y = abm->getMaxY(); // Trigger neighbors const std::vector &required_neighbors_s = @@ -885,6 +890,9 @@ public: v3s16 p = p0 + block->getPosRelative(); for (ActiveABM &aabm : *m_aabms[c]) { + if ((p.Y < aabm.min_y) || (p.Y > aabm.max_y)) + continue; + if (myrand() % aabm.chance != 0) continue; diff --git a/src/serverenvironment.h b/src/serverenvironment.h index c5ca463ee..8733c2dd2 100644 --- a/src/serverenvironment.h +++ b/src/serverenvironment.h @@ -67,6 +67,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,