Module:Skilling success chart/Sandbox
Documentation for this module may be created at Module:Skilling success chart/Sandbox/doc
local chart = require( 'Module:Chart data' )
local p = {}
function interp(low, high, level)
local value = math.floor(low*(99-level)/98 + high*(level-1)/98 + 0.5) + 1
return math.min(math.max(value / 256, 0), 1)
end
function oldInterp(low, high, level)
local value = math.modf(low*(99-level)/98) + math.modf(high*(level-1)/98) + 1
return math.min(math.max(value / 256, 0), 1)
end
function bonusInterp(low, high, bonuslow, bonushigh, level)
local value = interp(low, high, level)
return value + (1-value)*interp(bonuslow, bonushigh, level)
end
function exponentInterp(low, high, exponent, level)
return interp(low, high, level) ^ exponent
end
function cascadeInterp(bounds, level, index)
local rate = 1.0
for i, v in ipairs(bounds) do
local low = (level >= v.altreq) and v.altlow or v.low
local high = (level >= v.altreq) and v.althigh or v.high
if i == index then
rate = rate * interp(low, high, level)
return rate
end
if level >= v.req then
rate = rate * (1 - interp(low, high, level))
end
end
end
function birdhouseInterp(high, level)
local level = math.max(50, level)
local value = math.modf(high*(level-1)/98)
return value / 1000
end
function ctsYield(low, high, level, lives)
return lives / (1-interp(low, high, level))
end
function scriptInterp(low, high, level)
local value = math.modf(low*(99-level)/98 + high*(level-1)/98)
return math.min(math.max(value / 256, 0), 1)
end
function caviarInterp(level, denom)
return math.min(level, denom) / denom
end
function p._calculateDataSets(args)
local dataSets = {}
local inputs = {}
local i = 1
while args['label' .. i] do
table.insert(inputs, {
label = args['label' .. i],
low = args['low' .. i] or 0,
high = args['high' .. i],
bonuslow = args['bonuslow' .. i] or nil,
bonushigh = args['bonushigh' .. i] or nil,
altlow = args['altlow' .. i] or args['low' .. i] or 0,
althigh = args['althigh' .. i] or args['high' .. i],
altreq = tonumber(args['altreq' .. i] or math.huge),
denom = args['denom' .. i],
req = tonumber(args['req' .. i] or 1),
image = args['image' .. i] or 'hi',
color = args['color' .. i] or '',
exponent = args['exponent' .. i] or 1,
lives = args['lives' .. i] or 0
})
i = i + 1
end
args.lowLevel = tonumber(args.lowLevel or 1)
args.highLevel = tonumber(args.highLevel or 99)
for i, input in ipairs(inputs) do
local cutoffLevel = nil
local data = {}
for x = 1, input.req do
local y
if args.cascade then
y = cascadeInterp(inputs, x, i)
elseif args.birdhouse then
y = birdhouseInterp(input.high, x)
elseif (input.lives ~= 0) then
y = ctsYield(input.low, input.high, x, input.lives)
elseif args.script then
y = scriptInterp(input.low, input.high, x)
elseif args.caviar then
y = caviarInterp(x, input.denom)
elseif (input.exponent ~= 1) then
y = exponentInterp(input.low, input.high, input.exponent, x)
elseif input.bonuslow then
y = bonusInterp(input.low, input.high, input.bonuslow, input.bonushigh, x)
else
y = interp(input.low, input.high, x)
end
if args.showbefore ~= 'no' or input.req == x or (y >= 0.999 and input.lives == 0) then
table.insert(data, {x=x, y=y})
end
if y >= 0.999 and input.lives == 0 then
cutoffLevel = x
break
end
end
table.insert(dataSets, {
data = data,
label = input.label .. " ",
borderDash = {5, 5},
borderCapStyle = 'round',
pointRadius = 0,
baseColor = input.color,
pointStyleImg = input.image,
})
data = {}
for x = input.req, args.highLevel do
if cutoffLevel ~= nil then
break
end
local y
if args.cascade then
y = cascadeInterp(inputs, x, i)
elseif args.birdhouse then
y = birdhouseInterp(input.high, x)
elseif (input.lives ~= 0) then
y = ctsYield(input.low, input.high, x, input.lives)
elseif args.script then
y = scriptInterp(input.low, input.high, x)
elseif args.caviar then
y = caviarInterp(x, input.denom)
elseif (input.exponent ~= 1) then
y = exponentInterp(input.low, input.high, input.exponent, x)
elseif input.bonuslow then
y = bonusInterp(input.low, input.high, input.bonuslow, input.bonushigh, x)
else
y = interp(input.low, input.high, x)
end
if y >= 0.999 and cutoffLevel == nil and input.lives == 0 then
cutoffLevel = x
end
table.insert(data, {x=x, y=y})
end
table.insert(dataSets, {
data = data,
label = input.label .. " ",
borderDash = {},
borderCapStyle = 'round',
baseColor = input.color,
pointRadius = 0,
})
if cutoffLevel ~= nil then
table.insert(dataSets, {
data = {{x = cutoffLevel, y = 1}},
borderDash = {},
borderCapStyle = 'round',
baseColor = input.color,
pointRadius = 5,
})
else
table.insert(dataSets, {})
end
end
return dataSets
end
function p.main(frame)
local args = frame:getParent().args
return p._main(args)
end
function p._main(args)
local plot = chart.newChart{ type = 'scatter' }
:setTitle( args.label )
:setDimensions( '540px', '400px', '540px', '400px', true )
:setXLabel( args.xlabel or 'Level' )
:setYLabel( args.ylabel or 'Success rate' )
:setXLimits( nil, nil, 1 )
:setDatasetsPerGroup(3)
if args.lives1 == nil then
plot:setYFormat( 'percent' )
:setYLimits( nil, nil, 0.1 )
:setTooltipFormat( 'skillingSuccess' )
else
plot:setYLimits( 0, nil, (tonumber(args.ystep) or 5))
:setTooltipFormat( 'harvestLives' )
end
local dataSets = p._calculateDataSets(args)
for i, dataSet in ipairs(dataSets) do
plot:newDataSet(dataSet)
end
return plot
end
return p