WARFRAME Wiki
Advertisement
WARFRAME Wiki

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

---	'''Mods/infobox''' builds the infobox on mod pages and adds the 
--	appropriate category pages.<br />
--
--	@module		Mods
--	@alias		p
--	@author			[[User:FINNER|FINNER]]
--	@attribution	[[User:Cephalon Scientia|Cephalon Scientia]]
--	@attribution	[[User:Trajos|Trajos]]
--	@image		
--	@require	[[Module:Version]]
--	@require	[[Module:Polarity]]
--	@require	[[Module:Tooltips]]
--	@require	[[Module:DropTables]]
--	@require	[[Module:Vendors]]
--	@require	[[Module:Baro]]
--	@require	[[Module:InfoboxBuilder]]
--	@require	[[Module:Mods/data]]
--	@require	[[Module:DropTables/data]]
--	@release	stable
--	<nowiki>
local Version = require([[Module:Version]])
local Polarity = require([[Module:Polarity]])
local Tooltip = require([[Module:Tooltips]])
local DropTable = require([[Module:DropTables]])
local Vendor = require([[Module:Vendors]])
local Baro = require([[Module:Baro]])
local InfoboxBuilder = require([[Module:InfoboxBuilder]])
local Lang = mw.language.new('en')	-- Using for number formatting
local ModData = mw.loadData([[Module:Mods/data]])
local DropData = mw.loadData([[Module:DropTables/data]])

local function makeMTooltip(modTable)
	local str = {}
	for _, modIndex in ipairs(modTable) do
		table.insert(str, Tooltip.full(modIndex, 'Mods'))
	end
	return table.concat(str, '<br />')
end

-- For calculating Endo cost to max a mod
-- Note that there exist additional displayed rarities (e.g. Peculiar, Requiem)
-- that share one of the below 4 values
local RARITY_EMUM = {
	Common = 1,
	Uncommon = 2,
	Rare = 3,
	Legendary = 4,
}

-- Trading tax of mod in Credits
local TAX_MAP = {
	Common = 2000,
	Uncommon = 4000,
	Rare = 8000,
	Legendary = 1000000,
}

-- Mapping internal icon text to file links as stored on the wiki
local ICON_TEXT_MAP = {
	['<DT_IMPACT>'] = '[[File:Impact_b.png|x16px|class=dark-invert]]',
	['<DT_PUNCTURE>'] = '[[File:Puncture_b.png|x16px|class=dark-invert]]',
	['<DT_SLASH>'] = '[[File:Slash_b.png|x16px|class=dark-invert]]',
	['<DT_FIRE>'] = '[[File:Heat_b.png|x16px|class=dark-invert]]',
	['<DT_FREEZE>'] = '[[File:Cold_b.png|x16px|class=dark-invert]]',
	['<DT_ELECTRICITY>'] = '[[File:Electricity_b.png|x16px|class=dark-invert]]',
	['<DT_POISON>'] = '[[File:Toxin_b.png|x16px|class=dark-invert]]',
	['<DT_EXPLOSION>'] = '[[File:Blast_b.png|x16px|class=dark-invert]]',
	['<DT_RADIATION>'] = '[[File:Radiation_b.png|x16px|class=dark-invert]]',
	['<DT_GAS>'] = '[[File:Gas_b.png|x16px|class=dark-invert]]',
	['<DT_MAGNETIC>'] = '[[File:Magnetic_b.png|x16px|class=dark-invert]]',
	['<DT_VIRAL>'] = '[[File:Viral_b.png|x16px|class=dark-invert]]',
	['<DT_CORROSIVE>'] = '[[File:Corrosive_b.png|x16px|class=dark-invert]]',
	['<DT_RADIANT>'] = '[[File:VoidTearIcon_b.png|x16px|class=dark-invert]]',
	['<DT_SENTIENT>'] = '[[File:Tau_b.png|x16px|class=dark-invert]]',
	['<AMMO_MUTATION>'] = '[[File:AmmoMutation.png|x16px|class=dark-invert]]',
	['<LINE_SEPARATOR>'] = '<hr />',
	['<ENERGY>'] = '[[File:IconEnergy.gif|x16px]]',
	['<SHIELD>'] = '[[File:IconShield.png|x16px]]',
	['<SECONDARY_FIRE>'] = '&lt;SECONDARY_FIRE&gt;'
}

return {
buildInfobox = function(frame)
	local args = frame.args;
	local name = mw.text.decode(args['Name']);
	local modData = ModData.Mods[name];
	
	assert(modData ~= nil, ('p.buildInfobox(frame): mod with name "%s" does not exist in [[Module:Mods/data]]'):format(name))
	
	local formattedModDesc = modData.Description
	local damageTypeName = formattedModDesc:match('<[A-Z_]+>')	-- Matching strings in the form of "<DT_TYPE>"
	if (damageTypeName ~= nil) then
		formattedModDesc = formattedModDesc:gsub(damageTypeName, ICON_TEXT_MAP[damageTypeName])
		
		-- Matching a second different icon text like in the case of Rending Strike mod
		if (formattedModDesc:match('<[A-Z_]+>') ~= nil) then
			damageTypeName = formattedModDesc:match('<[A-Z_]+>')
			formattedModDesc = formattedModDesc:gsub(damageTypeName, ICON_TEXT_MAP[damageTypeName])
		end
	end
	
	local incompatibilityTags = {}
	for _, tag in ipairs(modData.IncompatibilityTags or {}) do
		table.insert(incompatibilityTags, tag)
	end
	incompatibilityTags = table.concat(incompatibilityTags, ', ')
	
	local compatibilityTags = {}
	for _, tag in ipairs(modData.CompatibilityTags or {}) do
		table.insert(compatibilityTags, tag)
	end
	compatibilityTags = table.concat(compatibilityTags, ', ')
	
	-- TODO: Some reason this snippet does not output a non-empty string when modData.IncompatibilityTags is not nil nor empty
	-- while the above loop + table.concat works. Determine if this is an upstream issue with table.concat's implementation. 
	-- local incompatibilityTags = table.concat(modData.IncompatibilityTags, ', ')
	
	local Infobox = InfoboxBuilder('WARFRAME Wiki:L10n/general.json', 'WARFRAME Wiki:L10n/meta.json')
		:tag('title')
			:tag('default')
				:tag('b'):wikitext(name..'[[Category:Mods]]'):done()
			:done()
		:done()
		:tag('image'):attr('source', 'Image')
			:tag('default')
				:tag('gallery'):wikitext((modData.Image and modData.Image..'|Full' or '')..'\n'..(modData.Icon and modData.Icon..'|Icon' or '')):done()
			:done()
		:done()
		:group()
			:caption('Tradeable', modData.Tradable and '[[File:TradableIcon.png|x32px|class=icon dark-invert]] [[Trading|{{text|green|Tradeable}}]][[Category:Tradeable Mods]]' or '{{text|red|Untradeable}}[[Category:Untradeable Mods]]')
			:caption('Exilus', modData.IsExilus and '[[:Category:Exilus Mods|{{text|green|EXILUS}}]][[Category:Exilus Mods]]' or nil)
			:caption('Transmutable', modData.Transmutable and '[[Transmutation|{{text|green|Can be obtained from transmutation}}]][[Category:Transmutable Mods]]' or '[[Transmutation|{{text|red|Cannot be obtained from transmutation}}]][[Category:Untransmutable Mods]]')
			:caption('CodexSecret', modData.CodexSecret and '[[Codex|%s]][[Category:Codex Secret]]' or nil, 'codex-secret')
			:caption('UpdateInfoboxData', '[[Module:Mods/data|📝 %s]]', 'update-infobox-data')
		:done()
		
		:group():header('%s', 'max-rank-description')
			:caption('Description', formattedModDesc)
		:done()

		:group():header('%s', 'general-information')
			:row('Type', '[[Mod#Item Compatibility|%s]]', modData.Type and modData.Type..'[[Category:'..modData.Type..' Mods]]', 'type')
			:row('Polarity', '[[Polarity|%s]]', modData.Polarity and Polarity._polarity(modData.Polarity)..' '..modData.Polarity..'[[Category:'..modData.Polarity..' Mods]]', 'polarity')
			:row('Rarity', '[[Rarity|%s]]', modData.Rarity and modData.Rarity..'[[Category:'..modData.Rarity..' Mods]]', 'rarity')
			:row('Class', '%s', modData.Class and modData.Class..'[[Category:'..modData.Class..' Mods]]', 'class')
			:row('CompatibilityTags', '[[Compatibility Tag|%s]]', modData.CompatibilityTags and compatibilityTags, 'compatibility-tags')
			:row('Incompatible', 'Incompatible Mods', modData.Incompatible and makeMTooltip(modData.Incompatible))
			:row('IncompatibilityTags', '[[Compatibility Tag|%s]]', modData.IncompatibilityTags and incompatibilityTags, 'incompatibility-tags')
			:row('MaxRank', '%s', modData.MaxRank, 'max-rank')
			:row('EndoCost', '[[Endo]] Required To Max', (modData.Rarity ~= nil and not modData.NotUpgradable) and Lang:formatNum(10 * RARITY_EMUM[modData.Rarity] * (math.pow(2, modData.MaxRank) - 1)) or nil)
			:row('CreditCost', '[[Credits]] Required To Max', (modData.Rarity ~= nil and not modData.NotUpgradable) and Lang:formatNum(483 * RARITY_EMUM[modData.Rarity] * (math.pow(2, modData.MaxRank) - 1)) or nil)
			:row('BaseDrain', 'Base Capacity Cost', modData.BaseDrain)
			:row('TradingTax', '[[Trade System|%s]]', modData.Tradable and Tooltip.icon('Credits', 'Resources')..'&nbsp;'..Lang:formatNum(TAX_MAP[modData.Rarity]) or nil, 'trading-tax')
			:row('Introduced', '%s', modData.Introduced and Version._getVersionLink(modData.Introduced)..Version._getVersionCategory(modData.Introduced), 'introduced')
		:done()
	
	local vendorStr = Vendor._buildVendorSourceStrings(name)
	local baroStr = Baro._buildBaroSourceStrings(name)
	
	Infobox:group():header('%s', 'vendor-sources')
		:tag('data'):attr('source', 'Offerings')
			:tag('default')
				:tag('div'):addClass('tabber-borderless')
					:wikitext(('<tabber>%s%s</tabber>'):format(
					(vendorStr ~= '') and '|-|Vendors='..vendorStr..'\n' or '',
					(baroStr ~= '') and '|-|Baro Ki\'Teer='..baroStr..'\n' or ''
				)):done()
			:done()
		:done()
	:done()
	:group():header('%s', 'official-drop-tables')
		:caption('official-drop-tables', 'https://www.warframe.com/droptables', 'official-drop-tables')
	:done()
	
	return frame:preprocess(tostring(Infobox))
end
}
Advertisement