Module:EffectSources

From Outward Wiki
Jump to navigation Jump to search

Lua module used by EffectSources template.


local p = {}

function p.sources(frame)
    local output = {}

    if frame == mw.getCurrentFrame() then
		args = require('Module:ProcessArgs').merge(true)
	else
		frame = mw.getCurrentFrame()
    end
    
    local _effect = args.name or mw.title.getCurrentTitle().text

    local fields = '_pageName, effect, type, buildup, chance, effectlevel'
    local cargoArgs = { where = string.format('effect="%s"', _effect), orderBy = '_pageName' }
	local result = mw.ext.cargo.query('EffectReference', fields, cargoArgs)

    if result then
        local html = mw.html.create()

        -- create nested tables to sort the results into
        local results = {
            PlayerInflicts = {},
            PlayerReceives = {},
            InflictsPlayer = {},
            Requires = {}, 
            Removes = {},
            BenefitsFrom = {},
            Prevents = {}
        }
        local hasEffectLevel = false

        -- also keep a table of all pages we've added, to avoid a weird duplicate issue.
        local checked = {}

        -- sort results into tables, and check if any have EffectLevel defined.
        for i,v in ipairs(result) do
            if checked[v._pageName.. ':' .. v.type] == nil then
                -- add to checked
                checked[v._pageName.. ':' .. v.type] = true
                -- append the result to the table. use index so we can iterate alphabetically.
                table.insert(results[v.type], #results[v.type] + 1, v)
                -- check for effect level
                if (hasEffectLevel == false and v.effectlevel ~= nil and tonumber(v.effectlevel) ~= nil) then
                    hasEffectLevel = true
                end
            end
        end

        -- list PlayerReceives (done separately because of the unique EffectLevel aspect)
        if #results['PlayerReceives'] > 0 then
            -- if no EffectLevel, just list them.
            if hasEffectLevel == false then                
                html:tag('b'):wikitext('Obtained from:'):done()
                local list = html:tag('ul')   
                for k,v in ipairs(results['PlayerReceives']) do
                    p.addResult(v, list)
                end
                list:done()
            else -- we have effect levels defined. 
                -- sort into tables for each level
                local levels = { {}, {}, {}, {}, {} }
                for _,v in ipairs(results['PlayerReceives']) do
                    table.insert(levels[tonumber(v.effectlevel)], #levels[tonumber(v.effectlevel)] + 1, v)
                end
                -- and print each level separately, if any defined.
                -- iterate in reverse order because we want to show highest level to lowest.
                for idx = #levels, 1, -1 do
                    level = levels[idx]
                    if #level > 0 then
                        html:tag('b'):wikitext('Level ' .. idx .. ':'):done()
                        local list = html:tag('ul')
                        for i,v in ipairs(level) do
                            p.addResult(v, list)
                        end
                        list:done()
                    end
                end
            end
        end

        -- For the other categories, just iterate automatically using this template table.
        local templates = {
            { key = 'Removes', title = 'Removed with:' },
            { key = 'Prevents', title = 'Resisted by:' },
            { key = 'PlayerInflicts', title = 'Inflicted with:' },
            { key = 'Requires', title = 'Required by:' },
            { key = 'BenefitsFrom', title = 'Has effect on:' },
            { key = 'InflictsPlayer', title = 'Inflicted by enemies:' }
        }

        -- for each template
        for _,template in ipairs(templates) do
            -- lookup the sorted results with the key
            local data = results[template.key]
            if #data > 0 then
                -- create the title
                html:tag('b'):wikitext(template.title):done()
                -- create the ul list
                local list = html:tag('ul')
                -- append each result
                for _,v in ipairs(data) do
                    p.addResult(v, list)
                end
                list:done()
            end
        end

        return html
    else
        -- return mw.html.create():css('width: 50%'):wikitext('Auto-generated list: No sources found.'):done() 
    end
end

function p.addResult(v, list)
    local output = string.format("[[%s]]", v._pageName)
    if tonumber(v.buildup) ~= nil then
        output = string.format('%s (%s%% [[Effects#Buildup|buildup]])', output, v.buildup)
    elseif tonumber(v.chance) ~= nil then
        output = string.format('%s (%s%% chance)', output, v.chance)
    end
    list:tag('li'):wikitext(output):done()
end

return p