89020e8340
This created a ton of dependency inversions, which necessitated moving a number of API functions up into higher layers, and restructuring dependency lists for a number of mods. BOLO: non-deterministic load errors due to missed dependencies.
75 lines
1.9 KiB
Lua
75 lines
1.9 KiB
Lua
-- 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
|