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( 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