Module:Trait

From HorizonXI Wiki

Documentation for this module may be created at Module:Trait/doc

--[[

A module for functions relating to job traits.

]]

local p = {}

--[[
tiers_to_jobs_table

Displays information about a job trait's different tiers in table format, given
the job trait name as a parameter. If no parameter is given, defaults to the
page name. Uses the Cargo table JobTraitUnlocks, which holds data set by the
{{job trait unlock}} templates on each job page.

Example:
{{#invoke:Trait|tiers to jobs table}} (on Attack Bonus page)

{{#invoke:Trait|tiers to jobs table|Attack Bonus}}
]]

function p.tiers_to_jobs_table(frame)
    local trait = frame.args[1]

	-- If no parameter, default to current page name
    if not trait or trait == '' then
    	trait = mw.title.getCurrentTitle().text
    end

	local cargo_result = mw.ext.cargo.query(
		"JobTraitUnlocks",
		[=[
			GROUP_CONCAT(CASE WHEN Job='Warrior' THEN Level END)=[[Warrior|WAR]],
			GROUP_CONCAT(CASE WHEN Job='Monk' THEN Level END)=[[Monk|MNK]],
			GROUP_CONCAT(CASE WHEN Job='White Mage' THEN Level END)=[[White Mage|WHM]],
			GROUP_CONCAT(CASE WHEN Job='Black Mage' THEN Level END)=[[Black Mage|BLM]],
			GROUP_CONCAT(CASE WHEN Job='Red Mage' THEN Level END)=[[Red Mage|RDM]],
			GROUP_CONCAT(CASE WHEN Job='Thief' THEN Level END)=[[Thief|THF]],
			GROUP_CONCAT(CASE WHEN Job='Paladin' THEN Level END)=[[Paladin|PLD]],
			GROUP_CONCAT(CASE WHEN Job='Dark Knight' THEN Level END)=[[Dark Knight|DRK]],
			GROUP_CONCAT(CASE WHEN Job='Beastmaster' THEN Level END)=[[Beastmaster|BST]],
			GROUP_CONCAT(CASE WHEN Job='Bard' THEN Level END)=[[Bard|BRD]],
			GROUP_CONCAT(CASE WHEN Job='Ranger' THEN Level END)=[[Ranger|RNG]],
			GROUP_CONCAT(CASE WHEN Job='Summoner' THEN Level END)=[[Summoner|SMN]],
			GROUP_CONCAT(CASE WHEN Job='Samurai' THEN Level END)=[[Samurai|SAM]],
			GROUP_CONCAT(CASE WHEN Job='Ninja' THEN Level END)=[[Ninja|NIN]],
			GROUP_CONCAT(CASE WHEN Job='Dragoon' THEN Level END)=[[Dragoon|DRG]],
			GROUP_CONCAT(CASE WHEN Job='Blue Mage' THEN Level END)=[[Blue Mage|BLU]],
			GROUP_CONCAT(CASE WHEN Job='Corsair' THEN Level END)=[[Corsair|COR]],
			GROUP_CONCAT(CASE WHEN Job='Puppetmaster' THEN Level END)=[[Puppetmaster|PUP]],
			GROUP_CONCAT(CASE WHEN Job='Dancer' THEN Level END)=[[Dancer|DNC]],
			GROUP_CONCAT(CASE WHEN Job='Scholar' THEN Level END)=[[Scholar|SCH]],
			GROUP_CONCAT(CASE WHEN Job='Geomancer' THEN Level END)=[[Geomancer|GEO]],
			GROUP_CONCAT(CASE WHEN Job='Rune Fencer' THEN Level END)=[[Rune Fencer|RUN]]
		]=],
		{
			where = "Trait='" .. trait .. "'",
			orderBy = "Tier",
			groupBy = "Tier"
		}
	)

	if not cargo_result or not cargo_result[1] then
		local message = mw.html.create("p")
		message:wikitext("No jobs learn this trait by leveling up. It may be granted by equipment only.")
		return tostring(message)
	end

	local jobs =
		{
			"[[Warrior|WAR]]",
			"[[Monk|MNK]]",
			"[[White Mage|WHM]]",
			"[[Black Mage|BLM]]",
			"[[Red Mage|RDM]]",
			"[[Thief|THF]]",
			"[[Paladin|PLD]]",
			"[[Dark Knight|DRK]]",
			"[[Beastmaster|BST]]",
			"[[Bard|BRD]]",
			"[[Ranger|RNG]]",
			"[[Summoner|SMN]]",
			"[[Samurai|SAM]]",
			"[[Ninja|NIN]]",
			"[[Dragoon|DRG]]",
			"[[Blue Mage|BLU]]",
			"[[Corsair|COR]]",
			"[[Puppetmaster|PUP]]",
			"[[Dancer|DNC]]",
			"[[Scholar|SCH]]",
			"[[Geomancer|GEO]]",
			"[[Rune Fencer|RUN]]"
		}

	-- prune empty columns from jobs, iterating backwards
	for i = #jobs, 1, -1 do
		if not cargo_result[1][jobs[i]] then
			table.remove(jobs, i)
		end
	end

	-- render the table
	local root = mw.html.create("table")
        :addClass("ffxi-table horizon-table sortable")
        :css("width", "auto")
        :css("text-align", "center")

    -- Table header row
    local header_row = root:tag("tr")

    header_row
		:tag("th")
		:attr("scope", "col")
		:wikitext("Tier")
		:done()

	for _, j in ipairs(jobs) do
		local header = header_row:tag("th")

		if j == "[[Blue Mage|BLU]]" or j == "[[Corsair|COR]]" or j == "[[Puppetmaster|PUP]]" then
			header:addClass("toau")
		elseif j == "[[Dancer|DNC]]" or j == "[[Scholar|SCH]]" then
			header:addClass("wotg")
		elseif j == "[[Geomancer|GEO]]" or j == "[[Rune Fencer|RUN]]" then
			header:addClass("soa")
		end

		header
			:attr("scope", "col")
			:addClass("unsortable")
			:wikitext(j)
			:done()
	end

    -- Table rows
	for tier, cargo_row in ipairs(cargo_result) do

        local row = root:tag("tr")

        row
        	:tag("td")
        	:attr("data-sort-value", tier)
        	:css("text-align", "left")
        	:wikitext(trait)
			:wikitext(
				tier == 2 and ' II' or
				tier == 3 and ' III' or
				tier == 4 and ' IV' or
				tier == 5 and ' V' or
				tier == 6 and ' VI' or
				''
			)
        	:done()

		for _, j in ipairs(jobs) do
			local cell = row:tag("td")
			
			if j == "[[Blue Mage|BLU]]" or j == "[[Corsair|COR]]" or j == "[[Puppetmaster|PUP]]" then
				cell:addClass("toau")
			elseif j == "[[Dancer|DNC]]" or j == "[[Scholar|SCH]]" then
				cell:addClass("wotg")
			elseif j == "[[Geomancer|GEO]]" or j == "[[Rune Fencer|RUN]]" then
				cell:addClass("soa")
			end
			
			cell:wikitext(cargo_result[tier][j] or "—")
			
			cell:done()
		end
		
		row:done()
    end
    
    root:done()
    
    return tostring(root)
end

p["tiers to jobs table"] = p.tiers_to_jobs_table -- alias

return p