local running = false local function strip_qty(itemstring) return string.match(itemstring,"(.*) .*") end local function compare_shaped_crafts(a,b) if a.output == b.output then return false end if minetest.registered_aliases[a.output] == b.output or minetest.registered_aliases[b.output] == a.output then return false end for i=1,9,1 do if a.items[i] ~= b.items[i] then return false end end return true end local function table_contains(tbl,search) for i,item in pairs(tbl) do if item == search then return i end end end local function compare_shapeless_crafts(a,b) if a.output == b.output then return false end if minetest.registered_aliases[a.output] == b.output or minetest.registered_aliases[b.output] == a.output then return false end local a_items = {} for _,item in pairs(a.items) do table.insert(a_items,item) end local b_items = {} for _,item in pairs(b.items) do table.insert(b_items,item) end for _,item in pairs(a_items) do local b_idx = table_contains(b_items,item) if not b_idx then return false end b_items[b_idx] = nil end for _ in pairs(b_items) do return false end return true end local function run() if running then return end running = true print() print() print("Craft analysis started") print() print("Building list of crafts...") local crafts = {} crafts.shaped = {} crafts.shapeless = {} for name in pairs(minetest.registered_items) do local crafts_for_name = minetest.get_all_craft_recipes(name) if crafts_for_name then for _,craft in pairs(crafts_for_name) do craft.output = strip_qty(craft.output) if craft.type == "normal" and craft.width > 0 then table.insert(crafts.shaped,craft) elseif craft.type == "normal" and craft.width == 0 then table.insert(crafts.shapeless,craft) end end end end print(#crafts.shaped.." shaped recipes") print(#crafts.shapeless.." shapeless recipes") print() local conflicts = {} print("Searching for shaped <-> shaped conflicts...") conflicts.shaped_shaped = {} print("0/"..#crafts.shaped.." crafts scanned") for src=1,(#crafts.shaped-1),1 do if src % 1000 == 0 then print(src.."/"..#crafts.shaped.." crafts scanned") end for dst=(src+1),#crafts.shaped,1 do local conflict = compare_shaped_crafts(crafts.shaped[src],crafts.shaped[dst]) if conflict then local conflictdef = {} conflictdef[1] = crafts.shaped[src].output conflictdef[2] = crafts.shaped[dst].output table.insert(conflicts.shaped_shaped,conflictdef) end end end print(#crafts.shaped.."/"..#crafts.shaped.." crafts scanned") print(#conflicts.shaped_shaped.." found") print() print("Searching for shapeless <-> shapeless conflicts...") conflicts.shapeless_shapeless = {} print("0/"..#crafts.shapeless.." crafts scanned") for src=1,(#crafts.shapeless-1),1 do if src % 1000 == 0 then print(src.."/"..#crafts.shapeless.." crafts scanned") end for dst=(src+1),#crafts.shapeless,1 do local conflict = compare_shapeless_crafts(crafts.shapeless[src],crafts.shapeless[dst]) if conflict then local conflictdef = {} conflictdef[1] = crafts.shapeless[src].output conflictdef[2] = crafts.shapeless[dst].output table.insert(conflicts.shapeless_shapeless,conflictdef) end end end print(#crafts.shapeless.."/"..#crafts.shapeless.." crafts scanned") print(#conflicts.shapeless_shapeless.." found") print() print("Searching for shaped <-> shapeless conflicts...") conflicts.shaped_shapeless = {} print("0/"..#crafts.shapeless.." crafts scanned") for src=1,#crafts.shapeless,1 do if src % 1000 == 0 then print(src.."/"..#crafts.shapeless.." crafts scanned") end for dst=1,#crafts.shaped,1 do local conflict = compare_shapeless_crafts(crafts.shapeless[src],crafts.shaped[dst]) if conflict then local conflictdef = {} conflictdef[1] = crafts.shaped[src].output conflictdef[2] = crafts.shapeless[dst].output table.insert(conflicts.shaped_shapeless,conflictdef) end end end print(#crafts.shapeless.."/"..#crafts.shapeless.." crafts scanned") print(#conflicts.shaped_shapeless.." found") print() print() print("=== SHAPED <-> SHAPED CRAFT CONFLICTS ===") if #conflicts.shaped_shaped == 0 then print("None found!") else for _,conflictdef in pairs(conflicts.shaped_shaped) do print(string.format("%s <-> %s",conflictdef[1],conflictdef[2])) end end print() print() print("=== SHAPELESS <-> SHAPELESS CRAFT CONFLICTS ===") if #conflicts.shapeless_shapeless == 0 then print("None found!") else for _,conflictdef in pairs(conflicts.shapeless_shapeless) do print(string.format("%s <-> %s",conflictdef[1],conflictdef[2])) end end print() print() print("=== SHAPED <-> SHAPELESS CRAFT CONFLICTS ===") if #conflicts.shaped_shapeless == 0 then print("None found!") else for _,conflictdef in pairs(conflicts.shaped_shapeless) do print(string.format("%s <-> %s",conflictdef[1],conflictdef[2])) end end print() print() print("Craft analysis complete, shutting down server") minetest.request_shutdown("Craft conflict detection finished - see terminal for results") end minetest.after(1,run)