Module:Util

local module = {}

function module.pie(frame) local content = {} local args = { start = 0 } local pargs = frame:getParent.args local params = {title = 'PieChart/Entry', args = args}

for k, v in ipairs(pargs) do       local value = tonumber(v)

if value > 0 then args.color = pargs['color' .. k]           args.text1 = pargs['text' .. k] or pargs['text' .. k .. '_1']           args.text2 = pargs['text' .. k .. '_2']           args.diff = value table.insert(content, frame:expandTemplate(params))

args.start = args.start + args.diff end end

if pargs.rest1 then local diff = 100 - args.start

if diff > 0 then local r = 1 local sum = 0 local rest = {} local value = tonumber(pargs.rest1) -- find sum of all rest values while value do               table.insert(rest, value)

r = r + 1 sum = sum + value value = tonumber(pargs['rest' .. r]) end -- get the rest and divide through the sum if sum > 0 then sum = diff / sum -- distribute the rest by each value for r, value in ipairs(rest) do                   if value > 0 then local key = string.format('rest%d_', r)                       args.color = pargs[key .. 'color'] args.text1 = pargs[key .. 'text'] or pargs[key .. 'text1'] args.text2 = pargs[key .. 'text2'] args.diff = sum * value

table.insert(content, frame:expandTemplate(params))

args.start = args.start + args.diff end end end end end

local eargs = { content = table.concat(content) }   for k, v in pairs(pargs) do        eargs[k] = v    end

return frame:expandTemplate{title = 'PieChart', args = eargs} end

function module.rewardTable(frame, args) frame = frame or mw.getCurrentFrame args = args or frame:getParent.args

local params = {}

for k, v in ipairs(args) do       params[k] = v    end

local length = #params local trim = mw.text.trim local count = tonumber(args.count) local lang = mw.getContentLanguage local columns = {'Reward', 'Amount', 'Chance'} local output = {} -- trim input for i = 1, length, 4 do       local data = {unpack(params, i, i + 3)}

for k, v in ipairs(data) do           data[k] = trim(v) end

table.insert(output, data) end -- calculate chance local sum = 0

for _, v in ipairs(output) do       local header, amount_string, amount_value, quantity = unpack(v) local value = tonumber(amount_value)

if value then value = tonumber(quantity) / value / count * 100 sum = sum + value else if amount_value == 'rest' then value = 100 - sum else value = nil end end

v.args = {header, amount_string, value and (lang:formatNum(math.floor(value * 100 + 0.5) / 100) .. '%') or '-'} v.chance = value end -- calculate reward chance if dub is set local dub = tonumber(args.dub)

if dub then sum = 100 / (100 - output[dub].chance)

for k, v in ipairs(output) do           table.insert(v.args, (not v.chance or k == dub) and '-' or (lang:formatNum(math.floor((v.chance * sum) * 100 + 0.5) / 100) .. '%'))       end

table.insert(columns, 'Reward chance') end -- call DataTable/Row local expand = {title = 'DataTable/Row'}

for k, v in ipairs(output) do       v = v.args expand.args = v       v.type1 = 'header'

output[k] = frame:expandTemplate(expand) end

return frame:expandTemplate{ title = 'DataTable', args = { class = 'sortable', sortType1 = 'text', content = table.concat(output), unpack(columns) },   } end

function module.ascension(frame, args) local args = args or frame:getParent.args local size = args.size local width = args.width local height = args.height local platform = args.platform local rank = args.rank or 0 local hero = args.hero -- fetch parameters local content = {} local params = {}

for k, v in ipairs(args) do       params[k] = v    end

local length = #params local idx = 1 local map = { skill = function(params, idx, file) local x, y, parent, skill = unpack(params, idx, idx + 4)

skill = tonumber(skill)

if skill > 0 then return idx + 4, {file = file, x = tonumber(x), y = tonumber(y), parent = tonumber(parent), skill = skill} else return idx + 4, {file = file, x = tonumber(x), y = tonumber(y), parent = tonumber(parent)} end end, default = function(params, idx, file) local x, y, parent = unpack(params, idx, idx + 3)

return idx + 3, {file = file, x = tonumber(x), y = tonumber(y), parent = tonumber(parent)} end, }   while idx < length do        local file = params[idx] local func = map[file]

if not func then func = map.default end

idx, func = func(params, idx + 1, file)

func.size = size func.hero = hero func.platform = platform func.id = string.format('%d_%d', rank, #content)

table.insert(content, func) end

if #content > 0 then -- find max and min x and y       local min_x = content[1].x        local max_x = min_x local min_y = content[1].y       local max_y = min_y for _, v in ipairs(content) do           local x = v.x            local y = v.y

if x < min_x then min_x = x           elseif x > max_x then max_x = x           end if y < min_y then min_y = y           elseif y > max_y then max_y = y           end end -- rescale local scale_x = (width - size) / (max_x - min_x) local scale_y = (height - size) / (max_y - min_y) for _, v in ipairs(content) do           v.x = (v.x - min_x) * scale_x v.y = (v.y - min_y) * scale_y end -- calculate lines for _, v in ipairs(content) do           local parent = v.parent if parent >= 0 then local t = content[parent + 1] local xd = t.x - v.x               local yd = v.y - t.y

v.line = math.sqrt(xd * xd + yd * yd) v.angle = math.atan2(yd, xd) * 180 / math.pi            end end -- call templates local template = {title = 'Ascension/Plot/Node'}

for k, v in ipairs(content) do           template.args = v            content[k] = frame:expandTemplate(template) end return frame:expandTemplate{ title = 'Ascension/Plot', args = { width = args.width, height = args.height, style = args.style, content = table.concat(content), },       }    end end

return module