Module:Elemental weakness table

From RuneRealm Wiki
Jump to navigation Jump to search
Module documentation
This documentation is transcluded from Module:Elemental weakness table/doc. [edit] [history] [purge]
Module:Elemental weakness table's function main is invoked by Template:Elemental weakness table.
Module:Elemental weakness table requires Module:Array.
Module:Elemental weakness table requires Module:PageListTools.
Module:Elemental weakness table requires strict.

require('strict')

local p = {}

local arr = require('Module:Array')
local pagelisttools = require('Module:PageListTools')
local pageswithcats = pagelisttools.pageswithcats

local smwstats = {}

-- Formats a table header
function p.header(tbl, verbose)
    local tr = tbl:tag('tr')
        :tag('th'):attr('colspan', '2'):wikitext('Monster'):done()
        :tag('th'):wikitext('Members'):done()
        :tag('th'):wikitext('Weak To'):done()
        :tag('th'):wikitext('Weakness'):done()
end

-- Main entrypoint
function p.main(frame)
    local args = frame:getParent().args
    return p._main(args)
end

function p._main(args)
	local element = 'all'
	if args[1] then
		element = args[1]
	end
	
    -- Gather the data
    local fulldata = p.loadData(element)
    local data = p.filterData(fulldata)
    local fulldata = nil

    -- Format the output page
    local div = mw.html.create('div')

    local tbl = div:tag('table'):addClass('wikitable sortable mw-collapsible mw-collapsed')
        :addClass('align-center-1 align-left-2 align-center-3 align-center-4 align-center-5')

    p.header(tbl)

    -- Render rows
    
    local function makeRow(entry)
        local name = mw.text.split(entry['name'], '#', true)
        if name[2] then
        	name[2] = name[2]:gsub('_', ' ')
        end

        local membsicon = ''
        if type(entry['members']) == 'table' then
	        local ismem = arr.contains(entry['members'], true)
    		local isftp = arr.contains(entry['members'], false)
        	if ismem then
        		membsicon = '[[File:Member icon.png|center|link=Members|alt=Members]]'
        	end
        	if isftp then
        		membsicon = '[[File:Free-to-play icon.png|center|link=Free-to-play|alt=Free-to-play]]'
        	end
        	if ismem and isftp then
        		membsicon = '[[File:Member icon.png|link=Members|alt=Members]] / [[File:Free-to-play icon.png|link=Free-to-play|alt=Free-to-play]]'
        	end
    	else
    		membsicon = entry['members'] and '[[File:Member icon.png|center|link=Members|alt=Members]]' or '[[File:Free-to-play icon.png|center|link=Free-to-play|alt=Free-to-play]]'
        end
        local tr = mw.html.create('tr')
            :tag('td'):css('height', '64px'):wikitext(entry['image'] and string.format('[[%s|link=|64x64px|%s%s]]', entry['image'], name[1], (name[2] and ' - ' .. name[2]) or '') or '' ):done()
            :tag('td'):wikitext(string.format('[[%s|%s]]%s', entry['name'], name[1], name[2] and '<br/><i>' .. name[2] .. '</i>' or '') ):done()
            :tag('td'):wikitext(membsicon):done()
            :tag('td'):wikitext(string.format('[[File:%s_rune.png|link=|alt=%s]]', entry['elemental weakness'], entry['elemental weakness'])):done()
            :tag('td'):wikitext(entry['elemental weakness percent'] .. '%'):done()
        return tr
	end
    
    local errors = {}
    for e, entry in ipairs(data) do
    	local isnoterr, ret = pcall(makeRow, entry)
    	if isnoterr then
    		tbl:node(ret)
    	else
    		table.insert(errors, 'Error message: '..ret..'<br>Affected entry: <code>'..mw.text.nowiki(mw.text.jsonEncode(entry))..'</code>')
    	end
    end
    if #errors > 0 then
    	local errtag = div:tag('div'):addClass('error'):wikitext('Errors with this query shown below:[[Category:Pages with script errors]]')
    	for i,v in ipairs(errors) do
    		errtag:newline():wikitext('* ',v)
    	end
    end
    return div
end

-- Filter discontinued monsters
function p.filterData(indata)
    -- Fetch exclusion list
    local exlist = {}

    table.insert(exlist, '[[Category:Monsters]] [[Category:Discontinued content]]')

    local pages_excl = pageswithcats(exlist)

    -- Post-process the data
    local data = {}

    for _, entry in ipairs(indata) do
        local process = true

        if arr.contains(pages_excl, entry['variantof']) or arr.contains(pages_excl, entry['name']) then
            process = false
        end

        if process then
            table.insert(data, entry)
        end
    end

    return data
end

-- Sends a query to SMW and returns the data
function p.loadData(element)
    local props = {
        ['Image']             = 'image',
        ['Is members only']   = 'members',
        ['Elemental weakness'] = 'elemental weakness',
        ['Elemental weakness percent'] = 'elemental weakness percent',
        ['Is variant of']     = 'variantof'
    }

    local query = {}

    -- Conditions part of query
    local condition = { '[[Uses infobox::Monster]] [[Elemental weakness percent::≥1]]' }
    if not (element == 'all') then
    	table.insert(condition, '[[Elemental weakness::' .. element .. ']]')
    end
    table.insert(query, table.concat(condition))

    -- Printouts part of query
    table.insert(query, '?=#-')
    for k, pr in pairs(props) do
        table.insert(query, string.format('?%s #- = %s', k, pr))
    end

    -- Parameters part of query
    query.offset = 0
    query.limit = 500

    -- Fetch the data
    local smw = mw.smw.ask(query)
    if not smw or #smw == 0 then
        smw = {}
    end

    -- Post-process the data
    local data = {}

    for _, entry in ipairs(smw) do
        local dataline = entry

        dataline['name'] = dataline[1]
        dataline[1] = nil
        if type(dataline['image']) == 'table' then
            dataline['image'] = dataline['image'][1]
        end

        table.insert(data, dataline)
    end

    return data
end

return p