Module:User:HertzDevil

local Util = require 'Module:Util' local List = require 'Module:ListUtil' local Hash = require 'Module:HashUtil' local Debug = require 'Module:DebugUtil' local DATA = mw.loadData 'Module:User:HertzDevil/data' local TAGS = DATA.tags local LIMIT_TIMING_PAIRS = DATA.limit_timing_pairs local cargo = mw.ext.cargo local CargoUtil = require 'Module:CargoUtil' local mf = require 'Module:MF'.main1 local toboolean = require 'Module:Bool'.toboolean local parseArgs = require 'Module:ObjectArg'.parse local RewardText = require 'Module:RewardText'

local getTagTextFields = function (kind, id) local t = TAGS[kind][tonumber(id)] if t then if mw.ustring.find(t, kind, 1, false) == 1 then return ('%s %d: %s'):format(kind, id, t)		end return ('%s %d: %s'):format(kind, id, mw.ustring.sub(t, 1, 7) .. '...'), t	end return '???', ('%s %d'):format(kind, id) end

local getTagWikitext = function (kind, id, frame) local text, tooltip = getTagTextFields(kind, id) return tooltip == nil and :format(text) or		:format(tooltip, text) end

local unusedTagsTable = function (args, frame) local stids = parseArgs(args.stid or '[]') or {} local slids = parseArgs(args.slid or '[]') or {} local saids = parseArgs(args.said or '[]') or {}

local tbl = mw.html.create('table'):addClass('wikitable'):addClass('unsortable')

local tr = tbl:tag('tr') tr:tag('th'):wikitext('Type') tr:tag('th'):wikitext('Tags')

tr = tbl:tag('tr') tr:tag('td'):wikitext('SkillTiming ID') tr:tag('td'):wikitext(#stids == 0 and 'None' or table.concat(List.map(stids, function (x) return getTagWikitext('STID', x, frame) end), ' '))

tr = tbl:tag('tr') tr:tag('td'):wikitext('SkillLimit ID') tr:tag('td'):wikitext(#slids == 0 and 'None' or table.concat(List.map(slids, function (x) return getTagWikitext('SLID', x, frame) end), ' '))

tr = tbl:tag('tr') tr:tag('td'):wikitext('SkillAbility ID') tr:tag('td'):wikitext(#saids == 0 and 'None' or table.concat(List.map(saids, function (x) return getTagWikitext('SAID', x, frame) end), ' '))

return tbl end

local trtest = function (args, frame) if args[1] == 'html' then return tostring(mw.html.create('tr'):tag('td'):wikitext(1):done:tag('td'):wikitext(2):done:tag('td'):wikitext(3):done) else return '|-\n| 1 || 2 || 3' end end

local vardefinetest = function (args, frame) frame:callParserFunction('#vardefine', {'ab', 'ababab'}) frame:callParserFunction('#vardefine', {'cd', args[1]}) end

local ustringtest = function (args) if args[1] == 'len' then local STRINGS = List.generate(100, function (n) return ('!'):rep(n * 1000) end) List.map(STRINGS, Debug.timed(mw.ustring.len)) elseif args[1] == 'find' then local LONG_STRING = ('!'):rep(500000) .. 'nino' .. ('!'):rep(500000) for i = 1, 1000001, 10000 do			local t0 = os.clock string.match(LONG_STRING, 'nino', i)			local t1 = os.clock - t0			t0 = os.clock mw.ustring.match(LONG_STRING, 'nino', i)			local t2 = os.clock - t0			mw.log(('%d\t%.5f\t%.5f'):format(i, t1, t2)) end end end

local storetest = function (args, frame) return frame:callParserFunction('#cargo_store:_table=' .. 'Bug', {'',		abc = '123',		xyz = '4,5,6',	}) end

local spawns = function local maps = List.group_by(CargoUtil.full_query('Maps=M,MapUnits=MU', 'M.Map=map,M._pageName=page,MU.TabName=tab,GROUP_CONCAT(MU.Pos ORDER BY MU.Pos)=pos', { join = 'MU._pageName=M._pageName', where = 'spawn IS NULL', groupBy = 'MU._pageName,MU.TabName', orderBy = 'M.Map', }), function (v) return v.map end) local multiple = {} for map, vs in Hash.sorted_pairs(maps) do		local byPos = List.group_by(vs, function (v) return v.pos end) local tabGroups = {} for pos, vs2 in Hash.sorted_pairs(byPos) do			local tabs = List.map(vs2, function (v) return v.tab end) table.sort(tabs, Util.difficultySort) tabGroups[#tabGroups + 1] = tabs[1] mw.log(map, vs2[1].page, table.concat(tabs, '; '), pos) end if #tabGroups > 1 then table.sort(tabGroups, Util.difficultySort) multiple[#multiple + 1] = {map, tabGroups} end end mw.log mw.log('Maps with multiple initial spawns:') for _, v in ipairs(multiple) do		mw.log(v[1], maps[v[1]][1].page, table.concat(v[2], '; ')) end end

local skillsWithoutBuildsTab = function local skills = cargo.query('Skills', '_pageName,Scategory', {		where = "Next IS NULL AND Scategory!='assist' AND Scategory!='special'",		groupBy = '_pageName',		limit = 5000,	}) local skillsCat = Hash.from_ipairs(skills, function (v) return v._pageName, v.Scategory end)

local buildsPages = List.to_set(List.map_self(cargo.query('_pageData', '_pageName', {		where = "_pageName LIKE '%Fire Emblem Heroes Wiki:Build Center/Skill/%' AND _pageNamespace=4", groupBy = '_pageName', limit = 5000,	}), function (v) return mw.ustring.gsub(v._pageName, '^Fire Emblem Heroes Wiki:Build Center/Skill/', '') end))

local EXCLUSIONS = { '^Valaskjálf$', '^Élivágar$', '^Hel Scythe$', '^Glitnir$', '^Sökkvabekkr$', '^Adult %(.*%)$', '^Umbra Burst .*$', '^Embla\'s Ward$', '^Múspellflame$', '^Røkkr$', '^Initiate Seal .*$', '^Squad Ace .*$', '^Live for Bounty$', '^Live for Honor$', '^.* Experience$', '^.* Exp%.$', '^.* Valor$', }	mw.log('Create:') for k, cat in Hash.sorted_pairs(skillsCat) do		if not buildsPages[k] and List.none(EXCLUSIONS, function (pat) return mw.ustring.find(k, pat) end) then mw.log(('%q,'):format('Fire Emblem Heroes Wiki:Build Center/Skill/' .. k), ('# %s'):format(cat)) end end mw.log('') mw.log('Remove:') for k, cat in Hash.sorted_pairs(skillsCat) do		if buildsPages[k] and not List.none(EXCLUSIONS, function (pat) return mw.ustring.find(k, pat) end) then mw.log(('%q,'):format('Fire Emblem Heroes Wiki:Build Center/Skill/' .. k), ('# %s'):format(cat)) end end end

local plotly = function local FEHStatUtil = require 'Module:FEHStatUtil' local units = cargo.query('UnitStats,Units', "IFNULL(CONCAT(Name,': ',Title),Name)=name,MoveType,WeaponType,Lv1Atk5,Lv1Spd5,Lv1Def5,Lv1Res5,AtkGR3,SpdGR3,DefGR3,ResGR3", {		join = 'UnitStats.WikiName=Units.WikiName',		where = "IFNULL(Properties__full,'') NOT LIKE '%enemy%'",		groupBy = 'Units.WikiName',		orderBy = 'name',		limit = 1000,	}) local statFn = function (rarity, b, g)		return b and g and (b + FEHStatUtil.getGrowthValue(rarity, g)) end for _, v in ipairs(units) do		v.atk = statFn(5, tonumber(v.Lv1Atk5), tonumber(v.AtkGR3)) v.spd = statFn(5, tonumber(v.Lv1Spd5), tonumber(v.SpdGR3)) v.def = statFn(5, tonumber(v.Lv1Def5), tonumber(v.DefGR3)) v.res = statFn(5, tonumber(v.Lv1Res5), tonumber(v.ResGR3)) if v.atk and v.spd and v.def and v.res then v.total = v.atk + v.spd + v.def + v.res end end

mw.log('Hero', 'Move', 'Color', 'Weapon', 'X', 'Y', 'Z', '0', 'Display', 'Atk', 'Spd', 'Def', 'Res') for _, v in ipairs(units) do		--		v.atk / v.total * [0, 0, 0]		v.spd / v.total + [1, 1, 0]		v.def / v.total + [1, 0, 1]		v.res / v.total + [0, 1, 1] local x = (v.spd + v.def) / v.total local y = (v.spd + v.res) / v.total local z = (v.def + v.res) / v.total mw.log(v.name, v.MoveType, v.WeaponType:gsub(' .*', ), v.WeaponType:gsub('.* ', ),			('%.5f'):format(x), ('%.5f'):format(y), ('%.5f'):format(z), 0,			('#%02X%02X%02X'):format( math.max(0, math.min(255, math.floor(128 + 1000 * (x - 0.5)))), math.max(0, math.min(255, math.floor(128 + 1000 * (y - 0.5)))), math.max(0, math.min(255, math.floor(128 + 1000 * (z - 0.5))))),			v.atk, v.spd, v.def, v.res) end end

local functions = { SAID = function (args, frame) return getTagWikitext('SAID', args[1], frame) end, SLID = function (args, frame) return getTagWikitext('SLID', args[1], frame) end, STID = function (args, frame) return getTagWikitext('STID', args[1], frame) end, unusedTagsTable = unusedTagsTable,

trtest = trtest, vardefinetest = vardefinetest, ustringtest = ustringtest, storetest = storetest,

spawns = spawns, skillsWithoutBuildsTab = skillsWithoutBuildsTab,

plotly = plotly, } Hash.merge_self(functions, require 'Module:User:HertzDevil/Keywords')

local p = require 'Module:MakeMWModule'.makeMWModule(functions) p.logObject = function (frame) mw.logObject(Hash.clone(frame.args)) end return p