local S = sfcg.get_translator local esc = minetest.formspec_escape local function coords(i, cols) return i % cols, math.floor(i / cols) end local function recipe_fs(fs, data) local recipe = data.recipes[data.rnum] local width = recipe.width local cooktime, shapeless if recipe.method == "cooking" then cooktime, width = width, 1 elseif width == 0 then shapeless = true if #recipe.items == 1 then width = 1 elseif #recipe.items <= 4 then width = 2 else width = 3 end end table.insert(fs, ("label[5.5,1;%s]"):format(esc(data.show_usages and S("Usage @1 of @2", data.rnum, #data.recipes) or S("Recipe @1 of @2", data.rnum, #data.recipes)))) if #data.recipes > 1 then table.insert(fs, "image_button[5.5,1.6;0.8,0.8;craftguide_prev_icon.png;recipe_prev;]".. "image_button[6.2,1.6;0.8,0.8;craftguide_next_icon.png;recipe_next;]".. "tooltip[recipe_prev;"..esc(S("Previous recipe")).."]".. "tooltip[recipe_next;"..esc(S("Next recipe")).."]") end local rows = math.ceil(table.maxn(recipe.items) / width) if width > 3 or rows > 3 then table.insert(fs, ("label[0,1;%s]") :format(esc(S("Recipe is too big to be displayed.")))) return end local base_x = 3 - width local base_y = rows == 1 and 1 or 0 -- Use local variables for faster execution in loop local item_button_fs = sfcg.item_button_fs local extract_groups = sfcg.extract_groups local groups_to_item = sfcg.groups_to_item for i, item in pairs(recipe.items) do local x, y = coords(i - 1, width) local elem_name = item local groups = extract_groups(item) if groups then item = groups_to_item(groups) elem_name = esc(item.."."..table.concat(groups, "+")) end item_button_fs(fs, base_x + x, base_y + y, item, elem_name, groups) end if shapeless or recipe.method == "cooking" then table.insert(fs, ("image[3.2,0.5;0.5,0.5;craftguide_%s.png]") :format(shapeless and "shapeless" or "furnace")) local tooltip = shapeless and S("Shapeless") or S("Cooking time: @1", minetest.colorize("yellow", cooktime)) table.insert(fs, "tooltip[3.2,0.5;0.5,0.5;"..esc(tooltip).."]") end table.insert(fs, "image[3,1;1,1;sfinv_crafting_arrow.png]") item_button_fs(fs, 4, 1, recipe.output, recipe.output:match("%S*")) end local function get_formspec(player) local name = player:get_player_name() local data = sfcg.player_data[name] data.pagemax = math.max(1, math.ceil(#data.items / 32)) local fs = {} table.insert(fs, "style_type[item_image_button;padding=2]".. "field[0.3,4.2;2.8,1.2;filter;;"..esc(data.filter).."]".. "label[5.8,4.15;"..minetest.colorize("yellow", data.pagenum).." / ".. data.pagemax.."]".. "image_button[2.63,4.05;0.8,0.8;craftguide_search_icon.png;search;]".. "image_button[3.25,4.05;0.8,0.8;craftguide_clear_icon.png;clear;]".. "image_button[5,4.05;0.8,0.8;craftguide_prev_icon.png;prev;]".. "image_button[7.25,4.05;0.8,0.8;craftguide_next_icon.png;next;]".. "tooltip[search;"..esc(S("Search")).."]".. "tooltip[clear;"..esc(S("Reset")).."]".. "tooltip[prev;"..esc(S("Previous page")).."]".. "tooltip[next;"..esc(S("Next page")).."]".. "field_close_on_enter[filter;false]") if #data.items == 0 then table.insert(fs, "label[3,2;"..esc(S("No items to show.")).."]") else local item_button_fs = sfcg.item_button_fs local first_item = (data.pagenum - 1) * 32 for i = first_item, first_item + 31 do local item = data.items[i + 1] if not item then break end local x, y = coords(i % 32, 8) item_button_fs(fs, x, y, item, item) end end table.insert(fs, "container[0,5.6]") if data.recipes then recipe_fs(fs, data) elseif data.prev_item then table.insert(fs, ("label[2,1;%s]"):format(esc(data.show_usages and S("No usages.").."\n"..S("Click again to show recipes.") or S("No recipes.").."\n"..S("Click again to show usages.")))) end table.insert(fs, "container_end[]") return table.concat(fs) end local orig_update_for_player = sfcg.update_for_player function sfcg.update_for_player(playername) local player = orig_update_for_player(playername) if player then sfinv.set_player_inventory_formspec(player) end return player end sfinv.register_page("sfcraftguide:craftguide", { title = esc(S("Recipes")), get = function(self, player, context) return sfinv.make_formspec(player, context, get_formspec(player)) end, on_player_receive_fields = function(self, player, context, fields) if sfcg.on_receive_fields(player, fields) then sfinv.set_player_inventory_formspec(player) end end }) minetest.register_on_mods_loaded(function() sfinv.pages["mtg_craftguide:craftguide"] = nil for idx = #sfinv.pages_unordered, 1, -1 do local page = sfinv.pages_unordered[idx] if page.name == "mtg_craftguide:craftguide" then table.remove(sfinv.pages_unordered, idx) end end end)