Module:Sandbox/User:Microbrews/Skilling success chart
Jump to navigation
Jump to search
Module documentation
This documentation is transcluded from Template:Module sandbox/doc. [edit] [history] [purge]
Module:Sandbox/User:Microbrews/Skilling success chart requires Module:Chart data.
This module is a sandbox for Microbrews. It can be used to test changes to existing modules, prototype new modules, or just experimenting with lua features.
Invocations of this sandbox should be kept in userspace; if the module is intended for use in other namespaces, it should be moved out of the sandbox into a normal module and template.
This default documentation can be overridden by creating the /doc subpage of this module, as normal.
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( nil, 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