Module:Recipe: Difference between revisions

From Subnautica Wiki
(Wrapping ingredients and outputs into their own div's for better margin handling)
(adding one more wrapping div to the machine for consistency; adding class names for better identification and to start moving styling out of this module)
Line 67: Line 67:
end
end
iconOut = "<div style='position:relative;width:" .. iconWidth .. "px;'>"
iconOut = "<div class='recipe__icon' style='position:relative;width:" .. iconWidth .. "px;'>"
if iconBG then
if iconBG then
iconOut = iconOut .. "<span style='position:absolute;left:0;top:0;'>[[File:" .. iconBG .. " bg.png|" .. iconWidth .. "px|link=]]</span>"
iconOut = iconOut .. "<span class='recipe__icon__bg' style='position:absolute;left:0;top:0;'>[[File:" .. iconBG .. " bg.png|" .. iconWidth .. "px|link=]]</span>"
end
end
iconOut = iconOut .. "<span style='position:absolute;left:0;top:" .. iconOffset .. "px;'>[[File:" .. image .. "|" .. iconWidth .. "px|link=" .. name .. "|" .. name .. "]]</span><span style='visibility:hidden;width:" .. iconWidth .. "px;display:block;'><span style='height:" .. iconHeight .. "px;width:" .. iconWidth .. "px;display:inline-block;'></span><br>x0</span>"
iconOut = iconOut .. "<span class='recipe__icon__img' style='position:absolute;left:0;top:" .. iconOffset .. "px;'>[[File:" .. image .. "|" .. iconWidth .. "px|link=" .. name .. "|" .. name .. "]]</span><span class='recipe__icon__pseudo' style='visibility:hidden;width:" .. iconWidth .. "px;display:block;'><span class='recipe__icon__pseudo__img' style='height:" .. iconHeight .. "px;width:" .. iconWidth .. "px;display:inline-block;'></span>x0</span>"
if quantity > 1 then
if quantity > 1 then
iconOut = iconOut .. "<span style='display:block;position:absolute;top:" .. iconHeight .. "px;text-align:center;width:100%;'>x" .. quantity .. "</span>"
iconOut = iconOut .. "<span class='recipe__icon__quantity' style='display:block;position:absolute;top:" .. iconHeight .. "px;text-align:center;width:100%;'>x" .. quantity .. "</span>"
end
end
Line 84: Line 84:
function p.SN(frame)
function p.SN(frame)
local args = getArgs(frame)
local args = getArgs(frame)
local output = "<div style='display:flex;flex-wrap:wrap;align-items:center;'>"
local output = "<div class='recipe' style='display:flex;flex-wrap:wrap;align-items:center;'>"
-- 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
Line 98: Line 98:
if dataSN[itemID].recipe and dataSN[itemID].machine then
if dataSN[itemID].recipe and dataSN[itemID].machine then
-- Recipe is found, start creating the output
-- Recipe is found, start creating the output
output = output .. "<div class='recipe__machine'>"
local machineID = dataSN[itemID].machine
local machineID = dataSN[itemID].machine
if not dataSN[machineID] then
if not dataSN[machineID] then
Line 103: Line 104:
end
end
local iconMachine = p.createIcon(machineID, 0, dataSN, false)
local iconMachine = p.createIcon(machineID, 0, dataSN, false)
output = output .. iconMachine
output = output .. iconMachine .. "</div>"
output = output .. "<div style='display:flex;align-items:center;'>"
output = output .. "<div class='recipe__ingredients' style='display:flex;align-items:center;'>"
for i,v in ipairs(dataSN[itemID].recipe) do
for i,v in ipairs(dataSN[itemID].recipe) do
local icon = p.createIcon(v[1], v[2], dataSN, true)
local icon = p.createIcon(v[1], v[2], dataSN, true)
Line 112: Line 113:
output = output .. "</div>"
output = output .. "</div>"
output = output .. "<div style='display:flex;align-items:center;'>"
output = output .. "<div class='recipe__output' style='display:flex;align-items:center;'>"
local outNum = dataSN[itemID].quantity or 1
local outNum = dataSN[itemID].quantity or 1
local iconProduct = p.createIcon(itemID, outNum, dataSN, false)
local iconProduct = p.createIcon(itemID, outNum, dataSN, false)

Revision as of 23:56, 10 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='position:relative;width:" .. iconWidth .. "px;'>"
	
	if iconBG then
		iconOut = iconOut .. "<span class='recipe__icon__bg' style='position:absolute;left:0;top:0;'>[[File:" .. iconBG .. " bg.png|" .. iconWidth .. "px|link=]]</span>"
	end
	
	iconOut = iconOut .. "<span class='recipe__icon__img' style='position:absolute;left:0;top:" .. iconOffset .. "px;'>[[File:" .. image .. "|" .. iconWidth .. "px|link=" .. name .. "|" .. name .. "]]</span><span class='recipe__icon__pseudo' style='visibility:hidden;width:" .. iconWidth .. "px;display:block;'><span class='recipe__icon__pseudo__img' style='height:" .. iconHeight .. "px;width:" .. iconWidth .. "px;display:inline-block;'></span>x0</span>"
	
	if quantity > 1 then
		iconOut = iconOut .. "<span class='recipe__icon__quantity' style='display:block;position:absolute;top:" .. iconHeight .. "px;text-align:center;width:100%;'>x" .. quantity .. "</span>"
	end
	
	return iconOut .. "</div>"
end

function p.SN(frame)
	local args = getArgs(frame)
	local output = "<div class='recipe' style='display:flex;flex-wrap:wrap;align-items:center;'>"
	
	-- First, get the ID of the product item provided by template; pagename used by default
	local id = args[1] or mw.title.getCurrentTitle().text
	local itemID = p.getItemID(id, dataSN)
	if not itemID then error("Could not find recipe for item '" .. id .. "'") end
	
	-- Item is found, start processing it
	if dataSN[itemID].original then
		-- If the item is made as part of a different item's recipe
		error ("No standalone recipe for item '" .. itemID .. "' (use '" .. dataSN[itemID].original .. "' instead)")
	else
		if dataSN[itemID].recipe and dataSN[itemID].machine then
			-- Recipe is found, start creating the output
			output = output .. "<div class='recipe__machine'>"
			local machineID = dataSN[itemID].machine
			if not dataSN[machineID] then
				error ("Invalid machine listed in recipe for item '" .. itemID .. "'")
			end
			local iconMachine = p.createIcon(machineID, 0, dataSN, false)
			output = output .. iconMachine .. "</div>"
			
			output = output .. "<div class='recipe__ingredients' style='display:flex;align-items:center;'>"
			for i,v in ipairs(dataSN[itemID].recipe) do
				local icon = p.createIcon(v[1], v[2], dataSN, true)
				output = output .. icon
			end
			output = output .. "</div>"
			
			output = output .. "<div class='recipe__output' style='display:flex;align-items:center;'>"
			local outNum = dataSN[itemID].quantity or 1
			local iconProduct = p.createIcon(itemID, outNum, dataSN, false)
			output = output .. iconProduct
			if dataSN[itemID].additional then
				local addOut = dataSN[itemID].additional
				local addIcon
				for i,v in ipairs(addOut) do
				    addIcon = p.createIcon(v[1], v[2], dataSN, false)
				    output = output .. addIcon
				end
			end
			output = output .. "</div>"
			
			return output .. "</div>"
		else
			-- If there is no recipe for the item
			error ("Cannot craft item '" .. itemID .. "' (use Template:Uses instead)")
		end
	end
end

return p
-- </nowiki>