Module:Uses skill list
Jump to navigation
Jump to search
Module documentation
This documentation is transcluded from Module:Uses skill list/doc. [edit] [history] [purge]
Module:Uses skill list's function main is invoked by Template:Uses skill list.
Module:Uses skill list requires Module:Addcommas.
Module:Uses skill list requires Module:Exchange.
Module:Uses skill list requires Module:SCP.
Module:Uses skill list requires Module:Yesno.
Generates {{Uses skill list}}
.
local p = {}
local geprice = require('Module:Exchange')._price
local commas = require('Module:Addcommas')
local skillpic = require('Module:SCP')._main
local yesno = require('Module:Yesno')
local lang = mw.getContentLanguage()
local trim = mw.text.trim
-- Sorting function for two item objects, first by name, then by sub-text
function sortItemsByNameSubtext(item1, item2)
if (item1.output.name < item2.output.name) then
return true
elseif (item1.output.name > item2.output.name) then
return false
else
return (item1.output.subtxt or '') < (item2.output.subtxt or '')
end
end
function p.main(frame)
return p._main(frame:getParent().args)
end
function p._main(args)
local skills = {}
local skills_lowered = {}
local category = args.category and trim(args.category) or nil
-- Process skill arguments
if args == nil then
table.insert(skills, mw.title.getCurrentTitle().text)
else
local i = 1
while args[i] do
local arg = trim(args[i])
table.insert(skills, arg)
skills_lowered[arg:lower()] = true
i = i + 1
end
end
-- Build SMW query
local query = {
'[[Uses skill::' .. table.concat(skills, '||') .. ']]',
'[[Production JSON::+]]',
'?=#-',
'?Production JSON = json',
limit = args.limit or 500,
}
-- Add category filter if provided
if category then
table.insert(query, '[[RecipeCategory::' .. category .. ']]')
end
-- Fetch data
local t1 = os.clock()
local smw_data = mw.smw.ask(query)
local t2 = os.clock()
if not smw_data then
return 'Failed to find products with those skills - ensure they are spelled correctly. (ERR: no results from SMW)[[Category:Empty drop lists]]'
end
mw.log(string.format('SMW: entries %d, time elapsed: %.3f ms.', #smw_data, (t2 - t1) * 1000))
-- Post-process
data = {}
for _, e in ipairs(smw_data) do
if type(e.json) == 'string' then
local json = mw.text.jsonDecode(e.json)
table.insert(data, json)
elseif type(e.json) == 'table' then
for _, f in ipairs(e.json) do
local json = mw.text.jsonDecode(f)
table.insert(data, json)
end
end
end
smw_data = nil
-- Items with different variants (e.g. Divine battlemage potion has (1), (2), (3), (4) variants)
-- or methods (e.g. "4-dose oil" vs "3-dose oil" for pyre logs) may not come in sorted, so now do a final alphabetical sort on name, sub-text
table.sort(data, sortItemsByNameSubtext)
-- Render page
local t = mw.html.create('table')
t:addClass('wikitable sortable products-list align-center-1 align-right-3 align-right-4 autosort=3,a')
local ttlrow = t:tag('tr')
:tag('th')
:attr('colspan', '2')
:wikitext('Item')
:done()
:tag('th')
:wikitext('Members')
:done()
:tag('th')
:attr('data-sort-type', 'number')
:wikitext('Skills')
:done()
:tag('th')
:attr('data-sort-type', 'number')
:wikitext('XP')
:done()
:tag('th')
:wikitext('Materials')
:done()
local rows = 0
-- Render rows
for _, item in ipairs(data) do
local skill_match = false
for _, skill_info in ipairs(item.skills) do
if skills_lowered[skill_info.name:lower()] then
skill_match = true
break
end
end
if skill_match then
local name_str
if (tonumber(item.output.quantity) or 0) > 1 then
name_str = string.format('[[%s]] × %s', item.output.name, item.output.quantity)
else
name_str = string.format('[[%s]]', item.output.name)
end
if item.output.subtxt then
name_str = string.format('%s <br /><small>(%s)</small>', name_str, item.output.subtxt)
end
local member_str
if item.members == 'Yes' then
member_str = "[[File:Member icon.png|center|link=Members|alt=Members]]"
elseif item.members == 'No' then
member_str = "[[File:Free-to-play icon.png|center|link=Free-to-play|alt=Free-to-play]]"
end
local experience_cell = mw.html.create('td')
experience_cell:addClass('plainlist')
local experience_ul = experience_cell:tag('ul')
experience_ul:addClass('skills-list')
local skills_cell = mw.html.create('td')
skills_cell:addClass('plainlist')
local skills_ul = skills_cell:tag('ul')
skills_ul:addClass('skills-list')
if #item.skills == 0 then
local skill_li = skills_ul:tag('li')
local experience_li = experience_ul:tag('li')
experience_cell:addClass('table-na'):css('text-align', 'center')
experience_li:wikitext(string.format('None'))
skills_cell:addClass('table-na'):css('text-align', 'center')
skill_li:wikitext(string.format('None'))
else
for index, v in ipairs(item.skills) do
local skill_li = skills_ul:tag('li')
local experience_li = experience_ul:tag('li')
local stripped_experience = v.experience:gsub(',', '')
skill_li
:attr('data-sort-value', index == 1 and v.level or '')
:wikitext(skillpic(lang:ucfirst(v.name), v.level))
experience_li
:attr('data-sort-value', index == 1 and v.experience or '')
:wikitext(tonumber(stripped_experience) ~= nil and skillpic(lang:ucfirst(v.name), v.experience) or v.experience)
end
end
local mats_ul = mw.html.create('ul')
mats_ul:addClass('products-materials')
local mat_sort_val = nil
for _, mat_info in ipairs(item.materials) do
local mat_li = mats_ul:tag('li')
local qty = mat_info.quantity:gsub('%-', '–')
local mat_name = mat_info.name
if mat_sort_val == nil then
mat_sort_val = qty
end
mat_li:wikitext(string.format('%s × [[%s]]', commas._add(qty), mat_name))
end
local prow = t:tag('tr')
:tag('td')
:wikitext(item.output.image)
:tag('td')
:attr('data-sort-value', item.product)
:wikitext(name_str)
:done()
:tag('td')
:wikitext(member_str)
:node(skills_cell)
:node(experience_cell)
:tag('td')
:attr('data-sort-value', mat_sort_val)
:addClass('plainlist')
:node(mats_ul)
:done()
rows = rows + 1
end
end
if rows == 0 then
return 'Failed to find products with those skills - ensure they are spelled correctly. (ERR: no skills found in results)[[Category:Empty drop lists]]'
end
return t
end
--[[ DEBUG COPYPASTA
= p._main({'Mithril bar'})
--]]
return p