Module:Crafting Uses
Jump to navigation
Jump to search
local p = {} local findId = require("Module:FindId") local img = require("Module:Img") local craftingAugmentingData = mw.loadData("Module:CraftingAugmenting/data") local itemsData = mw.loadData("Module:Items/data") local pageName = mw.title.getCurrentTitle().fullText ---@alias mw.html table -- Convert from CSV string to table (converts a single line of a CSV file) local function fromCSV(s) s = s .. ',' -- ending comma local t = {} -- table to collect fields local fieldstart = 1 repeat local nexti = string.find(s, ',', fieldstart) table.insert(t, string.sub(s, fieldstart, nexti - 1)) fieldstart = nexti + 1 until fieldstart > string.len(s) return t end local function tablelength(T) local count = 0 for _ in pairs(T) do count = count + 1 end return count end local function pairsByKeys(t, f) local a = {} local orgi_key_type local orgi_key_numbered for n in pairs(t) do if tonumber(n) == nil then table.insert(a, n) orgi_key_type = "word" elseif type(n) == "number" then table.insert(a, n) orgi_key_type = "int" elseif type(n) == "string" and type(tonumber(n) == "number") then orgi_key_type = "number" table.insert(a, tonumber(n)) end end table.sort(a, f) local key local value local i = 0 -- iterator variable local iter = function() -- iterator function i = i + 1 if a[i] == nil then return nil elseif orgi_key_type == "word" or orgi_key_type == "int" then key = a[i] value = t[a[i]] elseif orgi_key_type == "number" then key = tostring(a[i]) value = t[tostring(a[i])] end return key, value end return iter end ---fetches an item object ---@param itemId integer|string or string ---@return table|string local function getItem(itemId) local item = itemsData[tostring(itemId)] if item then return item else return "Module:Items/data out of date" end end ---generates an mw.html table object ---@param names table ---@param collapse integer ---@return mw.html local function genTable(names, collapse) local collapseS = "" if collapse == 1 then collapseS = " mw-made-collapsible mw-collapsible" elseif collapse == 2 then collapseS = " mw-made-collapsible mw-collapsible mw-collapsed" end local t = mw.html.create("table") t:addClass("wikitable sortable jquery-tablesorter" .. collapseS) t:tag("tr") :tag("th") :attr("colspan", "2") :wikitext("Item Created") :done() :tag("th") :wikitext("Category") :done() :tag("th") :wikitext("Lvl.</br>Req.") :done() :tag("th") :wikitext("XP") :done() :tag("th") :wikitext("Materials") :done() :done() local matchedRecipes = {} local earlyreturn = false for _, itemName in ipairs(names) do local itemId = findId._findId({ itemName, "item" }) for iId, iData in pairsByKeys(craftingAugmentingData) do if iData.crafting then for _, fullRecipe in ipairs(iData.crafting) do for mId, mQuantity in pairsByKeys(fullRecipe.recipe) do if tonumber(mId) == itemId then matchedRecipes[iId] = {} local i = 0 local _dupe = false for _, v in pairs(matchedRecipes) do if v.recipe then for key, value in pairs(v.recipe) do if key == mId and value == mQuantity then i = i + 1 end if i == tablelength(fullRecipe.recipe) then _dupe = true earlyreturn = true break end end if earlyreturn then break end end end if not _dupe then table.insert(matchedRecipes[iId], fullRecipe) end end end end end end end for itemId, fullRecipes in pairsByKeys(matchedRecipes) do local item = getItem(itemId) local recipeCount = tablelength(matchedRecipes[itemId]) local matCellAddedCount = recipeCount local matCells = {} local imgCell = mw.html.create('td') if recipeCount > 1 then imgCell:attr("rowspan", tostring(recipeCount)) end imgCell:wikitext(img._img({ item.name, "40" })) local nameCell = mw.html.create('td') local categoryCell = mw.html.create('td') if recipeCount > 1 then categoryCell:attr("rowspan", tostring(recipeCount)) end categoryCell:wikitext(item.craftingStats.category) local lvlCell = mw.html.create('td') if recipeCount > 1 then lvlCell:attr("rowspan", tostring(recipeCount)) end lvlCell:wikitext(tostring(item.craftingStats.level)) local xpCell = mw.html.create('td') if recipeCount > 1 then xpCell:attr("rowspan", tostring(recipeCount)) end xpCell:wikitext(tostring(item.craftingStats.experience)) for _, fullRecipe in ipairs(fullRecipes) do local matS = "" for matId, matQuantity in pairs(fullRecipe.recipe) do local mat = getItem(matId) matS = matS .. tostring(matQuantity) .. img._img({ mat.name, '20', word = 1 }) .. "<br>" end local matCell = mw.html.create('td') matCell:wikitext(matS) table.insert(matCells, matCell) local multS = "" if item.craftingStats.multiplier then if fullRecipe.multiplier then if fullRecipe.multiplier > 1 then multS = tostring(fullRecipe.multiplier) .. "x " end else if item.craftingStats.multiplier > 1 then multS = tostring(item.craftingStats.multiplier) .. "x " end end end if recipeCount > 1 then nameCell:attr("rowspan", tostring(recipeCount)) end nameCell:wikitext(multS .. "[[" .. item.name .. "]]") end local dTr = t:tag("tr") :node(imgCell) :node(nameCell) :node(categoryCell) :node(lvlCell) :node(xpCell) for _, matCell in ipairs(matCells) do dTr:node(matCell) :allDone() matCellAddedCount = matCellAddedCount - 1 if matCellAddedCount > 0 then t:tag('tr') end end end return t end function p.craftingUses(frame) return p._craftingUses(frame:getParent().args) end function p._craftingUses(_args) local collapse = 0 local names = {} if tablelength(_args) == 0 then table.insert(names, pageName) elseif _args["collapse"] and not _args[1] then table.insert(names, pageName) elseif _args["collapse"] and _args[1] then names = fromCSV(_args[1]) else names = fromCSV(_args[1]) end if _args["collapse"] == "collapsible" then collapse = 1 elseif _args["collapse"] == "collapsed" then collapse =2 end local t = genTable(names, collapse) return t end return p