Module:Recipe: Difference between revisions
SlyAceZeta (talk | contribs) (adding createAllRecipes function to grab all recipes used by a provided ingredient; moving ID arguments to template calls to be able to create recipes inside createAllRecipes) |
SlyAceZeta (talk | contribs) (adding smarter error handling for Template:UsesSN and Template:UsesBZ) |
||
Line 164: | Line 164: | ||
else |
else |
||
-- If there is no recipe for the item |
-- If there is no recipe for the item |
||
if data == dataSN then |
|||
error ("Cannot craft item '" .. itemID .. "' (use Template: |
error ("Cannot craft item '" .. itemID .. "' (use Template:UsesSN instead)") |
||
elseif data == dataBZ then |
|||
error ("Cannot craft item '" .. itemID .. "' (use Template:UsesBZ instead)") |
|||
else |
|||
error ("Cannot craft item '" .. itemID .. "'") |
|||
end |
|||
end |
end |
||
end |
end |
Revision as of 22:47, 22 June 2022
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. See Template:RecipeNew for more information. Thanks to BryghtShadow for helping out with the loops!
--[[
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!
--]]
-- <nowiki>
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.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.createIcon(item, quantity, data, mid)
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
image = name .. " Icon.png"
if data[item].icon then
local iconBGSize = data[item].icon.size or "1x1"
local iconBGType = data[item].icon.bg or "default"
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"
end
end
iconOut = "<div class='recipe__icon' style='width:" .. iconWidth .. "px;'>"
if iconBG then
iconOut = iconOut .. "<span class='recipe__icon__bg'>[[File:" .. iconBG .. " bg.png|" .. iconWidth .. "px|link=]]</span>"
end
iconOut = iconOut .. "<span class='recipe__icon__img' style='top:" .. iconOffset .. "px;'>[[File:" .. image .. "|" .. iconWidth .. "px|link=" .. name .. "|" .. name .. "]]</span><span class='recipe__icon__pseudo' style='width:" .. iconWidth .. "px;'><span class='recipe__icon__pseudo__img' style='height:" .. iconHeight .. "px;width:" .. iconWidth .. "px;'></span>×0</span>"
if quantity > 1 then
iconOut = iconOut .. "<span class='recipe__icon__quantity' style='top:" .. iconHeight .. "px;'>×" .. quantity .. "</span>"
end
return iconOut .. "</div>"
end
function p.getItemId(id)
local id = id or mw.title.getCurrentTitle().text
if data[id] then
return id -- Entry by ID found.
end
-- Match by item name
for k, v in pairs(data) do
if v.name == id then
return k -- Entry by name found.
end
end
return nil -- Could not find entry
end
function p.createAllRecipes(id, data)
local itemID = p.getItemID(id, data)
if not itemID then error("Could not find item '" .. id .. "'") end
local allProducts = {}
-- Now try to find all products crafted using this ingredient
for productID, product in pairs(data) do
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
-- Do something with all products IDs
return ("%s is used by: %s"):format(id, table.concat(allProducts, ', '))
end
function p.createRecipe(id, 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 recipe for item '" .. id .. "'") end
local output = "<div class='recipe'>"
local arrow = "<div class='recipe__step'><div class='recipe__step__arrow'>[[File:Item Arrow.png|20px|link=]]</div><span class='recipe__step__pseudo'><span class='recipe__step__pseudo__img'></span>×0</span></div>"
-- Item is found, start processing it
if data[itemID].original then
-- If the item is made as part of a different item's recipe
error ("No standalone recipe for item '" .. itemID .. "' (use '" .. data[itemID].original .. "' instead)")
else
if data[itemID].recipe and data[itemID].machine then
-- Recipe is found, start creating the output
output = output .. "<div class='recipe__machine'>"
local machineID = data[itemID].machine
if not data[machineID] then
error ("Invalid machine listed in recipe for item '" .. itemID .. "'")
end
local iconMachine = p.createIcon(machineID, 0, data, false)
output = output .. iconMachine .. "</div>"
output = output .. arrow .. "<div class='recipe__ingredients'>"
for i,v in ipairs(data[itemID].recipe) do
local icon = p.createIcon(v[1], v[2], data, true)
output = output .. icon
end
output = output .. "</div>"
output = output .. arrow .. "<div class='recipe__output'>"
local outNum = data[itemID].quantity or 1
local iconProduct = p.createIcon(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.createIcon(v[1], v[2], data, false)
output = output .. addIcon
end
end
output = output .. "</div>"
return output .. "</div>"
else
-- If there is no recipe for the item
if data == dataSN then
error ("Cannot craft item '" .. itemID .. "' (use Template:UsesSN instead)")
elseif data == dataBZ then
error ("Cannot craft item '" .. itemID .. "' (use Template:UsesBZ instead)")
else
error ("Cannot craft item '" .. itemID .. "'")
end
end
end
end
function p.SN(frame)
local args = getArgs(frame)
local id = args[1] or mw.title.getCurrentTitle().text
return p.createRecipe(id, dataSN)
end
function p.allSN(frame)
local args = getArgs(frame)
local id = args[1] or mw.title.getCurrentTitle().text
return p.createAllRecipes(id, dataSN)
end
function p.BZ(frame)
local args = getArgs(frame)
local id = args[1] or mw.title.getCurrentTitle().text
return p.createRecipe(id, dataBZ)
end
function p.allBZ(frame)
local args = getArgs(frame)
local id = args[1] or mw.title.getCurrentTitle().text
return p.createAllRecipes(id, dataBZ)
end
return p
-- </nowiki>