Wiki Warframe

Utilisation du Wiki

Pour une meilleure utilisation du Wiki Warframe FR, merci d'activer les scripts Javascript lors de la consultation de certains pages, pour assurer le fonctionnement de certaines fonctionnalités.
Si vous souhaitez contribuer au Wiki, rejoignez-nous sur le Discord Warframe FR (espace wiki)

- Yazu 17:00 01/10/2022

EN SAVOIR PLUS

Wiki Warframe
S'inscrire
Advertisement

La documentation pour ce module peut être créée à Module:Warframes/doc

---	'''Warframes''' récupère et stock les données des [[Warframes]].<br/>
--  
--	Sur ce Wiki, Warframes est utilisé dans :
--	* {{t|WarframePage}}
--	* {{t|WarframeNavVisual}}
--
--	@module		warframes
--	@alias		p
--	@author		[[User:Falterfire|Falterfire]]
--	@attribution	[[User:FINNER|FINNER]]
--	@attribution	[[User:Flaicher|Flaicher]]
--	@attribution	[[User:Cephalon Scientia|Cephalon Scientia]]
--	@attribution	[[User:ADDRMeridan|ADDRMeridan]] (FR)
--	@attribution	[[User:Gigamicro|gigamicro]]
--	@image		IconWarframe.png
--	@require	[[Module:Warframes/data]]
--	@require	[[Module:Warframes/Conclave/data]]
--	@require	[[Module:Version]]
--	@require	[[Module:Polarity]]
--	@require	[[Module:Weapons]]
--	@require	[[Module:Table]]
--	@require	[[Module:String]]
--	@require	[[Module:Math]]
--	@require	[[Module:Tooltips]]
--	@release	stable
--	<nowiki>

local p = {}

local WarframeData = mw.loadData [[Module:Warframes/data]]
local ConclaveData = mw.loadData [[Module:Warframes/Conclave/data]]
local Version = require [[Module:Version]]
local Polarity = require [[Module:Polarity]]
local Weapons = require [[Module:Weapons]]
local Table = require [[Module:Table]]
local String = require [[Module:String]]
local Math = require [[Module:Math]]
local Tooltip = require [[Module:Tooltips]]

-- TODO: put this in another module maybe?
local function assertType(val, typ, num, fun)
	if type(val) ~= typ then
		error(('bad argument #%d to \'%s\' (%s expected, got %s)'):format(num, fun, typ, type(val)),3)
	end
end

function p._isPrime(wf)
	local name = wf.Name or wf
	local base, variant = name:match '%S+', name:match ' (%S+)'
	return variant and variant:lower() == 'prime', variant or 'Base', base
end

function p._buildName(base, variant)
	if variant and variant ~= '' and variant ~= 'Base' then
		return ('%s %s'):format(base, variant)
	else
		return base
	end
end

---	Returns a subset of Warframe entries as stored in <code>/data</code> or <code>/Conclave/data</code>.
--	@function		p._getWarframes
--	@param			{function} validateFunction Function to filter data by that returns a boolean value
--	@param[opt]		{boolean} ignoreSpecialWarframes If true, ignores special Warframes like Sevagoth's Shadow or Excalibur Umbra Prime
--	@param[opt]		{boolean} useConclaveData If true, uses <code>/Conclave/data</code>, otherwise uses <code>/data</code>
--	@return			{table} List of Warframe entries
function p._getWarframes(validateFunction, ignoreSpecialWarframes, useConclaveData)
	local wfs = {}
	
	if ignoreSpecialWarframes == nil then ignoreSpecialWarframes = false end
	if useConclaveData == nil then useConclaveData = false end
	assertType(ignoreSpecialWarframes, 'boolean', 2, 'p._getWarframes')
	assertType(useConclaveData, 'boolean', 3, 'p._getWarframes')
	
	for _, wf in Table.skpairs((useConclaveData and ConclaveData or WarframeData)["Warframes"]) do
		if validateFunction(wf) and not (ignoreSpecialWarframes and Table.contains(WarframeData["IgnoreInCount"], wf.Name)) then
			table.insert(wfs, wf)
		end
	end

	return wfs
end

---	Same as p._getWarframes, but uses <code>/Conclave/data</code>.
--	@function		p._getConclaveWarframes
--	@param			{function} validateFunction Function to filter data by that returns a boolean value
--	@return			{table} List of Warframe entries
function p._getConclaveWarframes(validateFunction)
	return p._getWarframes(validateFunction, false, true)
end

---	Lists each warframe as Tooltip(frame)..' ('..Tooltip(frame..' Prime')..')' or '[['..frame..']] ([['..frame..' Prime]])'
--	@function		p._linkList
--	@param			{table} wfs List of Warframes entries as seen in <code>/data</code>
--	@param			{boolean} doTooltip If true, Warframe names will have tooltips, otherwise 
--							  they will be normal article links
--	@return			{table} Resultant list of formatted Warframe name strings
function p._linkList(wfs, doTooltip)
	local variants = {}
	for key, wf in pairs(wfs) do
		local _, variant, base = p._isPrime(wf)
		if not variants[base] then variants[base] = {} end
		variants[base][variant] = wf
	end

	local link = doTooltip and Tooltip.getFullTooltip or function(name) return ('[[%s]]'):format(name) end
	local sort = function(a,b)
		if not a.Base or not b.Base then
			return not a.Base and b.base
		end
		return a.Base.Name < b.Base.Name
	end

	local out = {}
	for base, wfVariants in Table.skpairs(variants, sort) do
		-- Fallback to Prime variant since some base Warframes share different MR lock than Prime variant
		-- thus wfVariants.Base can be nil
		table.insert(out, link(wfVariants.Base and wfVariants.Base.Name or wfVariants.Prime.Name, 'Warframes'))
		vars = {}
		if (wfVariants.Base ~= nil) then
			for _, variant in ipairs{ wfVariants.Prime, wfVariants.Umbra } do
				table.insert(vars, link(variant.Name, 'Warframes'))
				-- local _ = variant == 'Base' or table.insert(vars, link(wfVariants[variant].Name, 'Warframes'))
			end
		end
		out[#out] = vars[1] and ('%s (%s)'):format(out[#out], table.concat(vars, ', ')) or out[#out]
	end
	return out
end

-- TODO: Refactor into a map of functions using attribute name as key to a function value
-- just like it is done in M:Weapons
local function getValue(Warframe, ValName, giveDefault, asString)
	if(giveDefault == nil) then giveDefault = false end
	if(asString == nil) then asString = false end

	if Warframe == nil then
		return nil
	end

	ValName = string.upper(ValName)
	if(ValName == "NAME") then
		if(Warframe.Name ~= nil) then
			return Warframe.Name
		else
			if (asString) then
				return ""
			else
				return nil
			end
		end
	elseif(ValName == "ARMORPLUS") then
		if(Warframe.Armor ~= nil) then
			if(asString) then
				local result = Math.round(Warframe.Armor, 1)
				if(Warframe.ArmorRank30 ~= nil) then
					result = result.." ("..Math.round(Warframe.ArmorRank30, 1).." au rang 30)"
				end
				return result
			else
				return Warframe.Armor
			end
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return ""
			else
				return nil
			end
		end
	elseif(ValName == "ARMORPLUSMINIMAL") then
		if(Warframe.Armor ~= nil) then
			if(asString) then
				local result = Math.round(Warframe.Armor, 1)
				if(Warframe.ArmorRank30 ~= nil) then
					result = result.." ("..Math.round(Warframe.ArmorRank30, 1)..")"
				end
				return result
			else
				return Warframe.Armor
			end
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return ""
			else
				return nil
			end
		end
	elseif(ValName == "ARMOR") then
		if(Warframe.Armor ~= nil) then
			return Warframe.Armor
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return "-"
			else
				return nil
			end
		end
	elseif(ValName == "ARMORRANK30") then
		if(Warframe.ArmorRank30 ~= nil) then
			return Warframe.ArmorRank30
		elseif(Warframe.Armor ~= nil) then
			return Warframe.Armor
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return "-"
			else
				return nil
			end
		end
	elseif(ValName == "AURAPOLARITY") then
		if(Warframe.AuraPolarity ~= nil) then
			if(asString and Warframe.AuraPolarity ~= "Aucun") then
				return Polarity._polarity(Warframe.AuraPolarity)
			else
				return Warframe.AuraPolarity
			end
		elseif giveDefault then
			return "Aucun"
		else
			return nil
		end
	elseif(ValName == "CONCLAVE") then
		if(Warframe.Conclave ~= nil) then
			return Warframe.Conclave
		else
			if (asString) then
				return ""
			else
				return nil
			end
		end
	elseif(ValName == "ENERGYPLUS") then
		if(Warframe.Energy ~= nil) then
			if(asString) then
				local result = Math.round(Warframe.Energy, 0.1)
				if(Warframe.EnergyRank30 ~= nil) then
					result = result.." ("..Math.round(Warframe.EnergyRank30, 0.1).." au rang 30)"
				else
					result = result.." ("..Math.round(Warframe.Energy * 1.5, 0.1).." au rang 30)"
				end
				return result
			else
				return Warframe.Energy
			end
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return ""
			else
				return nil
			end
		end
	elseif(ValName == "ENERGYPLUSMINIMAL") then
		if(Warframe.Energy ~= nil) then
			if(asString) then
				local result = Math.round(Warframe.Energy, 0.1)
				if(Warframe.EnergyRank30 ~= nil) then
					result = result.." ("..Math.round(Warframe.EnergyRank30, 0.1)..")"
				else
					result = result.." ("..Math.round(Warframe.Energy * 1.5, 0.1)..")"
				end
				return result
			else
				return Warframe.Energy
			end
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return ""
			else
				return nil
			end
		end
	elseif(ValName == "ENERGY") then
		if(Warframe.Energy ~= nil) then
			return Warframe.Energy
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return "-"
			else
				return nil
			end
		end
	elseif(ValName == "ENERGYRANK30") then
		if(Warframe.EnergyRank30 ~= nil) then
			return Warframe.EnergyRank30
		elseif(Warframe.Energy ~= nil) then
			return Math.round(Warframe.Energy * 1.5, 0.1)
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return "-"
			else
				return nil
			end
		end
	elseif(ValName == "HEALTHPLUS") then
		if(Warframe.Health ~= nil) then
			if(asString) then
				local result = Math.round(Warframe.Health, 1)
				if(Warframe.HealthRank30 ~= nil) then
					result = result.." ("..Math.round(Warframe.HealthRank30, 1).." au rang 30)"
				else
					result = result.." ("..Math.round(Warframe.Health * 3, 1).." au rang 30)"
				end
				return result
			else
				return Warframe.Health
			end
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return "-"
			else
				return nil
			end
		end
	elseif(ValName == "HEALTHPLUSMINIMAL") then
		if(Warframe.Health ~= nil) then
			if(asString) then
				local result = Math.round(Warframe.Health, 1)
				if(Warframe.HealthRank30 ~= nil) then
					result = result.." ("..Math.round(Warframe.HealthRank30, 1)..")"
				else
					result = result.." ("..Math.round(Warframe.Health * 3, 1)..")"
				end
				return result
			else
				return Warframe.Health
			end
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return "-"
			else
				return nil
			end
		end
	elseif(ValName == "HEALTH") then
		if(Warframe.Health ~= nil) then
			return Warframe.Health
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return "-"
			else
				return nil
			end
		end
	elseif(ValName == "HEALTHRANK30") then
		if(Warframe.HealthRank30 ~= nil) then
			return Warframe.HealthRank30
		elseif(Warframe.Health ~= nil) then
			return Warframe.Health * 3
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return "-"
			else
				return nil
			end
		end
	elseif(ValName == "EXILUSPOLARITY") then
		if(Warframe.ExilusPolarity ~= nil) then
			if(asString) then
				return Polarity._polarity(Warframe.ExilusPolarity)
			else
				return Warframe.ExilusPolarity
			end
		elseif giveDefault then
			return "Aucun"
		else
			return nil
		end
	elseif(ValName == "IMAGE") then
		if(Warframe.Image ~= nil) then
			return Warframe.Image
		elseif giveDefault then
			return "Panel.png"
		else
			return nil
		end
	elseif(ValName == "INTRODUCED") then
		if(Warframe.Introduced ~= nil) then
			local ver, num = Version._getVersion(Warframe.Introduced)
			if(ver ~= nil) then
				return Version.getVersionLink(Warframe.Introduced)
			else
				return "Inconnu"
			end
		elseif giveDefault then
			return ""
		else
			return nil
		end
	elseif(ValName == "VERNUM") then
		if(Warframe.Introduced ~= nil) then
			local ver, num = Version._getVersion(Warframe.Introduced)
			if(num ~= nil) then
				return num
			else
				return -1
			end
		elseif giveDefault then
			return -1
		else
			return nil
		end
	elseif(ValName == "MASTERY") then
		if(Warframe.Mastery ~= nil) then
			return Warframe.Mastery
		elseif giveDefault then
			return 0
		else
			return nil
		end
	elseif(ValName == "MOBILITY") then
		if(Warframe.Mobility ~= nil) then
			if(asString) then
				return Math.round(Warframe.Mobility, 0.1)
			else
				return Warframe.Mobility
			end
		elseif giveDefault then
			return "1"
		else
			return 1
		end
	elseif(ValName == "POLARITIES") then
		if(Warframe.Polarities ~= nil) then
			if(asString) then
				return Weapons.GetPolarityString(Warframe)
			else
				return Warframe.Polarities
			end
		elseif giveDefault then
			if(asString) then
				return "Aucune"
			else
				return {}
			end
		else
			return nil
		end
	elseif(ValName == "PORTRAIT") then
		if(Warframe.Portrait ~= nil) then
			return Warframe.Portrait
		elseif giveDefault then
			return "Panel.png"
		else
			return nil
		end
	elseif(ValName == "PROGENITOR") then
		if(Warframe.Progenitor ~= nil) then
			return "[[Damage/"..Warframe.Progenitor.." Damage|"..Warframe.Progenitor.."]]"
		elseif(giveDefault) then
			return "Inconnue"
		else
			return nil
		end
	elseif(ValName == "RELEASEDATE") then
		if(Warframe.Introduced ~= nil) then
			local relDate = Version._getVersionDate(Warframe.Introduced)
			if(relDate == nil) then 
				return "Inconnu"
			else
				return relDate
			end
		else
			return "Inconnue"
		end
	elseif(ValName == "SEX") then
		if(Warframe.Sex ~= nil) then
			return Warframe.Sex
		else
			return "Inconnu"
		end
	elseif(ValName == "SHIELDPLUS") then
		if(Warframe.Shield ~= nil) then
			if(asString) then
				local result = Math.round(Warframe.Shield, 1)
				if(Warframe.Shield > 0) then
					if(Warframe.ShieldRank30 ~= nil) then
						result = result.." ("..Math.round(Warframe.ShieldRank30, 1).." au rang 30)"
					else
						result = result.." ("..Math.round(Warframe.Shield * 3, 1).." au rang 30)"
					end
				end
				return result
			else
				return Warframe.Shield
			end
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return ""
			else
				return nil
			end
		end
	elseif(ValName == "SHIELDPLUSMINIMAL") then
		if(Warframe.Shield ~= nil) then
			if(asString) then
				local result = Math.round(Warframe.Shield, 1)
				if(Warframe.Shield > 0) then
					if(Warframe.ShieldRank30 ~= nil) then
						result = result.." ("..Math.round(Warframe.ShieldRank30, 1)..")"
					else
						result = result.." ("..Math.round(Warframe.Shield * 3, 1)..")"
					end
				end
				return result
			else
				return Warframe.Shield
			end
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return ""
			else
				return nil
			end
		end
	elseif(ValName == "SHIELD") then
		if(Warframe.Shield ~= nil) then
			if(Warframe.Shield == 0 and asString) then
				return "-"
			else
				return Warframe.Shield
			end
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return "-"
			else
				return nil
			end
		end
	elseif(ValName == "SHIELDRANK30") then
		if(Warframe.ShieldRank30 ~= nil) then
			return Warframe.ShieldRank30
		elseif(Warframe.Shield ~= nil) then
			if(Warframe.Shield == 0 and asString) then
				return "-"
			else
				return Warframe.Shield * 3
			end
		elseif(giveDefault) then
			return 0
		else
			if (asString) then
				return "-"
			else
				return nil
			end
		end
	elseif(ValName == "SPRINT") then
		if(Warframe.Sprint ~= nil) then
			if(asString) then
				return Math.round(Warframe.Sprint, 0.01)
			else
				return Warframe.Sprint
			end
		elseif giveDefault then
			return ""
		else
			return nil
		end
	elseif(ValName == "THEMES") then
		if(Warframe.Themes ~= nil) then
			return Warframe.Themes
		elseif giveDefault then
			return ""
		else
			return nil
		end
	elseif(ValName == "VAULTED") then
		if(Warframe.Vaulted ~= nil) then
			if(asString) then
				if (Warframe.Vaulted == true) then return "Oui" 
				elseif (Warframe.Vaulted == false) then return "Non"
				else return tostring(Warframe.Vaulted) 
				end
			else 
				return Warframe.Vaulted 
			end
		elseif giveDefault then
			return "Non"
		else
			return nil
		end
	elseif(ValName == "SUBSUMED") then
		if(Warframe.Subsumed ~= nil) then
			return "[["..Warframe.Subsumed.."]]"
		end
	elseif(ValName == "SUBSUMEDTT") then --the tooltip of subsumed ability
		if(Warframe.Subsumed ~= nil) then
			return Tooltip.getFullTooltip(Warframe.Subsumed, "Ability")
		end
	end
end

-- TODO: Use string.format to build resultant string
local function getWarframeComparisonRow(wframe, useRank30)
	if(useRank30 == nil) then useRank30 = false end
	local addOn = ""
	if(useRank30) then addOn = "Rank30" end
	local styleString = ""--"border: 1px solid lightgray;"
	local td = '|| style = "'..styleString..'" |'
	local result = ''
	result = '\n|-\n| style = "'..styleString..'"|[['..wframe.Name.."]]"
	result = result..td..getValue(wframe, "Health"..addOn, false, true)
	result = result..td..getValue(wframe, "Shield"..addOn, false, true)
	result = result..td..getValue(wframe, "Energy"..addOn, false, true)
	result = result..td..getValue(wframe, "Armor"..addOn, false, true)
	result = result..td..getValue(wframe, "Sprint", false, true)
	return result
end

-- TODO: Use string.format to build resultant string
local function getWarframeComparisonTable(Warframes, useRank30)
	local styleString = "border: 1px solid black;border-collapse: collapse;"
	local tHeader = ""
	tHeader = tHeader..'\n{| cellpadding="1" cellspacing="0" class="listtable sortable" style="font-size:11px;"'
	tHeader = tHeader..'\n!style="'..styleString..'"|Name'
	tHeader = tHeader..'\n! data-sort-type="number" style="'..styleString..'"|[[Attributs#Santé|Santé]]'
	tHeader = tHeader..'\n! data-sort-type="number" style="'..styleString..'"|[[Attributs#Boucliers|Boucliers]]'
	tHeader = tHeader..'\n! data-sort-type="number" style="'..styleString..'"|[[Attributs#Énergie|Énergie]]'
	tHeader = tHeader..'\n! data-sort-type="number" style="'..styleString..'"|[[Attributs#Armure|Armure]]'
	tHeader = tHeader..'\n! data-sort-type="number" style="'..styleString..'"|[[Mouvement#Courir|Sprint]]'
	local tRows = ""
	for i, wframe in Table.skpairs(Warframes) do
		local didWork, rowStr = pcall(getWarframeComparisonRow, wframe, useRank30)
		if(didWork)then
			tRows = tRows..rowStr
		else
			mw.log("Error trying to build row for "..wframe.Name..": "..rowStr)
		end
	end
 
	return tHeader..tRows.."\n|}[[Category:Table de Comparaison Automatique]]"
end

function p.getWarframeComparisonTable(frame)
	return getWarframeComparisonTable(WarframeData["Warframes"])
end

function p.getWarframeRank30ComparisonTable(frame)
	return getWarframeComparisonTable(WarframeData["Warframes"], true)
end

function p.getConclaveWarframeComparisonTable(frame)
	return getWarframeComparisonTable(ConclaveData["Warframes"])
end

function p.getConclaveWarframeRank30ComparisonTable(frame)
	return getWarframeComparisonTable(ConclaveData["Warframes"], true)
end

---	Returns a wikitable of all armor values of Warframes as seen on [[Armor#Warframe Armor and Effective Health]].
--	@function		p.getArmorChart
--	@param			{table} frame Frame object
--	@return			{string} Wikitext of resultant wikitable
function p.getArmorChart(frame)
	--replicating the array templates that used to be on page "Armor/Chart". This will replace those
	--first the table's top rows
	local chart = {'{| class="armortable" cellpadding="3" width="100%" style="line-height:90%; font-size:90%; border-collapse:collapse; text-align:center;"'}
	table.insert(chart, [[
|- style="background-color:lightgray;"
! width="15%" style="line-height: 100%;" | Armure
! width="15%" style="line-height:100%;" | Réduction des Dégâts
! width="70%" style="line-height:100%;" | Warframe
|-]])
	
	--then a local function to figure out the background color and damage reduction
	local function bgcolor(armor)
		--calculating the damage reduction from armor, and rounding it to two decimals
		local DR = tonumber(string.format("%.2f",(100*armor/(armor+300))))
		local color = 'E4BAD2'
		if DR > 90 then color = 'F26C4F'
		elseif DR > 80 then color = 'FF8878'
		elseif DR > 70 then color = 'F9AD81'
		elseif DR > 60 then color = 'FFC7A3'
		elseif DR > 50 then color = 'FFFFB3'
		elseif DR > 40 then color = 'D0F7BD'
		elseif DR > 30 then color = '98E5DA'
		elseif DR > 20 then color = '9ECFF6'
		elseif DR > 10 then color = 'C4ADCF'
		end
		--returning the background color's hexacode and DR
		return color, DR
	end
	
	--the table for collecting warframes under the armor values
	local armorTable ={}
	--next looping through the Warframes for that armor
	for i, warframe in Table.skpairs(WarframeData["Warframes"]) do
		--if armor value exists, and rank 30 armor value doesn't
		if warframe.Armor ~= nil then
			--creating a table for armor value if doesn't exist
			if armorTable[warframe.Armor] == nil then
				armorTable[warframe.Armor] = {}
			end
			--checking if has rank 30 value. If yes, insert the "name (unranked)" link to unranked value's table. Else the regular link
			if warframe.ArmorRank30 ~= nil then
				table.insert(armorTable[warframe.Armor], '[['..warframe.Name..'|'..warframe.Name..' (Rang 0)]]')
			else
				table.insert(armorTable[warframe.Armor], '[['..warframe.Name..']]')
			end
			--a second check whether the Warframe has rank 30 specific armor value, such as Nidus. If so, add the value again but this time "name (max rank)" to rank 30 value's table
			if warframe.ArmorRank30 ~= nil then
				--checking if the table for armor value exists, if not, create
				if armorTable[warframe.ArmorRank30] == nil then
					armorTable[warframe.ArmorRank30] = {}
				end
				--inserting the value
				table.insert(armorTable[warframe.ArmorRank30], '[['..warframe.Name..'|'..warframe.Name..' (Rang Max.)]]')
			end
		end
	end
	
	local armorRows = {}
	--looping through the armorTable with skpairs with the second argument as true, making its sorting reversed
	for armor, aTable in Table.skpairs(armorTable, true) do
		--getting background color and damage reduction values based on the armor
		local color, dr = bgcolor(armor)
		local bgColor = 'style="background-color:#'..color..'; border-top: 1px dotted black;"'
		--looping through the names of Warframe's with this armor value and inserting to tempList as links
		local tempList = {}
		for n, wfLink in pairs(aTable) do
			table.insert(tempList, wfLink)
		end
		--inserting the table's columns to armowRows, including list of Warframe links with "table.concat"
		table.insert(armorRows,'|'..bgColor..'|'..armor..'||'..bgColor..'|'..dr..'%||'..bgColor..'|'..table.concat(tempList, ', '))
	end
	--filling the rows to the chart
	table.insert(chart, table.concat(armorRows, '\n|-\n'))
	--finishing the table by closing it
	table.insert(chart, '|}')

	return table.concat(chart, '\n')
end

---	Gets the total count of Warframes in the game.
--	@function		p.getWarframeCount
--	@param			{table} frame Frame object
--	@return			{number} Number of Warframes in the game, including variants
function p.getWarframeCount(frame)
	local count = 0
	for i, val in Table.skpairs(WarframeData["Warframes"]) do
		if (not Table.contains(WarframeData["IgnoreInCount"], i)) then
			count = count + 1
		end
	end
	return count
end

---	Returns a list of Warframes that have a particular Mastery Rank unlock as seen on
--	[[Mastery Rank#Mastery Rank Benefits]].
--	@function		p.getMasteryShortList
--	@param			{table} frame Frame object with the first argument being the Mastery Rank to filter by
--	@return			{string} List of Warframes separated by ' • '
function p.getMasteryShortList(frame)
	local masteryRank = tonumber(frame.args[1])
	
	local frameArray = p._getWarframes(function(x) 
									if (x.Mastery ~= nil) then
										return x.Mastery == masteryRank
									end
									return masteryRank == 0
								end, true)
 
	local result = ""
	local shortList = p._linkList(frameArray, true)
	for i, pair in Table.skpairs(shortList) do
		if (string.len(result) > 0) then result = result.." • " end
		result = result..pair
	end
	return result
end

---	Returns a list of Warframes that are playable in [[Conclave]].
--	@function		p.getConclaveList
--	@param			{table} frame Frame object
--	@return			{string} Wikitext of bulleted list of Warframes
function p.getConclaveList(frame)
	local frameArray = p._getWarframes(function(x) 
									if (x.Conclave ~= nil) then
										return x.Conclave
									end
									return false
								end)
 
	local result = ""
	local shortList = p._linkList(frameArray, false)
	for i, pair in Table.skpairs(shortList) do
		result = result..'\n* '..pair
	end
	return result
end

-- TODO: Make this into a local function?
function p._getReleaseDateRow(warframe, prime)
	local result = '\n|-'
	result = result..'\n| [['..warframe.Name..']] || '..getValue(warframe, 'SEX')..' || '..getValue(warframe, 'RELEASEDATE')..' || '
	
	local ver, num = getValue(warframe, 'INTRODUCED')
	if(ver ~= nil) then
		result = result..'data-sort-value="'..getValue(warframe, "VERNUM")..'" | '..ver
	end
	
	if (prime) then
		result = result..' || '..getValue(warframe, "VAULTED", true, true)	
	end
	
	return result
end

--- Builds a wikitable of the release dates of each Warframe.
--	@function			p.getReleaseDateTable
--	@param				{table} frame
--	@return				{string} Wikitext of wikitable
function p.getReleaseDateTable(frame)
	local category = frame.args ~= nil and frame.args[1] or frame
	if (category ~= nil) then category = string.upper(category) end
	
	local prime = false
	
	local warframes = {}
	local comparator = nil
	if (category == nil or category == "" or category == "ALL") then
		comparator = function(wf) return true end
	elseif (category == "ORIGINAL") then
		comparator = function(wf) return not p._isPrime(wf) end
	elseif (category == "PRIME") then
		comparator = function(wf) return p._isPrime(wf) end
		prime = true
	elseif (category == "FEMALE") then
		comparator = function(wf) return wf.Sex == "Féminine" or wf.Sex == "Androgyne" end
	elseif (category == "MALE") then
		comparator = function(wf) return wf.Sex == "Masculine" or wf.Sex == "Androgyne" end
	end
	
	warframes = p._getWarframes(comparator, true)
	
	local result = [[
{| class="listtable sortable" style="width:100%; white-space:nowrap;" align="center"'
|-
! data-sort-type="text" | Nom de la Warframe
! data-sort-type="text" | Sexe
! data-sort-type="date" | Date de Sortie <small>(<i>jour-mois-année</i>)</small>
! | Mise à Jour de Version
]]

	if (prime) then result = result..'\n! data-sort-type="text" | En Soute Prime<br>' end
	
	for name, warframe in pairs(warframes) do
		result = result..p._getReleaseDateRow(warframe, prime)
	end
	
	result = result..'\n|}'
	return result
end

---	Returns a wikitable of all sprint speed values of Warframes as seen on [[Sprint Speed]].
--	@function		p.getSprintList
--	@param			{table} frame Frame object
--	@return			{string} Wikitext of resultant wikitable
function p.getSprintList(frame)
	local sprintTable = { '{| class="emodtable" style="border:1px solid black; width:100%; border-collapse:collapse; text-align:center;"\n|-\n! style="white-space:nowrap; width:20%;"|Vitesses de Sprint \n!Warframes' }
	local tempTable = {} -- for storing the sorted data
	
	for warframe, wfData in Table.skpairs(WarframeData["Warframes"]) do --going through the Warframes in order with Table.skpairs
		local speedTemp = wfData["Sprint"]
		if speedTemp and tempTable[speedTemp] == nil then --if sprint speed exists and a table for one this doesn't
			tempTable[speedTemp] = {} --create a table for this speed
			table.insert(tempTable[speedTemp], wfData["Name"]) --insert the warframe to this speed
		elseif speedTemp then
			table.insert(tempTable[speedTemp], wfData["Name"])
		end
	end

	for speed, speedData in Table.skpairs(tempTable, true) do --going through the sorted data in order
		table.insert(sprintTable, '\n|-\n|'..speed..'\n|') --inserting the speed as the "header"
		for nn, fName in pairs(speedData) do
			table.insert(sprintTable, Tooltip.getFullTooltip(fName, 'Warframes'))
			if (nn < #speedData) then --if table position is less than table's length, insert comma
				table.insert(sprintTable,', ')
			end
		end
	end
	table.insert(sprintTable, '\n|}')
	return table.concat(sprintTable)
end

--- Builds visual navigation box element for Warframes as seen on [[Template:WarframeNavVisual]].
--	@function		buildWarframeVisualBox
--	@param			{table} wf Base Warframe table entry as seen in <code>/data</code>
--	@param[opt]		{table} primeWf Prime Warframe table entry as seen in <code>/data</code>
--	@param[opt]		{boolean} conclave If true, links go to Conclave namespace, false otherwise; default is false
--	@return			{string} Resultant wikitext of navigation bar
local function buildWarframeVisualBox(wf, primeWf, conclave)
	local hasPrime = primeWf ~= nil
	local defaultLink = conclave and conclave ~= '' and 'Conclave:'..wf.Link or wf.Link

	local ret = ('<div class="WarframeNavBox"><div class="WarframeNavBoxImage" %s>[[File:%s|64px|link=%s]]</div><span class="WarframeNavBoxText">[[%s|<span style="color:%s;">%s</span>]]%s</span>'):format(
		hasPrime and '' or 'style="transition:0s"',
		wf.Portrait,
		defaultLink,
		defaultLink,
		hasPrime and 'gold' or 'white',
		wf.Name,
		hasPrime and '⭐' or ''
	)
	
	ret = ret..('<div class="WarframeNavBoxImage2" %s>[[File:%s|64px|link=%s]]</div>'):format(
		hasPrime and '' or 'style="transition:0s"',
		hasPrime and primeWf.Portrait or wf.Portrait,
		defaultLink
	)

	return ret..'</div>'
end

--- Builds visual navigation bar for Warframes as seen on [[Template:WarframeNavVisual]].
--	@function		p.buildWarframeVisualNav
--	@param			{table} frame Frame object
--	@return			{string} Resultant wikitext of navigation bar
function p.buildWarframeVisualNav(frame)
	local conclave = frame.args['conclave']
	local wfList, primeList

	if (conclave and conclave ~= '') then
		wfList = p._getWarframes(function(wf)
				return string.find(wf.Name, "Prime") == nil and string.find(wf.Name, "Umbra") == nil and wf.Conclave
			end, true)
		primeList = p._getWarframes(function(wf)
				return string.find(wf.Name, "Prime") ~= nil and wf.Conclave
			end, true)
	else
		wfList = p._getWarframes(function(wf)
				return string.find(wf.Name, "Prime") == nil and string.find(wf.Name, "Umbra") == nil
			end, true)
		primeList = p._getWarframes(function(wf)
				return string.find(wf.Name, "Prime") ~= nil
			end, true)
	end

	local ret = { '<div class="flex-container">' }
	local found = false
	for _, wf in ipairs(wfList) do
		for i = 1, #primeList do
			if primeList[i].Name == wf.Name..' Prime' then
				table.insert(ret, buildWarframeVisualBox(wf, primeList[i], conclave))
				primeList[i] = primeList[#primeList]
				primeList[#primeList] = nil
				found = true
				break
			end
		end
		if not found then
			table.insert(ret, buildWarframeVisualBox(wf, nil, conclave))
		end
		found = false
	end
	table.insert(ret, '</div>')

	return table.concat(ret)
end

return p
Advertisement