Module:MutationValue

local p = {} local cap = 60 local descending = 0

local function round_half_up(n) local base, frac = math.modf(n) if frac >= 0.5 then return base + 1 else return base end end

function truncate_to(number, max_digits) local integral_part_digits = math.floor(math.log10(number)) + 1 if integral_part_digits >= max_digits then return round_half_up(number) else local digit_diff_pow10 = 10^(max_digits - integral_part_digits) return round_half_up(number * digit_diff_pow10) / digit_diff_pow10 end end

function searchcapascend(formula, limit, initial, left, right) if left > right then return false end local mid = math.floor((left+right)/2) local equat = formula:gsub('base', initial):gsub('i', tostring(mid-1)) if tonumber(mw.ext.ParserFunctions.expr(equat)) >= limit then cap = mid searchcapascend(formula, limit, initial, left, mid-1) else searchcapascend(formula, limit, initial, mid+1, right) end end

function searchcapdescend(formula, limit, initial, left, right) if left > right then return false end local mid = math.floor((left+right)/2) local equat = formula:gsub('base', initial):gsub('i', tostring(mid-1)) if tonumber(mw.ext.ParserFunctions.expr(equat)) <= limit then cap = mid searchcapdescend(formula, limit, initial, left, mid-1) else searchcapdescend(formula, limit, initial, mid+1, right) end end

function testarray(formula) local equat = formula:gsub('base', '1'):gsub('i', '1') if tonumber(mw.ext.ParserFunctions.expr(equat)) >= 1 then descending = 0 else descending = 1 end end

function p.main(frame) local args = require("Module:Arguments").getArgs(frame) local base = args['base'] local eqt = args['equation'] local unit = args['unit'] local d = args['digits'] local vcap = args['value_cap'] local cap2 = args['cap'] local clear = args['clear'] if (not base) or (not eqt) then return '' end if not d then d = 1 end if not unit then unit = '' end base = tonumber(base) if cap2 then cap = cap2 end testarray(eqt) if descending == 0 then if vcap then vcap = tonumber(vcap) searchcapascend(eqt, vcap, base, 1, 60) else vcap = 9999999 end else if vcap then vcap = tonumber(vcap) searchcapdescend(eqt, vcap, base, 1, 60) else vcap = 0 end end d = tonumber(d)

result = {} result[1] = ' ' if clear then result[2] = ' ' else result[2] = ' ' end result[3] = '{| class=wikitable style="text-align:center;'	result[4] = '!Number of stats || 1 '	result[5] = '|-'	result[6] = '|Mutation effect || ' .. base .. unit .. ' '	result[7] = '|}'	result[8] = ' '	local step = 1	if cap>10 then		step = math.floor((cap-10)/10)		if (step == 0) or (math.fmod(cap-10, step) ~= 0) then step = step+1 end	end	local equation = ''	local value = 0	for k = 2, math.min(10, cap-1) do		result[4] = result[4] .. '|| ' .. k		equation = eqt:gsub('base', base):gsub('i', tostring(k-1))		value = tonumber(mw.ext.ParserFunctions.expr(equation))		value = truncate_to(value, d)		result[6] = result[6] .. '|| ' .. value .. unit	end	for k = math.floor(10/step)+1, math.floor((cap-1)/step) do		local ks = k*step		result[4] = result[4] .. '|| ' .. ks		equation = eqt:gsub('base',base):gsub('i', tostring(ks-1))		value = tonumber(mw.ext.ParserFunctions.expr(equation))		value = truncate_to(value, d) result[6] = result[6] .. '|| ' .. value .. unit end result[4] = result[4] .. '|| ' .. cap equation = eqt:gsub('base',base):gsub('i', tostring(cap-1)) value = tonumber(mw.ext.ParserFunctions.expr(equation)) value = truncate_to(value, d)	if descending ==0 then value = math.min(vcap, value) else value = math.max(vcap, value) end result[6] = result[6] .. '|| ' .. value .. unit if cap < 60 then result[4] = result[4] .. '+ ' end result[4] = result[4] .. '|| ...'	result[6] = result[6] .. '|| ...'	return table.concat(result, "\n") end

return p