Module:Sandbox/MoonOverMira/class attributes: Difference between revisions

From Path of Exile Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 13: Line 13:
     errors = {
     errors = {
         invalid_cols = 'Invalid columns. Only str, dex, and int are allowed.',
         invalid_cols = 'Invalid columns. Only str, dex, and int are allowed.',
        invalid_sort_col = 'Invalid sort_col. One of str, dex, or int is allowed.',
     },
     },
     messages = {},
     messages = {},
Line 111: Line 112:
     Examples
     Examples
     --------
     --------
     = p.class_attributes_table{cols='str,dex,int', show_total=True}
     = p.class_attributes_table{cols='str,dex,int', show_total=true, sort_col='str', reverse_sort=true}
     ]]
     ]]


Line 120: Line 121:
frame = mw.getCurrentFrame()
frame = mw.getCurrentFrame()
local show_total = tpl_args.show_total
local show_total = tpl_args.show_total
local sort_col = tpl_args.sort_col
local reverse_sort = tpl_args.reverse_sort
      
      
     -- Validate cols arg
     -- Validate cols arg
Line 130: Line 133:
error(i18n.errors.invalid_cols, tpl_args.cols)
error(i18n.errors.invalid_cols, tpl_args.cols)
end
end
    end
   
    -- Validate sort_col
    if sort_col and h.col_to_attr[sort_col] == nil then
error(i18n.errors.invalid_sort_col, sort_col)
     end
     end


Line 136: Line 144:
     -- ------------------------------------------------------------------------
     -- ------------------------------------------------------------------------
     local tbl = p._shared.class_tbl_head(cols, show_total)
     local tbl = p._shared.class_tbl_head(cols, show_total)
-- The default order is the game order.
local characters = m_game.constants.characters_order
if sort_col and sort_col ~= "" then
-- The sort will first compare by the sort_col, then by class name.
function cmp(a, b)
a_attr = m_game.constants.characters[a][sort_col]
b_attr = m_game.constants.characters[b][sort_col]
if a_attr ~= b_attr then
if reverse_sort then
return a_attr > b_attr
else
return a_attr < b_attr
end
end
return a < b
end
table.sort(characters, cmp)
end


-- Each class gets a row
-- Each class gets a row
     for _, class in ipairs(m_game.constants.characters_order) do
     for _, class in ipairs(characters) do
local tr = tbl:tag('tr')
local tr = tbl:tag('tr')
p._shared.class_row(tr, class, cols, show_total)
p._shared.class_row(tr, class, cols, show_total)
Line 151: Line 178:


return p
return p
-- Console testing:
-- mw.logObject(p.class_attributes_table({cols='str,dex,int'}))

Revision as of 04:23, 4 March 2023

Module documentation[view] [edit] [history] [purge]


See Template:Sandbox/MoonOverMira/class attributes for documentation on this module, since it transparently uses this module's class_attributes_table.

Usage

{{#invoke:Class attributes|class_attributes_table}}


local m_game = require('Module:Game')
local getArgs = require('Module:Arguments').getArgs

-- Return table
local p = {}
p._shared = {}

-- ----------------------------------------------------------------------------
-- Strings
-- ----------------------------------------------------------------------------

local i18n = {
    errors = {
        invalid_cols = 'Invalid columns. Only str, dex, and int are allowed.',
        invalid_sort_col = 'Invalid sort_col. One of str, dex, or int is allowed.',
    },
    messages = {},
    char_class = {
        class = 'Class ↓',
        total = 'Total',
    },
}

-- ----------------------------------------------------------------------------
-- Helper functions and globals
-- ----------------------------------------------------------------------------


local h = {}

h.col_to_attr = {
	str = 'strength',
	dex = 'dexterity',
	int = 'intelligence',
}

function h.pretty_attr(attr)
	-- Returns the pretty name of the attribute from the canonical name.
	-- eg. strength -> Strength
	return m_game.constants.attributes[attr].long_upper
end

function h.link(page_name)
	-- Returns a wikitext internal link for the specified page name.
	return string.format('[[%s]]', page_name)
end

function h.attribute_header(attr)
	-- Returns a wikitext snippet for the attribute that includes a link to
	-- its page and an image of its icon.

	local link = h.link(h.pretty_attr(attr))
	local icon = m_game.constants.attributes[attr].icon
	
	return link .. " " .. icon
end

-- ----------------------------------------------------------------------------
-- Page functions
-- ----------------------------------------------------------------------------
function p._shared.class_tbl_head(cols, show_total)
	--[[
	Creates a table with a header for class, each specified attribute, and the
	total.
	]]

    local tbl = mw.html.create('table')
    tbl:attr('class', 'wikitable sortable')
    local tr = tbl:tag('tr')
    
    tr:tag('th')
		:wikitext(i18n.char_class.class)

	for _, col in ipairs(cols) do
		attr = h.col_to_attr[col]
		tr:tag('th')
			:wikitext(h.attribute_header(attr))
	end

	if show_total then
		tr:tag('th')
			:wikitext(i18n.char_class.total)
	end

    return tbl
end

function p._shared.class_row(tr, class_name, cols, show_total)
	-- Populates a tr for the specified class with columns for attrs and a total.

	tr:tag('th')
		:wikitext(h.link(class_name))

	local class = m_game.constants.characters[class_name]
	for _, col in ipairs(cols) do
		tr:tag('td')
			:wikitext(class[col])
	end

	if show_total then
		tr:tag('td')
			:wikitext(class.str + class.dex + class.int)
	end
end

function p.class_attributes_table(frame)
    --[[
    Displays a table of character classes and their attributes.
    cols is a comma-separated list of attributes to include as columns in the
    table.

    Examples
    --------
    = p.class_attributes_table{cols='str,dex,int', show_total=true, sort_col='str', reverse_sort=true}
    ]]

    -- Get args
    local tpl_args = getArgs(frame, {
        parentFirst = true
    })
	frame = mw.getCurrentFrame()
	local show_total = tpl_args.show_total
	local sort_col = tpl_args.sort_col
	local reverse_sort = tpl_args.reverse_sort
    
    -- Validate cols arg
    if #(tpl_args.cols) == 0 then
    	error(i18n.errors.invalid_cols, tpl_args.cols)
    end
    local cols = mw.text.split(tpl_args.cols, ",")
    for _, col in ipairs(cols) do
    	if h.col_to_attr[col] == nil then
			error(i18n.errors.invalid_cols, tpl_args.cols)
		end
    end
    
    -- Validate sort_col
    if sort_col and h.col_to_attr[sort_col] == nil then
		error(i18n.errors.invalid_sort_col, sort_col)
    end

    -- ------------------------------------------------------------------------
    -- Build output table
    -- ------------------------------------------------------------------------
    local tbl = p._shared.class_tbl_head(cols, show_total)

	-- The default order is the game order.
	local characters = m_game.constants.characters_order
	if sort_col and sort_col ~= "" then
		-- The sort will first compare by the sort_col, then by class name.
		function cmp(a, b)
			a_attr = m_game.constants.characters[a][sort_col]
			b_attr = m_game.constants.characters[b][sort_col]
			if a_attr ~= b_attr then
				if reverse_sort then
					return a_attr > b_attr
				else
					return a_attr < b_attr
				end
			end
			return a < b
		end
		table.sort(characters, cmp)
	end

	-- Each class gets a row
    for _, class in ipairs(characters) do
		local tr = tbl:tag('tr')
		p._shared.class_row(tr, class, cols, show_total)
    end

    return tostring(tbl)
end

-- ----------------------------------------------------------------------------
-- End
-- ----------------------------------------------------------------------------

return p

-- Console testing:
-- mw.logObject(p.class_attributes_table({cols='str,dex,int'}))