ABM "inversion" API

This is useful when we want to perform an
action on a commonly-occuring node (like
sand or item stacks) with a requirement of
a neighbor of a less common node type (like
igniters).  Checking for B with A nearby can
be a lot faster than A with B nearby if B is
less common, so fewer neighbor checks
actually need to happen.

This was already done "manually" for the
flammable/igniter interaction, but now this is
a general API for all ABMs, that allows the
inversion to be done nearly transparently
with just a flag in the definition, and so the
ABM rules can be written more simply, with
the inversion handled elsewhere.

TODO: Rewrite current manual-inversions,
including the ones for flammable/igniter and
lava/stone hardening/softening.
This commit is contained in:
Aaron Suen 2021-03-21 12:08:08 -04:00
parent abc5dc2cd2
commit 7fd51c1a6c
2 changed files with 44 additions and 0 deletions

View File

@ -0,0 +1,43 @@
-- LUALOCALS < ---------------------------------------------------------
local ipairs, minetest, nodecore, pairs
= ipairs, minetest, nodecore, pairs
-- LUALOCALS > ---------------------------------------------------------
local hash = minetest.hash_node_position
local oldreg = minetest.register_abm
function minetest.register_abm(def, ...)
if not def.neighbors_invert then return oldreg(def, ...) end
local nnames = def.nodenames
def.nodenames = def.neighbors
def.neighbors = nnames
local oldact = def.action
local queue
local function process()
for _, v in pairs(queue) do
local nnode = minetest.get_node(v.pos)
if nnode.name == v.node.name then
oldact(v.pos, nnode)
end
end
queue = nil
end
function def.action(pos)
if not queue then
queue = {}
minetest.after(0, process)
end
for _, npos in ipairs(nodecore.find_nodes_around(pos, nnames, 1)) do
queue[hash(pos)] = {
pos = npos,
node = minetest.get_node(npos)
}
end
end
return oldreg(def, ...)
end

View File

@ -8,6 +8,7 @@ nodecore.amcoremod()
nodecore.register_limited_abm = function(...) return minetest.register_abm(...) end
include("abmmux")
include("abminvert")
include("stasis")
include("dnts")
include("aism")