-- LUALOCALS < --------------------------------------------------------- local math, minetest, nodecore, pairs, unpack = math, minetest, nodecore, pairs, unpack local math_random = math.random -- LUALOCALS > --------------------------------------------------------- local genlabels = 0 function nodecore.register_limited_abm(def) def = nodecore.underride(def, { limited_queue = {}, limited_seen = {}, limited_qty = 0, limited_max = 1000, limited_interval = 1, limited_jitter = 0.05, limited_action = def.action or function() end, catch_up = false }) if not def.label then def.label = minetest.get_current_modname() .. ":" .. genlabels genlabels = genlabels + 1 end def.limited_alert = def.limited_alert or def.limited_max def.action = function(pos, ...) local hash = minetest.hash_node_position(pos) local seen = def.limited_seen if seen[hash] then return end seen[hash] = true local q = def.limited_queue local max = def.limited_max local nqty = def.limited_qty + 1 if #q < max then q[#q + 1] = {pos, ...} else local r = math_random(1, nqty) if r <= #q then q[r] = {pos, ...} end end def.limited_qty = nqty end local function pumpq() minetest.after(def.limited_interval - def.limited_jitter + def.limited_jitter * math_random() * 2, pumpq) if def.limited_qty >= def.limited_alert then minetest.log("limited abm \"" .. def.label .. "\" filled (" .. def.limited_qty .. "/" .. def.limited_max .. ")") end local act = def.limited_action for _, args in pairs(def.limited_queue) do local pos = args[1] local node = pos and args[2] local nn = node and minetest.get_node_or_nil(pos) if nn and nn.name == node.name then act(unpack(args)) end end def.limited_queue = {} def.limited_seen = {} def.limited_qty = 0 end pumpq() return minetest.register_abm(def) end