Module:StatTable

local mw = mw local html = mw.html local query = mw.ext.cargo.query local bit32 = require 'bit32' local HeroUtil = require 'Module:HeroUtil' local escq = require 'Module:EscQ'.main1

local downgradeHeroStats = function (stats, rarity) local atko = (stats[2] >= stats[3] and 1 or 0) + (stats[2] >= stats[4] and 1 or 0) + (stats[2] >= stats[5] and 1 or 0) local spdo = (stats[3] > stats[2] and 1 or 0) + (stats[3] >= stats[4] and 1 or 0) + (stats[3] >= stats[5] and 1 or 0) local defo = (stats[4] > stats[2] and 1 or 0) + (stats[4] >  stats[3] and 1 or 0) + (stats[4] >= stats[5] and 1 or 0) local reso = (stats[5] > stats[2] and 1 or 0) + (stats[5] >  stats[3] and 1 or 0) + (stats[5] >  stats[4] and 1 or 0)

local truestats = {stats[1], stats[2], stats[3], stats[4], stats[5]}

if rarity == 1 then for i = 1, #truestats do			truestats[i] = truestats[i] - 2 end elseif rarity <= 3 then for i = 1, #truestats do			truestats[i] = truestats[i] - 1 end end

if rarity == 2 or rarity == 4 then truestats[1] = truestats[1] - 1 if atko < 2 then truestats[2] = truestats[2] - 1 end if spdo < 2 then truestats[3] = truestats[3] - 1 end if defo < 2 then truestats[4] = truestats[4] - 1 end if reso < 2 then truestats[5] = truestats[5] - 1 end end

return truestats end

local getGrowthVector; do	local VECTORS = mw.loadData 'Module:StatTable/data' getGrowthVector = function (basestat, rate, rarity, vbase) local gvgv = math.floor(rate * (0.79 + 0.07 * rarity)) local vid = (3 * basestat + vbase + gvgv) % 0x40 local growth = math.floor(0.39 * gvgv) if growth 39 then return {} end local lobytes = VECTORS[growth * 128 + vid * 2 - 127] local hibytes = VECTORS[growth * 128 + vid * 2 - 126]

local vec = {} for i = 2, 31 do		if bit32.extract(lobytes, i) ~= 0 then vec[i] = true end end for i = 32, 40 do		if bit32.extract(hibytes, i - 32) ~= 0 then vec[i] = true end end return vec end; end

local calculateStats = function (base, base5, rate, rarity, vbase, iv) local truebase = base if iv > 0 then truebase = truebase + 1 rate = rate + 5 elseif iv < 0 then truebase = truebase - 1 rate = rate - 5 end local vec = getGrowthVector(base5, rate, rarity, vbase)

local t = {truebase} for i = 2, 40 do		t[i] = t[i - 1] + (vec[i] and 1 or 0) end return t end

local getStatTables = function (stats, rates, rarity, bvid) local truestats = downgradeHeroStats(stats, rarity)

return { calculateStats(truestats[1], stats[1], rates[1], rarity, bvid - 35, -1), calculateStats(truestats[1], stats[1], rates[1], rarity, bvid - 35, 0), calculateStats(truestats[1], stats[1], rates[1], rarity, bvid - 35, 1), calculateStats(truestats[2], stats[2], rates[2], rarity, bvid - 28, -1), calculateStats(truestats[2], stats[2], rates[2], rarity, bvid - 28, 0), calculateStats(truestats[2], stats[2], rates[2], rarity, bvid - 28, 1), calculateStats(truestats[3], stats[3], rates[3], rarity, bvid - 21, -1), calculateStats(truestats[3], stats[3], rates[3], rarity, bvid - 21, 0), calculateStats(truestats[3], stats[3], rates[3], rarity, bvid - 21, 1), calculateStats(truestats[4], stats[4], rates[4], rarity, bvid - 14, -1), calculateStats(truestats[4], stats[4], rates[4], rarity, bvid - 14, 0), calculateStats(truestats[4], stats[4], rates[4], rarity, bvid - 14, 1), calculateStats(truestats[5], stats[5], rates[5], rarity, bvid - 7, -1), calculateStats(truestats[5], stats[5], rates[5], rarity, bvid - 7,  0), calculateStats(truestats[5], stats[5], rates[5], rarity, bvid - 7,  1), } end

local statTable; do	local STAT_STRS = {'HP', 'Atk', 'Spd', 'Def', 'Res'} local IV_STRS = {'−', '∅', '+'} statTable = function (args) local hero = args.hero local bvid = tonumber(args.bvid, 16) local rarity = tonumber(args.rarity)

local q = query('Units,UnitStats', 'Lv1HP5,Lv1Atk5,Lv1Spd5,Lv1Def5,Lv1Res5,HPGR3,AtkGR3,SpdGR3,DefGR3,ResGR3', {		join = 'Units.WikiName=UnitStats.WikiName',		where = ("Units._pageName='%s' AND IFNULL(Properties__full,'') NOT LIKE '%%enemy%%'"):format(escq(hero)),		groupBy = 'Units.WikiName',	})[1] if not q then return require 'Module:Error'.error("Failed to calculate stats!") end local base = {tonumber(q.Lv1HP5), tonumber(q.Lv1Atk5), tonumber(q.Lv1Spd5), tonumber(q.Lv1Def5), tonumber(q.Lv1Res5)} local rates = {tonumber(q.HPGR3), tonumber(q.AtkGR3), tonumber(q.SpdGR3), tonumber(q.DefGR3), tonumber(q.ResGR3)} local all_stats = getStatTables(base, rates, rarity, bvid) if not all_stats or not all_stats[1] or not next(all_stats[1]) then return require 'Module:Error'.error("Failed to calculate stats!") end

local tbl = html.create('table'):addClass('wikitable'):css('text-align', 'center'):addClass('full-stats-table')

local tr = tbl:tag('tr')

-- stat title row tr:tag('th'):attr('scope', 'col'):attr('rowspan', 2):wikitext('Level') for _, v in ipairs(STAT_STRS) do		tr:tag('th'):attr('scope', 'colgroup'):attr('colspan', 3):wikitext(v) end -- IV title row tr = tbl:tag('tr') for i = 1, 5 do		for _, v in ipairs(IV_STRS) do			tr:tag('th'):attr('scope', 'col'):wikitext(v) end end

-- stats for i = 1, #all_stats[1] do		tr = tbl:tag('tr') tr:tag('th'):attr('scope', 'row'):wikitext(tostring(i)) for j = 1, #all_stats do			tr:tag('td'):wikitext(all_stats[j][i] or '?') end end

return ('==%d★==\n%s\n'):format(rarity, tostring(tbl)) end; end

local allStatTables = function (args) local hero = args.hero local bvid = tonumber(args.bvid, 16)

local avail = HeroUtil.getLowestRarities {page = hero} local rmin = avail:bounds or 6 avail.reward = {} local smin = avail:bounds or 6

local tables = {'\n'} for i = 5, 1, -1 do		if i >= smin then tables[#tables + 1] = statTable {hero = args.hero, bvid = args.bvid, rarity = i}		elseif i >= rmin then tables[#tables + 1] = statTable {hero = args.hero, bvid = args.bvid, rarity = i}		end end

if #tables == 1 then return 'This unit is not available.' end return table.concat(tables) end

return require 'Module:makeMWModule'.makeMWModule { statTable = statTable, allStatTables = allStatTables, }