Module:Disassembly junk calculator
Documentation for this module may be created at Module:Disassembly junk calculator/doc
-- <nowiki>
-- code for [[Template:Disassembly material calculator/t]]
-- and [[Template:Disassembly material calculator/t2]]
-- -> [[Calculator:Disassembly by material]]
-- test changes using [[Module:Disassembly material calculator/sandbox]]
local p = {}
local yesno = require('Module:Yesno')
local cats = mw.loadData('Module:Disassemble/data')
local materials = mw.loadData('Module:Disassemble/mats')
local exg = require('Module:ExchangeLite')
local coin = require('Module:Coins')._amount
local info = mw.loadData('Module:Disassembly category calculator/data') -- versioning info here
local commas = require('Module:Addcommas')._add
local Title = mw.title.getCurrentTitle()
local function gep(item)
item = info.gemwnames[item] or info.names[item] or item
local val = exg.price(item)
local err2, limit = pcall(exg.load, {item = item, dataType = 'limit'})
if val ~= nil then
if err2 then
return val, limit
else
return val, 0
end
else
return 0, -1
end
end
local function img(item)
return info.imgnames[item] or info.names[item] or item
end
local function junk(lv)
local junkpast75 = {
[75] = 4.2, [76] = 3.8, [77] = 3.4, [78] = 3.0, [79] = 2.7,
[80] = 2.3, [81] = 2.0, [82] = 1.7, [83] = 1.4, [84] = 1.2,
[85] = 1.0, [86] = 0.8, [87] = 0.6, [88] = 0.4, [89] = 0.3 }
lv = tonumber(lv) or 1
if lv >= 90 then
return 0
elseif lv >= 75 then
return junkpast75[lv]
else
return 100 - 1.1 * lv
end
end
local function plink(page, name, img)
return string.format('[[File:%s.png|link=%s]] [[%s|%s]]', img, page, page, name)
end
local function coins(td, am)
if am == 0 then
td :wikitext("''N/A''")
:addClass('table-na')
else
td :wikitext(coin(am, false))
end
td :attr('data-sort-value', am)
end
local function round(n)
-- significant figure funciton
-- only applies to numbers < 1
local function sigfig(n, f)
f = math.floor(f)
if n > 1 or f < 1 then
return n
end
local prec = 0
for i = 3, 10, 1 do
if n * 10^i >= 1 then
prec = i + f - 2
break
end
end
if prec == 0 then
return 0
end
return string.format('%.' .. prec .. 'f', n)
end
if n >= 10 then
return string.format('%.1f', n)
elseif n >= 0.1 then
return string.format('%.2f', n)
else
return sigfig(n, 2)
end
end
-- non-special mat row
-- item | cqty | junk | price per dis | buy limit | chance of mat per nonjunk | overall chance per item | cost per mat | mats per hour
local function make_row(data)
local tr = mw.html.create('tr')
local junkperdis = 0
local val = {}
local str
if data.iqty > 1 then
str = string.format('%s %s %s', data.iqty, '×', plink(data.page, data.name, data.img))
else
str = plink(data.page, data.name, data.img)
end
junkperdis = data.junk/100 * data.cqty
local priceperdis = data.price * data.iqty
val.base = priceperdis / junkperdis
val.matsperhour = 3000 * junkperdis
--round to 0dp if >100, else 2dp
for i,v in pairs(val) do
if v < 100 then
val[i] = string.format("%.2f", v)
else
val[i] = string.format("%.0f", v)
end
end
-- TODO: javascript support
tr :attr({
['data-dis-mats'] = data.cqty,
['data-dis-junk'] = data.junk,
['data-dis-price'] = priceperdis,
['data-dis-raw'] = 100,
})
:addClass('dis-calc-row')
:tag('td')
:css('text-align','left')
:wikitext(str)
:attr('data-sort-value', data.name)
:done()
:tag('td')
:wikitext(data.cqty)
:attr('data-sort-value', data.cqty)
:done()
:tag('td')
:wikitext(string.format('%.1f%%', data.junk))
:attr('data-sort-value', data.junk)
:addClass('data-dis-junkcell')
:done()
coins(tr:tag('td'), priceperdis)
if tonumber(data.limit) and data.limit > 0 then
tr :tag('td')
:attr('data-sort-value', data.limit)
:wikitext(commas(data.limit))
:done()
elseif tonumber(data.limit) and data.limit < 0 then
tr :tag('td')
:attr('data-sort-value', 0)
:wikitext("''N/A''")
:addClass('table-na')
:done()
else
tr :tag('td')
:attr('data-sort-value', 0)
:wikitext("''Unknown''")
:done()
end
tr :tag('td')
:attr('data-sort-value', junkperdis)
:wikitext(junkperdis)
:addClass('data-dis-chancecell-junkcalc')
:done()
local costtd = tr:tag('td')
costtd:addClass('data-dis-costcell-junkcalc')
coins(costtd, val.base)
tr :tag('td')
:attr('data-sort-value', val.matsperhour)
:wikitext(commas(val.matsperhour))
:addClass('data-dis-mphcell-junkcalc')
:done()
return tostring(tr)
end
-- special case: potions
-- cqty does not vary, it might actually idk
local function potion(data)
local rows = {}
if data.calcvalue and data.calccomp then
data.name = string.format('%s (%s)', data.page, data.calccomp)
data.img = img(data.name)
data.cqty = data.calccomp
data.price = data.calcvalue
data.limit = -1
return make_row(data)
end
-- setup 6-dose
data.name = data.page .. ' (6)'
data.img = img(data.name)
data.cqty = 6
data.price, data.limit = gep(data.name)
if data.price > 0 then
-- if 6-dose has a price, then this is a flask; only show 6 dose (5 and lower not GE-able)
return make_row(data)
else
data.name = data.page .. ' (4)'
data.price, data.limit = gep(data.name)
if data.price > 0 then
-- if 4 dose has a price, this is a 4-dose vial
for i = 4, 1, -1 do
data.name = string.format('%s (%s)',data.page,i)
data.img = img(data.name)
data.cqty = i
data.price, data.limit = gep(data.name)
table.insert(rows, make_row(data))
end
else
-- if 4 dose does not have a price, this is a 2-dose mix
for i = 2, 1, -1 do
data.name = string.format('%s (%s)',data.page,i)
data.img = img(data.name)
data.cqty = i
data.price, data.limit = gep(data.name)
table.insert(rows, make_row(data))
end
end
return table.concat(rows, '\n')
end
end
-- main parsing function and module entry point
p._main = function (args)
local cat = cats[string.lower(args.category)]
if not cat then
return ''
end
local data = {}
local rows = {}
local pot = args.potion or cat.potion or false
pot = string.lower(tostring(pot))
data.iqty = tonumber(cat.itemqty) or 1
data.page = args['%PAGE%']
data.junk = junk(args.level)
if data.junk == 0 then
return ''
end
-- defaults
data.cqty = tonumber(cat.compqty) or 1
data.name = data.page
data.img = img(data.page)
data.calcvalue = tonumber(args.calcvalue) or nil
data.calccomp = tonumber(args.calccomp) or nil
if yesno(pot) then
return potion(data)
end
if info.versions[args['%PAGE%']] then
for i,v in ipairs(info.versions[args['%PAGE%']]) do
data.name = v
if data.calcvalue then
data.price, data.limit = data.calcvalue, -1
else
data.price, data.limit = gep(v)
end
data.img = img(v)
table.insert(rows, make_row(data))
end
return table.concat(rows, '\n')
else
if data.calcvalue then
data.price, data.limit = data.calcvalue, -1
else
data.price, data.limit = gep(data.page)
end
return make_row(data)
end
end
-- normal component entry point
p.main = function(frame)
return p._main(frame:getParent().args)
end
return p