Difference between revisions of "Module:Crafting Uses"
Jump to navigation
Jump to search
(added sortability) |
m (misspell) |
||
(7 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | local p ={} | + | local p = {} |
local findId = require("Module:FindId") | local findId = require("Module:FindId") | ||
local img = require("Module:Img") | local img = require("Module:Img") | ||
Line 6: | Line 6: | ||
local pageName = mw.title.getCurrentTitle().fullText | 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 function tablelength(T) | ||
− | + | local count = 0 | |
− | + | for _ in pairs(T) do count = count + 1 end | |
− | + | return count | |
end | end | ||
Line 49: | Line 63: | ||
end | end | ||
+ | ---fetches an item object | ||
+ | ---@param itemId integer|string or string | ||
+ | ---@return table|string | ||
local function getItem(itemId) | local function getItem(itemId) | ||
local item = itemsData[tostring(itemId)] | local item = itemsData[tostring(itemId)] | ||
Line 58: | Line 75: | ||
end | end | ||
− | function | + | ---generates an mw.html table object |
− | + | ---@param names table | |
− | end | + | ---@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 " | |
− | if | + | end |
− | + | else | |
− | + | if item.craftingStats.multiplier > 1 then | |
+ | multS = tostring(item.craftingStats.multiplier) .. "x " | ||
end | end | ||
end | end | ||
end | end | ||
− | if | + | 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() | :allDone() | ||
− | + | matCellAddedCount = matCellAddedCount - 1 | |
− | + | if matCellAddedCount > 0 then | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
t:tag('tr') | t:tag('tr') | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
end | 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 | return t | ||
end | end | ||
return p | return p |
Latest revision as of 15:23, 3 July 2024
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