Module:Crafting usage

The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Documentation for this module may be created at Module:Crafting usage/doc

local p = {}
function p.dpl( f )
	local args = f:getParent().args
	local grid = require( 'Module:Grid' )
	local ingredients = args[1] and mw.text.split( args[1], '%s*,%s*' ) or { mw.title.getCurrentTitle().text }
	local matchTypes = args.match and args.match:find( ',' ) and mw.text.split( args.match, '%s*,%s*' ) or args.match

	local argList = {
		'ignoreusage', 'upcoming', 'name', 'ingredients', 'arggroups',
		1, 2, 3, 4, 5, 6, 7, 8, 9,
		'A1', 'B1', 'C1', 'A2', 'B2', 'C2', 'A3', 'B3', 'C3',
		'Output', 'description', 'fixed', 'notfixed'
	}
	local anonToShaped = { 'A1', 'B1', 'C1', 'A2', 'B2', 'C2', 'A3', 'B3', 'C3' }
	local shapedToAnon = { A1 = 1, B1 = 2, C1 = 3, A2 = 4, B2 = 5, C2 = 5, A3 = 6, B3 = 7, C3 = 8 }

	local data = ''
	if args.category then
		data = f:callParserFunction( '#dpl', {
			category = args.category,
			nottitleregexp = args.ignore,
			include = '{Crafting}:' .. table.concat( argList, ':' ),
			mode = 'userformat',
			secseparators = '====',
			multisecseparators = '====',
			''
		} )
	else
		-- #dpl has a limit of four, so do it in chunks of 4
		for i = 1, #ingredients, 4 do
			data = data .. f:callParserFunction( '#dpl', {
				category = 'Recipe using ' .. table.concat( ingredients, '|Recipe using ', i, math.min( i + 3, #ingredients ) ),
				nottitleregexp = args.ignore,
				include = '{Crafting}:' .. table.concat( argList, ':' ),
				mode = 'userformat',
				secseparators = '====',
				multisecseparators = '====',
				''
			} )
		end
	end
	
	-- Comment this next line out if you're not using any aliases
	local aliases = mw.loadData( 'Module:Grid/Aliases' )
	
	local function matchPattern( ingredient, ingredientNum )
		local matchType = matchTypes
		if type( matchType ) == 'table' then
			matchType = matchTypes[ingredientNum]
		end
		local pattern
		local escaped = ingredient:gsub( '([%(%)])', '%%%1' )
		if matchType == 'start' then
			pattern = '[;:%]]%s*' .. escaped
		elseif matchType == 'end' then
			pattern = escaped .. '%s*[,;%[]'
		elseif matchType == 'any' then
			pattern = escaped
		else
			pattern = '[;:%]]%s*' .. escaped .. '%s*[,;%[]'
		end
		
		return pattern
	end

	local function compareTables( a, b )
		for k, v in pairs( a ) do
			if type( b[k] ) ~= type( v ) then
				return false
			end
			if type( v ) == 'table' then
				if not compareTables( v, b[k] ) then
					return false
				end
			elseif v ~= b[k] then
				return false
			end
		end
		for k, v in pairs( b ) do
			if a[k] == nil then
				return false
			end
		end
		return true
	end

	local out = {}
	local showDesciption
	local templates = {}
	for template in mw.text.gsplit( data, '====' ) do
		-- If ignoreusage is empty
		if template:find( '^%s*|' ) then
			local tArgs = {}
			local i = 0
			-- Extract the arguments from the DPL query
			for tArg in mw.text.gsplit( template, '\n|' ) do
				i = i + 1
				if tArg ~= '' then
					local key = argList[i]
					tArgs[key] = tArg
				end
			end
			
			local craftingArgs = {
				tArgs[1] or tArgs.A1 or '' or 'Infuse', tArgs[2] or tArgs.B1 or '' or 'Input', tArgs[3] or tArgs.C1 or '',
				tArgs[4] or tArgs.A2 or '', tArgs[5] or tArgs.B2 or '', tArgs[6] or tArgs.C2 or '',
				tArgs[7] or tArgs.A3 or '', tArgs[8] or tArgs.B3 or '', tArgs[9] or tArgs.C3 or '',
				Output = tArgs.Output
			}
			
			local expandedFrames = {}
			local hasIngredient
			local argsWithIngredient = {}
			local argGroups = {}
			for i, v in pairs( craftingArgs ) do
				if v ~= '' then
					if aliases then
						expandedFrames[i] = {}
						local expandedFrame = {}
						for frame in mw.text.gsplit( v, '%s*;%s*' ) do
							local parts = grid.getParts( frame )
							local alias = aliases[parts.name]
							if alias then
								local expandedAlias = grid.expandAlias( parts, alias ):gsub( '%s*([%[%]:,;])%s*', '%1' )
								expandedFrames[i][frame] = expandedAlias:gsub( '([%(%)])', '%%%1' )
								table.insert( expandedFrame, expandedAlias )
							else
								table.insert( expandedFrame, frame )
							end
						end
						
						v = table.concat( expandedFrame, ';' )
						craftingArgs[i] = v
					end
					if i ~= 'Output' then
						local delimitedFrames = ';' .. v .. ';'
						for ingredientNum, ingredient in pairs( ingredients ) do
							if delimitedFrames:find( matchPattern( ingredient, ingredientNum ) ) then
								if not v:find( ';' ) then
									hasIngredient = 'static'
								elseif not hasIngredient then
									hasIngredient = 'animated'
								end
								
								argsWithIngredient[i] = true
							end
						end
					end
					
					if not tArgs.arggroups and hasIngredient ~= 'static' then
						local _, frameCount = v:gsub( ';', '' )
						if frameCount > 0 then
							frameCount = frameCount + 1
							local group = argGroups[frameCount]
							if not group then
								group = { args = {} }
								argGroups[frameCount] = group
							end
							group.count = frameCount
							group.args[i] = true
						end
					end
				end
			end
			
			if hasIngredient then
				if tArgs.description then
					showDescription = true
				end
				
				if hasIngredient == 'animated' then
					if tArgs.arggroups then
						for argGroup in mw.text.gsplit( tArgs.arggroups, '%s*;%s*' ) do
							local group = {}
							local _, frameCount
							for arg in mw.text.gsplit( argGroup, '%s*,%s*' ) do
								if not tArgs[1] then
									arg = shapedToAnon[arg]
								end
								if not frameCount then
									_, frameCount = craftingArgs[arg]:gsub( ';', '' )
								end
								group[arg] = true
							end
							table.insert( argGroups, { count = frameCount + 1, args = group } )
						end
					end
					
					for _, groupData in pairs( argGroups ) do
						local frameCount = groupData.count
						local group = groupData.args
						local requiredFrames = {}
						local requiredFramesCount = 0
						for arg in pairs( group ) do
							if argsWithIngredient[arg] then
								local frames = craftingArgs[arg]
								local frameNum = 0
								for frame in mw.text.gsplit( frames, '%s*;%s*' ) do
									frameNum = frameNum + 1
									if not requiredFrames[frameNum] then
										local delimitedFrame = ';' .. frame .. ';'
										for ingredientNum, ingredient in pairs( ingredients ) do
											if delimitedFrame:find( matchPattern( ingredient, ingredientNum ) ) then
												requiredFrames[frameNum] = true
												requiredFramesCount = requiredFramesCount + 1
											end
										end
									end
								end
							end
						end
						
						-- Not all frames will be used
						if requiredFramesCount > 0 and requiredFramesCount < frameCount then
							for arg in pairs( group ) do
								local frames = craftingArgs[arg]
								local newFrames = {}
								local frameNum = 0
								for frame in mw.text.gsplit( frames, '%s*;%s*' ) do
									frameNum = frameNum + 1
									if requiredFrames[frameNum] then
										table.insert( newFrames, frame )
									end
								end
								newFrames = table.concat( newFrames, ';' )
								
								-- If the whole expanded alias survived, collapse it again
								if expandedFrames[arg] then
									for frame, expandedAlias in pairs( expandedFrames[arg] ) do
										--newFrames = 'blah' .. expandedAlias
										newFrames = newFrames:gsub( expandedAlias, frame )
									end
								end
								
								local tArg = arg
								if arg ~= 'Output' and not tArgs[1] then
									tArg = anonToShaped[arg]
								end
								tArgs[tArg] = newFrames
							end
							
							-- Let Module:Crafting handle the name and ingredients columns
							tArgs.name = nil
							tArgs.ingredients = nil
						end
					end
				end
				
				tArgs.nocat = '1'

				local found = false
				for i, v in ipairs( templates ) do
					if compareTables( v, tArgs ) then
						found = true
						break
					end
				end
				if not found then
					table.insert( templates, tArgs )
				end
			end
		end
	end
	if #templates == 0 then
		return '[[Category:Empty crafting usage]]'
	end
	
	templates[1].head = '1'
	templates[1].showname = '1'
	if showDescription and args.showdesciption ~= '0' or args.showdesciption == '1' then
		templates[1].showdescription = '1'
	end
	if not args.continue then
		templates[#templates].foot = '1'
	end
	
	local crafting = require( 'Module:Crafting' )
	local out = {}
	for i, v in ipairs( templates ) do
		table.insert( out, crafting.table( v ) )
	end
	
	return table.concat( out, '\n' )
end
return p
Cookies help us deliver our services. By using our services, you agree to our use of cookies.

Need wiki hosting?

Do you need a wiki for your Minecraft mod/gaming wiki? We'll host it for free! Contact us.

Other wikis

Indie-game wikis
Powered by Indie Wikis