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:
parent
abc5dc2cd2
commit
7fd51c1a6c
43
mods/nc_api_active/abminvert.lua
Normal file
43
mods/nc_api_active/abminvert.lua
Normal 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
|
@ -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")
|
||||
|
Loading…
x
Reference in New Issue
Block a user