Module:MutationValue

From Dead Cells Wiki
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 by value_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
3.65
1242.23
0.0042
0.34567


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