Module:Average drop value
Documentation for this module may be created at Module:Average drop value/doc
local curr = require('Module:Currency')._amount
local dpl = require('Module:DPLlua')
local geprices = mw.loadJsonData('Module:GEPrices/data.json')
local p = {}
function calcValue(item, lowqty, highqty, rarity, rolls, alchprice, alchonly, options)
local avgqty = (tonumber(lowqty) + tonumber(highqty)) / 2
local rar_good, price
-- parse price
local i_lo = item:lower()
if i_lo == 'brimstone key' and options.brimstone ~= nil then
if alchonly then
price = tonumber(mw.getCurrentFrame():preprocess('{{KDTAlchValue}}'))
else
price = tonumber(mw.getCurrentFrame():preprocess('{{KDTValue}}'))
end
elseif (i_lo == 'larran\'s key' or i_lo == 'slayer\'s enchantment') and options.wildernessslayer == nil then
price = 0
elseif i_lo == 'ecumenical key' then
price = 0
elseif alchonly then
price = alchprice or 0
else
-- strip '#' or replace w/ a space for lookup
-- 'Prayer potion#(4)' to 'Prayer potion(4)'
-- 'Iron dart#(p)' to 'Iron dart (p)'
price = geprices[item:gsub('#','')] or geprices[item:gsub('#',' ')] or alchprice or 0
end
if not price then
mw.log('0 price for '..item)
return 0
end
-- parse rarity
if rarity:lower() == 'always' then
rarity = 1
else
rarity = rarity:gsub(',', '')
rar_good, rarity= pcall(mw.ext.ParserFunctions.expr, rarity)
if not rar_good then
mw.log('0 rarity for '..item)
return 0
end
rarity = tonumber(rarity)
if not rarity then
mw.log('0 rarity for '..item)
return 0
end
end
local val = price * avgqty * rarity * rolls
mw.log(string.format('item %s: %s * %s * %s * %s = %s', item, price, lowqty, rarity, rolls, val))
return val
end
function _DPLcontains(arr,s)
for k, v in ipairs(arr) do
if v == s then return true end
end
return false
end
function p.getDropData(mob)
--modified from loadData in [[Module:Bestiary]]
query = function(x) --anonymous function to generate query for mob x
return{
'[[Dropped from::'..x..']]',
'?Drop JSON',
limit = 500
}
end
local smw = {}
if smw and smw ~= {} and smw ~='' then
return smw --drops were successfully retrieved for the mob
end
--failed to retrieve drops for mob, fall back to mobroot (e.g. 'Barbarian' rather than 'Barbarian#level 8')
mobroot, _ = mob:match('([^#]*)#?(.*)') -- not ideal that this is repeat code however it removes the need for the mobs table
if mobroot ~= mob then
smw = mw.smw.ask(query(mobroot))
if smw and smw ~= {} and smw ~='' then
return smw --data was successfully retrieved for the mobroot
end
end
--failed to retrieve drops for mob log error
local errorstring = string.format("Failed to retrieve drops for %s%s",mob,mobroot~=mob and ' or ' .. mobroot or '')
mw.log(errorstring)
return smw
end
function p.totalvalfromdata(data,itemOptions,category, categoryFilter, exclude, excludeFilter, alchonly)
--used in [[Module:Bestiary]] too
if (not data) or data == {} or data =='' then
return '?'
end
local totalval = 0
local options = itemOptions or {}
for i,v in ipairs(data) do
local j = mw.text.jsonDecode(v['Drop JSON'] or '{}')
if (not category) or _DPLcontains(categoryFilter,j['Dropped item']) then
if (not exclude) or (not _DPLcontains(excludeFilter,j['Dropped item'])) then
totalval = totalval + calcValue(j['Dropped item'], j['Quantity Low'], j['Quantity High'], j['Rarity'], j['Rolls'], j['Drop Value'], alchonly, options)
end
end
end
return totalval
end
function p.totalval(mob, itemOptions, category, categoryFilter, exclude, excludeFilter, alchonly)
local data = p.getDropData(mob)
return p.totalvalfromdata(data,itemOptions,category, categoryFilter, exclude, excludeFilter, alchonly)
end
function p.main(frame)
return p._main(frame, frame:getParent().args)
end
function p._main(frame, args)
local pageName = mw.title.getCurrentTitle().text
local mob = ''
if args.mob or args[1] then
mob = args.mob or args[1]
else
mob = pageName
end
local mobname = mob
local mobroot, moblevel = mob:match('([^#]*)#?(.*)')
if args.mobname then
mobname = args.mobname
elseif moblevel ~= "" then
mobname = string.format('%s (%s)',mobroot, moblevel)
end
if mobroot ~= pageName then --link to the mob if it's from a different page
mobname = string.format('[[%s|%s]]',mobroot,mobname)
end
local alchstr = ''
local worthstr = ''
if args.alch then
alchstr = 'high alch value of a'
else
worthstr = 'worth '
end
local killname = args.killname or 'kill'
local itemOptions = {
brimstone = args.brimstone,
wildernessslayer = args.wildernessslayer
}
local categoryFilter = {}
local excludeFilter = {}
local catReportString = ""
filter = function(cat)
return dpl.ask({
namespace = '',
ignorecase = 'true',
category = cat,
allowcachedresults = 'true'
})
end
if args.category then
categoryFilter = filter(args.category)
catReportString = 'counting only '..(args.category:lower())..' '
end
if args.exclude then
excludeFilter = filter(args.exclude)
catReportString = catReportString..'excluding all '..(args.exclude:lower())..' '
end
local totalval = p.totalval(mob, itemOptions, args.category,
categoryFilter, args.exclude, excludeFilter, args.alch)
if totalval == '?' then --failed
return ''
end
if args.round then
totalval = math.floor(totalval)
end
if args.raw then
return totalval
end
local brimString = args.brimstone ~= nil and ' while on a [[Konar]] task' or ''
local wildyString = args.wildernessslayer ~= nil and ' while on a [[Krystilia]] task' or ''
local coinString = curr(totalval, 'coins')
return string.format('The average %s %s %s%s%s %sis %s%s.',
alchstr, mobname, killname, brimString, wildyString, catReportString, worthstr, coinString)
end
return p