Jump to: navigation, search

Module:Crafting: Difference between revisions

(Undo this, it broke a lot. Will redo once I understand what's happening.)
(Updated fully again)
 
Line 1: Line 1:
local p = {}
local p = {}


local i18n = {
colored = 'Colored',
coloredDyes = {
'Orange Dye', 'Magenta Dye', 'Light Blue Dye', 'Dandelion Yellow', 'Lime Dye',
'Pink Dye', 'Gray Dye', 'Light Gray Dye', 'Cyan Dye', 'Purple Dye',
'Lapis Lazuli', 'Cocoa Beans', 'Cactus Green', 'Rose Red', 'Ink Sac',
},
categoryIngredientUsage = 'Category:Recipe using $1',
categoryRecipeType = 'Category:$1 recipe',
categoryUpcoming = 'Category:Upcoming',
itemBlockOfQuartz = 'Block of Quartz',
itemBoneMeal = 'Bone Meal',
itemBrownMushroom = 'Brown Mushroom',
itemCharcoal = 'Charcoal',
itemCoal = 'Coal',
itemColoredDye = 'Colored Dye',
itemDye = 'Dye',
itemMushroom = 'Mushroom',
itemQuartzBlock = 'Quartz Block',
itemRedMushroom = 'Red Mushroom',
itemStone = 'Stone',
moduleArgs = [[Module:ProcessArgs]],
moduleRecipe = [[Module:Recipe table]],
moduleSlot = [[Module:Inventory slot]],
stoneVariants = { 'Stone', 'Andesite', 'Granite', 'Diorite' },
type = 'Crafting',
variantPages = {
'Andesite', 'Banner', 'Bed', 'Diorite', 'Firework Star', 'Granite',
'Pressure Plate', 'Sand', 'Sandstone', 'Shield', 'Slab', 'Stained Glass Pane',
'Stained Glass', 'Stairs', 'Stone Bricks', 'Wood Planks', 'Wood', 'Wool',
},
}
p.i18n = i18n
local slot = require( i18n.moduleSlot )
local recipeTable = require( i18n.moduleRecipe ).table
local cArgVals = { 'A1', 'B1', 'C1', 'A2', 'B2', 'C2', 'A3', 'B3', 'C3' }
local cArgVals = { 'A1', 'B1', 'C1', 'A2', 'B2', 'C2', 'A3', 'B3', 'C3' }
p.cArgVals = cArgVals
p.cArgVals = cArgVals
Line 7: Line 43:
local args = f
local args = f
if f == mw.getCurrentFrame() then
if f == mw.getCurrentFrame() then
args = require( 'Module:ProcessArgs' ).merge()
args = require( i18n.moduleArgs ).merge( true )
else
else
f = mw.getCurrentFrame()
f = mw.getCurrentFrame()
end
local grid = require( 'Module:Grid' )
-- Start table when appropriate
local multirow = f:callParserFunction( '#dplvar', 'multirow' )
if multirow ~= '1' then
multirow = nil
end
local head = args.head or ''
if multirow then
head = ''
elseif head ~= '' then
multirow = 1
f:callParserFunction( '#dplvar:set', 'multirow', '1' )
else
head = 1
end
-- End table when appropriate
local foot = args.foot or ''
if multirow then
if foot ~= '' then
multirow = nil
f:callParserFunction( '#dplvar:set', 'multirow', '0' )
end
else
foot = 1
end
local header = ''
if head ~= '' then
local name = ''
local description = ''
if args.showname == '1' or multirow and args.showname ~= '0' then
name = 'Name !! '
f:callParserFunction( '#dplvar:set', 'craftingname', '1' )
end
if args.showdescription == '1' then
description = ' !! class="unsortable" | Description'
f:callParserFunction( '#dplvar:set', 'craftingdescription', '1' )
end
local class = args.class or ''
local recipeClass = ''
if multirow then
class = 'sortable collapsible ' .. class
recipeClass = 'class="unsortable collapse-button" |'
end
header = table.concat( {
' {| class="wikitable ' .. class .. '"',
'! ' .. name .. 'Ingredients !! ' .. recipeClass .. ' Crafting recipe' .. description,
'|-'
}, '\n' )
end
-- Name cell
local nameCell
if f:callParserFunction( '#dplvar', 'craftingname' ) == '1' then
if args.name or '' ~= '' then
nameCell = args.name
else
local names = {}
local links = {}
for v in mw.text.gsplit( args.Output or '', '%s*;%s*' ) do
parts = grid.getParts( v, args.Mod )
parts.mod = parts.mod or ''
if not names[parts.mod .. ':' .. parts.name] then
local link = ''
if parts.mod ~= '' then
link = 'Mods/' .. parts.mod .. '/' .. parts.name .. '|'
end
if parts.name:find( '^Any ' ) then
table.insert( links, 'Any [[' .. link .. parts.name:sub( 4 ) .. ']]' )
else
table.insert( links, '[[' .. link .. parts.name .. ']]' )
end
names[parts.mod .. ':' .. parts.name] = 1
end
end
nameCell = table.concat( links, '&nbsp;or<br>' )
end
end
if nameCell and args.upcoming then
nameCell = nameCell .. '<br>([[' .. args.upcoming .. ']])'
end
-- Create ingredient list
local ingredients = {}
local ingredientKeys = {}
local animatedIngredients = {}
local animatedKeys = {}
for k, v in pairs( args ) do
v = mw.text.trim( v )
if v ~= '' and tostring( k ):find( '^%u?%d%d?$' ) then
if v:find( ';' ) then
table.insert( animatedKeys, v )
else
local parts = grid.getParts( v, args.Mod )
parts.mod = parts.mod or ''
local fullName = parts.mod .. ':' .. parts.name
if not ingredients[fullName] then
table.insert( ingredientKeys, fullName )
ingredients[fullName] = { mod = parts.mod, name = parts.name }
end
end
end
end
for k, v in ipairs( animatedKeys ) do
local frames = mw.text.split( v, '%s*;%s*' )
local length = #frames
for k2, v2 in ipairs( frames ) do
local parts = grid.getParts( v2, args.Mod )
parts.mod = parts.mod or ''
local fullName = parts.mod .. ':' .. parts.name
if v2 ~= '' and not ingredients[fullName] and not animatedIngredients[fullName] then
table.insert( ingredientKeys, fullName )
animatedIngredients[fullName] = { mod = parts.mod, name = parts.name, final = k2 == length }
end
end
end
-- Ingredients cell
local ingredientsCell
if args.ingredients or '' ~= '' then
ingredientsCell = args.ingredients
else
ingredientsCell = {}
for k, v in ipairs( ingredientKeys ) do
local link = ''
local separator = '&nbsp;+'
if k == #ingredientKeys then
separator = ''
elseif animatedIngredients[v] and not animatedIngredients[v].final then
separator = '&nbsp;or'
end
local mod = ( ingredients[v] or animatedIngredients[v] ).mod
local name = ( ingredients[v] or animatedIngredients[v] ).name
if mod ~= '' then
link = 'Mods/'.. mod .. '/' .. name .. '|'
end
if name:find( '^Any ' ) then
table.insert( ingredientsCell, 'Any [[' .. link .. name:sub( 5 ) .. ']]' .. separator )
else
table.insert( ingredientsCell, '[[' .. link .. name .. ']]' .. separator )
end
end
ingredientsCell = table.concat( ingredientsCell, '<br>\n' )
end
end
-- Automatic shapeless positioning
-- Automatic shapeless positioning
local newArgs = {}
if args[1] then
if args[1] then
newArgs.shapeless = 1
args.shapeless = 1
if args[7] then
if args[7] then
newArgs.A1 = args[1]
args.A1 = args[1]
newArgs.B1 = args[2]
args.B1 = args[2]
newArgs.C1 = args[3]
args.C1 = args[3]
newArgs.A2 = args[4]
args.A2 = args[4]
newArgs.B2 = args[5]
args.B2 = args[5]
newArgs.C2 = args[6]
args.C2 = args[6]
if args[8] then
if args[8] then
-- ◼◼◼      ◼◼◼
-- ◼◼◼      ◼◼◼
-- ◼◼◼  OR  ◼◼◼
-- ◼◼◼  OR  ◼◼◼
-- ◼◼◼      ◼◼◻
-- ◼◼◼      ◼◼◻
newArgs.A3 = args[7]
args.A3 = args[7]
newArgs.B3 = args[8]
args.B3 = args[8]
newArgs.C3 = args[9]
args.C3 = args[9]
if args[9] then
if args[9] then
local identical = true
local identical = true
Line 186: Line 70:
if args[i] ~= args[i + 1] then
if args[i] ~= args[i + 1] then
identical = false
identical = false
break
end
end
end
end
if identical then
if identical then
newArgs.shapeless = nil
args.shapeless = nil
end
end
end
end
Line 196: Line 81:
-- ◼◼◼
-- ◼◼◼
-- ◻◼◻
-- ◻◼◻
newArgs.B3 = args[7]
args.B3 = args[7]
end
end
elseif args[2] then
elseif args[2] then
newArgs.A2 = args[1]
args.A2 = args[1]
newArgs.B2 = args[2]
args.B2 = args[2]
if args[5] then
if args[5] then
-- ◻◻◻      ◻◻◻
-- ◻◻◻      ◻◻◻
-- ◼◼◼  OR  ◼◼◼
-- ◼◼◼  OR  ◼◼◼
-- ◼◼◼      ◼◼◻
-- ◼◼◼      ◼◼◻
newArgs.C2 = args[3]
args.C2 = args[3]
newArgs.A3 = args[4]
args.A3 = args[4]
newArgs.B3 = args[5]
args.B3 = args[5]
newArgs.C3 = args[6]
args.C3 = args[6]
elseif args[4] then
elseif args[4] then
-- ◻◻◻
-- ◻◻◻
-- ◼◼◻
-- ◼◼◻
-- ◼◼◻
-- ◼◼◻
newArgs.A3 = args[3]
args.A3 = args[3]
newArgs.B3 = args[4]
args.B3 = args[4]
else
else
-- ◻◻◻      ◻◻◻
-- ◻◻◻      ◻◻◻
-- ◼◼◻  OR  ◼◼◻
-- ◼◼◻  OR  ◼◼◻
-- ◻◼◻      ◻◻◻
-- ◻◼◻      ◻◻◻
newArgs.B3 = args[3]
args.B3 = args[3]
end
end
else
else
Line 225: Line 110:
-- ◻◼◻
-- ◻◼◻
-- ◻◻◻
-- ◻◻◻
newArgs.B2 = args[1]
args.B2 = args[1]
newArgs.shapeless = nil
args.shapeless = nil
end
for i = 1, 9 do
args[i] = nil
end
end
else
newArgs.A1 = args.A1
newArgs.B1 = args.B1
newArgs.C1 = args.C1
newArgs.A2 = args.A2
newArgs.B2 = args.B2
newArgs.C2 = args.C2
newArgs.A3 = args.A3
newArgs.B3 = args.B3
newArgs.C3 = args.C3
newArgs.fixed = args.fixed
newArgs.notfixed = args.notfixed
end
end
-- Any other args we want to pass along
-- Create recipe table, and list of ingredients
newArgs.Mod = args.Mod
local out, ingredientSets = recipeTable( args, {
newArgs.Output = args.Output
uiFunc = 'craftingTable',
newArgs.Otitle = args.Otitle
type = i18n.type,
newArgs.Olink = args.Olink
ingredientArgs = cArgVals,
outputArgs = { 'Output' },
} )
-- Recipe cell
local title = mw.title.getCurrentTitle()
local recipeCell = grid.craftingTable( newArgs )
if args.nocat == '1' or title.namespace ~= 0 or title.isSubpage then
return out
local row = { ingredientsCell, recipeCell }
if nameCell then
table.insert( row, 1, nameCell )
end
if f:callParserFunction( '#dplvar', 'craftingdescription' ) == '1' then
table.insert( row, args.description or '' )
end
end
row = table.concat( row, '\n|\n' )
if nameCell then
local categories = {}
row = '!\n' .. row
local cI = 1
else
if args.upcoming then
row = '|\n' .. row
categories[cI] = '[[' .. i18n.categoryUpcoming .. ']]'
cI = cI + 1
end
end
local footer = ''
if args.type then
if foot ~= '' then
categories[cI] = '[[' .. i18n.categoryRecipeType:gsub( '%$1', args.type ) .. ']]'
footer = '|}'
cI = cI + 1
f:callParserFunction( '#dplvar:set', 'craftingname', '0', 'craftingdescription', '0' )
end
end
-- Create ingredient categories for DPL
if args.ignoreusage ~= '1' then
local title = mw.title.getCurrentTitle()
-- Create ingredient categories for DPL
local categories = ''
local usedNames = {}
if args.nocat ~= '1' and title.namespace == 0 and not title.isSubpage then
for _, ingredientSet in pairs( ingredientSets ) do
categories = {}
for _, ingredient in pairs( ingredientSet ) do
local name = ingredient.name
if args.upcoming then
if not ingredient.mod and not usedNames[name] and name ~= title.text then
table.insert( categories, '[[Category:Upcoming]]' )
-- List each dye individually as they have their own pages
end
if
name == slot.i18n.prefixes.any .. ' ' .. i18n.itemDye or
if args.type then
name == slot.i18n.prefixes.matching .. ' ' .. i18n.itemDye or
table.insert( categories, '[[Category:' .. args.type .. ' recipe]]' )
name == slot.i18n.prefixes.any .. ' ' .. i18n.itemColoredDye or
end
name == slot.i18n.prefixes.matching .. ' ' .. i18n.itemColoredDye
then
if args.ignoreusage ~= '1' then
if not name:find( i18n.colored ) then
for k, v in ipairs( ingredientKeys ) do
categories[cI] = '[[' .. i18n.categoryIngredientUsage:gsub( '%$1', i18n.itemBoneMeal ) .. ']]'
v = v:sub( 2 )
cI = cI + 1
if not v:find( ':' ) then
usedNames[i18n.itemBoneMeal] = true
if v == 'Any Dye' or v == 'Any Colored Dye' then
local dyes = {
'Orange Dye', 'Magenta Dye', 'Light Blue Dye', 'Dandelion Yellow', 'Lime Dye',
'Pink Dye', 'Gray Dye', 'Light Gray Dye', 'Cyan Dye', 'Purple Dye',
'Lapis Lazuli', 'Cocoa Beans', 'Cactus Green', 'Rose Red', 'Ink Sac'
}
if v == 'Any Dye' then
table.insert( dyes, 1, 'Bone Meal' )
end
end
for _, dye in ipairs( dyes ) do
for _, dye in pairs( i18n.coloredDyes ) do
table.insert( categories, '[[Category:Recipe using ' .. dye .. ']]' )
categories[cI] = '[[' .. i18n.categoryIngredientUsage:gsub( '%$1', dye ) .. ']]'
cI = cI + 1
usedNames[dye] = true
end
-- List stone variants individually as they have their own pages
elseif
name == slot.i18n.prefixes.any .. ' ' .. i18n.itemStone or
name == slot.i18n.prefixes.matching .. ' ' .. i18n.itemStone
then
for _, stone in pairs( i18n.stoneVariants ) do
categories[cI] = '[[' .. i18n.categoryIngredientUsage:gsub( '%$1', stone ) .. ']]'
cI = cI + 1
usedNames[stone] = true
end
end
else
else
if v == 'Sticky Piston' then v = 'Piston'
-- Merge item variants which use a single page
elseif v== 'Any Mushroom' or v == 'Red Mushroom' or v == 'Brown Mushroom' then v = 'Mushroom'
if
elseif v == 'Red Sand' then v = 'Sand'
name == slot.i18n.prefixes.any .. ' ' .. i18n.itemMushroom or
elseif v == 'Charcoal' then v = 'Coal'
name == slot.i18n.prefixes.matching .. ' ' .. i18n.itemMushroom or
elseif v:find( ' Wood$' ) then v = 'Wood'
name == i18n.itemRedMushroom or
elseif v:find( ' Wood Planks$' ) then v = 'Wood Planks'
name == i18n.itemBrownMushroom
elseif v:find( ' Stained Glass$' ) then v = 'Stained Glass'
then name = i18n.itemMushroom
elseif v:find( ' Stained Glass Pane$' ) then v = 'Stained Glass Pane'
elseif name == i18n.itemCharcoal then name = i18n.itemCoal
elseif v:find( ' Wool$' ) then v = 'Wool'
elseif name:find( ' ' .. i18n.itemQuartzBlock .. '$' ) then name = i18n.itemBlockOfQuartz
elseif v:find( 'Red Sandstone$' ) then v = 'Red Sandstone'
else
elseif v:find( ' Sandstone$' ) then v = 'Sandstone'
for _, variant in pairs( i18n.variantPages ) do
elseif v:find( ' Stairs$' ) then v = 'Stairs'
if name:find( ' ' .. variant .. '$' ) then
elseif v:find( ' Slab$' ) then v = 'Slab'
name = variant
elseif v:find( ' Pressure Plate$' ) then v = 'Pressure Plate'
break
elseif v:find( ' Firework Star$' ) then v = 'Firework Star'
end
elseif v:find( ' Stone Bricks$' ) then v = 'Stone Bricks'
end
elseif v:find( ' Quartz Block$' ) then v = 'Block of Quartz'
elseif v:find( ' Andesite$' ) then v = 'Andesite'
-- Remove prefixes
elseif v:find( ' Diorite$' ) then v = 'Diorite'
for _, prefix in pairs( slot.i18n.prefixes ) do
elseif v:find( ' Granite$' ) then v = 'Granite'
if name:find( '^' .. prefix .. ' ' ) then
name = name:gsub( '^' .. prefix .. ' ', '' )
break
end
end
end
end
table.insert( categories, '[[Category:Recipe using ' .. v .. ']]' )
if not usedNames[name] then
categories[cI] = '[[' .. i18n.categoryIngredientUsage:gsub( '%$1', name ) .. ']]'
cI = cI + 1
usedNames[name] = true
end
end
end
end
end
end
end
end
end
categories = table.concat( categories, '' )
end
end
if args.debug == '1' then
return out, table.concat( categories, '' )
return '<pre>' .. header .. '\n' .. row .. '\n|-\n' .. footer .. categories .. '</pre>'
else
return header .. '\n' .. row .. '\n|-\n' .. footer .. categories
end
end
end
return p
return p

Latest revision as of 12:58, 12 May 2017

Documentation

This module implements {{crafting}}.

Parent arguments are automatically merged with directly passed arguments (the latter overwriting the former).

Dependencies

See also

The above documentation is transcluded from Module:Crafting/doc.

This module implements {{crafting}}.

Parent arguments are automatically merged with directly passed arguments (the latter overwriting the former).

Dependencies

See also


local p = {}

local i18n = {
	colored = 'Colored',
	coloredDyes = {
		'Orange Dye', 'Magenta Dye', 'Light Blue Dye', 'Dandelion Yellow', 'Lime Dye',
		'Pink Dye', 'Gray Dye', 'Light Gray Dye', 'Cyan Dye', 'Purple Dye',
		'Lapis Lazuli', 'Cocoa Beans', 'Cactus Green', 'Rose Red', 'Ink Sac',
	},
	categoryIngredientUsage = 'Category:Recipe using $1',
	categoryRecipeType = 'Category:$1 recipe',
	categoryUpcoming = 'Category:Upcoming',
	itemBlockOfQuartz = 'Block of Quartz',
	itemBoneMeal = 'Bone Meal',
	itemBrownMushroom = 'Brown Mushroom',
	itemCharcoal = 'Charcoal',
	itemCoal = 'Coal',
	itemColoredDye = 'Colored Dye',
	itemDye = 'Dye',
	itemMushroom = 'Mushroom',
	itemQuartzBlock = 'Quartz Block',
	itemRedMushroom = 'Red Mushroom',
	itemStone = 'Stone',
	moduleArgs = [[Module:ProcessArgs]],
	moduleRecipe = [[Module:Recipe table]],
	moduleSlot = [[Module:Inventory slot]],
	stoneVariants = { 'Stone', 'Andesite', 'Granite', 'Diorite' },
	type = 'Crafting',
	variantPages = {
		'Andesite', 'Banner', 'Bed', 'Diorite', 'Firework Star', 'Granite', 
		'Pressure Plate', 'Sand', 'Sandstone', 'Shield', 'Slab', 'Stained Glass Pane', 
		'Stained Glass', 'Stairs', 'Stone Bricks', 'Wood Planks', 'Wood', 'Wool',
	},
}
p.i18n = i18n

local slot = require( i18n.moduleSlot )
local recipeTable = require( i18n.moduleRecipe ).table
local cArgVals = { 'A1', 'B1', 'C1', 'A2', 'B2', 'C2', 'A3', 'B3', 'C3' }
p.cArgVals = cArgVals

function p.table( f )
	local args = f
	if f == mw.getCurrentFrame() then
		args = require( i18n.moduleArgs ).merge( true )
	else
		f = mw.getCurrentFrame()
	end
	
	-- Automatic shapeless positioning
	if args[1] then
		args.shapeless = 1
		if args[7] then
			args.A1 = args[1]
			args.B1 = args[2]
			args.C1 = args[3]
			args.A2 = args[4]
			args.B2 = args[5]
			args.C2 = args[6]
			if args[8] then
				-- ◼◼◼      ◼◼◼
				-- ◼◼◼  OR  ◼◼◼
				-- ◼◼◼      ◼◼◻
				args.A3 = args[7]
				args.B3 = args[8]
				args.C3 = args[9]
				if args[9] then
					local identical = true
					for i = 1, 8 do
						if args[i] ~= args[i + 1] then
							identical = false
							break
						end
					end
					if identical then
						args.shapeless = nil
					end
				end
			else
				-- ◼◼◼
				-- ◼◼◼
				-- ◻◼◻
				args.B3 = args[7]
			end
		elseif args[2] then
			args.A2 = args[1]
			args.B2 = args[2]
			if args[5] then
				-- ◻◻◻      ◻◻◻
				-- ◼◼◼  OR  ◼◼◼
				-- ◼◼◼      ◼◼◻
				args.C2 = args[3]
				args.A3 = args[4]
				args.B3 = args[5]
				args.C3 = args[6]
			elseif args[4] then
				-- ◻◻◻
				-- ◼◼◻
				-- ◼◼◻
				args.A3 = args[3]
				args.B3 = args[4]
			else
				-- ◻◻◻      ◻◻◻
				-- ◼◼◻  OR  ◼◼◻
				-- ◻◼◻      ◻◻◻
				args.B3 = args[3]
			end
		else
			-- ◻◻◻
			-- ◻◼◻
			-- ◻◻◻
			args.B2 = args[1]
			args.shapeless = nil
		end
		
		for i = 1, 9 do
			args[i] = nil
		end
	end
	
	-- Create recipe table, and list of ingredients
	local out, ingredientSets = recipeTable( args, {
		uiFunc = 'craftingTable',
		type = i18n.type,
		ingredientArgs = cArgVals,
		outputArgs = { 'Output' },
	} )
	
	local title = mw.title.getCurrentTitle()
	if args.nocat == '1' or title.namespace ~= 0 or title.isSubpage then
		return out
	end
	
	local categories = {}
	local cI = 1
	if args.upcoming then
		categories[cI] = '[[' .. i18n.categoryUpcoming .. ']]'
		cI = cI + 1
	end
	
	if args.type then
		categories[cI] = '[[' .. i18n.categoryRecipeType:gsub( '%$1', args.type ) .. ']]'
		cI = cI + 1
	end
	
	if args.ignoreusage ~= '1' then
		-- Create ingredient categories for DPL
		local usedNames = {}
		for _, ingredientSet in pairs( ingredientSets ) do
			for _, ingredient in pairs( ingredientSet ) do
				local name = ingredient.name
				if not ingredient.mod and not usedNames[name] and name ~= title.text then
					-- List each dye individually as they have their own pages
					if
						name == slot.i18n.prefixes.any .. ' ' .. i18n.itemDye or
						name == slot.i18n.prefixes.matching .. ' ' .. i18n.itemDye or
						name == slot.i18n.prefixes.any .. ' ' .. i18n.itemColoredDye or
						name == slot.i18n.prefixes.matching .. ' ' .. i18n.itemColoredDye
					then
						if not name:find( i18n.colored ) then
							categories[cI] = '[[' .. i18n.categoryIngredientUsage:gsub( '%$1', i18n.itemBoneMeal ) .. ']]'
							cI = cI + 1
							usedNames[i18n.itemBoneMeal] = true
						end
						
						for _, dye in pairs( i18n.coloredDyes ) do
							categories[cI] = '[[' .. i18n.categoryIngredientUsage:gsub( '%$1', dye ) .. ']]'
							cI = cI + 1
							usedNames[dye] = true
						end
					-- List stone variants individually as they have their own pages
					elseif
						name == slot.i18n.prefixes.any .. ' ' .. i18n.itemStone or
						name == slot.i18n.prefixes.matching .. ' ' .. i18n.itemStone
					then
						for _, stone in pairs( i18n.stoneVariants ) do
							categories[cI] = '[[' .. i18n.categoryIngredientUsage:gsub( '%$1', stone ) .. ']]'
							cI = cI + 1
							usedNames[stone] = true
						end
					else
						-- Merge item variants which use a single page
						if
							name == slot.i18n.prefixes.any .. ' ' .. i18n.itemMushroom or
							name == slot.i18n.prefixes.matching .. ' ' .. i18n.itemMushroom or
							name == i18n.itemRedMushroom or
							name == i18n.itemBrownMushroom
						then name = i18n.itemMushroom
						elseif name == i18n.itemCharcoal then name = i18n.itemCoal
						elseif name:find( ' ' .. i18n.itemQuartzBlock .. '$' ) then name = i18n.itemBlockOfQuartz
						else
							for _, variant in pairs( i18n.variantPages ) do
								if name:find( ' ' .. variant .. '$' ) then
									name = variant
									break
								end
							end
							
							-- Remove prefixes
							for _, prefix in pairs( slot.i18n.prefixes ) do
								if name:find( '^' .. prefix .. ' ' ) then
									name = name:gsub( '^' .. prefix .. ' ', '' )
									break
								end
							end
						end
						
						if not usedNames[name] then
							categories[cI] = '[[' .. i18n.categoryIngredientUsage:gsub( '%$1', name ) .. ']]'
							cI = cI + 1
							usedNames[name] = true
						end
					end
				end
			end
		end
	end
	
	return out, table.concat( categories, '' )
end

return p


Cookies help us deliver our services. By using our services, you agree to our use of cookies.