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('ATK'):done :tag('th'):css('width', '14%'):wikitext('DEF'):done :tag('th'):css('width', '14%'):wikitext('INT'):done :tag('th'):css('width', '14%'):wikitext('MDEF'):done :tag('th'):css('width', '14%'):wikitext('DEX'):done :tag('th'):css('width', '14%'):wikitext('SKILL'):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 if not args.Hero then return 'Error: Missing Hero argument. ' end local lowestHeroSummon = not isEnemy and util.getHeroLowestRarity(args.Hero, 'summon') or 6 local lowestHeroRarity = not isEnemy and util.getHeroLowestRarity(args.Hero) or 1

--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)

local cargotable = {} local cargoAddStats = function (table, rarity, var, statSet) cargotable[#cargotable + 1] = {title = table, args = { rar = rarity, var = var, hp = statSet[1], atk = statSet[2], spd = statSet[3], def = statSet[4], res = statSet[5], }} end

--Fill in rows of Lv1 table local Lv1StatTable = makeStatTableHeader for rarity, statset in ipairs(full1Neuts) do   if rarity >= lowestHeroRarity then local tr = Lv1StatTable:tag('tr') tr:tag('td'):wikitext(RARITY_TXT[rarity]) if rarity >= lowestHeroSummon then cargoAddStats('Stats_Page/BaseStatDefinitions', rarity, 'Bane', full1Banes[rarity]) cargoAddStats('Stats_Page/BaseStatDefinitions', rarity, 'Boon', full1Boons[rarity]) end cargoAddStats('Stats_Page/BaseStatDefinitions', rarity, 'Neut', statset) for stat, val in ipairs(statset) do       local statString = '' if rarity >= lowestHeroSummon then statString = full1Banes[rarity][stat] .. '/' .. val .. '/' .. full1Boons[rarity][stat] else statString = full1Neuts[rarity][stat] end tr:tag('td'):wikitext(statString) end tr:tag('td'):wikitext(ListUtil.reduce(statset, function (x, y) return x + y end)):css(SUM_CSS_PROP, SUM_CSS_VAL) end 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] if rarity >= lowestHeroRarity then local tr = Lv40StatTable:tag('tr') tr:tag('td'):wikitext(RARITY_TXT[rarity]) cargoAddStats('Stats_Page/MaxStatDefinitions', rarity, 'Neut', neutset) if rarity >= lowestHeroSummon then cargoAddStats('Stats_Page/MaxStatDefinitions', rarity, 'Bane', baneset) cargoAddStats('Stats_Page/MaxStatDefinitions', rarity, 'Boon', boonset) end

for stat, val in ipairs(neutset) do       local statString = '' if rarity >= lowestHeroSummon then statString = ('%s/%s/%s'):format(baneset[stat], val, boonset[stat]) else statString = tostring(val) end tr:tag('td'):wikitext(statString) end local sumString = '-' local sum = ListUtil.reduce(neutset, function (x, y) return x + y end) if rarity >= lowestHeroSummon 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 end

--Fill in rows of GR table local wikiGRTable = makeStatTableHeader local tr = wikiGRTable:tag('tr') tr:tag('td'):wikitext(RARITY_TXT[3]) cargotable[#cargotable + 1] = {title = 'Stats_Page/GrowthRateDefinitions', args = {hp = rateNeuts[1], atk = rateNeuts[2], spd = rateNeuts[3], def = rateNeuts[4], res = rateNeuts[5]}} for _, rate in ipairs(rateNeuts) do   tr:tag('td'):wikitext(rate .. '%') end tr:tag('td') :wikitext(ListUtil.reduce(rateNeuts, function (x, y) return x + y end) .. '%') :css(SUM_CSS_PROP, SUM_CSS_VAL)

if not isEnemy and not mw.title.getCurrentTitle.isSubpage and mw.title.getCurrentTitle.namespace == 0 then for i = #cargotable, 1, -1 do     frame:expandTemplate(cargotable[i]) end end

if isEnemy then 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) 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

return p