Módulo:DropsLine

De RuneScape Wiki
Ir para: navegação, pesquisa
Documentação do módulo
Esta documentação é transcluída de Módulo:DropsLine/doc. [editar] [atualizar]
Módulo:DropsLine é invocada por .
Módulo:DropsLine requer Módulo:Coins image.
Módulo:DropsLine requer Módulo:Currency Image.
Módulo:DropsLine requer Módulo:Mercado.
Módulo:DropsLine requer Módulo:Paramtest.
Módulo:DropsLine requer Módulo:Yesno.
Módulo:DropsLine carrega dados de Módulo:DropsLine/itemData.
Módulo:DropsLine carrega dados de Módulo:GEHighAlchs/data.
Módulo:DropsLine carrega dados de Módulo:GEPrices/data.

Este módulo controla tabelas de objetos largados, incluindo monstros, Arqueologia, Trilhas do Tesouro etc. Para seu funcionamento, veja {{ObjetoLargado}}.


-- <nowiki>
local p = {}

local params = require('Módulo:Paramtest')
local lang = mw.language.getContentLanguage()
local coins_image = require('Módulo:Coins image')
local curr_image = require('Módulo:Currency Image')
local exchange = require('Módulo:Mercado') 
local yesno = require('Módulo:Yesno')
local VariablesLua = mw.ext.VariablesLua

-- precalculated cached data
local droppeditem_data = mw.loadData('Módulo:DropsLine/itemData')
local geprices_data = mw.loadData('Módulo:GEPrices/data')
local highalch_data = mw.loadData('Módulo:GEHighAlchs/data')

local geprice = exchange._price
local f_gealch = exchange._highalch
local ptitle = mw.title.getCurrentTitle()
local ns = ptitle.nsText
local title = ptitle.fullText
local pgTitle = ptitle.text

local _membs = '&nbsp;<sub title="Members only" style="cursor:help; margin-left:3px;">(m)</sub>'
local _membscols =  {
	[true] = {
		content = '[[Arquivo:P2P ícone.png|25px|link=Membros]]',
		title = 'Membros',
		style = {
			cursor = 'help'
		},
		class = 'members-item'
	},
	[false] = {
		content = '[[Arquivo:F2P ícone.png|25px|link=Jogadores gratuitos]]',
		title = 'Jogadores gratuitos',
		style = {
			cursor = 'help'
		},
		class = 'nonmembers-item'
	}
}
local _noted = '&nbsp;<span class="dropsline-noted">(notas)</span>'
local _altval = '<span class="dropsline-altval" style="margin-left:0.3em;">[[Arquivo:AltValue.png|link=|frameless|20px]]</span>'
local _gealch = '<span class="dropsline-gealch" style="margin-left:0.3em;">[[Arquivo:Alquimia Avançada.png|link=Alquimia Avançada|frameless|20px]]</span>'

local _priceStrings = {
    alch = {
        coins = "%s moeda%s",
        ge = "%s moeda%s cada",
        smw = "%s moeda%s cada",
        cache = "%s moeda%s cada.",
        alch = "%s moeda%s cada",
        alt = "%s %s%s cada; este objeto tem um valor distinto, embora não possa ser alquimizado."
    },
    ge = {
        coins = "%s moeda%s",
        ge = "%s moeda%s cada",
        cache = "%s moeda%s cada.",
        alch = "%s moeda%s cada; este é o valor da alquimia avançada, pois este objeto não pode ser negociado no Mercado Geral.",
        alt = "%s %s%s cada; este objeto tem um valor distinto, embora não possa ser negociado no Mercado Geral ou ser alquimizado."
    }
}

local _version_separator_ = ','

local smwData = nil
function getSMWInfo(item)
    if smwData ~= nil then
        return smwData
    end
    local smw = mw.smw.ask({
        '[['..item..']]',
        '?Alquimia Avançada',
        '?É somente para membros'
    })
    if smw and smw[1] then
        smwData = {
            alch = smw[1]['Alquimia Avançada'],
            members = smw[1]['É somente para membros']
        }
    else
        smwData = false
    end
    return smwData
end

local dropType = {
    thieving = {
        'Saqueado de', 'Objeto saqueado', 'Variante de objeto saqueado'
    },
    reward = {
        'Recompensa de', 'Objeto de recompensa', 'Variante de objeto de recompensa'
    },
    drop = {
        'Largado de', 'Objeto largado', 'Variante de objeto largado'
    },
    fishing = {
    	'Pescado de', 'Objeto pescado', 'Variante de objeto pescado'
    },
    hunter = {
    	'Caçado de', 'Objeto caçado', 'Variante de objeto caçado'
    },
    archaeology = {
    	'Escavado de', 'Objeto escavado', 'Variante de objeto escavado'
    },
    mining = {
    	'Minerado de', 'Objeto minerado', 'Variante de objeto minerado'
    },
    woodcutting = {
    	'Cortado de', 'Objeto cortado', 'Variante de objeto cortado'
    },
    divination = {
    	'Coletado de', 'Objeto coletado', 'Variante de objeto coletado'
    }
}

--bg, txt, sort
local rarities = {
	sempre = { 'table-bg-blue', 1 },
	comum = { 'table-bg-green', 16 },
	incomum = { 'table-bg-yellow', 64 },
	raro = { 'table-bg-orange', 256 },
	['muito raro'] = { 'table-bg-red', 1024 },
	['aleatório'] = { 'table-bg-pink', 4096 },
	varia = { 'table-bg-pink', 4096 },
	_default = { 'table-bg-grey', 65536 }
}

-- arbitrary numbers
local rarities2 = {
	{ 1, 'table-bg-blue' },
	{ 1/16, 'table-bg-green' },
	{ 1/64, 'table-bg-yellow' },
	{ 1/256, 'table-bg-orange' },
	{ 1/1024, 'table-bg-red' }
}

function get_rarity_class(val)
	for i,v in ipairs(rarities2) do
		curr = v
		if val >= v[1] then
			break
		end
	end
	return curr[2]
end

function commas(n)
	if tonumber(n) then
		return lang:formatNum(tonumber(n))
	else
		return n
	end
end

-- list of items to automatically not use gemw
-- this should only be used for items dropped by many monsters
local nogemw = {
	'pergaminho de dicas ', 'antiga efígie faminta', 'tabela de objetos raros', 'tabela comum da terra selvagem', ' de guerreiro de ', 'intimação judicial', 'pergaminho lacrado'
}
-- list of items to automatically not use high alch
-- this should only be used for items dropped by many monsters
local noalch = {
	'pergaminho de dicas ', 'antiga efígie faminta', 'tabela de objetos raros', 'tabela comum da terra selvagem', ' de guerreiro de ', 'intimação judicial', 'espírito da pedra de', 'pergaminho lacrado'
}
-- list of items with alch value of 0.2 * value  (runes)
local alch02 = {
	'runa do ar', 'runa da mente', 'runa da água', 'runa da terra', 'runa do fogo', 'runa corporal',
	'runa cósmica', 'runa do caos', 'runa da natureza', 'runa da lei', 'runa da morte', 'runa astral',
	'runa do sangue', 'runa da alma', 'runa de armadyl', 'runa do pó', 'runa da lava', 'runa da névoa',
	'runa da lama', 'runa da fumaça', 'runa do vapor'
}

function expr(t)
	local noerr, val = pcall(mw.ext.ParserFunctions.expr, t)
	if noerr then
		return tonumber(val)
	else
		return false
	end
end
function sigfig(n, f)
	f = math.floor(f-1)
	if n == 0 then return 0 end
	local m = math.floor(math.log10(n))
	local v = n / (10^(m-f))
	-- floor(x + 0.5) is standard rounding to one decimal place
	v = math.floor(v+0.5) * 10^(m-f)
	return v
end
p.sigfig = sigfig
function sigfigalt(n)
	if n >= 100 then
		return math.floor(n)
	else
		return sigfig(n, 3)
	end
end

function p.main(frame)
	local args = frame:getParent().args
	local tempArgs = frame.args
	-- Params and defaults
	local name,namenotes,
		quantity,quantitynotes,
		rarity,raritynotes,memsover,
		altcur,monVers,altSource = params.defaults{
					{args.nome,'Objeto'},
					{args.nomeNotas,''},
					{args.quantidade,'Desconhecido'},
					{args.quantidadeNotas,''},
					{args.raridade,'Desconhecido'},
					{args.raridadeNotas,''},
					{args.membros,''},
					{args.moedaAlt,''},
					{args.Version,''},
					{args.fonteAlt,'GazBot'},
				}
	if altSource ~= "GazBot" then
		pgTitle = altSource
	end
	local isCoins = name:lower() == 'moedas'
	local altname = params.default_to(args.Alt,name)
	local gemwname = params.default_to(args.gemwname,name)
	local _smwname = params.default_to(args.smwname,gemwname)
	--local raritynotes = args.Raritynotes or ''
	-- Remove version number from potions, enchanted jewellery, waterskins etc for smw
	local cleanedName
	local dropVers = ''
	if _smwname:match(' %(%d%)$') then
		cleanedName, dropVers = mw.ustring.match(_smwname, '^(.-) (%(%d%))$')
    elseif _smwname:match('%#') then
        cleanedName, dropVers = mw.ustring.match(_smwname, '^(.-)%#([%w%s%(%)_]+)$')
    else
        cleanedName = mw.ustring.gsub(_smwname, ' %(%d%)$', '')
    end
    cleanedName = mw.text.trim(cleanedName)
    dropVers = mw.text.trim(dropVers)
    
    local smwname = cleanedName 
    if dropVers ~= '' then
        -- get subobject instead
        smwname = cleanedName..'#'..dropVers
    end
	
	local rarity_value
	if rarities[rarity:lower()] then
		rarity = params.ucflc(rarity)
	else
		rarity_value = expr(rarity)
	end
	
	local hasCur = false
	if params.has_content(altcur) and mw.ustring.lower(altcur) ~= 'moedas' then
		hasCur = true
	end

	quantity = mw.ustring.lower(quantity)
	local gemw = yesno(args.mercado or 'sim', false)
	local alch = yesno(args.alq or 'sim', false)

	-- automatic no gemw
    for _, v in ipairs(nogemw) do
        -- can't use a plain table lookup because this uses match
		if mw.ustring.match(mw.ustring.lower(name or ''), v) then
			gemw = false
			break
		end
	end
	-- automatic no alch
	for _, v in ipairs(noalch) do
        -- can't use a plain table lookup because this uses match
		if mw.ustring.match(mw.ustring.lower(name or ''), v) then
			alch = false
			break
		end
	end

	-- Test for existance of alch value
    local hasmwalch, smwalchval
    local valueInfo = {
        alch = {
            has = false,
            value = 0,
            from = nil
        },
        ge = {
            has = false,
            value = 0,
            from = nil
        }
    }
    
    local cached_dropdata = droppeditem_data[smwname]
    local cached_members, cached_alch = nil,nil
    if type(cached_dropdata) == 'table' then
    	if cached_dropdata[1] ~= nil and cached_dropdata[2] ~= nil then
    		cached_members = cached_dropdata[1]
    		cached_alch = cached_dropdata[2]
    	elseif cached_dropdata[1] ~= nil then
    		cached_dropdata = cached_dropdata[1]
    		if type(cached_dropdata) == 'boolean' then
    			cached_members = cached_dropdata
    		elseif type(cached_dropdata) == 'number' then
    			cached_alch = cached_dropdata
    		end
    	end
    end
    
    local geprice_frombulk = geprices_data[gemwname]
    if not (type(geprice_frombulk) == 'number' and geprice_frombulk > 0) then
    	geprice_frombulk = nil
    end
    
    if cached_alch == nil then
    	cached_alch = highalch_data[gemwname]
    	if not (type(cached_alch) == 'number' and cached_alch > -1) then
    		cached_alch = nil
    	end
    end
    	
    
    if isCoins then
        -- coins override
		valueInfo = {
            alch = {
                has = true,
                value = 1,
                from = 'moedas'
            },
            ge = {
                has = true,
                value = 1,
                from = 'moedas'
            }
        }
    elseif alch then
    	if cached_alch ~= nil then
    		valueInfo.alch = {
    			has = true,
    			value = cached_alch,
    			from = 'cache'
    		}
        elseif gemw then
            -- is not on the no-ge list/override
            -- lookup in GEMW
            local hasgealch, gealchval = pcall(f_gealch,gemwname)
        -- is not on the no-alch list or has alch disabled (and is not coins)
            if hasgealch then
            	if gealchval > -1 then
	                -- has a alch value from GEMW
	                valueInfo.alch = {
	                    has = true,
	                    value = tonumber(gealchval),
	                    from = 'ge'
	                }
                end
            end
        end
        if not valueInfo.alch.has then
            -- failed to find alch in GEMW or is on the no-ge list/override
            -- lookup in SMW
            local smwret = getSMWInfo(smwname)
            if smwret and smwret.alch ~= nil then
                -- alch is defined, use it
                valueInfo.alch = {
                    has = true,
                    value = smwret.alch,
                    from = 'smw'
                }
            elseif args.AltValue then
                --AltValue set, no alch from GE or SMW, use alt as regular alch
                valueInfo.alch = {
                    has = true,
                    value = tonumber(args.AltValue),
                    from = 'alt'
                }
                if hasCur then
                    valueInfo.alch.curr = altcur
                end
            else
            	alch = false
            end
        end
    else
        -- is on the no-alch list (and is not coins)
        if args.AltValue then
            --Altvalue set, no alch value
            valueInfo.alch = {
                has = true,
                value = tonumber(args.AltValue),
                from = 'alt'
            }
            if hasCur then
                valueInfo.alch.curr = altcur
            end
        end
    end
	-- Test for existence of an exchange page
    if not isCoins then
        if gemw then
        	if geprice_frombulk ~= nil then
                valueInfo.ge = {
                    has = true,
                    value = geprice_frombulk,
                    from = 'cache'
                }
        	else
	            local hasgemw, gepric = pcall(geprice,gemwname)
	            if hasgemw then
	                valueInfo.ge = {
	                    has = true,
	                    value = gepric,
	                    from = 'ge'
	                }
	            else
	                valueInfo.ge = {
	                    has = true,
	                    value = valueInfo.alch.value,
	                    from = 'alch'
	                }
	            end
        	end
        elseif args.AltValue then
            valueInfo.ge = {
                has = true,
                value = tonumber(args.AltValue),
                from = 'alt'
            }
            if hasCur then
                valueInfo.ge.curr = altcur
            end
        elseif alch then
            valueInfo.ge = {
                has = true,
                value = valueInfo.alch.value,
                from = 'alch'
            }
        end
    end

	-- Check members or F2P
	local members, smwmem
    local hasmwmem = false
    
    if params.has_content(memsover) then
        -- overridden
        members = yesno(memsover, false)
    elseif cached_members ~= nil then
    	members = cached_members
    else
        local smwret = getSMWInfo(smwname)
        if smwret and smwret.members ~= nil then
            members = smwret.members
            hasmwmem = true
        end
    end

	-- Add to name of item if members item
	if members == true then
		imgmembs = _membs
	else
		imgmembs = ''
	end
	-- Use 'File:<name>.png' if no image param
	-- Use 'File:<image>' if image param; image param will include extension
	-- Special catch for coins
	local image,image_n
	if isCoins then
		image_n = coins_image(quantity)
	else
		image_n = params.default_to(args.imagem, name .. '.png')
		image_n = mw.ustring.gsub(image_n, '#.+$', '.png')
	end
	if image_n:lower() == 'não' or params.is_empty(args.nome) then
		image = ''
	else
		image = mw.ustring.format('[[Arquivo:%s|link=%s|alt=%s: RS3 %s drops %s with rarity %s in quantity %s]]', image_n, name, image_n, title, name, rarity, quantity)
	end
	-- this only affects the JSON
	local smwjson = string.lower(args.smwjson or '')
	if params.has_content(args.nosmw) then
		smwjson = false
	elseif smwjson == 'não' then
		smwjson = false
	elseif smwjson == 'rdt' then
		smwjson = 'rdt'
	else
		smwjson = true
	end
	
	-- Level for Fishing, Archaeology, Mining, Woodcutting and Divination
	local level = 0
	if args['nível'] and tonumber(args['nível'], 10) then
		level = tonumber(args['nível'], 10)
	end
		
	-- Table row
	local ret =  p._main{ name,
			altname,namenotes,
			quantity,quantitynotes,
			rarity,rarity_value,raritynotes,
			image,members,
			valueInfo,gemw,alch,alt,
			isCoins,
			tempArgs,monVers,
			cleanedName,dropVers,level,smwname,
			smwjson }

	-- categories for mainspace
	local cats = ''
	
	if ns == '' then
		cats = categories{name,quantity,rarity}
	end
	return ret..cats
end

-- main function to generate the row
function p._main(...)
	local name,altname,namenotes,quantity,quantitynotes,
		rarity,rarity_value,raritynotes,
		image,members,
		valueInfo,gemw,alch,alt,
		isCoins,
		tempArgs,monVers,
		cleanedName,dropVers,level,
		smwname,smwjson = unpack(...)

    -- GE value, alch value, quantity cell contents
	local total, alchtotal, vsort, vasort, _h, _l
    quantity, _h, _l = qty(quantity)
    if valueInfo.ge.has then
	    total, vsort = get_total(valueInfo.ge.value,_h,_l)
        total = total or 'Não comprável ou alquimizável'
    end
    if valueInfo.alch.has then
	    alchtotal, vasort = get_total(valueInfo.alch.value,_h,_l)
        alchtotal = alchtotal or 'Não alquimizável'
    end
    
    -- value sorts
	if type(vsort) ~= 'number' then
		vsort = 0
	end
	if type(vasort) ~= 'number' then
		vasort = 0
	end

    -- quantity notes
	if #quantitynotes > 3 then
		quantity = quantity..quantitynotes
    end
    
    -- rarity cell contents
	local rare_class, rare_sort
	if rarity_value == undefined then
		rare_class, rare_sort = unpack(rarities[rarity:lower()] or rarities._default)
	elseif rarity_value == false then
		rare_class, rare_sort = unpack(rarities._default)
	else
		rare_sort = 1/rarity_value
		rare_class = get_rarity_class(rarity_value)
	end
	local _r = rarity

    -- members cell contents
    -- @TODO
	local membinfo = _membscols[members] or _membscols[false]
	
    -- monster versions
	local monVersT, monVersTRef, monVersTSubobj = {}, {}, {}
	local hasRowwideVersion = false
	local tblVers = tempArgs.Version
    if params.has_content(tblVers) and params.has_content(tblVers) and mw.ustring.lower(tblVers) ~= 'all' then
        -- versions applied to the entire table
        monVersT = mw.text.split(tblVers, _version_separator_)
    end
    if params.has_content(monVers) and mw.ustring.lower(monVers) ~= 'all' then
        -- versions applied to this row
        for i,v in ipairs(mw.text.split(monVers, _version_separator_)) do
            table.insert(monVersT, v)
        end
        hasRowwideVersion = true
    end
    if #monVersT > 0 and hasRowwideVersion then
        -- setup reference for this row
        local refname = {'autod-'}
        for i,v in ipairs(monVersT) do
            v = mw.text.trim(v)

            -- subobjects to insert into
            local cleanV = mw.ustring.gsub(mw.ustring.sub(v,0,5), '%.', '')..mw.ustring.sub(v,6)
            table.insert(monVersTSubobj, cleanV)

            -- reference name
            local cleanref = mw.ustring.gsub(mw.ustring.lower(v), '%W', '') -- remove all non-word characters
            -- add characters to make this unique enough of a reference name
            table.insert(refname, mw.ustring.sub(v, 1, 3))
            table.insert(refname, mw.ustring.sub(v, -3, -1))
        end
        -- create and append the reference
        local verText
        if #monVersT == 1 then
			verText = monVersT[1]
		elseif #monVersT == 2 then
			verText = monVersT[1] .. ' and ' .. monVersT[2]
		else
			verText = mw.text.listToText(monVersT, ', ', ', and ')
		end
		
        raritynotes = raritynotes .. mw.getCurrentFrame():extensionTag{
        	name = 'ref',
        	content = mw.ustring.format('Largado apenas pela versão do %s.',
        		                        verText,
        		                        #monVersT > 1 and 's' or ''),
            args = { group = 'd', name = table.concat(refname, '') }
        }
    end

	-- Table row creation
    local ret = mw.html.create('tr')
            -- row-wide things
			:addClass(membinfo.class)
            :css('text-align','center')
            -- inventory image
			:tag('td')
				:addClass('inventory-image')
				:attr('data-sort-value',namesort(name,rare_sort))
				:wikitext(image)
            :done()
            -- item name
			:tag('td')
				:css('text-align','left')
				:addClass('item-col')
				:wikitext(string.format('[[%s|%s]]%s%s',name,altname,#namenotes > 3 and namenotes or '',imgmembs))
            :done()
            -- members
			:tag('td')
                :addClass('members-column')
                :attr('title', membinfo.title)
                :css(membinfo.style)
				:wikitext(membinfo.content)
            :done()
            -- quantity
			:tag('td')
				:attr('data-sort-value',_h)
				:wikitext(quantity)
            :done()
    
    -- rarity
	local rarity_cell = ret:tag('td')
	local rarity_span = rarity_cell:tag('span')
	rarity_span:wikitext(rarity)
	rarity_cell:attr('data-sort-value',rare_sort)
				:addClass(rare_class)
	if type(rarity_value) == 'number' then
		rarity_cell:attr('title', string.format('%.3g%%', 100 * rarity_value))
		rarity_span:attr({
			['data-drop-fraction'] = rarity,
			['data-drop-oneover'] = '1/' .. sigfigalt(1/rarity_value),
			['data-drop-percent'] = sigfig(100 * rarity_value, 3),
			['data-drop-permil'] = sigfig(1000 * rarity_value, 3),
			['data-drop-permyriad'] = sigfig(10000 * rarity_value, 3),
		})
	end
	if #raritynotes > 3 then
		rarity_cell:wikitext(raritynotes)
	end

    -- setup GE and alch cells
    local ge_td = ret:tag('td')
    local alch_td = ret:tag('td')

    -- common attributes
    ge_td   :attr('data-sort-value',vsort)
    :addClass('ge-column')
    :css({
        ['text-align'] = 'right',
        cursor = 'help'
    })
    alch_td :attr('data-sort-value',vsort)
            :addClass('alch-column')
            :css({
                ['text-align'] = 'right',
                cursor = 'help'
            })

    local ge_td_title, ge_td_content, alch_td_title, alch_td_content
    --Cases for the GE and alch values
    local smwValue = 0
    if isCoins then
        local coinsStr = lang:plural(vsort, '', 's')
		ge_td_title = mw.ustring.format(_priceStrings.ge.coins, total, coinsStr)
		ge_td_content = total
		alch_td_title = mw.ustring.format(_priceStrings.alch.coins, total, coinsStr)
		alch_td_content = total
    else
        if valueInfo.ge.has then
            if valueInfo.ge.from == 'alt' then
                local _img, _currency = nil,nil
                if valueInfo.ge.curr then
                    _img, _currency = currency(valueInfo.ge.curr,valueInfo.ge.value,vsort)
                end
                ge_td_title = mw.ustring.format(_priceStrings.ge.alt, commas(valueInfo.ge.value) or '', _currency or 'coin', lang:plural(valueInfo.ge.value or 0, '', 's'))
                ge_td_content = total .. (_img or _altval)
                smwValue = valueInfo.ge.value
            else
                ge_td_title = mw.ustring.format(_priceStrings.ge[valueInfo.ge.from], commas(valueInfo.ge.value), lang:plural(valueInfo.ge.value, '', 's'))
                ge_td_content = total
                if valueInfo.ge.from == 'alch' then
                	ge_td_content = ge_td_content .. _gealch
                	smwValue = valueInfo.ge.value
                end
            end
        end
        if valueInfo.alch.has then
            if valueInfo.alch.from == 'alt' then
                local _img, _currency = nil,nil
                if valueInfo.alch.curr then
                    _img, _currency = currency(valueInfo.alch.curr,valueInfo.alch.value,vasort)
                end
                alch_td_title = mw.ustring.format(_priceStrings.alch.alt, commas(valueInfo.alch.value) or '', _currency or 'coin', lang:plural(valueInfo.alch.value or 0, '', 's'))
                alch_td_content = alchtotal .. (_img or _altval)
            else
                alch_td_title = mw.ustring.format(_priceStrings.alch[valueInfo.alch.from], commas(valueInfo.alch.value), lang:plural(valueInfo.alch.value, '', 's'))
                alch_td_content = alchtotal
            end
        end
        
        if gemw and not valueInfo.ge.has then
            -- GEMW should be available but we didn't find it earlier
            ge_td_title = 'Página de mercado não encontrada para "'..name..'". Verifique novamente se o nome e os capitais do objeto são usados para o parâmetro "nome". Adicione "gemw = não" a esta predefinição se este objeto não puder ser negociado no Mercado Geral ou ignore este erro e aguarde a página de troca ser feita.'
            ge_td_content = '<span style="color:#FF0000; border-bottom:1px dashed; font-weight:bold;">Erro</span>'
        elseif ge_td_content == nil then
            -- nothing else triggered
            ge_td_content = 'Não vendido'
            ge_td_title = 'Este objeto não pode ser negociado no Mercado Geral nem alquimizado e não tem valor aplicável para exibir.'
            ge_td:css('color', '#999')
        end
        
        if alch and not valueInfo.alch.has then
            -- alch should be available but we didn't find it earlier
            alch_td_title = 'Valor de alquimia não encontrado para "'..name..'". Verifique novamente se o nome e os capitais do objeto são usados para o parâmetro "nome". Adicione "alch = não" a esta predefinição se este objeto não puder ser alquimizado ou ignore este erro e espere que a página de troca seja feita.'
            alch_td_content = '<span style="color:#FF0000; border-bottom:1px dashed; font-weight:bold;">Erro</span>'
        elseif alch_td_content == nil then
            -- nothing else triggered
            alch_td_content = 'Não alquimizável'
            alch_td_title = 'Este objeto não é alquimizável e não tem valor para mostrar.'
            alch_td:css('color', '#999')
        end
    end
    ge_td:wikitext(ge_td_content):attr('title', ge_td_title)
    alch_td:wikitext(alch_td_content):attr('title', alch_td_title)

	-- SMW
	if ns == '' then
		local smw = {}
		local smw_sub = {}
		local smw_done = false
		local smw_variant_pattern = '[%(]' -- things to apply the variant property to - if name matches this pattern, apply property
		-- check if applies to all or only a version
        local source = pgTitle
        local varSubobjs
		if #monVersT > 0 then
			--apply to specified versions
			varSubobjs = monVersT --only subobject id
			source = {}
			for _,v in pairs(monVersT) do
				local subobj = pgTitle..'#'..v --add pagename before subobject id
				table.insert(source, subobj)
			end
		end
		--add function to reduce image to File:Some name.png
		local smwImage = mw.text.encode(image)
		local smwNameNote = mw.text.killMarkers(namenotes)
		local smwQuantity = mw.text.killMarkers(quantity)
		smwQuantity = smwQuantity:gsub('<span class="dropsline%-noted">', '')
		smwQuantity = smwQuantity:gsub('</span>', '')
		smwQuantity = smwQuantity:gsub(',', '')
		smwQuantity = smwQuantity:gsub('&nbsp;', ' ')
		smwQuantity = smwQuantity:gsub(';', ',')
		local smwRarityNote = mw.text.killMarkers(raritynotes)
		local subcount = 1
		if VariablesLua.varexists( 'dropcount' ) then
			subcount =	VariablesLua.var( 'dropcount', 1 )
			subcount = subcount + 1
			VariablesLua.vardefine( 'dropcount', subcount)
		else
			VariablesLua.vardefine( 'dropcount', 1)
		end
		local subname = 'DROP_'..smwname..'_'..smwQuantity..'_'..rarity..'_'..subcount
        if smwjson == true then
            smw_sub = {['Imagem do objeto largado']=smwImage, ['Objeto largado']=smwname, ['Texto do objeto largado']=altname, ['Notas de nome']=smwNameNote, ['Quantidade largada']=smwQuantity, ['Quantidade máxima']=_h, ['Quantidade mínima']=_l, Raridade=rarity, ['Tipo de raridade']=100/(tonumber(rare_sort) or 1), ['Notas de raridade']=smwRarityNote}
            local smwparams = dropType[tempArgs.dtype] or dropType.drop
            smw_sub[smwparams[1]] = source
            smw[smwparams[2]] = name
            if name:find(smw_variant_pattern) then
                smw[smwparams[3]] = name
            end
            if string.match(raritynotes, 'UNIQ%-%-ref') then
            	smw_sub['Notas de raridade Ref'] = true
            end
            if string.match(quantity, 'UNIQ%-%-ref') then
            	smw_sub['Notas de quantidade Ref'] = true
            end
			if smwValue > 0 then
				smw_sub['Valor do Objeto Largado'] = smwValue
			end
			if tempArgs.dtype == 'fishing' and level > 0 then
				smw_sub['Nível de Pesca'] = level
			end
			if tempArgs.dtype == 'archaeology' and level > 0 then
				smw_sub['Nível de Arqueologia'] = level
			end
			if tempArgs.dtype == 'mining' and level > 0 then
				smw_sub['Nível de Mineração'] = level
			end
			if tempArgs.dtype == 'woodcutting' and level > 0 then
				smw_sub['Nível de Corte de Lenha'] = level
			end
			if tempArgs.dtype == 'divination' and level > 0 then
				smw_sub['Nível de Divinição'] = level
			end
            smw_done = true
		elseif smwjson == 'rdt' then
			smw_sub = {['Imagem do objeto largado']=smwImage, ['Objeto largado da RDT']=smwname, ['Texto do objeto largado']=altname, ['Notas de nome']=smwNameNote, ['Quantidade largada']=smwQuantity, ['Quantidade máxima']=_h, ['Quantidade mínima']=_l, Raridade=rarity, ['Tipo de raridade']=100/(tonumber(rare_sort) or 1), ['Notas de raridade']=smwRarityNote}
			if tempArgs.dtype and string.lower(tempArgs.dtype) == 'thieving' then
				smw_sub['RDT saqueado de'] = source
			elseif tempArgs.dtype and string.lower(tempArgs.dtype) == 'reward' then
				smw_sub['RDT recompensado de'] = source
			else
				smw_sub['RDT largado de'] = source
			end
			smw['Objeto largado da RDT'] = name
			if name:find(smw_variant_pattern) then
				smw['Variante de objeto largado da RDT'] = name
			end
			if string.match(raritynotes, 'UNIQ%-%-ref') then
				smw_sub['Notas de raridade Ref'] = true
			end
			if string.match(quantity, 'UNIQ%-%-ref') then
				smw_sub['Notas de quantidade Ref'] = true
			end
			if smwValue > 0 then
				smw_sub['Valor do objeto largado'] = smwValue
			end
			smw_done = true
		end
		if smw_done then
			if type(source) == 'string' then
				-- no variants, source is pagetitle
				mw.smw.set(smw) -- add data to page
				mw.smw.subobject(smw_sub, subname) -- add drop-subobject to page
			else
				-- variants, source contains applicable varints
				mw.smw.subobject(smw_sub, subname) -- drop is subobject of page
				for _,v in pairs(varSubobjs) do
					mw.smw.subobject(smw, v) -- add data to variant-subobject
				end
			end
		end
	end
	
	return tostring(ret)
end

function qty(quantity)
	-- if no quantity is given, return unknown
	if string.lower(quantity) == 'varia' then
		return 'Varia'
	end
	if not quantity or string.lower(quantity) == 'desconhecido' then
		return 'Desconhecido'
	end
	-- en dashes are the proper dash for number ranges
	-- replace all hyphens and em dashes with en
	-- strip *all* whitespace
	-- change '(notas)' to '$n' for parsing
	quantity = mw.ustring.gsub(quantity,'[-—]','–')
		:gsub('%s','')
		:gsub('%(notas%)','$n')
	-- split list into table
	local vals = mw.text.split(quantity,'[,;]')
	local low = 2147483648
	local high = 0
	-- recreate the quantity string to ensure consistent formatting
	local numstr = {}
	for i, v in ipairs(vals) do
		local clean = v:gsub('$n','')
		-- if list element contains an en dash (indicating range)
		-- Find the smaller/larger number (just in case)
		-- Compare them to the current min/max
		-- put them in order with desired format
		if mw.ustring.find(v,'–') then
			local splitvals = mw.text.split(clean,'–')
			-- assume a is smaller, b is larger
			local a = tonumber(splitvals[1])
			local b = tonumber(splitvals[2])
			-- Just in case
			if a > b then
				a,b = b,a
			end
			if a < low then
				low = a
			end
			if b > high then
				high = b
			end
			local addx = commas(a)..'–'..commas(b)
			if v:find('$n') then
				addx = addx.._noted
			end
			table.insert(numstr,addx)
		else
			local a = tonumber(clean)
			if a < low then
				low = a
			end
			if a > high then 
				high = a
			end
			local addx = commas(a)
			if v:find('$n') then
				addx = addx.._noted
			end
			table.insert(numstr,addx)
		end
	end
	-- Add a line break if there are too many elements
	-- To keep the tables thin
	if #numstr > 11 then
		local mid = math.floor(#numstr/2)
		numstr[mid] = '<br/>'..numstr[mid]
	end
	-- To prevent any possible confusion with formatted numbers
	-- elements should be separated with semicolons followed by a space
	numstr = table.concat(numstr,'; ')
	-- If no numbers are found in the string, return unknown
	if not numstr:find('%d') then
		return 'Desconhecido', price
	end

	return numstr, high, low
end

function get_total(value,qhigh,qlow)
	-- if no alch value is given, return unknown
	if not value or string.lower(value) == 'unknown' then
		return value
	end
	-- if value is negative (from smw/ge) it cannot be alched
	if tonumber(value) and tonumber(value) < 0 then
		return false
	end
	-- if no numbers return Não alquimizável
	if not tonumber(value) and not value:find('%d') then
		return false
	end

	-- en dashes are the proper dash for number ranges
	-- replace all hyphens and em dashes with en
	-- strip *all* whitespace
	value = mw.ustring.gsub(value,'[-—]','–')
		:gsub('%s','')
	-- split list into table
	local vals = mw.text.split(value,'[,;]')
	-- All value ranges will be a range
	-- e.g. if items valued at 100 coins are dropped in quantities of 1, 3, 5
	-- the value returned will be 100–500 rather than 100; 300; 500
	-- If low and high vars are the same in the end, only 1 value is displayed
	local low = 2147483648
	local high = 0
	-- recreate the alchval string to ensure consistent formatting
	for i, v in ipairs(vals) do
		local clean = v:gsub('$n','')
		-- if list element contains an en dash (indicating range)
		-- Find the smaller/larger number (just in case)
		-- Compare them to the current min/max
		-- put them in order with desired format
		if mw.ustring.find(v,'–') then
			local splitvals = mw.text.split(clean,'–')
			-- assume a is smaller, b is larger
			local a = tonumber(splitvals[1])
			local b = tonumber(splitvals[2])
			-- Just in case
			if a > b then
				a,b = b,a
			end
			if a < low then
				low = a
			end
			if b > high then
				high = b
			end
		else
			local a = tonumber(clean)
			if a < low then
				low = a
			end
			if a > high then 
				high = a
			end
		end
	end

	local valret, sort
	if not qhigh or not qlow then
		sort = high
		valret = commas(high)
	else
		local lower = qlow * low
		local higher = qhigh * high
		if higher == lower then
			valret = commas(higher)
		else
			valret = commas(lower)..'-'..commas(higher)
		end
		sort = higher
	end

	return valret, sort
end

-- function to get the currency image and name (singular vs plural)
function currency(altcur,price,total)
	price = tostring(price)
	total = tostring(total)
	-- body
	local lowcur = string.lower(altcur)
	local clean = price:gsub('%W','')
	local retcur, img
	if tonumber(clean) and tonumber(clean) ~= 1 then
		retcur = altcur
	else
		if lowcur == 'zemomarcos' or lowcur == 'tokkul' or lowcur == 'teci' then
			retcur = altcur
		elseif lowcur == 'peças de oito' then
			retcur = 'peças de oito'
		else
			retcur = string.sub(altcur,1,(string.len(altcur)-1))
		end
	end
	img = curr_image(altcur,total) or 'AltValue.png'
	img = '<span class="dropsline-altval style="margin-left:0.3em;">[[Arquivo:'..img..'|link=|frameless|20px]]</span>'
	return img, retcur
end

-- match -> category
-- pattern matching allowed
-- all lowercase
-- DO NOT INFLATE THIS TABLE
-- If a specific item does not fall into the category you want it to
-- then oh well
-- get over it
-- if items fall into a category they shouldn't, that's fine too
-- these aren't directly visible and are only used a rough sort
local sortnames = {
	runes = { 'runa ' },
	talismans = { 'talismã' },
	armour = { 'cota de placa', 'perneiras', 'escarcela', 'elmo', 'escudo ogival', 'escudo ', 'luvas', 'botas', 
			'malha', 'capa', 'couraça', 'manoplas' },
	weapons = { 'machado', 'espada', 'cajado', 'dardo longo', 'arco', 'machado', 'varinha', 'lança', 'alabarda', 'garra',
			'maça', 'martelo de guerra', 'chicote', 'adaga', 'arremesso', 'dardo', '^hasta', 'cimitarra' },
	ammunition = { 'flecha', 'seta', 'piche de guam', 'piche de tarromin', 'piche de harralander' },
	logs = { 'lenha' },
	herbs = { ' sujo$', ' limpo$' },
	seeds = { 'semente', 'esporo' },
	spirits = {'^espirito da pedra de'},
	ores = { '^minério ', 'carvão' },
	bars = { '^barra ' },
	gems = { 'brut' },
	raw = { 'cru' },
	potions = { 'poção ', 'antiveneno', 'soro', 'calmante de guthix', 'equilíbrio de guthix', 'óleo', 'azeite', 'explosivo de pesca', 'superataque',
			'frasco de fedor', 'superenergia', 'superforça', 'super-restauradora', 'supercaçador', 'superdefesa', 'antifogo',
			'superdivinação', 'veneno de arma', 'super criador de runas', 'preparado de zamorak', 'caçador extremo', 'preparado de saradomin',
			'superinvenção', 'extremo ataque', 'extrema força', 'divinação extrema', 'extrema defesa', 'extrema magia',
			'criador de runas extremo', 'extremo arqueiro', 'superdevoto', 'renovação', 'invenção extrema', 'sobrecarregamento', 'mistura',
			'bálsamo sobrecarreg.' },
	salvage = {'reaproveitável'}, -- don't think there's any other drops with word salvage in them
	teleport = { 'teleporte' },
	godpage = { '^antigo, página %d', '^bandos, página %d', '^armadyl, página %d', '^zamorak, página %d', '^guthix, página %d', '^saradomin, página %d' }, -- God book pages
	['!!ossos'] = {'ossos', 'cinzas hereges', 'cinzas malditas', 'cinzas infernais', 'cinzas torturadas', 'cinzas abrasadoras'},
	-- Sorting of common items to consistent places
	-- sort rare drop table to back
	zzz = { 'tabela de objetos raros' },
	-- sort wilderness shared loot table to back
	zzzz = { 'tabela comum da terra selvagem' },
	-- sort coins to front
	['!!!'] = { '^moedas' },
}

-- adds a category in front of the name to give it a slightly improved sorting function
function namesort(arg,rarg)
	local arg = string.lower(arg or '')
	local cat = '!other' -- "!" to keep in front

	for w, v in pairs(sortnames) do
		for _, x in ipairs(v) do
			if mw.ustring.match(arg,x) then
				cat = w
				break
			end
		end
	end

	return string.format('%s %s %s',cat,rarg,arg)
end

-- adding categories to mainspace
function categories(...)
	local name,quantity,rarity = unpack(...)
	local ret = ''
	name = name:lower()
	quantity = quantity:lower()
	if name:find('efígie') then
		ret = ret .. '[[Categoria:Monstros que largam efígies]]'
	elseif name:find('pergaminho lacrado ') then
		ret = ret .. '[[Categoria:Monstros que largam pergaminhos de dicas]]'
	elseif name:find('rare drop table') then
		ret = ret .. '[[Categoria:Monstros com acesso a tabela de objetos raros]]'
	elseif name:find('wilderness shared loot table') then
		ret = ret .. '[[Categoria:Monstros com acesso a tabela comum da Terra Selvagem]]'
	end
	if not rarities[rarity:lower()] then
		ret = ret .. '[[Categoria:Precisa de raridade]]'
	end
	if quantity:find('Desconhecido') then
		ret = ret .. '[[Categoria:Precisa de quantidade]]'
	end
	return ret
end

return p
-- </nowiki>