Module:RenderCraftingRecipesTable

local cargo = mw.ext.cargo

local p = {}

local generateRecipeTableRow = function(recipe) local html = '' -- fix some parameters recipe.alternateRecipe = (tonumber(recipe.alternateRecipe) or 0) > 0 recipe.inCraftBench = (tonumber(recipe.inCraftBench) or 0) > 0 recipe.inWorkShop = (tonumber(recipe.inWorkShop) or 0) > 0 if recipe.craftedIn == nil or #tostring(recipe.craftedIn) <= 1 then -- <=1 instead of ==0 just in case of \n or single space characters; normally craftedIn is a long word if recipe.inWorkShop then recipe.craftedIn = 'Equipment Workshop' elseif recipe.inCraftBench then recipe.craftedIn = 'Craft Bench' else recipe.craftedIn = 'Construction Tool' end end -- split ingredients and products from recipe into separate arrays local ingredients = {} for i=1, 9, 1 do   local item = recipe["ingredient" .. i]   if item ~= nil and #item > 0 then ingredients[i] = { name = item, amount = tonumber(recipe["quantity" .. i]) or 1 } end end

local products = {} for i=1, 4, 1 do   local item = recipe["product" .. i]   if item ~= nil and #item > 0 then products[i] = { name = item, amount = tonumber(recipe["productCount" .. i]) or 1 } end end -- calculations for table cells local ingredientsCols = #ingredients <= 1 and 1 or math.max(2, math.ceil(#ingredients/2)) local ingredientsRows = math.ceil(#ingredients/ingredientsCols) local ingredientsColspan = 12 / ingredientsCols -- ingredients column is 12 columns wide (with colspan) to be divisible by 1, 2, 3 or 4 local productsCols = #products <= 1 and 1 or math.max(2, math.ceil(#products/2)) local productsRows = math.ceil(#products/productsCols) local productsColspan = 2 / productsCols local maxRows = math.max(ingredientsRows, productsRows) local ingredientsRowspan = maxRows / ingredientsRows local productsRowspan = maxRows / productsRows local ingredientCells = {} local productCells = {} -- function generates HTML for ingredients/products cells and stores generated code in targetTable array local generateCells = function(list, rowspan, colspan, targetTable) for i=1, #list, 1 do     local td = '' local ipm = 60 / (tonumber(recipe.craftingTime) or 0) * list[i].amount -- td = td .. list[i].amount .. ' × ' .. mw.getCurrentFrame:expandTemplate{title='ItemLink', args={[1]=list[i].name}} .. ' '     td = td .. ' ' .. list[i].amount .. ' × '      td = td .. ' ' .. list[i].name .. '  '      if tonumber(recipe.craftingTime) or 0 > 0 then td = td .. ' ' .. ipm .. ' / min ' else -- if no craftingTime and no ipm to display then add some empty block for proper spacing td = td .. ' '     end td = td .. ' '     targetTable[i] = td    end -- odd amount of ingredients/products leaves one empty cell in the column, which should be filled by a blank cell -- also generate one empty cell when there's no ingredients/products at all if #list == 0 or #list > 1 and #list % 2 == 1 then targetTable[#targetTable+1] = ' ' end end -- generate all ingredients and products cells generateCells(ingredients, ingredientsRowspan, ingredientsColspan, ingredientCells) generateCells(products, productsRowspan, productsColspan, productCells) -- assemble the table for i=1, maxRows, 1 do   -- recipe name column if i == 1 then recipeName = recipe.recipeName if recipe.alternateRecipe then recipeName = recipeName .. ' ' .. 'Alternate ' end html = html .. '' .. '' .. recipeName .. ' '   else html = html .. ' '   end -- ingredients column for j=1, ingredientsCols, 1 do     local index = (i-1)*ingredientsCols+j if index <= #ingredientCells then html = html .. ingredientCells[index] end end -- building column if i == 1 then html = html .. ' ' .. recipe.craftedIn .. ' ' if tonumber(recipe.craftingTime) or 0 > 0 then html = html .. ' ' .. recipe.craftingTime .. ' sec' end if recipe.inCraftBench or recipe.inWorkShop then local displayText = ' × ' .. recipe.craftingClicks local tooltipText = 240 / (tonumber(recipe.craftingClicks) or 0) .. ' / min' html = html ..' ' .. mw.getCurrentFrame:expandTemplate{title='Tooltip', args={[1]=displayText, [2]=tooltipText, [3]='no underline'}} end html = html .. ' '   end -- products column for j=1, productsCols, 1 do     local index = (i-1)*productsCols+j if index <= #productCells then html = html .. productCells[index] end end html = html .. ' ' end return html end

local fields = 'recipeName, alternateRecipe, craftedIn, inCraftBench, inWorkShop, craftingTime, craftingClicks, product=product1, product2, product3, product4, productCount=productCount1, productCount2, productCount3, productCount4, ingredient1, quantity1, ingredient2, quantity2, ingredient3, quantity3, ingredient4, quantity4, ingredient5, quantity5, ingredient6, quantity6, ingredient7, quantity7, ingredient8, quantity8'

local generateTable = function(recipes) local html = ' ' return html end

p.generateCraftingRecipes = function(frame) local itemName = frame.args.item or frame.args[1] local tables = 'crafting_recipes' local args = { where = 'product="' .. itemName .. '" or product2="' .. itemName .. '" or product3="' .. itemName .. '" or product4="' .. itemName .. '"', orderBy = 'alternateRecipe ASC' } local recipes = cargo.query(tables, fields, args) return generateTable(recipes) end

p.generateCraftingUsage = function(frame) local itemName = frame.args.item or frame.args[1] local tables = 'crafting_recipes' local args = { where = 'product IS NOT NULL and (ingredient1="' .. itemName .. '" or ingredient2="' .. itemName .. '" or ingredient3="' .. itemName .. '" or ingredient4="' .. itemName .. '" or ingredient5="' .. itemName .. '" or ingredient6="' .. itemName .. '" or ingredient7="' .. itemName .. '" or ingredient8="' .. itemName .. '" or ingredient9="' .. itemName .. '" or ingredient10="' .. itemName .. '")', orderBy = 'alternateRecipe ASC, product ASC' } local recipes = cargo.query(tables, fields, args) return generateTable(recipes) end

return p