Module:ListEffects

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

Module used to list Effects.

Usage

Automatic list:

{{#invoke:ListEffects|main|type=Hex}}
IconNameDurationEffects
Chill.png
Chill240 seconds
Confusion.png
Confusion240 seconds
Curse.png
Curse240 seconds
Doomed.png
Doomed240 seconds
Haunted.png
Haunted240 seconds
Pain.png
Pain240 seconds
Scorched.png
Scorched240 seconds

Manual list:

{{#invoke:ListEffects|list|Greater Decay Imbue|Greater Ethereal Imbue}}
IconNameDurationEffects
PoisonImbue.PNG
Greater Decay Imbue180 seconds
  • Increases damage by 20% as Decay Decay damage
  • Grants +15 flat Decay damage.
EtherealImbue.PNG
Greater Ethereal Imbue180 seconds
  • Increases base damage by 10% as Ethereal Ethereal damage
  • Grants +15 flat Ethereal damage.

local p = {}

-- function for listing specific effects by name.
-- usage is {{#invoke:ListEffects|list|EffectOne|EffectTwo|EffectThree|etc...}}
function p.list(frame)
    if frame == mw.getCurrentFrame() then
		args = require('Module:ProcessArgs').merge(true)
	else
		frame = mw.getCurrentFrame()
    end

    local cargoWhere = ''
    for i,v in ipairs(args) do
        if cargoWhere ~= '' then cargoWhere = cargoWhere .. ' OR ' end
        cargoWhere = cargoWhere .. '_pageName=\'' .. v .. '\''
    end

    -- basic cargo query
    local fields = '_pageName, type, name, image, duration, effects, dlc'
    local cargoArgs = { orderBy = '_pageName', where = cargoWhere, limit = 5000 }
    local data = mw.ext.cargo.query('Effects', fields, cargoArgs)

    if #data < 1 then
        return 'No results!'
    end

    -- build table output 
    local html = mw.html.create()
    buildoutput(nil, data, html, frame, true)
    return html
end

-- function for listing all effects, with optional category filter.
-- usage is {{#invoke:ListEffects|main}} or {{#invoke:ListEffects|main|type=Boon}}
function p.main(frame)
    if frame == mw.getCurrentFrame() then
		args = require('Module:ProcessArgs').merge(true)
	else
		frame = mw.getCurrentFrame()
    end

    local cargoWhere = ''
    if args.type ~= nil then
        cargoWhere = 'type=\'' .. args.type .. '\''
    end

    -- basic cargo query
    local fields = '_pageName, type, name, image, duration, effects, dlc'
    local cargoArgs = { orderBy = '_pageName', where = cargoWhere, limit = 5000 }
    local data = mw.ext.cargo.query('Effects', fields, cargoArgs)

    if #data < 1 then
        return '<b>No results found!</b>'
    end
    
    -- build table output 
    local html = mw.html.create()

    if args.type ~= nil then
        -- filtered, no sorting required
        buildoutput(nil, data, html, frame, true)
    else
        -- the intended order for the outputted tables.
        -- we can iterate over this with ipairs to retain the sort.
        local order = {
            'Unsorted',
            'Vital',            -- ==Positive Effects==
            'Boon',
            'Buff',
            'Imbue',
            'Weather',
            'Sleep',
            'Other Positive',
            'Hex',              -- ==Negative Effects==
            'Debuff',
            'DoT',
            'Disease',
            'Needs',
            'Corruption',
            'Weight',
            'Other Negative'
        }

        -- prepare sorted list holders (create empty tables corresponding to the type)
        local sorted = {}
        for _, v in ipairs(order) do
            sorted[v] = {}
        end

        -- sort builds into their holder
        for _, v in ipairs(data) do
            local wasSorted = false
            if notempty(v.type) then
                local tbl = find(sorted, v.type)
                if tbl ~= nil then
                    table.insert(tbl, v)
                    wasSorted = true
                end
            end
        
            if not wasSorted then
                table.insert(sorted['Unsorted'], v)
            end        
        end

        -- iterate using the intended order
        for _, v in ipairs(order) do
            --buildoutput(v, sorted[v], html, frame)
            if #sorted[v] > 0 then
                buildoutput(v, sorted[v], html, frame, false)
            end
        end
    end

    return html
end

function buildoutput(title, data, html, frame, noTitle) 
    if not noTitle then
        if title == 'Unsorted' then
            html:wikitext(frame:preprocess('<h2>' .. title .. '</h2>'))
        else
            if title == 'Vital' then
                html:wikitext(frame:preprocess('<h2>Positive Effects</h2>'))
            elseif title == 'Hex' then
                html:wikitext(frame:preprocess('<h2>Negative Effects</h2>'))
            end
            html:wikitext(frame:preprocess('<h3>' .. title .. '</h3>'))
        end
    end

    local table = html:tag('table'):addClass('wikitable sortable')
    local header = table:tag('tr')
    header:tag('th'):wikitext('Icon')
    header:tag('th'):wikitext('Name')
    header:tag('th'):wikitext('Duration')
    header:tag('th'):cssText('min-width:250px'):wikitext('Effects')

    for _,v in ipairs(data) do
        local tr = table:tag('tr')
		-- icon
        tr:tag('td'):cssText('max-width:50px')
        	:wikitext(frame:preprocess('[[File:' .. v.image .. '|40x40px|frameless|none|link=' .. v._pageName .. ']]'))
        -- name
        local name = v.name
        if name == nil or name == '' then name = v._pageName end
        name = '[[' .. v._pageName .. '|' .. name .. ']]'
        if v.dlc ~= nil and v.dlc ~= '' then name = name .. ' {{' .. v.dlc .. '}}' end
        tr:tag('td'):cssText('min-width:100px'):wikitext(frame:preprocess(name))
        -- duration
        tr:tag('td'):cssText(''):wikitext(v.duration)
        -- effects
        tr:tag('td'):cssText('min-width:250px'):wikitext(frame:preprocess(v.effects))
    end

    return table
end


----------------------------------------------------------------
--------------------------- HELPERS ----------------------------

function find(tbl, val)
    for k, v in pairs(tbl) do
        if k == val then return v end
    end
    return nil
end

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

function hasmatch(table1, table2)
    for _,v in ipairs(table1) do
        if contains(table2, v) then
            return true
        end
    end
    return false
end

function contains(table, value)
    for _,v in ipairs(table) do
        if v == value then
            return true
        end
    end
    return false
end

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

return p