Module:Fishing chance calculator
Documentation for this module may be created at Module:Fishing chance calculator/doc
local data = mw.loadData('Module:Fishing chance calculator/data')
local geprices = mw.loadData('Module:GEPrices/data')
local yn = require('Module:Yesno')
local pt = require('Module:Paramtest')
local p = {}
local lang = mw.getContentLanguage()
function plink(link, image, text)
if text == nil then
text = link
end
if image == nil then
image = link
end
return string.format('[[File:%s.png|link=%s]] [[%s|%s]]', image, link, link, text)
end
function plinkT(x)
return plink(x.link, x.image, x.text)
end
function jagexInterpolation(hi, lo, lvl)
return math.floor( ( (99-lvl)*lo + (lvl-1)*hi ) / 98 )
end
function multifloor(x, m)
local _x = x
for i,v in ipairs(m) do
_x = math.floor( _x * v )
end
return _x
end
function gep(x)
return geprices[x] or 0
end
function fnum(num, dp)
local ret = math.pow(10, dp) * num + 0.5
ret = math.floor(ret)
ret = math.pow(10, -dp) * ret
return lang:formatNum(ret)
end
function perc(x)
return fnum(x*100,1)..'%'
end
function p.makeSimpleTable()
local t = mw.html.create('table')
t:addClass('wikitable sortable mw-collapsible mw-collapsed align-center-1 align-center-3 align-center-4 align-right-6 align-right-7')
:tag('caption'):wikitext('Fish high- and lowchances'):done()
:tag('tr')
:tag('th'):wikitext('Order'):done()
:tag('th'):wikitext('Fish'):done()
:tag('th'):wikitext('Level'):done()
:tag('th'):wikitext('Base XP'):done()
:tag('th'):wikitext('Fishing spot'):done()
:tag('th'):wikitext('Lowchance'):done()
:tag('th'):wikitext('Highchance'):done()
for i,v in ipairs(data) do
t:newline()
t:tag('tr')
:tag('td')
:wikitext(i)
:done()
:tag('td')
:wikitext(plinkT(v))
:done()
:tag('td')
:wikitext(v.level)
:done()
:tag('td')
:wikitext(v.xp)
:done()
:tag('td')
:wikitext(lang:ucfirst(v.spot or v.text))
:done()
:tag('td')
:wikitext(v.low)
:done()
:tag('td')
:wikitext(v.high)
:done()
end
t:newline()
return t
end
function p.calculator(frame)
return p._calculator(frame:getParent().args)
end
function p.calculator_notemplate(frame)
return p._calculator(frame.args)
end
local multipliers_list = {
skillchompa = {
cobalt = 1.01,
viridian = 1.02,
azure = 1.03,
crimson = 1.04,
crystal = 1.05
},
aura = {
basic = 1.03,
greater = 1.05,
master = 1.07,
supreme = 1.1,
legendary = 1.15
},
outfit = {
shark = 1.05,
['fury shark'] = 1.07
},
rod = {
['crystal rod'] = 1.05,
["tavia's rod"] = 1.1,
["tavia's rod"] = 1.1
},
ring = 1.03,
dsf = 1.1,
juju = 1.05,
menaphos = 1.1,
familiar = {
['granite crab'] = 1,
['ibis'] = 3,
['granite lobster'] = 4
}
}
function p._calculator(args)
local level = tonumber(args.level) or 99
local spots = {}
local spots_order = {}
-- setup multipliers
local hi_multipliers = {}
local lo_multipliers = {}
local xp_multipliers = {}
-- if table.insert(t, nil) is a noop
for i,v in ipairs({ 'rod', 'skillchompa', 'outfit', 'aura' }) do
if pt.has_content(args[v]) then
table.insert(hi_multipliers, multipliers_list[v][string.lower(args[v])])
end
end
for i,v in ipairs({'ring', 'juju', 'dsf'}) do
if yn(args[v]) then
table.insert(hi_multipliers, multipliers_list[v])
end
end
-- only applies to menaphos fish
local menaphos = {}
if yn(args.menaphos) then
menaphos = { multipliers_list.menaphos }
end
-- both hi and low
local _h = tonumber(args.honed) or 0
local honed = 0
if _h > 0 then
honed = 1 + 0.02 * _h
end
-- familiar is special
local familiar = 0
if pt.has_content(args.familiar) then
familiar = multipliers_list.familiar[string.lower(args.familiar)] or 0
end
local is_gws_toggled = yn(args.gws_toggle)
--[==[
-- undecided if i want to add this, since i then should really add all of the other xp multipliers and there's a lot
if (tonumber(args.xpoutfit) or 0) > 0 then
if tonumber(args.xpoutfit) >= 4 then
table.insert(xp_multipliers, 1.05)
else
table.insert(xp_multipliers, 1+(0.01*tonumber(args.xpoutfit)))
end
end
--]==]
-- filter into spot-groupings of the relevant things based on level
for i,v in ipairs(data) do
local addSpot = level >= v.level
if v.is_gws_toggle then
addSpot = addSpot and is_gws_toggled
end
if addSpot then
local spotName = v.spot or v.name
if spots[spotName] == nil then
spots[spotName] = { v }
table.insert(spots_order, spotName)
else
table.insert(spots[spotName], v)
end
end
end
-- construct output table
local ret = mw.html.create('table')
ret:addClass('wikitable sortable sticky-header align-right-3 align-right-4 align-right-5 align-right-6 align-right-7')
:tag('tr')
:tag('th'):wikitext('Spot'):done()
:tag('th'):wikitext('Available fish'):done()
:tag('th'):wikitext('Fish XP'):done()
:tag('th'):wikitext('Fish chance'):done()
:tag('th'):wikitext('Fish/hr'):done()
:tag('th'):wikitext('Overall XP/hr'):done()
:tag('th'):wikitext('Overall GP/hr'):done()
ret:newline()
for i,v in ipairs(spots_order) do
local tr = ret:tag('tr')
tr:tag('td'):wikitext(lang:ucfirst(v))
local info = { links={}, xps={}, rawchance={}, actualchance={}, fchance = {}, fph = {} }
local rollingChance = 0
local delay = spots[v][1].delay or 4
local totalGPH = 0
local totalXPH = 0
for j,u in ipairs(spots[v]) do
table.insert(info.links, plinkT(u))
table.insert(info.xps, u.xp)
local newHi = multifloor(u.high, hi_multipliers)
if u.is_menaphos then
newHi = multifloor(newHi, menaphos)
end
local newLo = multifloor(u.low, lo_multipliers)
if honed > 0 then
newHi = math.ceil( newHi * honed )
newLo = math.ceil( newLo * honed )
end
if familiar > 0 then
local fambuff = math.floor( familiar * math.floor(10*(u.high-u.low)/98) /10 )
newHi = newHi + fambuff
newLo = newLo + fambuff
end
local rawchance = jagexInterpolation(newHi, newLo, level)
table.insert(info.rawchance, rawchance)
local newRollingChance = (1-rollingChance) *math.max(math.min(rawchance/256, 1), 0)
table.insert(info.actualchance, newRollingChance)
table.insert(info.fchance, perc(newRollingChance))
local fph = 3600/(u.delay or 4) * newRollingChance
table.insert(info.fph, fnum(fph, 0))
totalGPH = totalGPH + fph * gep(u.ge or u.link)
totalXPH = totalXPH + fph * u.xp
rollingChance = rollingChance + newRollingChance
end
if (1-rollingChance) > 0 then
table.insert(info.links, "''Nothing''")
table.insert(info.xps, "''0''")
table.insert(info.rawchance, 255)
table.insert(info.actualchance, string.format("''%s''", 1-rollingChance))
table.insert(info.fchance, string.format("''%s''", perc(1-rollingChance)))
table.insert(info.fph, string.format("''%s''", fnum(3600/(delay or 4) * (1-rollingChance), 0)))
end
tr:tag('td'):wikitext(table.concat(info.links, '<br>')):done()
:tag('td'):wikitext(table.concat(info.xps, '<br>')):done()
:tag('td'):wikitext(table.concat(info.fchance, '<br>')):done()
:tag('td'):wikitext(table.concat(info.fph, '<br>')):done()
:tag('td'):wikitext(fnum(totalXPH, 1)):done()
:tag('td'):wikitext(fnum(totalGPH, 0)):done()
ret:newline()
mw.logObject(info)
end
return ret
end
return p