Module:Recipes

local item_link = require('Module:Item').go local trim = mw.text.trim local cargo = mw.ext.cargo

-- credit: http://richard.warburton.it -- this version is with trim. local function explode(div,str) if (div=='') then return false end local pos,arr = 0,{} -- for each divider found for st,sp in function return string.find(str,div,pos,true) end do		table.insert(arr, trim(string.sub(str,pos,st-1))) -- Attach chars left of current divider pos = sp + 1 -- Jump past current divider end table.insert(arr, trim(string.sub(str,pos))) -- Attach chars right of last divider return arr end

local metals = { ['Copper/Tin'] = 1, ['Silver/Tungsten'] = 1, ['Gold/Platinum'] = 1, ['Iron/Lead'] = 1, ['Cobalt/Palladium'] = 1, ['Mythril/Orichalcum'] = 1, ['Adamantite/Titanium'] = 1, ['Tin/Copper'] = 2, ['Tungsten/Silver'] = 2, ['Platinum/Gold'] = 2, ['Lead/Iron'] = 2, ['Palladium/Cobalt'] = 2, ['Orichalcum/Mythril'] = 2, ['Titanium/Adamantite'] = 2, }

-- retuan a array of itemname, split xxx/yyy to item1=xxx, item2=yyy. If it's something like "Lead/Iron Bar", it will normalize as item1 = Iron Bar, item2 = Lead Bar. local function split(name) local count = select(2, name:gsub("/", "/", 2)) if count == 0 then -- only 1 item return { trim(name) } elseif count == 1 then -- 2 items local item1a, item1b, item2a, item2b = name:match("^%s*(%S+)%s*(.-)/%s*(%S+)%s*(.-)$") local x = metals[item1a..'/'..item2a] if tostring(item1b) == '' and x then item1b = item2b end if x == 2 then return {trim(item2a..' '..item2b), trim(item1a..' '..item1b)} else return {trim(item1a..' '..item1b), trim(item2a..' '..item2b)} end else -- 3 or more items return explode('/', name) end end

-- return 1 or 2 value(s), when input is name[note], return item, note. local function itemname(str) local item, note = str:match("^(.-)(%b[])$") if item then return item, note else return str end end

-- normalize ingredient name input, Lead Bar=>¦Lead Bar¦, Iron/Lead Bar => ¦Iron Bar¦Lead Bar¦, Lead/Iron Bar => ¦Iron Bar¦Lead Bar¦ .... local function normalize(name) local result = '¦' for k, v in pairs(split(name)) do result = result .. itemname(v) .. '¦'	end return result end

local function escape(str) return str:gsub("'", "\'"):gsub("&#39;", "\'") end local function enclose(str) return "'" .. escape(str) .. "'" end

local function getItemGroupName(item) if item == 'Wood' or item == 'Ebonwood' or item == 'Rich Mahogany' or item == 'Pearlwood' or item == 'Shadewood' or item == 'Spooky Wood' or item == 'Boreal Wood' or item == 'Palm Wood' then return 'Any Wood' elseif item == 'Iron Bar' or item == 'Lead Bar' then return 'Any Iron Bar' elseif item == 'Sand Block' or item == 'Pearlsand Block' or item == 'Crimsand Block' or item == 'Ebonsand Block' or item == 'Hardened Sand Block' then return 'Any Sand' elseif item == 'Red Pressure Plate' or item == 'Green Pressure Plate' or item == 'Gray Pressure Plate' or item == 'Brown Pressure Plate' or item == 'Blue Pressure Plate' or item == 'Yellow Pressure Plate' or item == 'Lihzahrd Pressure Plate' then return 'Any Pressure Plate' elseif item == 'Bird' or item == 'Blue Jay' or item == 'Cardinal' then return 'Any Bird' elseif item == 'Black Scorpion' or item == 'Scorpion' then return 'Any Scorpion' elseif item == 'Squirrel' or item == 'Red Squirrel' then return 'Any Squirrel' elseif item == 'Grubby' or item == 'Sluggy' or item == 'Buggy' then return 'Any Bug' elseif item == 'Mallard Duck' or item == 'Duck' then return 'Any Duck' elseif item == 'Sulphur Butterfly' or item == 'Julia Butterfly' or item == 'Monarch Butterfly' or item == 'Purple Emperor Butterfly' or item == 'Red Admiral Butterfly' or item == 'Tree Nymph Butterfly' or item == 'Ulysses Butterfly' or item == 'Zebra Swallowtail Butterfly' then return 'Any Butterfly' elseif item == 'Firefly' or item == 'Lightning Bug' then return 'Any Firefly' elseif item == 'Snail' or item == 'Glowing Snail' then return 'Any Snail' end end

local function criStr(args) local constraints = {} -- station = ? local _station = trim(args['station'] or '') if _station ~= '' then constraints['station'] = 'station = ' .. enclose(_station) end -- result = ? local _result = trim(args['result'] or '') if _result ~= '' then local str = '' for _, v in pairs(explode('/', _result)) do			if str ~= '' then str = str .. ' OR ' end str = str .. 'result = ' .. enclose(v) end constraints['result'] = str end -- ingredient = ? local _ingredient = trim(args['ingredient'] or '') if _ingredient ~= '' then local str = '' for _, v in pairs(explode('/', _ingredient)) do			if str ~= '' then str = str .. ' OR ' end str = str .. "ingredients HOLDS LIKE '%¦" .. escape(v) .. "¦%'"			-- any xxx local group = getItemGroupName(v) if group then str = str .. " OR ingredients HOLDS LIKE '%¦" .. escape(group) .. "¦%'"			end end constraints['ingredient'] = str end local where = '' if constraints['station'] then where = constraints['station'] end if constraints['result'] then if where ~= '' then where = where .. ' AND ' end where = where .. '(' .. constraints['result'] .. ')' end if constraints['ingredient'] then if where ~= '' then where = where .. ' AND ' end where = where .. '(' .. constraints['ingredient'] .. ')' end return where end

local p = {}

-- for p.register = function(frame) local args = frame:getParent.args local _result = trim(args['result'] or '') local _amount = trim(args['amount'] or '') local _version = trim(args['version'] or ''):lower

-- ingredients local serialized = '' local ingredients = {} -- list of {index, itemname, amount} for k, v in pairs(args) do		if(type(k) == 'number') then if k % 2 == 1 then -- 2n-1, nth item local index, item, amount = (k+1)/2, trim(v), trim(args[k+1]) table.insert(ingredients, {index, item, amount}) serialized = serialized .. '^' .. index .. '¦' .. item .. '¦' .. amount end end end serialized = mw.ustring.sub(serialized, 2)

table.sort(ingredients, function(a, b) return a[2] < b[2] end) local ingredients_string = '' local ingredients_string_full = '' for _, v in pairs(ingredients) do		local _, name, amount = unpack(v) local ingstr = normalize(name) ingredients_string = ingredients_string .. '^' .. ingstr ingredients_string_full = ingredients_string_full .. '^' .. ingstr .. amount end --store frame:callParserFunction('#cargo_store:_table=newRecipes',{		result = _result,		amount = _amount,		version = _version,		station = trim(args['station'] or ''), 		ingredients = mw.ustring.sub(ingredients_string, 2),		ings = mw.ustring.sub(ingredients_string_full, 2),		args = serialized,	}) end

p.query = function(frame) local args = frame:getParent.args local where = trim(args['where'] or '')

if where == '' then where = criStr(args) end

-- no constraint no result. if where == '' then return '' end

local result = mw.ext.cargo.query('newRecipes', 'result,amount,version,station,ingredients,args', {		where = where,		groupBy="result, amount, ings, version",		orderBy="station, result, version",		limit = 2000,	})

return mw.logObject(result)

end

return p