Site News
Warning: This wiki contains spoilers. Read at your own risk!

Social media: If you would like, please join our Discord server, and/or follow us on X (Twitter) or Tumblr!

Module:FEH skill availability

From Fire Emblem Wiki, your source on Fire Emblem information. By fans, for fans.
Revision as of 14:50, 9 September 2023 by Thecornerman (talk | contribs)

A function for {{FEH skill availability}}. Has two functions:

  • main, where most of the program is executed
  • tierSet, which main calls to fill out the list of skills based on a given base skill name and number of tiers

local p = {}
local cargo = mw.ext.cargo

function p.main(frame)
	in_args = frame:getParent().args	-- fields from template call
	
	skills = {}; name = ''	-- list of skill names, and base skill name
	
	if in_args['skill'] ~= nil then	-- if a skill field is declared
		name = in_args['skill']	-- sets base name to that skill field
	else
		-- sets base name to page name
		name = tostring(mw.title.getCurrentTitle()):gsub("Attack", "Atk"):
			gsub("Speed", "Spd"):gsub("Defense", "Def"):
			gsub("Resistance", "Res"):gsub("⁄", "/")
	end
	
	if in_args['tiers'] ~= nil then	-- if tiers field is declared
		tierSet(in_args['tiers'])	-- calls function to fill skill list by tier
	elseif in_args['skill1'] ~= nil then	-- if skill1 field is declared
		skillList()	-- calls function to fill skill list by skill# fields
	else
		skills[1] = name	-- skill list is 1 item long, just base name
	end
	
	local length = #skills	-- sets length variable to length of skill list
	
	local args = {	-- additional arguments for cargo query
		-- what data to include
		where = "_pageNamespace=0 AND skill='" .. skills[1]:gsub("'", "\\'") .. "'",
		orderBy = 'sort'	-- how to sort data
	}
	
	-- lookup table for skills, converting skill name to a number
	-- using numbers allows ipairs to conserve the order of the skills
	local skl_lookup = {
		[skills[1]] = 1
	}
	
	local skl_hdr = ''	-- initializing sub-header for skill list in table
	
	if length > 1 then	-- if more than 1 skill is listed
		-- sets skill header; unnecessary for fewer than 1 skill
		skl_hdr = '|-\n' ..
				  '! ' .. skills[1] .. '\n'
	end
	
	local i = 0	-- initializing counter
	
	for i = 2, length do	-- loop for i between 2 and length
		-- expands "where" argument
		args['where'] = args['where'] ..
						" OR skill='" .. skills[i]:gsub("'", "\\'") .. "'"
		skl_lookup[skills[i]] = i	-- expands skill lookup table
		skl_hdr = skl_hdr .. '! ' .. skills[i] .. '\n'	-- expands skill header
	end
	
	local hdr = '! style="border-top-left-radius: 10px" '	-- main header
	
	if skl_hdr ~= '' then	-- if skill header is not blank
		-- first cell of main header needs rowspan to accommodate skill header
		hdr = hdr .. 'rowspan="2" '
	end
	
	hdr = hdr .. '| Method\n' ..	-- pimary text of main header
		  '! style="border-top-right-radius: 10px" '..
		  'colspan="' .. length .. '"| Data\n'
	
	-- availability table; numbered fields allows ipairs to iterate in order
	local avail = {
		[1] = {},
		[2] = {},
		[3] = {},
		[4] = {},
		[5] = {},
		[6] = {},
		[7] = {}
	}
	
	-- cargo query
	local results = cargo.query('FEH_skill_sets',
			'unit, _pageName, rarity, skill', args);
		local lastrar = 0	-- last row of avail filled
	
	for _, v in ipairs(results) do	-- iterates through cargo results
		rar = tonumber(v['rarity'])	-- rarity of unit
		skl = skl_lookup[v['skill']]	-- number corresponding to skill version
		
		if rar > lastrar then	-- if current rarity is greater than last
			lastrar = rar
		end
		
		-- if skill at given rarity has not appeared yet
		if avail[rar][skl] == nil or avail[rar][skl] == '—' then
			avail[rar][skl] = ''	-- declares as empty string
		else
			avail[rar][skl] = avail[rar][skl] .. ' • '	-- adds seperator
		end
		
		-- Sets first element of row to —.
		-- If unset, would appear as row of length 0.
		if avail[rar][1] == nil then -- if skill 1 at rarity has not appeared
			avail[rar][1] = '—'
		end
		
		-- adds unit
		avail[rar][skl] = avail[rar][skl] ..
			'[[' .. v['_pageName'] .. '|' .. v['unit'] .. ']]'
	end
	
	if in_args['trial'] ~= nil then	-- if trial field is declared
		avail[6][1] = in_args['trial']	-- sets trial data
		lastrar = 6	-- updates rarity
	end
	
	-- if seal1 or seal2 field is declared
	if in_args['seal1'] ~= nil or in_args['seal2'] ~= nil then
		lastrar = 7	-- updates last rarity
		
		for i = 1, length do	-- iterates i from 1 to length
			if in_args['seal' .. i] ~= nil then	-- if seal# exists
				avail[7][i] = in_args['seal' .. i]	-- adds seal# data to avail
			else
				avail[7][i] = "—"
			end
		end
	end
	
	-- initializes main output variable and temporary row variable
	local output = ''; local row = ''
	
	for k, v in ipairs(avail) do	-- iterates through avail table
		last = k == lastrar	-- when last row is reached
		
		if #v ~= 0 then	-- if row is not empty
			row = '|-\n'	-- starts new row
			if last then	-- if last row is reached
				-- adds corner rounding
				row = row .. '| style="border-bottom-left-radius: 10px" '
			end
			
			-- sets first cell of row
			if k == 6 then	-- tempest trials row
				row = row .. '| [[Tempest Trials]]\n'
			elseif k == 7 then	-- sacred seal row
				row = row .. '| [[Sacred Seal Forge]]\n'
			else	-- unit rows
				row = row .. '| Unit (' .. ('★'):rep(k) .. ')\n'
			end
			
			for i = 1, length do	-- iterates for each skill
				-- if last row and last column is reached
				if last and i == length then
					-- add corner rounding
					row = row .. '| style="border-bottom-right-radius: 10px" '
				end
				
				row = row .. '| '
				
				if v[i] == nil then	-- if table element is empy
					row = row .. '—'	-- sets cell to em dash
				else
					row = row .. v[i]	-- sets cell to element content
				end
				
				row = row .. '\n'
			end
			
			output = output .. row	-- adds row to output
		end
	end
	
	return hdr .. skl_hdr .. output	-- final output
end

function tierSet(tiers)
	local i = 0
	
	-- if tiers is set to + or II
	if tiers == '+' or tiers == 'II' then
		-- sets skill list as base name and base name with + or II
		skills[1] = name
		skills[2] = name .. tiers:gsub('II', ' II')
	else
		for i = 1, tiers do	-- iterates for number of specified tiers
			-- sets skill list as base name and tiers 1–# set
			skills[i] = name .. ' ' .. i
		end
	end
end

function skillList()
	local i = 1
	
	while in_args['skill' .. i] ~= nil do	-- for each skill# that exists
		skills[i] = in_args['skill' .. i]	-- adds skill# field to skill list
		i = i + 1	-- increment
	end
end

return p