--[[ TechAge ======= Copyright (C) 2019 Joachim Stolberg AGPL v3 See LICENSE.txt for more information Recipe lib for formspecs ]]-- local S = techage.S local M = minetest.get_meta local Recipes = {} -- {rtype = {ouput = {....},...}} local NormalizedRecipes = {} -- {output = "", items = {...}} local range = techage.in_range techage.recipes = {} local GROUP_ITEMS = { stone = "default:cobble", wood = "default:wood", book = "default:book", sand = "default:sand", leaves = "default:leaves", stick = "default:stick", tree = "default:tree", vessel = "vessels:glass_bottle", wool = "wool:white", } local RECIPE = { output = {name = "", num = 0}, waste = {name = "", num = 0}, input = { {name = "", num =0}, {name = "", num =0}, {name = "", num =0}, {name = "", num =0}, }, } local function filter_recipes_based_on_points(recipes, owner) local ex_points = 0 if owner then local player = minetest.get_player_by_name(owner) ex_points = techage.get_expoints(player) or 0 end local tbl = {} for _,item in ipairs(recipes) do if ex_points >= (item.ex_points or 0) then tbl[#tbl + 1] = item end end return tbl end -- Formspec local function input_string(recipe) local tbl = {} for idx, item in ipairs(recipe.input) do local x = ((idx-1) % 2) local y = math.floor((idx-1) / 2) tbl[idx] = techage.item_image(x, y, item.name.." "..item.num) end return table.concat(tbl, "") end function techage.recipes.get(nvm, rtype, owner) local recipes = Recipes[rtype] or {} if owner then recipes = filter_recipes_based_on_points(recipes, owner) end return recipes[nvm.recipe_idx or 1] or recipes[1] end -- Add 4 input/output/waste recipe -- { -- output = " ", -- units = 1..n -- waste = " ", -- units = 1..n -- input = { -- up to 4 items -- " ", -- " ", -- }, -- } function techage.recipes.add(rtype, recipe) if not Recipes[rtype] then Recipes[rtype] = {} end local name, num, output local item = {input = {}} for idx = 1,4 do local inp = recipe.input[idx] or "" name, num = unpack(string.split(inp, " ")) item.input[idx] = {name = name or "", num = tonumber(num) or 0} end if recipe.waste then name, num = unpack(string.split(recipe.waste, " ")) else name, num = "", "0" end item.waste = {name = name or "", num = tonumber(num) or 0} name, num = unpack(string.split(recipe.output, " ")) item.output = {name = name or "", num = tonumber(num) or 0} item.catalyst = recipe.catalyst item.ex_points = recipe.ex_points or 0 Recipes[rtype][#Recipes[rtype]+1] = item output = name techage.recipes.register_craft({ output = recipe.output, items = recipe.input, type = rtype, }) NormalizedRecipes[output] = { output = recipe.output, items = recipe.input, } end function techage.recipes.formspec(x, y, rtype, nvm, owner) local recipes = Recipes[rtype] or {} recipes = filter_recipes_based_on_points(recipes, owner) nvm.recipe_idx = range(nvm.recipe_idx or 1, 1, #recipes) local idx = nvm.recipe_idx local recipe = recipes[idx] or RECIPE local output = recipe.output.name.." "..recipe.output.num local waste = recipe.waste.name.." "..recipe.waste.num local catalyst = recipe.catalyst and techage.item_image_small(2.05, 0, recipe.catalyst, S("Catalyst")) or "" return "container["..x..","..y.."]".. "background[0,0;4,3;techage_form_grey.png]".. input_string(recipe).. "image[2,0.7;1,1;techage_form_arrow.png]".. catalyst.. techage.item_image(2.95, 0, output).. techage.item_image(2.95, 1, waste).. "button[0,2;1,1;priv;<<]".. "button[1,2;1,1;next;>>]".. "label[1.9,2.2;"..S("Recipe")..": "..idx.."/"..#recipes.."]".. "container_end[]" end function techage.recipes.on_receive_fields(pos, formname, fields, player) if minetest.is_protected(pos, player:get_player_name()) then return end local nvm = techage.get_nvm(pos) nvm.recipe_idx = nvm.recipe_idx or 1 if not nvm.running then if fields.next == ">>" then nvm.recipe_idx = nvm.recipe_idx + 1 return true elseif fields.priv == "<<" then nvm.recipe_idx = nvm.recipe_idx - 1 return true end end end function techage.recipes.get_recipe(name) return NormalizedRecipes[name] end function techage.recipes.set_recipe(pos, rtype, idx) local nvm = techage.get_nvm(pos) if not nvm.running then local recipes = Recipes[rtype] or {} idx = tonumber(idx) or 1 nvm.recipe_idx = range(idx, 1, #recipes) end end function techage.recipes.get_default_group_item_name(item_name) if item_name and item_name:sub(1, 6) == "group:" then local default_name = GROUP_ITEMS[item_name:sub(7)] if default_name then return default_name end end return item_name end function techage.recipes.add_group_item(group, default_item_name) GROUP_ITEMS[group] = default_item_name end ------------------------------------------------------------------------------- -- Borrowed from ghaydn ------------------------------------------------------------------------------- local has_i3 = minetest.get_modpath("i3") local has_ui = minetest.get_modpath("unified_inventory") local has_cg = minetest.get_modpath("craftguide") local function format_i3(input) local output = {} for _, entry in ipairs(input) do local secondput = "" if type(entry) == "table" then for _, secondtry in ipairs(entry) do secondput = secondput..secondtry.."," end table.insert(output, secondput) else table.insert(output, entry) end end return output end techage.recipes.register_craft_type = function(name, def) if has_cg then local cg_def = { description = def.description, icon = def.icon, } craftguide.register_craft_type(name, cg_def) end if has_i3 then local i3_def = { description = def.description, icon = def.icon, width = def.width or 3, height = def.height or 3, dynamic_display_size = def.dynamic_display_size or nil, uses_crafting_grid = def.uses_crafting_grid, } i3.register_craft_type(name, i3_def) end if has_ui then local ui_def = { description = def.description, icon = def.icon, width = def.width or 3, height = def.height or 3, dynamic_display_size = def.dynamic_display_size or nil, uses_crafting_grid = def.uses_crafting_grid, } unified_inventory.register_craft_type(name, ui_def) end end techage.recipes.register_craft = function(def) if not def.items then if def.input then def.items = table.copy(def.input) elseif def.recipe then def.items = table.copy(def.recipe) end end if not def.result then if def.output then def.result = def.output end end if has_cg then local cg_def = { result = def.result, type = def.type, items = def.items, } craftguide.register_craft(cg_def) end if has_i3 then local i3_def = { result = def.result, type = def.type, items = format_i3(def.items), width = def.width or 3, } i3.register_craft(i3_def) end if has_ui then local ui_def = { output = def.result, type = def.type, items = def.items, width = def.width or 3, height = def.height or 3, } unified_inventory.register_craft(ui_def) end end