"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:
parent
a63b38f72a
commit
a78bf0ea2a
@ -75,64 +75,65 @@ 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
|
||||||
if data.before then data.before(pos, data) end
|
return function()
|
||||||
if recipe.before then recipe.before(pos, data) end
|
if data.before then data.before(pos, data) end
|
||||||
for _, v in ipairs(recipe.nodes) do
|
if recipe.before then recipe.before(pos, data) end
|
||||||
if v.replace then
|
for _, v in ipairs(recipe.nodes) do
|
||||||
local p = rel(v.x, v.y, v.z)
|
if v.replace then
|
||||||
local r = v.replace
|
local p = rel(v.x, v.y, v.z)
|
||||||
while type(r) == "function" do
|
local r = v.replace
|
||||||
r = r(p, v)
|
while type(r) == "function" do
|
||||||
end
|
r = r(p, v)
|
||||||
if r and type(r) == "string" then
|
end
|
||||||
r = {name = r}
|
if r and type(r) == "string" then
|
||||||
end
|
r = {name = r}
|
||||||
if v.match.excess then
|
end
|
||||||
local s = nodecore.stack_get(p)
|
if v.match.excess then
|
||||||
local x = s:get_count() - (v.match.count or 1)
|
local s = nodecore.stack_get(p)
|
||||||
if x > 0 then
|
local x = s:get_count() - (v.match.count or 1)
|
||||||
s:set_count(x)
|
if x > 0 then
|
||||||
nodecore.item_eject(p, s)
|
s:set_count(x)
|
||||||
|
nodecore.item_eject(p, s)
|
||||||
|
end
|
||||||
|
nodecore.stack_set(p, ItemStack(""))
|
||||||
|
end
|
||||||
|
if r then
|
||||||
|
local n = minetest.get_node(p)
|
||||||
|
r.param2 = n.param2
|
||||||
|
nodecore.set_loud(p, r)
|
||||||
|
nodecore.fallcheck(p)
|
||||||
end
|
end
|
||||||
nodecore.stack_set(p, ItemStack(""))
|
|
||||||
end
|
end
|
||||||
if r then
|
if v.dig then
|
||||||
local n = minetest.get_node(p)
|
local p = rel(v.x, v.y, v.z)
|
||||||
r.param2 = n.param2
|
minetest.node_dig(p, minetest.get_node(p))
|
||||||
nodecore.set_loud(p, r)
|
|
||||||
nodecore.fallcheck(p)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if v.dig then
|
if recipe.items then
|
||||||
local p = rel(v.x, v.y, v.z)
|
for _, v in pairs(recipe.items) do
|
||||||
minetest.node_dig(p, minetest.get_node(p))
|
nodecore.item_eject(rel(v.x or 0, v.y or 0, v.z or 0),
|
||||||
|
v.name, v.scatter, v.count, v.velocity)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
if recipe.consumewield then
|
||||||
if recipe.items then
|
nodecore.consume_wield(data.crafter, recipe.consumewield)
|
||||||
for _, v in pairs(recipe.items) do
|
elseif recipe.toolgroups and recipe.toolwear and data.crafter then
|
||||||
nodecore.item_eject(rel(v.x or 0, v.y or 0, v.z or 0),
|
nodecore.wear_wield(data.crafter, recipe.toolgroups, recipe.toolwear)
|
||||||
v.name, v.scatter, v.count, v.velocity)
|
|
||||||
end
|
end
|
||||||
|
if recipe.after then recipe.after(pos, data) end
|
||||||
|
if data.after then data.after(pos, data) end
|
||||||
|
nodecore.player_discover(data.crafter, "craft:" .. recipe.label)
|
||||||
|
local witness = data.witness or recipe.witness
|
||||||
|
if witness then
|
||||||
|
nodecore.witness(pos, {recipe.action, recipe.label, data.label})
|
||||||
|
end
|
||||||
|
nodecore.log("action", (data.crafter and data.crafter:get_player_name() or "unknown")
|
||||||
|
.. " completed recipe \"" .. recipe.label .. "\" at " ..
|
||||||
|
minetest.pos_to_string(pos) .. " upon " .. node.name)
|
||||||
end
|
end
|
||||||
if recipe.consumewield then
|
|
||||||
nodecore.consume_wield(data.crafter, recipe.consumewield)
|
|
||||||
elseif recipe.toolgroups and recipe.toolwear and data.crafter then
|
|
||||||
nodecore.wear_wield(data.crafter, recipe.toolgroups, recipe.toolwear)
|
|
||||||
end
|
|
||||||
if recipe.after then recipe.after(pos, data) end
|
|
||||||
if data.after then data.after(pos, data) end
|
|
||||||
nodecore.player_discover(data.crafter, "craft:" .. recipe.label)
|
|
||||||
local witness = data.witness or recipe.witness
|
|
||||||
if witness then
|
|
||||||
nodecore.witness(pos, {recipe.action, recipe.label, data.label})
|
|
||||||
end
|
|
||||||
nodecore.log("action", (data.crafter and data.crafter:get_player_name() or "unknown")
|
|
||||||
.. " completed recipe \"" .. recipe.label .. "\" at " ..
|
|
||||||
minetest.pos_to_string(pos) .. " upon " .. node.name)
|
|
||||||
return true
|
|
||||||
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user