Module:Recipe

--	This module standardizes the display of crafting recipes	and makes it easy to display a specified item's recipe	or all recipes that use a specified ingredient.	Thanks to User:BryghtShadow for helping out with the loops! --

-- local p = {} local dataSN = mw.loadData('Module:Recipe/SN') local dataBZ = mw.loadData('Module:Recipe/BZ') local getArgs = require('Dev:Arguments').getArgs local width = 50 local widthBig = 75

function p.getGame(data) if data == dataSN then return "Subnautica" elseif data == dataBZ then return "Below Zero" end return "" end

function p.getItemID(id, data) -- removing disambiguations from pagenames id = string.gsub(id, " %(Subnautica%)", "") id = string.gsub(id, " %(Below Zero%)", "") -- if item ID is provided directly... if data[id] then return id	end -- ...otherwise try to find by item name for k, v in pairs(data) do		if v.name == id then -- item found return k		end end return nil -- Could not find item end

function p.getIcon(item, quantity, data, mid) if not data[item] then error("Could not generate icon for " .. p.getGame(data) .. " item '" .. item .. "'") end local iconOut = "" local iconWidth = width if not mid then iconWidth = widthBig end local iconHeight = iconWidth local iconOffset = 0 local name = data[item].name local image = data[item].image local iconBG if not image then if data[item].icon then local iconBGSize = data[item].icon.size or "1x1" local iconBGType = data[item].icon.bg or "default" image = data[item].icon.file or name .. " Icon.png" iconBG = iconBGSize .. " " .. iconBGType if iconBGSize == "1x2" then iconHeight = iconWidth * 2 elseif iconBGSize == "3x2" then iconHeight = (iconWidth / 3) * 2 elseif iconBGSize == "2x3" then iconHeight = (iconWidth / 2) * 3 end iconOffset = math.max(0, ((iconHeight - iconWidth) / 2)) else iconBG = "1x1 default" image = name .. " Icon.png" end end iconOut = "" if iconBG then iconOut = iconOut .. " " end -- disambiguation check local namefix = "" if data == dataBZ then namefix = name .. " (Below Zero)" else namefix = name .. " (Subnautica)" end local exists = mw.getCurrentFrame:callParserFunction('PROTECTIONEXPIRY:edit', namefix) ~= '' if not exists then -- disambiguated poge does not exist namefix = name end iconOut = iconOut .. "  ×0 " if quantity > 1 then iconOut = iconOut .. "×" .. quantity .. " "	end return iconOut .. " " end

function p.getAllRecipes(id, machine, data) -- First, get the ID of the product item provided by template; pagename used by default local itemID = p.getItemID(id, data) if not itemID then error("Could not find " .. p.getGame(data) .. " item '" .. id .. "'") end -- Item is found, start finding all recipes using it	local allProducts = {} for productID, product in pairs(data) do		productMachine = product.machine or "" if machine == "all" or machine == productMachine then for _, ingredient in ipairs(product.recipe or {}) do				local ingredientID = ingredient[1] local count = ingredient[2] if ingredientID == itemID then allProducts[#allProducts+1] = productID end end end end if #allProducts == 0 then if machine == "all" then error("No " .. p.getGame(data) .. " recipes use item '" .. id .. "'") else if(data[machine]) then error("No " .. p.getGame(data) .. " recipes use item '" .. id .."' and machine '" .. machine .. "'") else error(p.getGame(data) .. " machine '" .. machine .. "' does not exist") end end end local output = "" for _, product in ipairs(allProducts) do output = output .. p.getRecipe(product, false, data) end return output end

function p.testAllRecipes local allProducts = {} for productID, product in pairs(dataBZ) do		if dataBZ[productID].machine then allProducts[#allProducts+1] = productID end end local output = "" for _, product in ipairs(allProducts) do		local ran, recipe = pcall(p.getRecipe, product, false, dataBZ) if ran then output = output .. recipe else output = output .. " " .. recipe .. " "		end end

return output end

function p.getRecipe(id, power, data) -- First, get the ID of the product item provided by template; pagename used by default local itemID = p.getItemID(id, data) if not itemID then error("Could not find " .. p.getGame(data) .. " item '" .. id .. "'") end -- Item is found, start processing it	local output = " " local arrow = "  ×0 " if data[itemID].original and not power then -- If the item is made as part of a different item's recipe error (p.getGame(data) " item '" .. itemID .. "' cannot be directly crafted (use '" .. data[itemID].original .. "' instead)") elseif power then -- power output = output .. "" local machineID = "" local outNum = 0 local usedRod = false if data[itemID].energy then machineID = "basebioreactor" outNum = data[itemID].energy elseif data[itemID].nuclear then machineID = "basenuclearreactor" outNum = data[itemID].nuclear usedRod = true else error(p.getGame(data) .. " item '" .. itemID .. "' does not generate power") end local iconMachine = p.getIcon(machineID, 0, data, false) output = output .. iconMachine .. " "		output = output .. arrow .. "" output = output .. p.getIcon(itemID, 1, data, true) output = output .. " "		output = output .. arrow .. "" local iconProduct = p.getIcon("energy", outNum, data, false) output = output .. iconProduct if usedRod then local iconRod = p.getIcon("depletedreactorrod", 1, data, false) output = output .. iconRod end output = output .. " "		return output .. " "	else -- standard recipe if data[itemID].machine then -- Item is craftable, start writing the output output = output .. "" local machineID = data[itemID].machine if not data[machineID] then error ("Invalid machine listed in " .. p.getGame(data) .. " recipe for item '" .. itemID .. "'") end local iconMachine = p.getIcon(machineID, 0, data, false) output = output .. iconMachine .. " "			if data[itemID].recipe then output = output .. arrow .. "" for i,v in ipairs(data[itemID].recipe) do					local icon = p.getIcon(v[1], v[2], data, true) output = output .. icon end output = output .. " "			end output = output .. arrow .. "" local outNum = data[itemID].quantity or 1 local iconProduct = p.getIcon(itemID, outNum, data, false) output = output .. iconProduct if data[itemID].additional then local addOut = data[itemID].additional local addIcon for i,v in ipairs(addOut) do					addIcon = p.getIcon(v[1], v[2], data, false) output = output .. addIcon end end output = output .. " "			return output .. " "		else if data[itemID].recipe then error ("Machine is missing for " .. p.getGame(data) .. " item '" .. itemID .. "'") else error (p.getGame(data) .. " item '" .. itemID .. "' is not craftable") end end end end

function p.main(frame) local args = getArgs(frame) local id = args[1] or mw.title.getCurrentTitle.text local source = args[2] or "SN" local func = args[3] or "recipe" local dataSrc = dataSN if source == "BZ" then dataSrc = dataBZ end if func == "recipe" then return p.getRecipe(id, false, dataSrc) elseif func == "uses" then local machine = args[4] or "all" return p.getAllRecipes(id, machine, dataSrc) elseif func == "power" then return p.getRecipe(id, true, dataSrc) end end

function p.SN(frame) local args = getArgs(frame) local id = args[1] or mw.title.getCurrentTitle.text return p.getRecipe(id, false, dataSN) end

function p.allSN(frame) local args = getArgs(frame) local id = args[1] or mw.title.getCurrentTitle.text local machine = args[2] or "all" return p.getAllRecipes(id, machine, dataSN) end

function p.powerSN(frame) local args = getArgs(frame) local id = args[1] or mw.title.getCurrentTitle.text return p.getRecipe(id, true, dataSN) end

function p.BZ(frame) local args = getArgs(frame) local id = args[1] or mw.title.getCurrentTitle.text return p.getRecipe(id, false, dataBZ) end

function p.allBZ(frame) local args = getArgs(frame) local id = args[1] or mw.title.getCurrentTitle.text local machine = args[2] or "all" return p.getAllRecipes(id, machine, dataBZ) end

function p.powerBZ(frame) local args = getArgs(frame) local id = args[1] or mw.title.getCurrentTitle.text return p.getRecipe(id, true, dataBZ) end

return p --