Módulo:Equipment bonuses infotable

De RuneScape Wiki
Ir para navegação Ir para pesquisar
Documentação do módulo
Esta documentação é transcluída de Módulo:Equipment bonuses infotable/doc. [editar] [histórico] [atualizar]
Este(a) módulo não possui nenhuma documentação. Por favor, considere adicionar uma documentação em Módulo:Equipment bonuses infotable/doc. [editar]
Módulo:Equipment bonuses infotable a função main é invocada por Predefinição:Tabela equipamento.
Lista de funções
L 112 — isnotempty
L 116 — isempty
L 120 — cleanItemName
L 127 — imagearg
L 142 — imageargmain
L 151 — imageargalt
L 161 — p.main

-- <nowiki>
local p = {}
local infobox = require('Módulo:Infobox')
local yesno = require("Módulo:Yesno")
local Exchange = require("Módulo:Mercado")._price_simple
local Coins = require("Módulo:Moedas")._amount
local AddCommas = require("Módulo:Addcommas")._add
local skillClickpic = require("Módulo:Skill clickpic")._main
local onmain = require("Módulo:Mainonly").on_main
local editbutton = require('Módulo:Edit button')
local edit = editbutton("'''?''' (edit)")

local imagearg, imageargmain, imageargalt

-- Accepted rowTypes
local rowTypes = {
    ['corpo a corpo'] = "[[Arquivo:Ataque ícone.png|x26px|link=Corpo a corpo]] [[Corpo a corpo]]",
    ['ícone corpo a corpo'] = "[[Arquivo:Ataque ícone.png|x26px|link=Corpo a corpo]]",
    ['combate à distância'] = "[[Arquivo:Combate à Distância ícone.png|x26px|link=Combate à Distância]] [[Combate à Distância]]",
    ['ícone combate à distância'] = "[[Arquivo:Combate à Distância ícone.png|x26px|link=Combate à Distância]]",
    magia = "[[Arquivo:Magia ícone.png|x26px|link=Magia]] [[Magia]]",
    ['ícone magia'] = "[[Arquivo:Magia ícone.png|x26px|link=Magia]]",
    necromancia = "[[Arquivo:Necromancia ícone.png|x26px|link=Necromancia]] [[Necromancia]]",
    ['ícone necromancia'] = "[[Arquivo:Necromancia ícone.png|x26px|link=Necromancia]]",
    ['híbrido'] = "[[Arquivo:Combate ícone grande.png|x26px|link=Armadura#Híbrida]] [[Armadura#Híbrida|Híbrida]]",
    ['ícone híbrido'] = "[[Arquivo:Combate ícone grande.png|x26px|link=Armadura#Híbrida]]",
    todos = "[[Arquivo:Combate ícone grande.png|x26px|link=Armadura#Todas]] [[Armadura#Todas|Todas]]",
    ['ícone todos'] = "[[Arquivo:Combate ícone grande.png|x26px|link=Armadura#Todas]]",
    ['impede ataque'] = "Impede ataque",
    nenhum = " - "
}

-- Accepted headerTypes
local headerTypes = {
    ['corpo a corpo'] = "[[Arquivo:Ataque.png|x34px|link=Corpo a corpo]]<br />Objeto",
    ['combate à distância'] = "[[Arquivo:Combate à Distância.png|x34px|link=Combate à Distância]]<br />Objeto",
    magia = "[[Arquivo:Magia.png|x34px|link=Magia]]<br />Objeto",
    necromancia = "[[Arquivo:Necromancia.png|x34px|link=Necromancia]]<br />Objeto",
    ['híbrido'] = "[[Arquivo:Combate ícone grande.png|x34px|link=Armadura#Híbrida]]<br />Objeto",
    todos = "[[Arquivo:Combate ícone grande.png|x34px|link=Armadura#Tudo]]<br />Objeto",
    misturado = "Objeto",
    nenhum = "Objeto"
}

-- Accepted weapon styles
local styles = {
    perfurar = "'''Perfurar'''",
    ['perfuração'] = "'''Perfurar'''",
    esmagar = "'''Esmagar'''",
    ['esmagamento'] = "'''Esmagar'''",
    dilacerar = "'''Dilacerar'''",
    ['dilaceração'] = "'''Dilacerar'''",
    flecha = "'''Flecha'''",
    flechas = "'''Flechas'''",
    seta = "'''Seta'''",
    setas = "'''Setas'''",
    arremesso = "'''Arremesso'''",
    ['feitiço'] = "'''Feitiço'''",
    ['feitiços'] = "'''Feitiços'''",
    necromancia = "'''Necromancia'''",
    nenhum = "'''Nenhum'''"
}

-- Row args that are summed and displayed in the totals row (if present)
local totalArgs = {
	dano = 0,
	armadura = 0,
	vida = 0,
	['oração'] = 0,
	['força'] = 0,
	['distância'] = 0,
	magia = 0,
	necromancia = 0,
    danoRecurso = 0,
}

-- Images used for slot display
local slot_images = {
	['cabeça'] = '[[Arquivo:Slot de Cabeça.png|link=Slot de cabeça]]',
	elmo = '[[Arquivo:Slot de Cabeça.png|link=Slot de cabeça]]',
	['munição'] = '[[Arquivo:Slot de munições.png|link=Slot de munições]]',
	['munições'] = '[[Arquivo:Slot de munições.png|link=Slot de munições]]',
	['pescoço'] = '[[Arquivo:Slot de Pescoço.png|link=Slot de pescoço]]',
	colar = '[[Arquivo:Slot de Pescoço.png|link=Slot de pescoço]]',
	amuleto = '[[Arquivo:Slot de Pescoço.png|link=Slot de pescoço]]',
	costas = '[[Arquivo:Slot de Costas.png|link=Slot de costas]]',
	['primária'] = '[[Arquivo:Slot de Mão Primária.png|link=Slot de mão primária]]',
	['arma primária'] = '[[Arquivo:Slot de Mão Primária.png|link=Slot de mão primária]]',
	['arma de mão primária'] = '[[Arquivo:Slot de Mão Primária.png|link=Slot de mão primária]]',
	['arma 2m'] = '[[Arquivo:Slot de Duas-Mãos.png|link=Slot de duas-mãos]]',
	['arma de 2m'] = '[[Arquivo:Slot de Duas-Mãos.png|link=Slot de duas-mãos]]',
	corpo = '[[Arquivo:Slot de Tronco.png|link=Slot de Tronco]]',
	tronco = '[[Arquivo:Slot de Tronco.png|link=Slot de Tronco]]',
	cota = '[[Arquivo:Slot de Tronco.png|link=Slot de Tronco]]',
	['secundária'] = '[[Arquivo:Slot de Mão Secundária.png|link=Slot de mão secundária]]',
	['arma secundária'] = '[[Arquivo:Slot de Mão Secundária.png|link=Slot de mão secundária]]',
	['arma de mão secundária'] = '[[Arquivo:Slot de Mão Secundária.png|link=Slot de mão secundária]]',
	['mão secundária'] = '[[Arquivo:Slot de Mão Secundária.png|link=Slot de mão secundária]]',
	perneiras = '[[Arquivo:Slot de Pernas.png|link=Slot de pernas]]',
	pernas = '[[Arquivo:Slot de Pernas.png|link=Slot de pernas]]',
	['mãos'] = '[[Arquivo:Slot de Mãos.png|link=Slot de mãos]]',
	luvas = '[[Arquivo:Slot de Mãos.png|link=Slot de mãos]]',
	['pés'] = '[[Arquivo:Slot de Pés.png|link=Slot de pés]]',
	botas = '[[Arquivo:Slot de Pés.png|link=Slot de pés]]',
	anel = '[[Arquivo:Slot de anel|link=Slot de anel]]',
	aura = '[[Arquivo:Slot de Aura|link=Slot de aura]]',
	bolso = '[[Arquivo:Slot de bolso.png|link=Slot de bolso]]',
	selo = '[[Arquivo:Slot de selo|link=Slot de selo]]',
	e = 'Nenhum'
}

local function isnotempty(s)
    return not (s == nil or s == "")
end

local function isempty(s)
	return not isnotempty(s)
end

local function cleanItemName(argstable, isSMW)
	local pattern = isSMW and "%[%[([^|%]]+)" or "%[%[([^|#%]]+)"

	return (argstable.mg and (argstable.mg:match(pattern) or argstable.mg))
        or (argstable.name and (argstable.name:match(pattern) or argstable.name))
end

function imagearg(f)
	local height = 250
	if not infobox.isDefined(f) then
		return nil
	end
	f = tostring(f)
	if string.lower(f) == 'não' then
		return nil
	end
	f = f:gsub('[Aa]rquivo:',''):gsub('{{!}}','|')
	f = mw.text.split(f, '|')
	f = f[1]

	return mw.ustring.format('[[Arquivo:%s|x%spx|frameless|alt=%s: %s equipado por um jogador]]', f, height, f, mw.title.getCurrentTitle().text)
end
function imageargmain(i, m, f)
	if not infobox.isDefined(i) then
		if infobox.isDefined(m) then
			return imagearg(m)
		end
		return edit
	end
	return imagearg(i)
end
function imageargalt(i, m, f)
	if not infobox.isDefined(i) then
		if infobox.isDefined(f) then
			return imagearg(f)
		end
		return edit
	end
	return imagearg(i)
end

function p.main(frame)
    local frameargs = frame:getParent().args
    local htmltable = mw.html.create("table") -- The output of this module
    local tblrow
    local tblcell
    local totalPrice = 0                      -- Sum of the individual prices
    local totalspanrange = 7                  -- Minimum spanrange of the label in case the totals parameter is used (attr + style cols)
    local imageRowsSpan = 2                   -- Row span counter (including 2 header rows)
    local imageCells = {}                     -- Image table cell(s)
    local bucketmismatch = false                 -- Template data disagrees with SMW data
    local bucketerror = false                    -- Error occurred while retrieving SMW data
    local totalsmismatch = false              -- Template data for totals row disagrees with auto-calc'd sum

    -- Create the tabel header
    --[[Parameters used 	(variable type)     [note]
        classe / tipo   	(string)            [@mandatory]
        seminv          	(sim/não)           [@optional, default is no, if yes the rowspan of the class header is 1 otherwise its 2]
        habilidade          (string)            [@optional, accepted values are those for Módulo:Skill clickpic]
        habilidade2         (string)            [@optional, accepted values are those for Módulo:Skill clickpic]
        semarma     		(sim/não)           [@optional, default is no, if yes hides the weapons stats]
        semestilo			(sim/não)			[@optional, default is no, if yes hides the style bonuses]
        sematributo			(sim/não)			[@optional, default is no, if yes hides the attribute bonuses]
        semsomarstats   	(sim/não)           [@optional, default is no, if yes will not automatically sum stat values to display in totals row]
        preço           	(mg/number/string)  [@optional, ge is the the string "mg", mg and number are preferred so it adds to the totalprice]
        imagem          	(string)            [@optional, image is given by the form "image name.png"]
        imagem2         	(string)            [@optional]
        imagem3             (string)            [@optional]
        linhas          	(number)            [@optional, only affects image, image2, and image3]
        tot             	(number)            [@optional, only affects image, image2, and image3]
        organizável     	(sim/não)           [@optional]
        tipoícone       	(sim/não)           [@optional, default is no, if yes will force rows' "type" values to only show icons]
		mostrarmembros		(sim/não)			[@optional]
		mostrardegradável	(sim/não)			[@optional]
    ]]

    htmltable
        :addClass("wikitable infotableBonuses")
        :css("text-align", "center")

        -- Make first header row
        tblrow = htmltable:tag("tr")

            -- Set the header class
            tblcell = tblrow:tag("th")
                :attr("rowspan", "2")
                :wikitext(headerTypes[string.lower(frameargs.classe or frameargs.tipo or "")] or ("''Tipo desconhecido<br /><small>[" .. tostring(mw.uri.fullUrl( mw.title.getCurrentTitle().prefixedText, "action=edit")) .. " edit]</small>''"))
                :attr("data-sort-type", "text")
                if not yesno(frameargs.seminv) then
                    tblcell
                        :attr("colspan", "2")
                end

			if yesno(frameargs.mostrarmembros) then
				tblrow
					:tag("th")
						:attr("rowspan", "2")
                        :wikitext("Membros")
				totalspanrange = totalspanrange + 1
			end

            -- Add extra type column if the header class is mixed
            if string.lower(frameargs.classe or frameargs.tipo or "") == "misturado" then
                tblrow
                    :tag("th")
                        :attr("rowspan", "2")
                        :attr("data-sort-type", "text")
                        :wikitext("Tipo")
                    :done()
                totalspanrange = totalspanrange + 1
            end

            -- Add extra skill column
            if isnotempty(frameargs.habilidade) then
                tblrow
                    :tag("th")
                        :attr("rowspan", "2")
                        :attr("data-sort-type", "number")
                        :css("vertical-align", "bottom")
                        :wikitext(skillClickpic(frameargs.habilidade or ""))
                            :tag("br")
                            :done()
                        :tag("span")
                            :css("font-size", "90%")
                            :wikitext("Nível")
                        :done()
                    :done()
                totalspanrange = totalspanrange + 1
            end

            -- Add extra skill2 column
            if isnotempty(frameargs.habilidade2) then
                tblrow
                    :tag("th")
                        :attr("rowspan", "2")
                        :attr("data-sort-type", "number")
                        :css("vertical-align", "bottom")
                        :wikitext(skillClickpic(frameargs.habilidade2 or ""))
                            :tag("br")
                            :done()
                        :tag("span")
                            :css("font-size", "90%")
                            :wikitext("Nível")
                        :done()
                    :done()
                totalspanrange = totalspanrange + 1
            end

            -- Show/hide weapon stats
            if not yesno(frameargs.semarma) then
                tblrow
                    :tag("th")
                        :attr("title", "Estilo de ataque")
                        :attr("rowspan", "2")
                        :wikitext("Estilo")
                    :done()
                    :tag("th")
                        :attr("title", "Espaço de equipamento usado")
                        :attr("rowspan", "2")
                        :wikitext("Espaço")
                    :done()
                    :tag("th")
                        :attr("title", "Alcance de ataque da arma")
                        :attr("data-sort-type", "number")
                        :attr("rowspan", "2")
                        :wikitext("Alcance")
                    :done()
                    :tag("th")
                        :attr("title", "Precisão da arma")
                        :attr("data-sort-type", "number")
                        :attr("rowspan", "2")
                        :wikitext("Precisão")
                    :done()
                    :tag("th")
                        :attr("colspan", "2")
                        :wikitext("Dano")
                    :done()
                totalspanrange = totalspanrange + 6
            end

            -- Add atribute columns
            if not yesno(frameargs.sematributo) then
	            tblrow
	                :tag("th")
	                    :attr("colspan", "3")
	                    :attr("title", "Determina a resistência do personagem de acordo com a classe de armadura, aumento de pontos vitais e bônus de oração.")
	                    :wikitext("Atributo")
	                :done()
	        end

            -- Add style bonuses columns
			if not yesno(frameargs.semestilo) then
				tblrow
					:tag("th")
						:attr("colspan", "4")
						:wikitext("Bônus&nbsp;de&nbsp;estilo")
					:done()
            end

            -- Add price column
            if yesno(frameargs['preço']) then
                tblrow
                    :tag("th")
                        :attr("rowspan", "2")
                        :attr("data-sort-type", "number")
                        :wikitext("Preço")
                    :done()
                totalspanrange = totalspanrange + 1
            end

			if yesno(frameargs['mostrardegradável']) then
				tblrow
					:tag("th")
						:attr("rowspan", "2")
                        :wikitext("Degrada")
				totalspanrange = totalspanrange + 1
			end

            -- Add image column
            if frameargs.imagem ~= 'não' and (isnotempty(frameargs.imagem) or isnotempty(frameargs.imagem2) or isnotempty(frameargs.imagem3) or isnotempty(frameargs.masculinoimagem) or isnotempty(frameargs.femininoimagem) or isnotempty(frameargs.altimagem)) then
	            table.insert(imageCells, tblrow
	                :tag("th")
	                    :addClass('unsortable')
	                    :css("width", "125px")
	                    :css("vertical-align", "center")
	                    :wikitext(imageargmain(frameargs.imagem, frameargs.masculinoimagem, frameargs.femininoimagem))
                )
                tblrow:done()

	            -- Add image2 comlumn
	            table.insert(imageCells, tblrow
	                :tag("th")
	                    :addClass('unsortable')
	                    :css("width", "125px")
	                    :css("vertical-align", "center")
	                    :wikitext(imageargalt(frameargs.imagem2, frameargs.masculinoimagem, frameargs.femininoimagem))
                )
                tblrow:done()

	            -- Add image3 comlumn
	            if isnotempty(frameargs.imagem3) or isnotempty(frameargs.altimagem) then
	                table.insert(imageCells, tblrow
	                    :tag("th")
	                        :attr("rowspan", tostring(2 + tonumber(frameargs.rows or imageRowsSpan) + tonumber(frameargs.tot or 0)))
	                        :addClass('unsortable')
	                        :css("width", "125px")
	                        :css("text-align", "center")
	                        :css("vertical-align", "center")
	                        :wikitext(imagearg(frameargs.altimagem or frameargs.imagem3))
                    )
                    tblrow:done()
	            end
			end

        -- Make second header row
        tblrow = htmltable:tag("tr")

            -- Show/hide weapon stats
            if not yesno(frameargs.semarma) then
                tblrow
                    :tag("th")
                        :attr("title", "Dano de ataque automático de arma")
                        :attr("data-sort-type", "number")
                        :wikitext("Auto")
                    :done()
                    :tag("th")
                        :attr("title", "Dano de recurso de arma")
                        :attr("data-sort-type", "number")
                        :wikitext("Recurso")
                    :done()
            end

            -- Add attribute and style bonuses columns
            if not yesno(frameargs.sematributo) then
	            tblrow
	                :tag("th")
						:attr("data-sort-type", "number")
	                    :wikitext(skillClickpic("Defesa"))
	                :done()
	                :tag("th")
						:attr("data-sort-type", "number")
	                    :wikitext(skillClickpic("Condição Física"))
	                :done()
	                :tag("th")
						:attr("data-sort-type", "number")
	                    :wikitext(skillClickpic("Oração"))
	                :done()
	            :done()
	        end
            if not yesno(frameargs.semestilo) then
	            tblrow
	                :tag("th")
						:attr("data-sort-type", "number")
	                    :wikitext("[[Arquivo:Ataque ícone.png|20px|link=Corpo a corpo]]")
	                :done()
	                :tag("th")
						:attr("data-sort-type", "number")
	                    :wikitext("[[Arquivo:Combate à Distância ícone.png|20px|link=Combate à Distância]]")
	                :done()
	                :tag("th")
						:attr("data-sort-type", "number")
	                    :wikitext("[[Arquivo:Magia ícone.png|20px|link=Magia]]")
	                :done()
	                :tag("th")
						:attr("data-sort-type", "number")
	                    :wikitext("[[Arquivo:Necromancia ícone.png|20px|link=Necromancia]]")
	                :done()
	            :done()
            end

        -- sortable
        if yesno(frameargs['organizável']) then
            htmltable:addClass("sortable")
        end
    -- Header ends here

    -- Table rows are created here
    --[[Parameters used     (variable type)     [note]
            [all paramerers are @optional]
        totais          	(sim/não)           [Default is no]
        label           	(string)            [Only has an effect if totals is used]
        mg              	(string)
        imagem          	(string)            [Only works if the ge parameter is not used]
        nome            	(string)            [Only works if the ge parameter is not used]
        smwname(descontinuado) (string)            [Override the name used in the SMW query for stats]
        bucketname          (string)            [Override the name used in the bucket query for stats]
        tipo            	(string)            [Default is "-"]
        nível/habilidade    (number/string)     [Default is "-"]
        nível2/habilidade2  (number/string)     [Default is "-"]
        estilo          	(string)            [Default is "-"]
        dano            	(number)            [Default is "-"]
        precisão            (number)            [Default is "-"]
        armadura        	(number)            [Default is "-"]
        vida            	(number)            [Default is "-"]
        oração          	(number)            [Default is "-"]
        força       		(number)            [Default is "-"]
        distância       	(number)            [Default is "-"]
        magia       		(number)            [Default is "-"]
        necromancia     	(number)            [Default is "-"]
        preço           	(mg/number/string)  [ge only works if the ge parameter is used. ge and number are preferred if the totals prameter is used]
        preçoimagem     	(string)            [can be used incase the ge parameter is not used but you want the price to add to the totalprice]
        naoadctotal 		(sim/não)           [default is no]
        semtotalmoedas  	(sim/não)           [default is no]
        ref             	(string)
    ]]
    local argstables = {}
    local replacedrows = {}
    for rownum, j in ipairs(frameargs) do     -- Iterate in order over all frameargs with a integer key
        -- Parse the framearg j into a table of rowargs, j = {{Equipment bonuses inforow}}
        argstables[rownum] = {}
        local argstable = argstables[rownum]
        for argduo in j:gmatch("!(.-)!") do
            local argname = argduo:match("&(.-)&")
            local argvalue = argduo:match( "µ(.-)µ")
            if argvalue == "" then
                argvalue = nil
            end
            argstable[argname] = argvalue
        end

        -- Set up rowarg mapping to bucket fields
        if not (yesno(argstable.totals) or yesno(frameargs.bucket) or yesno(argstable.bucket) or yesno(frameargs.semsmw) or yesno(argstable.semsmw)) then
			local bucketprops = {}

        	bucketprops["tipo"] = "class"
			if yesno(frameargs['nível']) then
				bucketprops["habilidade"] = "requirements"
			end
        	if not yesno(frameargs.semarma) then
        		bucketprops["estilo"] = "style"
        		bucketprops["dano"] = "damage"
        		bucketprops["precisão"] = "accuracy"
                bucketprops["danoRecurso"] = "ability_damage"
                bucketprops["danoRecursoDisp"] = "ability_damage_note"
                bucketprops["alcance"] = "attack_range"
                bucketprops["slot"] = "slot"
    		end
    		if not yesno(frameargs.sematributo) then
    			bucketprops["armadura"] = "armour"
    			bucketprops["vida"] = "lp"
    			bucketprops["oração"] = "prayer"
			end
			if not yesno(frameargs.semestilo) then
				bucketprops["força"] = "strength"
				bucketprops["distância"] = "ranged"
				bucketprops["magia"] = "magic"
				bucketprops["necromancia"] = "necromancy"
			end
			if yesno(frameargs['mostrardegradável']) then
				bucketprops["degradável"] = "charges"
			end

			local bucketname = argstable.bucketname or argstable.bucketname or cleanItemName(argstable, true)
			if isempty(bucketname) then
				mw.log("Erro de SMW na tabela de equipamento: Nome vazio na linha #" .. rownum)
				bucketerror = true
			else
				mw.log(bucketname)
				local t1 = os.clock()
				local result = bucket('infobox_bonuses')
					.select('page_name', 'page_name_sub', 'infobox_bonuses.json', 'infobox_item.is_members_only', 'infobox_item.item_name')
					.join('infobox_item', 'infobox_bonuses.page_name', 'infobox_item.page_name')
					.where(bucket.Or({'page_name', bucketname}, {'page_name_sub', bucketname}))
					-- .limit(10)
					.run()

				local t2 = os.clock()
				mw.log(string.format('EQ Infotable Bucket: %d, time: %.3f ms.', #result, (t2 - t1) * 1000))

				if #result == 0 then
					mw.log("EQ Infotable Bucket error: Ask failed for item:"..bucketname)
					bucketerror = true
				else
					-- prioritise results:
					--  1) SMW (sub)object title or "Is variant of" match
					--  2) item name match
					--  3) first result (fallback)
					local resultNum
					do
						local fallbackResultNum
						for i = 1, #result do
							if result[i]["page_name_sub"] == bucketname then
								resultNum = i
								break
							elseif (fallbackResultNum == nil
								and result[i]["page_name"] == bucketname) then
								fallbackResultNum = i
							end
						end
						resultNum = resultNum or fallbackResultNum or 1
					end
					
					argstable.membros = yesno(result[resultNum]["infobox_item.is_members_only"])
					if result[resultNum]["infobox_bonuses.json"] then
						result = mw.text.jsonDecode(result[resultNum]["infobox_bonuses.json"])
					end
					argstable.skill = argstable.habilidade or result.reqiosotps

					for argname, propname in pairs(bucketprops) do
                        if tonumber(result[propname]) ~= nil then
                            result[propname] = tonumber(result[propname])
                        end

						if argstable[argname] == nil and result[propname] ~= 0 then
							argstable[argname] = result[propname]
						elseif argstable[argname] ~= nil and result[propname] ~= 0 then
							-- Only flag mismatches of numerical values if they differ by >= 1.0
							-- Allows rounding/truncation of decimal values to not flag
							-- This seems to have been a common practice when composing the
							-- older Infotables; remove if accurate values w/ decimals are preferred
							if (type(result[propname]) == "number" and math.abs(tonumber(argstable[argname]) - result[propname]) >= 1) or
							   (type(result[propname]) == "string" and not (argname == "style" or argname == "level") and result[propname]:lower() ~= argstable[argname]:lower() ) or
							   (argname == "style" and styles[string.lower(result[propname] or "")] ~= styles[argstable[argname]:lower()]) then
								smwmismatch = true
								mw.log("EQ Infotable SMW warning: Row mismatch for parameter: " .. argname)
								mw.log("    Nome do objeto: " .. bucketname)
								mw.log("    Valor da predefinição: " .. argstable[argname])
								mw.log("    Valor do bucket: " .. (result[propname] or ""))
							end
						end
					end
				end
			end
		end

		-- Track number of rows for image spans
		imageRowsSpan = imageRowsSpan + 1

        -- Special processings for totals rows
        if yesno(argstable.totais) then
			-- Add extra row if the totals + label parameters are used
			if isnotempty(argstable.label) then
				imageRowsSpan = imageRowsSpan + 1
	            tblrow = htmltable:tag("tr")
	                :addClass("attribute-total sortbottom")
	                tblcell = tblrow:tag("th")
	                    :attr("rowspan", "2")
	                    :wikitext("Totais" .. ((argstable.ref and (" " .. argstable.ref)) or ""))
	                    if not yesno(frameargs.seminv) then
	                        tblcell
	                            :attr("colspan","2")
	                    end

	            tblrow
	                :tag("th")
	                    :attr("colspan", totalspanrange)
	                    :wikitext(argstable.label)
	                :done()
            end

            if not yesno(frameargs.semsomarstats) then
	            -- Default totals args to their corresponding sum if not specified
	            for arg, sum in pairs(totalArgs) do
					if sum ~= 0 then
						if isempty(argstable[arg]) then
							argstable[arg] = sum
						elseif tonumber(argstable[arg]) ~= sum then
							totalsmismatch = true
							mw.log("EQ Infotable totals mismatch for parameter: " .. arg)
							mw.log("    Predefinição: " .. argstable[arg])
							mw.log("    Calculado: " .. sum)
						end
					end
				end

				-- Default acc column to max value
				argstable['precisão'] = 0
				for k = 1, rownum - 1 do
					if not replacedrows[k] and isempty(argstables[k].totais) then
						argstable['precisão'] = math.max(argstable['precisão'], tonumber(argstables[k]['precisão']) or 0)
					end
				end

				-- Default skill level columns to max values
				if isnotempty(frameargs.habilidade) or isnotempty(frameargs.habilidade2) then
					argstable.habilidade = 0
					argstable.habilidade2 = 0

					for k = 1, rownum - 1 do
						if not replacedrows[k] and isempty(argstables[k].totais) then
							local rowSkill = string.match(argstables[k].habilidade or argstables[k]['nível'] or "", "%d+")
							local rowSkill2 = string.match(argstables[k].habilidade2 or argstables[k]['nível2'] or "", "%d+")
							argstable.habilidade = math.max(argstable.habilidade, tonumber(rowSkill) or 0)
							argstable.habilidade2 = math.max(argstable.habilidade2, tonumber(rowSkill2) or 0)
						end
					end
				end
			end
		else
			-- Support replacing previous rows with the current row's stats when summing totals
			if isnotempty(argstable.trocarlinha) then
				local replacenum = tonumber(argstable.trocarlinha)
				if replacenum == nil or replacenum < 1 or replacenum >= rownum or isnotempty(argstables[replacenum].totais) then
					mw.log("Erro na linha da tabela de equipamento: valor de 'trocarlinha' inválido para objeto: " .. cleanItemName(argstable))
					mw.log("    trocarlinha="..replacenum.."; rownum="..rownum.."; numrows="..#frameargs)
				else
					local replacedargs = argstables[replacenum]
					replacedrows[replacenum] = true

					-- Subtract replaced row's additions to the totals
					for arg, sum in pairs(totalArgs) do
						local argNum = tonumber(replacedargs[arg])
						if argNum ~= nil then
							totalArgs[arg] = sum - argNum
						end
					end

					-- Price is handled separately; subtract it if it's a number (from GE or as given)
					local argPrice = tonumber(replacedargs['preço'])
					if argPrice ~= nil then
						totalPrice = totalPrice - argPrice
					end
				end
			end
			if not yesno(frameargs.semsomarstats) and not yesno(argstable.naoadctotal) then
				-- Non-totals row; add totals args to their corresponding sum if a numerical value is specified
				for arg, sum in pairs(totalArgs) do
					local argNum = tonumber(argstable[arg])
					if argNum ~= nil then
						totalArgs[arg] = sum + argNum
					end
				end
			end
		end

        -- Create a new inforow
        tblrow = htmltable:tag("tr")

            -- Special handling for a totals row
            if yesno(argstable.totais) then
                tblrow
                    :addClass("attribute-total sortbottom")

	            -- Add the totals text cell (if not already added above due to requested label)
	            if isempty(argstable.label) then
	                tblcell = tblrow:tag("th")
	                    :wikitext("Totais" .. ((argstable.ref and (" " .. argstable.ref)) or ""))
	                    if not yesno(frameargs.seminv) then
	                        tblcell
	                            :attr("colspan","2")
	                    end
                end
            else
				-- Italicise rows that will not add to the total stats
				if isnotempty(argstable.naoadctotal) then
					tblrow:css("font-style", "italic")
				end

	            -- Add the item image and name cells
	            if isnotempty(argstable.mg) then
					local itemLink = argstable.mg:match("^%[%[") and argstable.mg or ("[[" .. argstable.mg .. "]]")
					local itemName = cleanItemName(argstable)
	                tblrow
	                    :tag("td")
	                        :wikitext("[[Arquivo:" .. itemName .. ".png|link=" .. itemName .. "]]")
	                        :addClass("inventory-image")
	                    :done()
	                    :tag("td")
	                        :css("text-align", "left")
	                        :wikitext(itemLink .. ((argstable.ref and (" " .. argstable.ref)) or ""))
	                    :done()
	            elseif isnotempty(argstable.imagem) then
	                tblrow
	                    :tag("td")
	                        :wikitext(argstable.imagem:find("[[Arquivo:", 1, true) and argstable.imagem or ("[[Arquivo:" .. argstable.imagem .. "]]"))
	                    :done()
	                if isnotempty(argstable.nome) then
	                    tblrow
	                        :tag("td")
	                            :css("text-align", "left")
	                            :wikitext(argstable.nome .. ((argstable.ref and (" " .. argstable.ref)) or ""))
	                        :done()
	                end
	            elseif isnotempty(argstable.nome) then
	                tblrow
	                    :tag("td")
	                        :css("text-align", "left")
	                        :wikitext(argstable.nome .. ((argstable.ref and (" " .. argstable.ref)) or ""))
	                    :done()
	            end
            end

            -- add members column
			if yesno(frameargs.mostrarmembros) then
				local val = argstable.membros and "[[Arquivo:P2P ícone.png|30px|link=Membros]]" or "[[Arquivo:F2P ícone.png|30px|link=Jogadores gratuitos]]"
				if yesno(argstable.totais) then
					val = "-"
				end
				tblrow
					:tag("td")
						:attr("data-sort-value", argstable.membros and 1 or 0)
						:wikitext(val)
			end

            -- Add the type cell incase the header class is mixed
            if string.lower(frameargs.classe or frameargs.tipo or "") == "misturado" then
				local argType = string.lower(argstable.tipo or "")
				if yesno(frameargs['tipoícone']) and isnotempty(argType) and not argType:match(" ícone$") then
					argType = argType .. " ícone"
				end

                tblrow
                    :tag("td")
	                    :css("text-align", "left")
                        :wikitext(rowTypes[argType] or argstable.tipo or "-")
                    :done()
            end

            -- Add the skill cell
            if isnotempty(frameargs.habilidade) then
				local skillArg = argstable['nível'] or argstable.habilidade
                tblrow
                    :tag("td")
                        :wikitext(skillArg or "-")
                        :attr("data-sort-value", skillArg or 0)
                    :done()
            end

            -- Add the skill2 cell
            if isnotempty(frameargs.habilidade2) then
				local skill2Arg = argstable['nível2'] or argstable.habilidade2
                tblrow
                    :tag("td")
                        :wikitext(skill2Arg or "-")
                        :attr("data-sort-value", skill2Arg or 0)
                    :done()
            end

            -- Show/hide weapon stats
            if not yesno(frameargs.semarma) then
                tblrow
                    :tag("td")
                        :addClass("attribute-value")
                        :wikitext(styles[string.lower(argstable.estilo or "")] or argstable.estilo or "-")
                    :done()
                    :tag("td")
                        :addClass("attribute-value")
                        :wikitext(slot_images[string.lower(argstable.slot or "")] or argstable.slot or "-")
                    :done()
                    :tag("td")
                        :addClass("attribute-value")
                        :wikitext(argstable.alcance or "-")
                        :attr("data-sort-value", argstable.alcance or 0)
                    :done()
                    :tag("td")
                        :wikitext(argstable['precisão'] or "-")
                        :attr("data-sort-value", argstable['precisão'] or 0)
                    :done()
                    :tag("td")
                        :wikitext(argstable.dano or "-")
                        :attr("data-sort-value", argstable.dano or 0)
                    :done()
                    :tag("td")
                        :wikitext(argstable.danoRecursoDisp or argstable.danoRecurso or "-")
                        :attr("data-sort-value", argstable.danoRecurso or 0)
                    :done()
            end

            -- Add atribute and style bonuses cells
            if not yesno(frameargs.sematributo) then
	            tblrow
	                :tag("td")
	                    :addClass("attribute-value")
	                    :wikitext(argstable.armadura or "-")
	                :done()
	                :tag("td")
	                    :addClass("attribute-value")
	                    :wikitext(argstable.vida or "-")
	                :done()
	                :tag("td")
	                    :addClass("attribute-value")
	                    :wikitext(argstable['oração'] or "-")
	                :done()
	            :done()
	        end
            if not yesno(frameargs.semestilo) then
				tblrow
	                :tag("td")
	                    :wikitext(argstable['força'] or "-")
	                    :attr("data-sort-value", argstable['força'] or 0)
	                :done()
	                :tag("td")
	                    :wikitext(argstable['distância'] or "-")
	                    :attr("data-sort-value", argstable['distância'] or 0)
	                :done()
	                :tag("td")
	                    :wikitext(argstable.magia or "-")
	                    :attr("data-sort-value", argstable.magia or 0)
	                :done()
	                :tag("td")
	                    :wikitext(argstable.necromancia or "-")
	                    :attr("data-sort-value", argstable.necromancia or 0)
	                :done()
				:done()
            end
            -- Add price cell
            if yesno(frameargs['preço']) then

                -- Total price
                if (yesno(argstable.totais) and argstable['preço'] == nil) or string.lower(argstable['preço'] or "") == "total" then
                    if isnotempty(argstable['preçoimagem']) then
                        tblrow
                            :tag("td")
                                :css("text-align", "right")
                                :wikitext((argstable['preçoimagem'] and ("[[Arquivo:" .. argstable['preçoimagem'] .. "]] ")) or "")
                                :tag("span")
                                    :addClass("coins coins-pos")
                                    :wikitext(AddCommas(totalPrice))
                                :done()
                            :done()
                    else
                        tblrow
                            :tag("td")
                                :css("text-align", "right")
                                :wikitext(Coins(totalPrice, false))
                            :done()
                    end

                -- GE price, this is the default value if no price parameter was given
                elseif argstable['preço'] == nil or string.lower(argstable['preço'] or "") == "mg" then
                    -- Check if the item exist on the GE
                    local itemName = cleanItemName(argstable)
                    local gePrice = Exchange(itemName)
                    if gePrice then
                    	argstable['preço'] = gePrice
                        if not yesno(argstable.naoadctotal) then
                            totalPrice = totalPrice + argstable['preço']
                        end
                        tblrow
                            :tag("td")
                                :css("text-align", "right")
                                :wikitext(Coins(argstable['preço'], false))
                            :done()
                    elseif string.lower(argstable['preço'] or "") == "mg" then
                        tblrow
                            :tag("td")
                                :tag("span")
                                    :css("color", "red")
                                    :wikitext("Objeto não existe no [[Mercado Geral|")
                                        :tag("span")
                                            :css("color", "darkred")
                                            :wikitext("Mercado Geral")
                                        :done()
                                    :wikitext("]]")
                                :done()
                            :done()
                    else
                        tblrow
                            :tag("td")
                                :wikitext("-")
                            :done()
                    end

                -- If the price parameter is just a number
                elseif tonumber(argstable['preço']) ~= nil then
                    if not yesno(argstable.naoadctotal) then
                        totalPrice = totalPrice + tonumber(argstable['preço'])
                    end
                    if argstable['preçoimagem'] == nil then
                        tblrow
                            :tag("td")
                                :css("text-align", "right")
                                :wikitext(Coins(tonumber(argstable['preço'])))
                            :done()
                    else
                        tblrow
                            :tag("td")
                                :css("text-align", "right")
                                :wikitext((argstable['preçoimagem'] and ("[[Arquivo:" .. argstable['preçoimagem'] .. "]] ")) or "")
                                :tag("span")
                                    :addClass("coins coins-pos")
                                    :wikitext(AddCommas(tonumber(argstable['preço'])))
                                :done()
                            :done()
                    end

                -- If the price parameter is a non recognized value
                else
                    tblrow
                        :tag("td")
                            :css("text-align", "right")
                            :wikitext(argstable['preço'])
                        :done()
                end
            end

			if yesno(frameargs['mostrardegradável']) then
				local val = isnotempty(argstable["degradável"]) and "[[Arquivo:Sim.svg|20px|link=]]" or "[[Arquivo:Não.svg|20px|link=]]"
				if yesno(argstable.totais) then
					val = "-"
				end
				tblrow
					:tag("td")
						:attr("data-sort-value", isnotempty(argstable["degradável"]) and 1 or 0)
						:wikitext(val)
			end
        -- Inforow ends here
    end

    -- Finalise rowspans for image cell(s)
    for _, cell in ipairs(imageCells) do
		cell:attr("rowspan", tostring(imageRowsSpan))
	end

    -- Table is complete here
    local retval = tostring(htmltable)

    -- Various tracking cats to monitor errors/incorrect values
    if onmain() then
		local cats = ""
	    if bucketerror then
			cats = cats .. "[[Categoria:Páginas com erro de script]]"
		end
		if smwmismatch then
			cats = cats .. "[[Categoria:Páginas com tabelas de equipamento usando valores divergentes do SMW]]"
		end
		if totalsmismatch then
			cats = cats .. "[[Categoria:Páginas com tabelas de equipamentos com totais incorretos]]"
		end
		if frameargs.imagem ~= 'não' then
			if not infobox.isDefined(frameargs.masculinoimagem) then
				cats = cats .. "[[Categoria:Precisa de imagem de equipamento masculino]]"
			end
			if not infobox.isDefined(frameargs.femininoimagem) then
				cats = cats .. "[[Categoria:Precisa de imagem de equipamento feminino]]"
			end
		end

		retval = retval .. cats
	end

    return retval
end

return p
-- </nowiki>