Module:ListBuilds

From Outward Wiki
Jump to navigation Jump to search
Template-info.svg Documentation

Module used to list Character Builds. Will list any Template:CharacterBuild defined.


local BREAKTHROUGH_KEYS = { 'breakthrough1', 'breakthrough2', 'breakthrough3' }
local EQUIP_KEYS = { 'weapon', 'offhand', 'helmet', 'armor', 'boots', 'backpack' }
local SLOT_KEYS = { 'quickslot1', 'quickslot2', 'quickslot3', 'quickslot4', 'quickslot5', 'quickslot6', 'quickslot7', 'quickslot8' }


local p = {}
local h = {}

function p.main(frame)
    if frame == mw.getCurrentFrame() then
        args = require('Module:ProcessArgs').merge(true)
    else
        frame = mw.getCurrentFrame()
    end

    local args = frame.args
    local category = args.category -- Category will be 'nil' if not defined.

    -- basic cargo query
    local fields = '_pageName, DLC, author, type, name, tags, description, breakthrough1, breakthrough2, breakthrough3, faction, weapon, offhand, helmet, boots, armor, backpack, quickslot1, quickslot2, quickslot3, quickslot4, quickslot5, quickslot6, quickslot7, quickslot8, beginner, advanced'
    local cargoArgs = { orderBy = 'type, _pageName', groupBy = 'name', limit = 5000 }
    local data = mw.ext.cargo.query('CharacterBuilds', fields, cargoArgs)

    if #data < 1 then
        return '<b>No results found!</b>'
    end

    -- If there is no category list all builds, otherwise only list the specific build types
    local categories = {}
    if (category == nil) then
	    for _, v in ipairs(data) do
	        if v.type ~= nil then
	        	-- If the category does not exist, create it
	        	if (not categories[v.type]) then
	        		categories[v.type] = {}
	        	end
	        	
	        	-- Insert the build into the category
	        	table.insert(categories[v.type], v)
	        end
	    end
    else
    	categories[category] = {}
    	for _, v in ipairs(data) do
    		if (v.type ~= nil and v.type == category) then
    			table.insert(categories[category], v)
			end
    	end
	end

    -- sort the categories alphabetically ("for k in pairs" will iterate the keys)
    local sorted = {}
    for k in pairs(categories) do sorted[#sorted + 1] = k end
    table.sort(sorted) -- lua's default sort

    -- build table output
    local html = mw.html.create()
    -- iterate alphabetical key list
    for _, type in ipairs(sorted) do
        buildoutput(type, categories[type], html, frame)
    end

    html:tag('i')
        :wikitext(frame:preprocess('The builds above were listed dynamically. Click [{{fullurl:{{PAGENAME}}|action=purge}} here] to force an update of the data.'))

    return html
end

function buildoutput(title, data, html, frame)
    html:wikitext(frame:preprocess('<h3>' .. title .. '</h3>'))

    local table = html:tag('table'):addClass('wikitable sortable')

    local header = table:tag('tr')
    header:tag('th'):css('min-width', '120px'):wikitext('Build Name')
    header:tag('th'):wikitext('Tags')
    header:tag('th'):wikitext('Faction')
    header:tag('th'):wikitext('Breakthroughs')
    header:tag('th'):wikitext('Equipment')
    header:tag('th'):wikitext('Quickslots')
    header:tag('th'):wikitext('Author')
    header:tag('th'):wikitext('Skill Level')
    header:tag('th'):wikitext('DLC')

    for _, v in ipairs(data) do
        if v ~= nil and v.type ~= nil then -- Check if v is not nil and has type field
            local tr = table:tag('tr')

            if v._pageName then
                tr:tag('td'):css('min-width', '120px'):wikitext(frame:preprocess('[[' .. v._pageName .. '|' .. string.sub(v._pageName, 7) .. ']]'))
            else
                tr:tag('td'):wikitext('No build name')
            end

            tr:tag('td'):wikitext(v.tags or 'No tags')

            local faction = tr:tag('td'):css('text-align', 'center')
            if h.notempty(v.faction) then
                faction:wikitext('[[File:' .. v.faction .. ' Banner.png|20px|link=' .. v.faction .. ']]')
            else
                faction:wikitext('Any')
            end

            tr:tag('td')
                :css('text-align', 'center')
                :wikitext(h.concatImages(v, BREAKTHROUGH_KEYS, ' • '))

            tr:tag('td')
                :css('text-align', 'center')
                :wikitext(h.concatImages(v, EQUIP_KEYS, '•'))

            tr:tag('td')
                :css('text-align', 'center')
                :wikitext(h.concatImages(v, SLOT_KEYS, ' ') or 'Not listed')

            local author = 'Anonymous'
            if h.notempty(v.author) then
                author = '[[User:' .. v.author .. '|' .. v.author .. ']]'
            end
            tr:tag('td')
                :css('min-width', '140px')
                :wikitext(author)

            local difficulty = 'Average'
            if (v.beginner ~= nil and v.beginner ~= '') then
                difficulty = 'Beginner'
            elseif (v.advanced ~= nil and v.advanced ~= '') then
                difficulty = 'Advanced'
            end
            tr:tag('td')
                :css('min-width', '80px')
                :wikitext(difficulty)

            local dlcs = 'None'
            if h.notempty(v.DLC) then
                dlcs = ''
                local list = h.split(v.DLC, ',')
                for _, dlc in ipairs(list) do
                    if dlcs ~= '' then dlcs = dlcs .. ', ' end
                    dlcs = dlcs .. '{{' .. dlc .. '}}'
                end
            end
            tr:tag('td'):wikitext(frame:preprocess(dlcs))
        end
    end

    return table
end

function h.concatImages(data, keys, delimiter)
    local tbl = {}
    for _, key in ipairs(keys) do
        local name = data[key]
        if h.notempty(name) then
            tbl[#tbl+1] = '[[File:' .. name .. '.png|25px|link=' .. name .. ']]'
        end
    end
    if #tbl == 0 then return nil end
    return table.concat(tbl, delimiter)
end

----------------- Helpers ---------------------

function h.notempty(string)
    return string ~= nil and string ~= ''
end

function h.split(inputstr, sep)
    if sep == nil then
        sep = "%s"
    end
    local t={}
    if h.notempty(inputstr) then
        for str in string.gmatch(inputstr .. ',', "([^"..sep.."]+)") do
            table.insert(t, str)
        end
    end
    return t
end

return p