Module:Passive skill table

-- -- 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

-- -- 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 Class', name = 'Name', id = 'Id', int_id = 'Integer id', stats = 'Stats', skill_points = 'Skill points', connections = 'Connections', flavour_text = 'Flavour text', reminder_text = 'Reminder text', is_notable = 'Notable', is_keystone = 'Keystone', },

errors = { invalid_args = 'Passive skill table: q_where must be specified', no_passives_found = 'No passive skills with the given name found', cats = 'Pages with broken passive skill tables', }, }

-- -- 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(                '&#91;%s&#93;',                row['passive_skills._pageName'],                j + (i-1) * #values[key]            ) end out[i] = string.format(           ' %s %s  ',            key,            table.concat(links, ' ')        ) end

return table.concat(out, ' ') end

function h.get_type(passive) --   Determine what type of passive skill this passive is. 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.na_or_val(tr, value, func, args) --[[

Parameters --   tr :

value :

func : function

args : list of       Valid keys are: * colour

]]   local args = args or {} 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

local td = tr:tag('td') td:attr('data-sort-value', raw_value) td:wikitext(value) if args.colour then td:attr('class', 'tc -' .. args.colour) end 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] = ' &#x2713; ' else fields[i] = ' &#x2717; ' 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(            '%s',            string.gsub(v, '_', '~'),            v        ) end return table.concat(fields, ', ') end

-- Display h.tbl = {} h.tbl.display = {}

h.tbl.display.factory = {} function h.tbl.display.factory.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) local value = h.data_page_links(values, order) h.na_or_val(tr, value, func, args) end end

-- -- Data mappings --

data = {} data.passive_skill_table = { tables = { passive_skill_stats = { join='passive_skills._pageID=passive_skill_stats._pageID', },       main_pages = { join='passive_skills.id=main_pages.id' }   },    -- 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 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'], }           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'] .. h.get_type(passive)                    ) :attr('style', 'text-align:center;') :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 ', 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.factory.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.factory.merged_values{field='passive_skills.int_id'}, order = 1002, sort_type = 'text', },   {        args = {'stat', 'stats', 'stat_text'}, header = i18n.passive_table.stats, fields = {'passive_skills.stat_text'}, display = h.tbl.display.factory.merged_values{field='passive_skills.stat_text', colour='mod'}, order = 2000, sort_type = 'text', },   {        args = 'skill_points', header = i18n.passive_table.skill_points, fields = {'passive_skills.skill_points'}, display = h.tbl.display.factory.merged_values{field='passive_skills.skill_points'}, order = 2001, sort_type = 'text', },   {        args = 'connections', header = i18n.passive_table.connections, fields = {'passive_skills.connections'}, display = h.tbl.display.factory.merged_values{ field='passive_skills.connections', fmt=h.fmt.passive_skill_link, },       order = 3000, sort_type = 'text', },   {        args = 'flavour_text', header = i18n.passive_table.flavour_text, fields = {'passive_skills.flavour_text'}, display = h.tbl.display.factory.merged_values{ field='passive_skills.flavour_text', colour='flavour', },       order = 3001, sort_type = 'text', },   {        args = 'reminder_text', header = i18n.passive_table.reminder_text, fields = {'passive_skills.reminder_text'}, display = h.tbl.display.factory.merged_values{ field='passive_skills.reminder_text', colour='help', },       order = 3002, sort_type = 'text', },   {        args = 'is_notable', header = i18n.passive_table.is_notable, fields = {'passive_skills.is_notable'}, display = h.tbl.display.factory.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.factory.merged_values{ field='passive_skills.is_keystone', fmt=h.fmt.boolean },       order = 4001, sort_type = 'number', }, }

-- -- Page functions --

local p = {}

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"', large=1, }   = p.passive_skill_table{ q_where='passive_skills.stat_text LIKE "%damage%taken%as%"', ascendancy=1, stat_text=1, }

]]   local t = os.clock

-- Get args local tpl_args = getArgs(frame, {       parentFirst = true    }) frame = m_util.misc.get_frame(frame)

-- Check if the correct parameters have been set: if tpl_args.q_where == nil then return m_util.html.error{msg=i18n.errors.invalid_args .. m_util.misc.add_category(i18n.errors.cats)} end

-- Cargo query settings: 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: local 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