Module:MutationValue
Jump to navigation
Jump to search
This module is used inside template {{MutationDetails}}
to generate the values table for mutation.
Markup[edit]
{{#invoke:MutationValue|main | base = | equation = | value_cap = | cap = | boss_percentage = | unit = | digits = | clear = }}
The parameters:
base
: The base value of the mutation's effect.equation
: The scaling equation. In the equation, base value is marked with "base", and "stat-1" is marked with "i". Examples:
Mutation's equation | Written in the module |
---|---|
[base value]+ 0.04*(stat - 1) | base+0.04*i
|
[base value]*1.05Stat-1 | base*1.05^i
|
value_cap
: The maximum value of the mutation's effect. Also used to determine the amount of stat when it reachs the maximum value. Optional.boss_percentage
: The nerfed scaling for bosses, if has any.cap
: The amount of stat when it reachs the maximum effect of the mutation. Overwritten byvalue_cap
. Optional.unit
: unit of the mutation's effect. usually it is "DPS", "s" or "%". Optional.digits
: A number "n" (optional). Values will display their most prominent "n" digits (ignore the first zeroes), in both integral and fractional parts. But if the integral part has more than "n" digits, it will display only the integral part. The final values are rounded. Examples:
Mutation's value | Value that displays |
---|---|
| digits = 2
1.23124 |
1.2 3.7 1242 0.0042 0.35 |
(This parameter is kinda complicated so just change it until you get the result you want :P)
clear
: If mentioned (any value), the table will have the property "clear:both;"
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']
local base_boss = args['boss_percentage']
base = tonumber(base)
if base_boss then base_boss = tonumber(base_boss) end
if (not base) or (not eqt) then return '' end
if not d then d = 1 end
if not unit then unit = '' end
if cap2 then cap = cap2 end
---------- Finding the mutation's scroll cap with the cap_value and equation ----------
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)
---------- Generating the first column of the table ----------
result = {}
table.insert(result, '<br/>')
if clear then table.insert(result, '<div style="overflow:auto; clear:both;">')
else table.insert(result, '<div style="overflow:auto;">')
end
table.insert(result, '{| class=wikitable style="text-align:center;')
table.insert(result, '!Number of stats || 1 ')
table.insert(result, '|-')
table.insert(result, '|Mutation effect || ' .. truncate_to(base, d) .. unit .. ' ')
if base_boss then
value = truncate_to(base*base_boss, d)
table.insert(result, '|-')
table.insert(result, '|Mutation effect (boss) || ' .. value .. unit .. ' ')
end
table.insert(result, '|}')
table.insert(result, '</div>')
---------- Writing the table that shows the first 10 values, then about 10 more values between the 11th value and the cap ----------
-------------------- Finding the "step" to choose which values to display, from the 11th value to the cap --------------------
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
-------------------- Displaying the first 10 values --------------------
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))
result[6] = result[6] .. '|| ' .. truncate_to(value, d) .. unit
if base_boss then result[8] = result[8] .. '|| ' .. truncate_to(value*base_boss, d) .. unit end
end
-------------------- Displaying 10 values from 11th to cap --------------------
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))
result[6] = result[6] .. '|| ' .. truncate_to(value, d) .. unit
if base_boss then result[8] = result[8] .. '|| ' .. truncate_to(value*base_boss, d) .. unit end
end
-------------------- Displaying the cap --------------------
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 base_boss then result[8] = result[8] .. '|| ' .. truncate_to(value*base_boss, d) .. unit end
if cap < 60 then result[4] = result[4] .. '+ ' end
result[4] = result[4] .. '|| ...'
result[6] = result[6] .. '|| ...'
if base_boss then result[8] = result[8] .. '|| ...' end
return table.concat(result, "\n")
end
return p