Module:Passive skill table
The above documentation is transcluded from Module:Passive skill table/doc.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
--
-- Module for passive skill table
--
local m_util = require('Module:Util')
local m_cargo = require('Module:Cargo')
local getArgs = require('Module:Arguments').getArgs
local f_passive_skill_link = require('Module:passive_skill_link').passive_skill_link
local p = {}
-- ----------------------------------------------------------------------------
-- Strings
-- ----------------------------------------------------------------------------
local i18n = {
icon_name = 'File:%s passive skill icon.png',
cats = {
data = 'Passive skill data',
keystone = 'Keystone passive skills',
notable = 'Notable passive skills',
basic = 'Basic passive skills',
ascendancy_notable = 'Ascendancy notable passive skills',
ascendancy_basic = 'Ascendancy basic passive skills',
},
passive_table = {
ascendancy_class = 'Ascendancy<br>Class',
name = 'Name',
id = 'Id',
int_id = 'Integer id',
stats = 'Stats',
connections = 'Connections',
is_notable = 'Notable',
is_keystone = 'Keystone',
},
errors = {
invalid_args = 'Passive skill link: id, int_id, page or name must be specified',
no_passives_found = 'No passive skills with the given name found',
},
}
-- ----------------------------------------------------------------------------
-- Constants & Data
-- ----------------------------------------------------------------------------
-- local c = {}
-- ----------------------------------------------------------------------------
-- Helper functions
-- ----------------------------------------------------------------------------
local h = {}
function h.make_order(results, field, args)
--[[
Merge duplicates and then create a ordered list.
]]
local values = {}
local order = {}
for _, row in ipairs(results) do
local val = row[field]
if args.fmt then
val = args.fmt(row[field])
end
-- Can't show results here that don't have a value:
if val then
if values[val] == nil then
values[val] = {row}
table.insert(order, val)
else
table.insert(values[val], row)
end
end
end
return values, order
end
function h.data_page_links(values, order)
local out = {}
for i, key in ipairs(order) do
local links = {}
for j, row in ipairs(values[key]) do
links[#links+1] = string.format(
'[[%s|[%s]]]',
row['passive_skills._pageName'],
j + (i-1) * #values[key]
)
end
out[i] = string.format(
'<span class="passive-line">%s <span class="passive-hover">%s</span></span>',
key,
table.concat(links, ' ')
)
end
return table.concat(out, '<hr>')
end
h.type_order = {
'basic',
'notable',
'keystone',
'ascendancy_basic',
'ascendancy_notable'
}
function h.get_type(passive)
local key
if tonumber(passive['passive_skills.is_keystone']) == 1 then
key = 'keystone'
elseif tonumber(passive['passive_skills.is_notable']) == 1 then
key = 'notable'
else
key = 'basic'
end
if passive['passive_skills.ascendancy_class'] ~= nil then
key = 'ascendancy_' .. key
end
return key
end
function h.sort_by_type(results)
local new = {}
for _, key in ipairs(h.type_order) do
new[key] = {}
end
for _, passive in ipairs(results) do
table.insert(new[h.get_type(passive)], passive)
end
return new
end
function h.na_or_val(tr, value, func)
if value == nil or value == '' then
tr:wikitext(m_util.html.td.na())
else
local raw_value = value
if func ~= nil then
value = func(value)
end
tr
:tag('td')
:attr('data-sort-value', raw_value)
:wikitext(value)
:done()
end
end
-- Format style for field:
h.fmt = {}
function h.fmt.link(field)
local fields = m_util.string.split(field, ',')
for i, v in ipairs(fields) do
fields[i] = string.format('[[%s]]', v)
end
return table.concat(fields, ', ')
end
function h.fmt.passive_skill_link(field)
local fields = m_util.string.split(field, ',')
for i, v in ipairs(fields) do
fields[i] = f_passive_skill_link{id=v}
end
return table.concat(fields, ', ')
end
function h.fmt.boolean(field)
local fields = m_util.string.split(field, ',')
for i, v in ipairs(fields) do
if m_util.cast.boolean(v) then
fields[i] = '<div class="table-yes" data-sort-value=1><span>✓</span></div>'
else
fields[i] = '<div class="table-no" data-sort-value=0><span>✗</span></div>'
end
end
return table.concat(fields, ', ')
end
function h.fmt.link_passive(field)
--[[
Create a link to the passive skill data page from the ID.
]]
local fields = m_util.string.split(field, ',')
for i, v in ipairs(fields) do
fields[i] = string.format(
'[[Passive Skill:%s|%s]]',
string.gsub(v, '_', '~'),
v
)
end
return table.concat(fields, ', ')
end
-- Display
h.tbl = {}
h.tbl.display = {}
function h.tbl.display.merged_values(args)
local args = args or {}
return function (tpl_args, frame, tr, rows, rowinfo)
local values, order = h.make_order(rows, args.field, args)
h.na_or_val(tr, h.data_page_links(values, order), nil)
end
end
-- ----------------------------------------------------------------------------
-- Page functions
-- ----------------------------------------------------------------------------
local p = {}
data = {}
data.passive_skill_table = {
tables = {
passive_skill_stats = {
join='passive_skills._pageID=passive_skill_stats._pageID',
},
},
-- display data
{
args = nil,
header = i18n.passive_table.name,
fields = {
-- Optional:
'passive_skills.is_keystone',
'passive_skills.is_notable',
'passive_skills.ascendancy_class',
'passive_skills.main_page',
'main_pages._pageName',
-- 'passive_skills.html',
-- Required:
'passive_skills._pageName',
'passive_skills.name',
'passive_skills.icon',
},
display = function (tpl_args, frame, tr, data)
local passive = data[1]
local type_key = h.get_type(passive)
local psl_args = {
skip_query = true,
page = passive['passive_skills.main_page']
or passive['main_pages._pageName']
or passive['passive_skills.name']
or passive['passive_skills._pageName'],
name = passive['passive_skills.name'],
icon = passive['passive_skills.icon'],
is_keystone = passive['passive_skills.is_keystone'],
is_notable = passive['passive_skills.is_notable'],
ascendancy_class = passive['passive_skills.ascendancy_class'],
html = passive['passive_skills.is_notable'],
}
if tpl_args.no_html == nil then
psl_args.html = passive['passive_skills.html']
end
if tpl_args.large then
psl_args.large = tpl_args.large
end
tr
:tag('td')
:attr(
'data-sort-value',
passive['passive_skills.name'] .. type_key
)
:wikitext(f_passive_skill_link(psl_args))
:done()
end,
order = 1000,
sort_type = 'text',
options = {
[1] = {optional=true},
[2] = {optional=true},
[3] = {optional=true},
[4] = {optional=true},
[5] = {optional=true},
},
},
{
args = {'ascendancy'},
header = i18n.passive_table.ascendancy_class,
fields = {'passive_skills.ascendancy_class'},
display = function (tpl_args, frame, tr, data)
local passive = data[1]
h.na_or_val(tr, passive['passive_skills.ascendancy_class'],
function ()
return string.format(
'[[%s]]<br>[[File:%s avatar.png|link=%s]]',
passive['passive_skills.ascendancy_class'],
passive['passive_skills.ascendancy_class'],
passive['passive_skills.ascendancy_class']
)
end
)
end,
order = 0,
sort_type = 'text',
},
{
args = 'id',
header = i18n.passive_table.id,
fields = {'passive_skills.id'},
display = h.tbl.display.merged_values{field='passive_skills.id'},
order = 1001,
sort_type = 'text',
},
{
args = 'int_id',
header = i18n.passive_table.int_id,
fields = {'passive_skills.int_id'},
display = h.tbl.display.merged_values{field='passive_skills.int_id'},
order = 1002,
sort_type = 'text',
},
{
arg = {'stat', 'stats', 'stat_text'},
header = i18n.passive_table.stats,
fields = {'passive_skills.stat_text'},
display = h.tbl.display.merged_values{field='passive_skills.stat_text'},
order = 2000,
sort_type = 'text',
},
{
arg = 'connections',
header = 'Connections',
fields = {'passive_skills.connections'},
display = h.tbl.display.merged_values{
field='passive_skills.connections',
-- fmt=h.fmt.link_passive,
fmt=h.fmt.passive_skill_link,
},
order = 3000,
sort_type = 'text',
},
{
args = 'is_notable',
header = i18n.passive_table.is_notable,
fields = {'passive_skills.is_notable'},
display = h.tbl.display.merged_values{
field='passive_skills.is_notable',
fmt=h.fmt.boolean
},
order = 4000,
sort_type = 'number',
},
{
args = 'is_keystone',
header = i18n.passive_table.is_keystone,
fields = {'passive_skills.is_keystone'},
display = h.tbl.display.merged_values{
field='passive_skills.is_keystone',
fmt=h.fmt.boolean
},
order = 4001,
sort_type = 'number',
},
}
function p.passive_skill_table(frame)
--[[
Displays a table of passive skills.
TODO: Why is the groupBy necessary?
Examples
--------
= p.passive_skill_table{
q_where = 'passive_skills.ascendancy_class = "Gladiator"',
name=1,
}
]]
local t = os.clock()
-- Get args
tpl_args = getArgs(frame, {
parentFirst = true
})
frame = m_util.misc.get_frame(frame)
-- Create cargo query:
if tpl_args.q_tables then
tpl_args.q_tables = tpl_args.q_tables .. ',' .. 'passive_skill_stats, main_pages'
else
tpl_args.q_tables = 'passive_skill_stats, main_pages'
end
if tpl_args.q_join then
tpl_args.q_join = tpl_args.q_join .. ',' .. 'passive_skills._pageID=passive_skill_stats._pageID, passive_skills.id=main_pages.id'
else
tpl_args.q_join = 'passive_skills._pageID=passive_skill_stats._pageID, passive_skills.id=main_pages.id'
end
tpl_args.q_groupBy = tpl_args.q_groupBy or 'passive_skills._pageID'
tpl_args.q_orderBy = tpl_args.q_orderBy or 'passive_skills.ascendancy_class IS NULL DESC, passive_skills.is_keystone, passive_skills.is_notable, passive_skills.name'
-- Run the query and display the results:
out = m_cargo.table_query{
tpl_args=tpl_args,
frame=frame,
main_table='passive_skills',
row_unique_fields={'passive_skills.name'},
data=data.passive_skill_table,
empty_cell=m_util.html.td.na()
}
mw.logObject({os.clock() - t, tpl_args})
return out
end
-- ----------------------------------------------------------------------------
-- End
-- ----------------------------------------------------------------------------
return p