Module:Armoury

From WIDEVERSE Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Armoury/doc

local hc = require('Module:Paramtest').has_content
local yn = require('Module:Yesno')
local QUERY_SIZE = 8

local p = {}

local cellDef = {
    name = { header = 'Item', class = 'armoury-name', type = 'eq_string' },
    ['Equipment tier'] = { header = 'Tier', class = 'armoury-tier', type = 'eq_number' },
    ['Combat class'] = { header = 'Class', class = 'armoury-class', type = 'eq_image' },
    ['Equipment type'] = { header = 'Type', class = 'armoury-type', type = 'eq_string' },
    ['Attack style'] = { header = 'Style', class = 'armoury-style', type = 'eq_number' },
    ['Equipment armour'] = { header = 'Armour', class = 'armoury-armour', type = 'eq_number' },
    ['Equipment life points'] = { header = 'Life<br />points', class = 'armoury-lifepoints', type = 'eq_number' },
    ['Strength bonus'] = { header = 'Strength<br />bonus', class = 'armoury-strength', type = 'eq_number' },
    ['Magic bonus'] = { header = 'Magic<br />bonus', class = 'armoury-magic', type = 'eq_number' },
    ['Ranged bonus'] = { header = 'Ranged<br />bonus', class = 'armoury-ranged', type = 'eq_number' },
    ['Prayer bonus'] = { header = 'Prayer<br />bonus', class = 'armoury-prayer', type = 'eq_number' },
    ['Weapon damage'] = { header = 'Damage', class = 'armoury-damage', type = 'eq_number' },
    ['Weapon accuracy'] = { header = 'Accuracy', class = 'armoury-accuracy', type = 'eq_number' },
    ['Weapon attack speed'] = { header = 'Speed', class = 'armoury-speed', type = 'eq_string' },
    ['Attack range'] = { header = 'Attack<br />range', class = 'armoury-attack-range', type = 'eq_number' }
}

local classImg = {
	melee = '[[File:Attack.png|x24px|link=Melee]]',
	ranged = '[[File:Ranged.png|x24px|link=Ranged]]',
	magic = '[[File:Magic.png|x24px|link=Magic]]',
	hybrid = '[[File:CombatSwords.png|x24px|link=Armour#Hybrid]]',
	all = '[[File:CombatSwords.png|x24px|link=Armour#All]]',
	none = ''
}

local printouts = {
	['_types'] = {
		head = 1,
		torso = 1,
		legs = 1,
		hands = 1,
		feet = 1,
		back = 1,
		['main hand weapon'] = 2,
		['2h weapon'] = 2,
		['off-hand'] = 3,
		['off-hand weapon'] = 3,
		neck = 4,
		ring = 4,
		pocket = 4,
		ammo = 5,
		aura = 6,
		sigil = 6
	},
    {'Combat class', 'Equipment tier', 'Equipment type', 'Equipment armour', 'Equipment life points', 'Strength bonus', 'Magic bonus', 'Ranged bonus', 'Prayer bonus'}, --armour
    {'Combat class', 'Equipment tier', 'Equipment type', 'Attack style', 'Weapon accuracy', 'Weapon damage', 'Prayer bonus', 'Weapon attack speed', 'Attack range'}, --mh/2h weapons
    {'Combat class', 'Equipment tier', 'Equipment type', 'Attack style', 'Weapon accuracy', 'Weapon damage', 'Equipment armour', 'Equipment life points', 'Prayer bonus', 'Weapon attack speed', 'Attack range'}, --offhands inc shields
    {'Combat class', 'Equipment tier', 'Equipment armour', 'Strength bonus', 'Magic bonus', 'Ranged bonus', 'Prayer bonus'}, -- ring neck pocket
    {'Combat class', 'Equipment tier', 'Weapon damage', 'Prayer bonus', 'Strength bonus', 'Magic bonus', 'Ranged bonus', 'Equipment armour' }, -- ammo
    {'Combat class', 'Equipment tier', 'Strength bonus', 'Magic bonus', 'Ranged bonus', 'Equipment armour' }, -- sigil pocket default
}

local sorts = {
	['Name'] = nil,
	['Tier'] = 'Equipment tier',
	['ID'] = 'Item ID',
}
local orders = {
	asc = 'asc',
	desc = 'desc'
}

local no_tier_search = {
	neck = true,
	ring = true,
	pocket = true,
	aura = true,
	sigil = true
}

local rowLayout

function p.main(frame)
	return p._main(frame:getParent().args)
end
function p._main(args)
	local query = {}
	local rowtype = printouts._types[args.slot]
	rowLayout = printouts[rowtype]
	
	if rowtype then
		table.insert(query, '[[Equipment slot::'..args.slot..']]')
	else
		error('Please provide a valid equipment slot')
	end
	
	if hc(args.cbclass) and args.cbclass ~= 'any' then
		table.insert(query, '[[Combat class::'..args.cbclass..']]')
	end
	if hc(args.members) and args.members ~= 'any' then
		table.insert(query, '[[Is members only::'..args.members..']]')
	end
	local tradeable = yn(args.tradeable)
	if tradeable ~= nil then
		table.insert(query, '[[Tradeable::'..tostring(tradeable)..']]')
	end
	if hc(args.restriction) and args.restriction ~= 'any' then
		table.insert(query, '[[Location restriction::'..args.restriction..']]')
	end
	-- TODO improve
	if hc(args.augmented) then
		if args.augmented == 'able' then
			table.insert(query, '[[Category:Augmentable items]]')
		elseif args.augmented == 'yes' then
			table.insert(query, '[[Category:Augmented items]]')
		end
	end
	if hc(args.hiderecolour) then
		if args.hiderecolour == 'true' then
			table.insert(query, '[[Is cosmetic recolour::false]]')
		end
	end
	local t_min = tonumber(args.tier_min)
	local t_max = tonumber(args.tier_max)
	if args.enable_tier_min == 'true' and t_min and t_min > 0 and not no_tier_search[args.slot] then
		table.insert(query, '[[Equipment tier::≥'..t_min..']]')
	end
	if args.enable_tier_max =='true' and t_max and t_max < 120 and not no_tier_search[args.slot] then
		table.insert(query, '[[Equipment tier::≤'..t_max..']]')
	end
	querySize = 0
	for i,v in ipairs(query) do
		if v and v ~= '' and string.match(v, '%[%[') then
			querySize = querySize + 1
		end
	end
	
	local limit = math.min(tonumber(args.limit) or 500, 500)
	local page = tonumber(args.page) or 0
	query.limit = limit
	query.offset = page * limit
	
	--name formatting
	table.insert(query, '?#-=page')
	table.insert(query, '?Is variant of#-')
	table.insert(query, '?Version anchor')
	
	-- other printouts
	for i,v in ipairs(rowLayout) do
		table.insert(query, '?'..v)
	end
	
	query.sort = sorts[args.sort]
	query.order = orders[args.order]
	
	local data = mw.smw.ask(query)
	
	if not data then
		local ret = mw.html.create('div')
		ret :addClass('armoury no-results-found table-bg-red')
			:attr({
				id = 'armoury-no-results-found',
				['data-page'] = page,
				['data-query'] = mw.text.nowiki(table.concat(query, ' '))
			})
			:wikitext('No results found for that filter set')
		return ret
	end
	
	local ret = mw.html.create('table')
	ret	:addClass('wikitable armoury sticky-header sortable alternating-rows')
		:attr({
			['data-page'] = page,
			['data-count'] = #data,
			['data-limit'] = query.limit,
			['data-offset'] = query.offset,
			['data-query'] = mw.text.nowiki(table.concat(query, ' '))
		})
	local trh = ret:tag('tr')
	trh:tag('th'):wikitext('Item')
	for i,v in ipairs(rowLayout) do
		trh:tag('th'):wikitext(cellDef[v].header)
	end
	
	for i,v in ipairs(data) do
		ret:node(p.row(v))
	end
	
	if querySize > QUERY_SIZE then
		return '<div id="armoury-query-size-limit-reached" class="armoury query-size-limit-reached table-bg-red">Warning: you have too many filters set and have exceeded the query size. The results provided below have ignored one or more of your filters. Set some filters to "Any"/"None"/disabled to reduce the size.</div>\n' .. tostring(ret)
	end
	return tostring(ret)
end

function convert(d)
	if d == nil then
		return ''
	end
	if type(d) == 'table' then
		return table.concat(d, ', ')
	end
	return tostring(d)
end

function p.row(data)
	local name
	if data['Is variant of'] and data['Version anchor'] then
		name = mw.ustring.format('[[%s|%s <span class="armoury-version">%s</span>]]', data.page, data['Is variant of'], data['Version anchor'])
	else
		name = '[['..data.page..']]'
	end
	
	data['Combat class'] = classImg[data['Combat class']] or data['Combat class']
	
	local tr = mw.html.create('tr')
	tr	:addClass('armouryrow')
		:tag('td')
			:wikitext(name)
			:addClass('armoury-name eq_string')
	
	for i,v in ipairs(rowLayout) do
		local cell = cellDef[v]
		tr	:tag('td')
				:wikitext(convert(data[v]))
				:addClass(cell.class)
				:addClass(cell.type)
			:done()
	end
	return tr
end

return p