Module:Recipe: Difference between revisions

From Subnautica Wiki
(adding check for disambiguated page)
(adding optional machine parameter for createAllRecipes)
Line 95: Line 95:
end
end


function p.createAllRecipes(id, data)
function p.createAllRecipes(id, machine, data)
-- First, get the ID of the product item provided by template; pagename used by default
-- First, get the ID of the product item provided by template; pagename used by default
local itemID = p.getItemID(id, data)
local itemID = p.getItemID(id, data)
Line 103: Line 103:
local allProducts = {}
local allProducts = {}
for productID, product in pairs(data) do
for productID, product in pairs(data) do
for _, ingredient in ipairs(product.recipe or {}) do
productMachine = product.machine or ""
if machine == "all" or machine == productMachine then
local ingredientID = ingredient[1]
for _, ingredient in ipairs(product.recipe or {}) do
local count = ingredient[2]
if ingredientID == itemID then
local ingredientID = ingredient[1]
allProducts[#allProducts+1] = productID
local count = ingredient[2]
end
if ingredientID == itemID then
allProducts[#allProducts+1] = productID
end
end
end
end
end
end
if #allProducts == 0 then error("No recipes use item '" .. id .. "'") end
if #allProducts == 0 then
if machine == "all" then
error("No recipes use item '" .. id .. "'")
else
error("No recipes use item '" .. id .."' and machine '" .. machine .. "'")
end
end
local output = ""
local output = ""
Line 187: Line 196:
local args = getArgs(frame)
local args = getArgs(frame)
local id = args[1] or mw.title.getCurrentTitle().text
local id = args[1] or mw.title.getCurrentTitle().text
local machine = args[2] or "all"
return p.createAllRecipes(id, dataSN)
return p.createAllRecipes(id, machine, dataSN)
end
end


Line 199: Line 209:
local args = getArgs(frame)
local args = getArgs(frame)
local id = args[1] or mw.title.getCurrentTitle().text
local id = args[1] or mw.title.getCurrentTitle().text
local machine = args[2] or "all"
return p.createAllRecipes(id, dataBZ)
return p.createAllRecipes(id, machine, dataBZ)
end
end



Revision as of 03:42, 25 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)
	if not data[item] then error("Could not generate icon for 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
		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
	
	-- disambiguation check
	local namefix = ""
	if data == dataBZ then
		namefix = name .. " (Below Zero)"
	else
		namefix = name .. " (Subnautica)"
	end
	if not mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY:edit', namefix) then
		-- disambiguated poge does not exist
		namefix = name
	end
	
	iconOut = iconOut .. "<span class='recipe__icon__img' style='top:" .. iconOffset .. "px;'>[[File:" .. image .. "|" .. iconWidth .. "px|link=" .. namefix .. "|" .. namefix .. "]]</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.createAllRecipes(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 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 recipes use item '" .. id .. "'")
		else
			error("No recipes use item '" .. id .."' and machine '" .. machine .. "'")
    	end
	end
    
    local output = ""
    for _, product in ipairs(allProducts) do
    	output = output .. p.createRecipe(product, data)
	end
    
    return output
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
	
	-- Item is found, start processing it
	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>"
	
	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 == dataBZ then
				error ("Cannot craft item '" .. itemID .. "' (use Template:UsesBZ instead)")
			else
				error ("Cannot craft item '" .. itemID .. "' (use Template:UsesSN instead)")
			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
	local machine = args[2] or "all"
	return p.createAllRecipes(id, machine, 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
	local machine = args[2] or "all"
	return p.createAllRecipes(id, machine, dataBZ)
end

return p
-- </nowiki>