Module:Uses skill list: Difference between revisions

From RuneRealm Wiki
Jump to navigation Jump to search
Content added Content deleted
No edit summary
No edit summary
 
(One intermediate revision by the same user not shown)
Line 26: Line 26:
local skills = {}
local skills = {}
local skills_lowered = {}
local skills_lowered = {}
local category = args.category and trim(args.category) or nil -- Optional category parameter
local category = args.category and trim(args.category) or nil
-- Process skill arguments
-- Process skill arguments
Line 48: Line 48:
'[[Uses skill::' .. table.concat(skills, '||') .. ']]',
'[[Uses skill::' .. table.concat(skills, '||') .. ']]',
'[[Production JSON::+]]',
'[[Production JSON::+]]',
'[[Category::Unf]]',
'?=#-',
'?=#-',
'?Production JSON = json',
'?Production JSON = json',
'?Category', -- Fetch the Category field for filtering later
limit = args.limit or 500,
limit = args.limit or 500,
}
}
Line 57: Line 55:
-- Add category filter if provided
-- Add category filter if provided
if category then
if category then
table.insert(query, '[[Category::' .. category .. ']]')
table.insert(query, '[[RecipeCategory::' .. category .. ']]')
end
end



Latest revision as of 22:04, 13 November 2024

Module documentation
This documentation is transcluded from Module:Uses skill list/doc. [edit] [history] [purge]
Module:Uses skill list's function main is invoked by Template:Uses skill list.
Module:Uses skill list requires Module:Addcommas.
Module:Uses skill list requires Module:Exchange.
Module:Uses skill list requires Module:SCP.
Module:Uses skill list requires Module:Yesno.

Generates {{Uses skill list}}.


local p = {}

local geprice = require('Module:Exchange')._price
local commas = require('Module:Addcommas')
local skillpic = require('Module:SCP')._main
local yesno = require('Module:Yesno')
local lang = mw.getContentLanguage()
local trim = mw.text.trim

-- Sorting function for two item objects, first by name, then by sub-text
function sortItemsByNameSubtext(item1, item2)
	if (item1.output.name < item2.output.name) then
		return true
	elseif (item1.output.name > item2.output.name) then
		return false
	else
		return (item1.output.subtxt or '') < (item2.output.subtxt or '')
	end
end

function p.main(frame)
	return p._main(frame:getParent().args)
end

function p._main(args)
	local skills = {}
	local skills_lowered = {}
    local category = args.category and trim(args.category) or nil
	
    -- Process skill arguments
    if args == nil then
		table.insert(skills, mw.title.getCurrentTitle().text)
	else
		local i = 1
		
		while args[i] do
			local arg = trim(args[i])
			
			table.insert(skills, arg)
	    	skills_lowered[arg:lower()] = true
	    	
			i = i + 1
		end
	end

    -- Build SMW query
    local query = {
        '[[Uses skill::' .. table.concat(skills, '||') .. ']]',
        '[[Production JSON::+]]',
        '?=#-',
        '?Production JSON = json',
        limit = args.limit or 500,
    }
    
    -- Add category filter if provided
    if category then
        table.insert(query, '[[RecipeCategory::' .. category .. ']]')
    end

    -- Fetch data
    local t1 = os.clock()
    local smw_data = mw.smw.ask(query)
    local t2 = os.clock()

    if not smw_data then
        return 'Failed to find products with those skills - ensure they are spelled correctly. (ERR: no results from SMW)[[Category:Empty drop lists]]'
    end
    
    mw.log(string.format('SMW: entries %d, time elapsed: %.3f ms.', #smw_data, (t2 - t1) * 1000))

    -- Post-process
    data = {}

    for _, e in ipairs(smw_data) do
    	if type(e.json) == 'string' then
            local json = mw.text.jsonDecode(e.json)
            table.insert(data, json)
        elseif type(e.json) == 'table' then
        	for _, f in ipairs(e.json) do
        		local json = mw.text.jsonDecode(f)
                table.insert(data, json)
        	end
    	end
    end
    
    smw_data = nil
    
    -- Items with different variants (e.g. Divine battlemage potion has (1), (2), (3), (4) variants)
    -- or methods (e.g. "4-dose oil" vs "3-dose oil" for pyre logs) may not come in sorted, so now do a final alphabetical sort on name, sub-text
    table.sort(data, sortItemsByNameSubtext)

    -- Render page
    local t = mw.html.create('table')
    t:addClass('wikitable sortable products-list align-center-1 align-right-3 align-right-4 autosort=3,a')

    local ttlrow = t:tag('tr')
        :tag('th')
            :attr('colspan', '2')
            :wikitext('Item')
        :done()
        :tag('th')
            :wikitext('Members')
            :done()
        :tag('th')
            :attr('data-sort-type', 'number')
            :wikitext('Skills')
        :done()
        :tag('th')
            :attr('data-sort-type', 'number')
            :wikitext('XP')
        :done()
        :tag('th')
            :wikitext('Materials')
        :done()

    local rows = 0

    -- Render rows
    for _, item in ipairs(data) do
        local skill_match = false
        for _, skill_info in ipairs(item.skills) do
            if skills_lowered[skill_info.name:lower()] then
                skill_match = true
                break
            end
        end

        if skill_match then
            local name_str

            if (tonumber(item.output.quantity) or 0) > 1 then
                name_str = string.format('[[%s]] × %s', item.output.name, item.output.quantity)
            else
                name_str = string.format('[[%s]]', item.output.name)
            end
            
            if item.output.subtxt then
            	name_str = string.format('%s <br /><small>(%s)</small>', name_str, item.output.subtxt)	
            end
            
            local member_str

            if item.members == 'Yes' then
				member_str = "[[File:Member icon.png|center|link=Members|alt=Members]]"	
			elseif item.members == 'No' then
				member_str = "[[File:Free-to-play icon.png|center|link=Free-to-play|alt=Free-to-play]]"	
			end
		
            local experience_cell = mw.html.create('td')
            experience_cell:addClass('plainlist')

            local experience_ul = experience_cell:tag('ul')
            experience_ul:addClass('skills-list')

            local skills_cell = mw.html.create('td')
            skills_cell:addClass('plainlist')

            local skills_ul = skills_cell:tag('ul')
            skills_ul:addClass('skills-list')

            if #item.skills == 0 then
        		local skill_li = skills_ul:tag('li')
        		local experience_li = experience_ul:tag('li')

        		experience_cell:addClass('table-na'):css('text-align', 'center')
        		experience_li:wikitext(string.format('None'))
        		skills_cell:addClass('table-na'):css('text-align', 'center')
        		skill_li:wikitext(string.format('None'))
        	else
        		for index, v in ipairs(item.skills) do
            		local skill_li = skills_ul:tag('li')
            		local experience_li = experience_ul:tag('li')
            		local stripped_experience = v.experience:gsub(',', '')

            		skill_li
                        :attr('data-sort-value', index == 1 and v.level or '')
                        :wikitext(skillpic(lang:ucfirst(v.name), v.level))
            		experience_li
                        :attr('data-sort-value', index == 1 and v.experience or '')
                        :wikitext(tonumber(stripped_experience) ~= nil and skillpic(lang:ucfirst(v.name), v.experience) or v.experience)
        		end
        	end

            local mats_ul = mw.html.create('ul')
            mats_ul:addClass('products-materials')

            local mat_sort_val = nil

            for _, mat_info in ipairs(item.materials) do
                local mat_li = mats_ul:tag('li')
                local qty = mat_info.quantity:gsub('%-', '–')
                local mat_name = mat_info.name
                
                if mat_sort_val == nil then
                	mat_sort_val = qty
                end
                
                mat_li:wikitext(string.format('%s × [[%s]]', commas._add(qty), mat_name))
            end

            local prow = t:tag('tr')
            	:tag('td')
            		:wikitext(item.output.image)
                :tag('td')
                	:attr('data-sort-value', item.product)
                    :wikitext(name_str)
                :done()
                :tag('td')
                	:wikitext(member_str)
                :node(skills_cell)
                :node(experience_cell)
                :tag('td')
                	:attr('data-sort-value', mat_sort_val)
                	:addClass('plainlist')
                    :node(mats_ul)
                :done()
            rows = rows + 1
        end
    end

    if rows == 0 then
        return 'Failed to find products with those skills - ensure they are spelled correctly. (ERR: no skills found in results)[[Category:Empty drop lists]]'
    end

    return t
end

--[[ DEBUG COPYPASTA
= p._main({'Mithril bar'})
--]]

return p