"Lazy" crafting API

Instead of checking for and immediately
completing a craft, the API can be told to
search for a recipe and return a function that
can be used to commit it later.  This way,
we can search for a valid recipe during the
"check" phase of a craft check and then
commit it during the "after" phase.
This commit is contained in:
Aaron Suen 2020-09-29 21:44:26 -04:00
parent a63b38f72a
commit a78bf0ea2a

View File

@ -75,9 +75,10 @@ local function craftcheck(recipe, pos, node, data, xx, xz, zx, zz)
if type(dur) == "function" then dur = dur(pos, data) end if type(dur) == "function" then dur = dur(pos, data) end
if not dur or dur < mindur then if not dur or dur < mindur then
if data.inprogress then data.inprogress(pos, data) end if data.inprogress then data.inprogress(pos, data) end
return 1 return false
end end
end end
return function()
if data.before then data.before(pos, data) end if data.before then data.before(pos, data) end
if recipe.before then recipe.before(pos, data) end if recipe.before then recipe.before(pos, data) end
for _, v in ipairs(recipe.nodes) do for _, v in ipairs(recipe.nodes) do
@ -132,7 +133,7 @@ local function craftcheck(recipe, pos, node, data, xx, xz, zx, zz)
nodecore.log("action", (data.crafter and data.crafter:get_player_name() or "unknown") nodecore.log("action", (data.crafter and data.crafter:get_player_name() or "unknown")
.. " completed recipe \"" .. recipe.label .. "\" at " .. .. " completed recipe \"" .. recipe.label .. "\" at " ..
minetest.pos_to_string(pos) .. " upon " .. node.name) minetest.pos_to_string(pos) .. " upon " .. node.name)
return true end
end end
local function tryall(rc, pos, node, data) local function tryall(rc, pos, node, data)
@ -182,12 +183,13 @@ local function checkall(pos, node, data, set)
data.recipe = rc data.recipe = rc
if data.rootmatch then data.rootmatch(data) end if data.rootmatch then data.rootmatch(data) end
local r = tryall(rc, pos, node, data) local r = tryall(rc, pos, node, data)
if r then return r == true end if r == false then return end
if r then return r end
end end
end end
end end
function nodecore.craft_check(pos, node, data) function nodecore.craft_search(pos, node, data)
if not data or not data.action then if not data or not data.action then
return error("craft_check without data.action") return error("craft_check without data.action")
end end
@ -203,7 +205,8 @@ function nodecore.craft_check(pos, node, data)
local key = data.action .. "|" .. node.name local key = data.action .. "|" .. node.name
local set = craftidx[key] local set = craftidx[key]
if set then if set then
if checkall(pos, node, data, set) then return true end local found = checkall(pos, node, data, set)
if found then return found end
for _, i in pairs(set) do seen[i] = true end for _, i in pairs(set) do seen[i] = true end
end end
end end
@ -217,7 +220,17 @@ function nodecore.craft_check(pos, node, data)
for _, i in ipairs(set) do for _, i in ipairs(set) do
if not seen[i] then unique[#unique + 1] = i end if not seen[i] then unique[#unique + 1] = i end
end end
if #unique > 0 and checkall(pos, node, data, unique) then return true end if #unique > 0 then
local found = checkall(pos, node, data, unique)
if found then return found end
end
end end
end end
end end
function nodecore.craft_check(...)
local commit = nodecore.craft_search(...)
if not commit then return end
commit()
return true
end