Difference between revisions of "Module:Crafting Uses"
Jump to navigation
Jump to search
m |
(now can generate a table for multiple items) |
||
| 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 | + | ---@return mw.html |
| + | local function genTable(names) | ||
| + | local t = mw.html.create("table") | ||
| + | t:addClass("wikitable sortable jquery-tablesorter") | ||
| + | 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 names = {} | ||
| + | if tablelength(_args) == 0 then | ||
| + | table.insert(names, pageName()) | ||
| + | else | ||
| + | names = fromCSV(_args[1]) | ||
| + | end | ||
| + | local t = genTable(names) | ||
return t | return t | ||
end | end | ||
return p | return p | ||
Revision as of 10:08, 2 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
---@return mw.html
local function genTable(names)
local t = mw.html.create("table")
t:addClass("wikitable sortable jquery-tablesorter")
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 names = {}
if tablelength(_args) == 0 then
table.insert(names, pageName())
else
names = fromCSV(_args[1])
end
local t = genTable(names)
return t
end
return p