Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Craft recipe checker for Minetest
-- Written by rubenwardy, WTFPL
-- To use:
-- * Save as mod_debug.lua in builtin/game
-- * add dofile(gamepath.."mod_debug.lua") to the last line of builtin/game/init.lua
-- OR
-- * Install as a mod. Needs to be run before any other mod.
local mod = {}
mod.recipes = {}
mod.aliases = {}
-- Sees if there is a node with this group/these groups
-- Supports AND view group:name,name
local function group_exists(groupname)
local flags = groupname:split(",")
for name, def in pairs(minetest.registered_items) do
local flag = true
for k, v in pairs(flags) do
local g = def.groups and def.groups[v:gsub('%group:', '')] or 0
if not g or g <= 0 then
flag = false
break
end
end
if flag then
return true
end
end
return false
end
-- Check that the item exists
function mod.assert(recipe, _name, output)
local name = mod.strip_name(_name)
if name == nil then
print("[RECIPE ERROR] nil in recipe for "..mod.strip_name(output))
print(recipe.from)
return
end
if mod.aliases[name] ~= nil then
name = mod.aliases[name]
end
if minetest.registered_items[name] == nil and not group_exists(name) then
print("[RECIPE ERROR] " .. name .. " in recipe for " .. mod.strip_name(output))
print(recipe.from)
end
end
-- Turns a itemstack name into just its item name
-- For example: "mod:item 99" -> "mod:item"
function mod.strip_name(name)
if name == nil then
return
end
res = name:gsub('%"', '')
if res:sub(1, 1) == ":" then
res = table.concat{res:sub(1, 1-1), "", res:sub(1+1)}
end
for str in string.gmatch(res, "([^ ]+)") do
if str ~= " " and str ~= nil then
res=str
break
end
end
if res == nil then
res=""
end
return res
end
-- Cycles through the recipe table, checking the items.
-- Recursive
function mod.check_recipe(recipe, table, output)
if type(table) == "table" then
for i=1,# table do
mod.check_recipe(recipe, table[i], output)
end
else
mod.assert(recipe, table,output)
end
end
-- Check recipes once the game has loaded
minetest.after(0, function()
for i=1, #mod.recipes do
if mod.recipes[i] and mod.recipes[i].output then
mod.assert(mod.recipes[i], mod.recipes[i].output, mod.recipes[i].output)
if type(mod.recipes[i].recipe) == "table" then
for a=1,# mod.recipes[i].recipe do
mod.check_recipe(mod.recipes[i], mod.recipes[i].recipe[a], mod.recipes[i].output)
end
else
mod.assert(mod.recipes[i], mod.recipes[i].recipe, mod.recipes[i].output)
end
end
end
end)
-- Override register_craft to catch craft recipes
local register_craft = minetest.register_craft
minetest.register_craft = function(recipe)
register_craft(recipe)
local name = mod.strip_name(recipe.output)
recipe.from = debug.traceback()
if name~=nil then
table.insert(mod.recipes, recipe)
end
end
-- Override register_alias to catch aliases
local register_alias = minetest.register_alias
minetest.register_alias = function(new,old)
register_alias(new, old)
local name = mod.strip_name(new)
local name2 = mod.strip_name(old)
if name~=nil and name2~=nil then
mod.aliases[new] = old
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.