Module:StatsPage

local util = require('Module:Util') local getArgs = require('Module:Arguments').getArgs local ListUtil = require 'Module:ListUtil' local FEHStatUtil = require 'Module:FEHStatUtil'

local SUM_CSS_PROP = 'font-style' local SUM_CSS_VAL = 'italic'

local makeStatTableHeader = function return mw.html.create('table') :addClass('wikitable default'):css('text-align', 'center'):css('width', '500px') :tag('tr') :tag('th'):css('width', '14%'):wikitext('Rarity'):done :tag('th'):css('width', '14%'):wikitext('HP'):done :tag('th'):css('width', '14%'):wikitext('Atk'):done :tag('th'):css('width', '14%'):wikitext('Spd'):done :tag('th'):css('width', '14%'):wikitext('Def'):done :tag('th'):css('width', '14%'):wikitext('Res'):done :tag('th'):css('width', '14%'):css(SUM_CSS_PROP, SUM_CSS_VAL):wikitext('Total'):done :done :done end

local getStatTotalBounds = function (neut, bane, boon) local sums = { neut[1] + neut[2] + neut[3] + neut[4] + neut[5], boon[1] + bane[2] + neut[3] + neut[4] + neut[5], boon[1] + neut[2] + bane[3] + neut[4] + neut[5], boon[1] + neut[2] + neut[3] + bane[4] + neut[5], boon[1] + neut[2] + neut[3] + neut[4] + bane[5], bane[1] + boon[2] + neut[3] + neut[4] + neut[5], neut[1] + boon[2] + bane[3] + neut[4] + neut[5], neut[1] + boon[2] + neut[3] + bane[4] + neut[5], neut[1] + boon[2] + neut[3] + neut[4] + bane[5], bane[1] + neut[2] + boon[3] + neut[4] + neut[5], neut[1] + bane[2] + boon[3] + neut[4] + neut[5], neut[1] + neut[2] + boon[3] + bane[4] + neut[5], neut[1] + neut[2] + boon[3] + neut[4] + bane[5], bane[1] + neut[2] + neut[3] + boon[4] + neut[5], neut[1] + bane[2] + neut[3] + boon[4] + neut[5], neut[1] + neut[2] + bane[3] + boon[4] + neut[5], neut[1] + neut[2] + neut[3] + boon[4] + bane[5], bane[1] + neut[2] + neut[3] + neut[4] + boon[5], neut[1] + bane[2] + neut[3] + neut[4] + boon[5], neut[1] + neut[2] + bane[3] + neut[4] + boon[5], neut[1] + neut[2] + neut[3] + bane[4] + boon[5], } return math.min(unpack(sums)), math.max(unpack(sums)) end

local p = {}

function p._statsPage(frame, args, isEnemy) local RARITY_TXT = util.getRarityTexts

-- parsing inputs --Hero args.Hero = args.Hero or mw.title.getCurrentTitle.text

--Lv1 stats local level1Inputs = ListUtil.map({   args.Lv1HP or , args.Lv1ATK or , args.Lv1SPD or , args.Lv1DEF or , args.Lv1RES or '',  }, function (x) return tonumber(x) or false end) if ListUtil.find(level1Inputs, false) then return makeStatTableHeader end

--Set up tables for all Lv1 stats local full1Neuts = FEHStatUtil.fullLv1Stats(level1Inputs) local full1Banes = ListUtil.map(full1Neuts, function (t) return ListUtil.map(t, function (base) return base - 1 end) end) local full1Boons = ListUtil.map(full1Neuts, function (t) return ListUtil.map(t, function (base) return base + 1 end) end)

--Growth rates local rateNeuts = ListUtil.map({   args.GRHP or , args.GRATK or , args.GRSPD or , args.GRDEF or , args.GRRES or '',  }, function (x) return tonumber(x) or false end) if ListUtil.find(rateNeuts, false) then return makeStatTableHeader end

local full40Neuts = FEHStatUtil.fullLv40Stats(rateNeuts, full1Neuts) local full40Banes = FEHStatUtil.fullLv40Stats(ListUtil.map(rateNeuts, function (rate) return rate - 5 end), full1Banes) local full40Boons = FEHStatUtil.fullLv40Stats(ListUtil.map(rateNeuts, function (rate) return rate + 5 end), full1Boons)

--Fill in rows of Lv1 table local Lv1StatTable = makeStatTableHeader for rarity, statset in ipairs(full1Neuts) do   local tr = Lv1StatTable:tag('tr') tr:tag('td'):wikitext(RARITY_TXT[rarity]) for stat, val in ipairs(statset) do     local statString = isEnemy and tostring(val) or ('%s/%s/%s'):format(full1Banes[rarity][stat], val, full1Boons[rarity][stat]) tr:tag('td'):wikitext(statString) end tr:tag('td'):wikitext(ListUtil.sum(statset)):css(SUM_CSS_PROP, SUM_CSS_VAL) end

--Fill in rows of Lv40 table local Lv40StatTable = makeStatTableHeader for rarity, neutset in ipairs(full40Neuts) do   local baneset = full40Banes[rarity] local boonset = full40Boons[rarity] local tr = Lv40StatTable:tag('tr') tr:tag('td'):wikitext(RARITY_TXT[rarity])

for stat, val in ipairs(neutset) do     local statString = isEnemy and tostring(val) or ('%s/%s/%s'):format(baneset[stat], val, boonset[stat]) tr:tag('td'):wikitext(statString) end local sumString = '-' local sum = ListUtil.sum(neutset) if not isEnemy then local lo, hi = getStatTotalBounds(neutset, baneset, boonset) sumString = lo ~= hi and ('%s~%s'):format(lo, hi) or tostring(lo) else sumString = tostring(sum) end tr:tag('td'):wikitext(sumString):css(SUM_CSS_PROP, SUM_CSS_VAL) end

--Fill in rows of GR table local wikiGRTable = makeStatTableHeader local tr = wikiGRTable:tag('tr') tr:tag('td'):wikitext(RARITY_TXT[3]) for _, rate in ipairs(rateNeuts) do   tr:tag('td'):wikitext(rate .. '%') end tr:tag('td') :wikitext(ListUtil.sum(rateNeuts) .. '%') :css(SUM_CSS_PROP, SUM_CSS_VAL)

if isEnemy then return ' Level 1 Stats ' .. tostring(Lv1StatTable) .. ' Level 40 Stats ' .. tostring(Lv40StatTable) .. ' Growth Rates This set of values, after being multiplied by a rarity factor, determines how much each stat will increase from level 1 to level 40, see stat growth.' .. tostring(wikiGRTable) else return 'All stats have a degree of variation. The stat growth page explains how the variation works. Level 1 stats ' .. tostring(Lv1StatTable) .. ' Level 40 stats ' .. tostring(Lv40StatTable) .. ' Growth Rates This set of values, after being multiplied by a rarity factor, determines how much each stat will increase from level 1 to level 40, see stat growth.' .. tostring(wikiGRTable) .. ' Stats between level 1 and 40 For stat values between level 1 and 40, see this page.' end end

function p.statsPage(frame) args = getArgs(frame, {wrappers = "Template:Stats Page"}) return p._statsPage(frame, args, false) end

function p.enemyStatsPage(frame) args = getArgs(frame, {wrappers = 'Template:Stats Page/Enemy'}) return p._statsPage(frame, args, true) end

return p