◆少前百科是非盈利性、非官方的少女前线维基百科。
◆如果您发现某些内容错误/空缺,请勇于修正/添加!参与进来其实很容易!点这里 加入少前百科
◆有任何意见、建议、纠错,欢迎在 GFwiki:反馈与建议 提出和讨论。编辑事务讨论QQ群:597764980,微博@GFwiki少前百科
◆To foreigners,You can use twitter to contact us.
Icon Nyto Silver.png

“模块:Equip info”的版本间的差异

来自少前百科GFwiki
跳转至: 导航搜索
 
(未显示同一用户的20个中间版本)
第17行: 第17行:
 
local costh = {'人力', '弹药', '口粮', '零件', '开发值'}
 
local costh = {'人力', '弹药', '口粮', '零件', '开发值'}
 
local equip
 
local equip
 +
local mid
 +
local all_bonuses = {}
 +
 +
local function setProperties()
 +
local obtains = {}
 +
for _,k in ipairs(edata.obtain) do obtains[#obtains+1] = odata[k] end
 +
local set = mw.getCurrentFrame():callParserFunction('#set', {
 +
'', ['编号'] = mid, ['图片'] = edata.code .. '.png',
 +
['页面名称'] = edata.altname or edata.name,
 +
['装备名称'] = edata.name, ['类型1'] = cats[tdata[edata.etype].category],
 +
['类型2'] = tdata[edata.etype].name,
 +
['获得途径'] = table.concat(obtains, '/'), ['描述'] = edata.intro,
 +
['装备属性描述'] = table.concat(all_bonuses, '<br>')
 +
})
 +
local categories = {}
 +
if edata.fits then for _,i in ipairs(edata.fits) do
 +
table.insert(categories, string.format('[[分类:%s专属装备]]', xdata[i][1])) end end
 +
root:wikitext(set .. table.concat(categories))
 +
end
 +
 +
local function makeCard(d, f, p)
 +
local typeinfo = tdata[d.etype]
 +
local desc = d.desc
 +
local dollar = (mw.ustring.find(desc, '$', 1, true))
 +
if dollar ~= nil and mw.ustring.sub(desc, dollar-4, dollar-1) == '<hr>' then
 +
desc = mw.ustring.gsub(desc, '%$', '')
 +
else desc = mw.ustring.gsub(desc, '%$', '<hr>') end
 +
for i = #bonuses, 1, -1 do
 +
local v = bonuses[i]
 +
if d[v] ~= nil and mw.ustring.find(desc, v) ~= nil then
 +
local rpl = d[v][2]
 +
if d.bonus_type ~= nil and d.bonus_type[v] ~= nil then
 +
rpl = math.floor(rpl*(1+d.bonus_type[v]/1000)) end
 +
desc = mw.ustring.gsub(desc, v, string.format('span>%d</span', rpl))
 +
end
 +
end
 +
local hrf = mw.ustring.gmatch(desc, '<hr>')
 +
local hrn = 0
 +
while true do if hrf() then hrn = hrn + 1 else break end end
 +
if hrn < 2 then desc = string.gsub(desc, '<hr>', '<hr>&nbsp;<hr>') end
 +
return f:expandTemplate{title = '装备/card', args = {
 +
['类型编号'] = d.etype,
 +
['星级'] = d.rank,
 +
['代号'] = d.code,
 +
['页面'] = p ~= nil and d.altname or d.name,
 +
['名称'] = d.name,
 +
['类别'] = cats[typeinfo.category],
 +
['类型'] = typeinfo.name,
 +
['描述'] = mw.ustring.gsub(desc, '<%%>', '<span>%</span>')
 +
}}
 +
end
 +
 +
local function findRelated()
 +
if edata.fits ~= nil then
 +
local fits = {}
 +
local allrels = {}
 +
for _, g in ipairs(edata.fits) do
 +
local rels = {}
 +
for _, e in ipairs(xdata[g][2]) do
 +
if e ~= mid then rels[#rels+1] = e end
 +
end
 +
if #rels > 0 then
 +
fits[#fits+1] = g
 +
allrels[#allrels+1] = rels
 +
end
 +
end
 +
if #fits > 0 then return fits, allrels end
 +
end
 +
end
 +
 +
local function addRelated()
 +
local fits, allrels = findRelated()
 +
if fits ~= nil then
 +
equip:tag('h2'):addClass('relate-tab'):wikitext('关联专属')
 +
local div = equip:tag('div'):addClass('equip-related')
 +
local f = mw.getCurrentFrame()
 +
for i, g in ipairs(fits) do
 +
local sgun = div:tag('div'):tag('div'):wikitext(xdata[g][1]):done():tag('div')
 +
for _, e in ipairs(allrels[i]) do
 +
sgun:wikitext(makeCard(data[e], f, 1)) end
 +
end
 +
end
 +
end
 +
 +
local function addSuit(egd)
 +
local div = equip:tag('div'):addClass('equip-suit')
 +
local suit = div:tag('table')
 +
suit:tag('tr')
 +
:tag('td'):wikitext(string.format('[[File:%s.png|link=]]<br>%s', egd.code, egd.name)):done()
 +
:tag('td'):wikitext(egd.des)
 +
local se = div:tag('div')
 +
local f = mw.getCurrentFrame()
 +
local groupSize = 3
 +
for _, e in ipairs(egd.equip_unit) do
 +
if e ~= mid and e ~= 0 then se:wikitext(makeCard(data[e], f, 1)) end
 +
if e == 0 then groupSize = groupSize - 1 end
 +
end
 +
if groupSize == 3 then
 +
suit:tag('tr'):tag('td'):attr('colspan', 2):wikitext("'''装备2件:'''", egd.group_skill1)
 +
suit:tag('tr'):tag('td'):attr('colspan', 2):wikitext("'''装备3件:'''", egd.group_skill2)
 +
else
 +
suit:tag('tr'):tag('td'):attr('colspan', 2):wikitext("'''装备2件:'''", egd.group_skill2)
 +
end
 +
end
 +
 +
local function addSuits()
 +
local egd = mw.loadData('Module:Equip info/group data')
 +
equip:tag('h2'):addClass('suit-tab'):wikitext('套装信息')
 +
for _, g in ipairs(edata.equip_group_id) do
 +
addSuit(egd[g])
 +
end
 +
end
  
 
local function addResources()
 
local function addResources()
第23行: 第135行:
 
if edata.rank ~= 2 and edata.max_level ~= 0 then
 
if edata.rank ~= 2 and edata.max_level ~= 0 then
 
local xp = 2500*2^(edata.rank-3)
 
local xp = 2500*2^(edata.rank-3)
if edata.fits ~= nil and edata.exclusive_rate == nil then xp = xp*3 end
+
if edata.fits ~= nil then xp = xp*(edata.exclusive_rate or 3) end
 
local cost = edata.powerup_cost or costs[edata.etype]
 
local cost = edata.powerup_cost or costs[edata.etype]
 
if cost == nil then
 
if cost == nil then
第69行: 第181行:
 
'<span>' .. formattime(edata.develop_duration) .. '</span>')
 
'<span>' .. formattime(edata.develop_duration) .. '</span>')
 
end
 
end
 +
end
 +
 +
local function percent(i)
 +
return (i == 6 or i == 7 or i == 10) and '%' or ''
 
end
 
end
  
第75行: 第191行:
 
thead:tag('th'):wikitext('强化等级')
 
thead:tag('th'):wikitext('强化等级')
 
for i, _ in ipairs(bonuses) do
 
for i, _ in ipairs(bonuses) do
if growing[i] ~= nil then thead:tag('th'):wikitext(
+
if growing[i] ~= nil then
string.format('[[File:Data %s.png|link=]]%s', unpack(titles[i])))
+
thead:tag('th'):wikitext(string.format(
 +
'[[File:Data %s.png|link=]]%s', unpack(titles[i])))
 +
local range, bonus = unpack(growing[i])
 +
table.insert(all_bonuses, string.format('%s%+d%s',
 +
titles[i][2], math.floor(range[2]*(1+bonus/1e3)), percent(i)))
 
end
 
end
 
end
 
end
第86行: 第206行:
 
local range, bonus = unpack(growing[i])
 
local range, bonus = unpack(growing[i])
 
local td = tr:tag('td')
 
local td = tr:tag('td')
if range[1] == range[2] then td:wikitext('+', math.floor(range[1]*(1+bonus*lv/1e4)))
+
local pct = percent(i)
else td:wikitext(string.format('<span>%+d</span><span>%+d</span>',
+
if range[1] == range[2] then td:wikitext('+', math.floor(range[1]*(1+bonus*lv/1e4)), pct)
math.floor(range[1]*(1+bonus*lv/1e4)), math.floor(range[2]*(1+bonus*lv/1e4))))
+
else
 +
td:wikitext(string.format('<span>%+d%s</span><span>%+d%s</span>',
 +
math.floor(range[1]*(1+bonus*lv/1e4)), pct,
 +
math.floor(range[2]*(1+bonus*lv/1e4)), pct))
 
end
 
end
 
end
 
end
第110行: 第233行:
 
p:tag('sub'):wikitext('校准率100%')
 
p:tag('sub'):wikitext('校准率100%')
 
end
 
end
 +
table.insert(all_bonuses, string.format('%s%+d%s', titles[i][2], vals[2], percent(i)))
 
end
 
end
 
end
 
end
if edata.sp_desc ~= nil then con:tag('p'):addClass('equip-sp'):wikitext(
+
if edata.sp_desc ~= nil then
'[[File:特殊技能icon.png|link=]]', edata.sp_desc) end
+
con:tag('p'):addClass('equip-sp'):wikitext(
 +
'[[File:特殊技能icon.png|link=]]', edata.sp_desc)
 +
table.insert(all_bonuses, edata.sp_desc)
 +
end
 
return tostring(con)
 
return tostring(con)
 
end
 
end
第121行: 第248行:
 
local div = equip:tag('div'):addClass('equip-spec')
 
local div = equip:tag('div'):addClass('equip-spec')
 
local fixed, growing, hasGrowing = {}, {}, false
 
local fixed, growing, hasGrowing = {}, {}, false
 +
local max_level = edata.max_level or (edata.etype == 4 and 0 or (edata.bonus_type and 10 or 0))
 
for i, v in ipairs(bonuses) do
 
for i, v in ipairs(bonuses) do
 
if edata[v] ~= nil then
 
if edata[v] ~= nil then
local bonus = edata.max_level ~= 0 and edata.bonus_type[v] or nil
+
local bonus = max_level ~= 0 and edata.bonus_type[v] or nil
 
if bonus ~= nil then
 
if bonus ~= nil then
 
growing[i] = {edata[v], bonus}
 
growing[i] = {edata[v], bonus}
第171行: 第299行:
 
banner:tag('span'):addClass('equip-banner-back1'):wikitext('DATASHEET')
 
banner:tag('span'):addClass('equip-banner-back1'):wikitext('DATASHEET')
 
banner:tag('span'):addClass('equip-banner-back2'):wikitext('装备详情')
 
banner:tag('span'):addClass('equip-banner-back2'):wikitext('装备详情')
end
 
 
local function makeCard(d, f)
 
local typeinfo = tdata[d.etype]
 
local desc = d.desc
 
local dollar = (mw.ustring.find(desc, '$', 1, true))
 
if mw.ustring.sub(desc, dollar-4, dollar-1) == '<hr>' then
 
desc = mw.ustring.gsub(desc, '%$', '')
 
else desc = mw.ustring.gsub(desc, '%$', '<hr>') end
 
for i = #bonuses, 1, -1 do
 
local v = bonuses[i]
 
if d[v] ~= nil and mw.ustring.find(desc, v) ~= nil then
 
local rpl = d[v][2]
 
if d.bonus_type ~= nil and d.bonus_type[v] ~= nil then
 
rpl = math.floor(rpl*(1+d.bonus_type[v]/1000)) end
 
desc = mw.ustring.gsub(desc, v, string.format('span>%d</span', rpl))
 
end
 
end
 
return f:expandTemplate{title = '装备/card', args = {
 
['类型图标'] = typeinfo.code,
 
['星级'] = d.rank,
 
['代号'] = d.code,
 
['名称'] = d.name,
 
['类别'] = cats[typeinfo.category],
 
['类型'] = typeinfo.name,
 
['描述'] = mw.ustring.gsub(desc, '<%%>', '<span>%</span>')
 
}}
 
 
end
 
end
  
第215行: 第316行:
  
 
local function _equipInfo(id)
 
local function _equipInfo(id)
 +
mid = id
 
root = mw.html.create()
 
root = mw.html.create()
 
edata = data[id]
 
edata = data[id]
第223行: 第325行:
 
addObtain()
 
addObtain()
 
addResources()
 
addResources()
 +
setProperties()
 +
if edata.equip_group_id ~= nil then addSuits() else addRelated() end
 
local f = mw.getCurrentFrame()
 
local f = mw.getCurrentFrame()
 
local styles = f:extensionTag{
 
local styles = f:extensionTag{

2024年2月29日 (四) 15:15的最新版本

此模块的文档可以在模块:Equip info/doc创建

local p = {}
local root
local data = mw.loadData('Module:Equip info/data')
local tdata = mw.loadData('Module:Equip info/type data')
local xdata = mw.loadData('Module:Gun info/ex data')
local odata = mw.loadData('Module:Gun info/obtain data')
local edata
local bonuses = {'pow', 'hit', 'dodge', 'speed', 'rate', 'critical_harm_rate',
	'critical_percent', 'armor_piercing', 'armor', 'night_view_percent', 'bullet_number_up'}
local titles = {{'Pow', '伤害'}, {'Hit', '命中'}, {'Dodge', '回避'},
	{'Move', '移速'}, {'Rate', '射速'}, {'CtPow', '暴伤'}, {'Ct', '暴击'},
	{'AP', '穿甲'}, {'Armor', '护甲'}, {'Night', '夜战'}, {'Bullet', '弹量'}}
local cats = {'配件', '弹匣', '人形'}
local costs = {[5] = {0.08, 0.5, 0.3, 0.3}, [6] = {0.48, 0.48, 0.08, 0.25},
	[7] = {0.08, 0.39, 0.08, 0.48}, [8] = {0.15, 0.6, 0.38, 0.23},
	[11] = {0.23, 0.23, 0.33, 0.33}}
local costh = {'人力', '弹药', '口粮', '零件', '开发值'}
local equip
local mid
local all_bonuses = {}

local function setProperties()
	local obtains = {}
	for _,k in ipairs(edata.obtain) do obtains[#obtains+1] = odata[k] end
	local set = mw.getCurrentFrame():callParserFunction('#set', {
		'', ['编号'] = mid, ['图片'] = edata.code .. '.png',
		['页面名称'] = edata.altname or edata.name,
		['装备名称'] = edata.name, ['类型1'] = cats[tdata[edata.etype].category],
		['类型2'] = tdata[edata.etype].name,
		['获得途径'] = table.concat(obtains, '/'), ['描述'] = edata.intro,
		['装备属性描述'] = table.concat(all_bonuses, '<br>')
	})
	local categories = {}
	if edata.fits then for _,i in ipairs(edata.fits) do
		table.insert(categories, string.format('[[分类:%s专属装备]]', xdata[i][1])) end end
	root:wikitext(set .. table.concat(categories))
end

local function makeCard(d, f, p)
	local typeinfo = tdata[d.etype]
	local desc = d.desc
	local dollar = (mw.ustring.find(desc, '$', 1, true))
	if dollar ~= nil and mw.ustring.sub(desc, dollar-4, dollar-1) == '<hr>' then
		desc = mw.ustring.gsub(desc, '%$', '')
	else desc = mw.ustring.gsub(desc, '%$', '<hr>') end
	for i = #bonuses, 1, -1 do
		local v = bonuses[i]
		if d[v] ~= nil and mw.ustring.find(desc, v) ~= nil then
			local rpl = d[v][2]
			if d.bonus_type ~= nil and d.bonus_type[v] ~= nil then
				rpl = math.floor(rpl*(1+d.bonus_type[v]/1000)) end
			desc = mw.ustring.gsub(desc, v, string.format('span>%d</span', rpl))
		end
	end
	local hrf = mw.ustring.gmatch(desc, '<hr>')
	local hrn = 0
	while true do if hrf() then hrn = hrn + 1 else break end end
	if hrn < 2 then desc = string.gsub(desc, '<hr>', '<hr>&nbsp;<hr>') end
	return f:expandTemplate{title = '装备/card', args = {
		['类型编号'] = d.etype,
		['星级'] = d.rank,
		['代号'] = d.code,
		['页面'] = p ~= nil and d.altname or d.name,
		['名称'] = d.name,
		['类别'] = cats[typeinfo.category],
		['类型'] = typeinfo.name,
		['描述'] = mw.ustring.gsub(desc, '<%%>', '<span>%</span>')
	}}
end

local function findRelated()
	if edata.fits ~= nil then
		local fits = {}
		local allrels = {}
		for _, g in ipairs(edata.fits) do
			local rels = {}
			for _, e in ipairs(xdata[g][2]) do
				if e ~= mid then rels[#rels+1] = e end
			end
			if #rels > 0 then
				fits[#fits+1] = g
				allrels[#allrels+1] = rels
			end
		end
		if #fits > 0 then return fits, allrels end
	end
end

local function addRelated()
	local fits, allrels = findRelated()
	if fits ~= nil then
		equip:tag('h2'):addClass('relate-tab'):wikitext('关联专属')
		local div = equip:tag('div'):addClass('equip-related')
		local f = mw.getCurrentFrame()
		for i, g in ipairs(fits) do
			local sgun = div:tag('div'):tag('div'):wikitext(xdata[g][1]):done():tag('div')
			for _, e in ipairs(allrels[i]) do
				sgun:wikitext(makeCard(data[e], f, 1)) end
		end
	end
end

local function addSuit(egd)
	local div = equip:tag('div'):addClass('equip-suit')
	local suit = div:tag('table')
	suit:tag('tr')
		:tag('td'):wikitext(string.format('[[File:%s.png|link=]]<br>%s', egd.code, egd.name)):done()
		:tag('td'):wikitext(egd.des)
	local se = div:tag('div')
	local f = mw.getCurrentFrame()
	local groupSize = 3
	for _, e in ipairs(egd.equip_unit) do
		if e ~= mid and e ~= 0 then se:wikitext(makeCard(data[e], f, 1)) end
		if e == 0 then groupSize = groupSize - 1 end
	end
	if groupSize == 3 then
		suit:tag('tr'):tag('td'):attr('colspan', 2):wikitext("'''装备2件:'''", egd.group_skill1)
		suit:tag('tr'):tag('td'):attr('colspan', 2):wikitext("'''装备3件:'''", egd.group_skill2)
	else
		suit:tag('tr'):tag('td'):attr('colspan', 2):wikitext("'''装备2件:'''", egd.group_skill2)
	end
end

local function addSuits()
	local egd = mw.loadData('Module:Equip info/group data')
	equip:tag('h2'):addClass('suit-tab'):wikitext('套装信息')
	for _, g in ipairs(edata.equip_group_id) do
		addSuit(egd[g])
	end
end

local function addResources()
	equip:tag('h2'):addClass('res-tab'):wikitext('资源收支')
	local div = equip:tag('div'):addClass('equip-res')
	if edata.rank ~= 2 and edata.max_level ~= 0 then
		local xp = 2500*2^(edata.rank-3)
		if edata.fits ~= nil then xp = xp*(edata.exclusive_rate or 3) end
		local cost = edata.powerup_cost or costs[edata.etype]
		if cost == nil then
			local t = edata.etype
			if t < 4 or t == 16 then cost = {.45,.15,.3,.15}
			elseif t == 9 or t == 10 then cost = {.3,.23,.15,.38}
			elseif t == 13 or t == 22 then cost = {.55,.23,.23,.23}
			elseif t == 14 or t == 21 then cost = {.1,.1,.1,.55}
			elseif t == 15 or t == 23 then cost = {.55,.16,.6,.16} end
		end
		local ctable = div:tag('table'):addClass('equip-cost')
		ctable:tag('caption'):wikitext('强化消耗')
		local th = ctable:tag('tr')
		for i = 1, 5 do th:tag('th'):wikitext(costh[i]) end
		local td = ctable:tag('tr')
		for i = 1, 4 do td:tag('td'):wikitext(math.floor(cost[i]*xp)) end
		td:tag('td'):wikitext(math.floor(xp))
	else div:tag('p'):wikitext('该装备不可强化') end
	local rtable = div:tag('table'):addClass('equip-return')
	rtable:tag('caption'):wikitext('拆解返还')
	local th = rtable:tag('tr')
	local td = rtable:tag('tr')
	for i = 1, 4 do
		th:tag('th'):wikitext(costh[i])
		td:tag('td'):wikitext(edata.retire[i])
	end
end

local function formattime(seconds)
	local minutes = math.floor(seconds/60)
	local hour = math.floor(minutes/60)
	minutes = minutes - hour*60
	return string.format('%02d:%02d:00', hour, minutes)
end

local function addObtain()
	equip:tag('h2'):addClass('obtain-tab'):wikitext('获取途径')
	local div = equip:tag('div'):addClass('equip-obtain')
	for _, v in ipairs(edata.obtain) do div:tag('p'):wikitext(odata[v]) end
	if edata.develop_duration then
		div:tag('div'):addClass('equip-develop'):wikitext(
			mw.getCurrentFrame():expandTemplate{
				title='fa', args={'clock', size='30px'}
			}, '<span>制造用时</span>',
			'<span>' .. formattime(edata.develop_duration) .. '</span>')
	end
end

local function percent(i)
	return (i == 6 or i == 7 or i == 10) and '%' or ''
end

local function addGrowing(growing, gtable)
	local thead = gtable:tag('tr')
	thead:tag('th'):wikitext('强化等级')
	for i, _ in ipairs(bonuses) do
		if growing[i] ~= nil then
			thead:tag('th'):wikitext(string.format(
				'[[File:Data %s.png|link=]]%s', unpack(titles[i])))
			local range, bonus = unpack(growing[i])
			table.insert(all_bonuses, string.format('%s%+d%s',
				titles[i][2], math.floor(range[2]*(1+bonus/1e3)), percent(i)))
		end
	end
	for lv = 0, 10 do
		local tr = gtable:tag('tr')
		tr:tag('td'):wikitext(lv)
		for i, _ in ipairs(bonuses) do
			if growing[i] ~= nil then
				local range, bonus = unpack(growing[i])
				local td = tr:tag('td')
				local pct = percent(i)
				if range[1] == range[2] then td:wikitext('+', math.floor(range[1]*(1+bonus*lv/1e4)), pct)
				else
					td:wikitext(string.format('<span>%+d%s</span><span>%+d%s</span>',
						math.floor(range[1]*(1+bonus*lv/1e4)), pct,
						math.floor(range[2]*(1+bonus*lv/1e4)), pct))
				end
			end
		end
	end
end

local function addFixed(fixed)
	local con = mw.html.create()
	for i, _ in ipairs(bonuses) do
		if fixed[i] ~= nil then
			local p = con:tag('p')
			p:wikitext(string.format('[[File:Data %s.png|link=]]%s',
				unpack(titles[i])))
			local vals = fixed[i]
			p:wikitext(string.format('<span%s>%+d</span>',
				vals[1] < 0 and ' style="color:red"' or '', vals[1]))
			if vals[1] ~= vals[2] then 
				p:tag('sub'):wikitext('校准率0%')
				p:wikitext(string.format('<span style="color:#ffb400">%+d</span>', vals[2]))
				p:tag('sub'):wikitext('校准率100%')
			end
			table.insert(all_bonuses, string.format('%s%+d%s', titles[i][2], vals[2], percent(i)))
		end
	end
	if edata.sp_desc ~= nil then
		con:tag('p'):addClass('equip-sp'):wikitext(
			'[[File:特殊技能icon.png|link=]]', edata.sp_desc)
		table.insert(all_bonuses, edata.sp_desc)
	end
	return tostring(con)
end

local function addSpec()
	equip:tag('h2'):addClass('spec-tab'):wikitext('装备数据')
	local div = equip:tag('div'):addClass('equip-spec')
	local fixed, growing, hasGrowing = {}, {}, false
	local max_level = edata.max_level or (edata.etype == 4 and 0 or (edata.bonus_type and 10 or 0))
	for i, v in ipairs(bonuses) do
		if edata[v] ~= nil then
			local bonus = max_level ~= 0 and edata.bonus_type[v] or nil
			if bonus ~= nil then
				growing[i] = {edata[v], bonus}
				hasGrowing = true
			else fixed[i] = edata[v] end
		end
	end
	div:wikitext(addFixed(fixed))
	if hasGrowing then
		local gtable = div:tag('table')
		addGrowing(growing, gtable)
	end
end

local function bannerLeft()
	local left = mw.html.create('div')
	local ex, ext = 'ex', '专属' 
	if edata.fits == nil then ex, ext = 'general', '通用' end
	left:wikitext(string.format(
		'[[File:%s_equipment_icon.png|link=]]<span class="cat cat-%s">%s装备</span>',
		ex, ex, ext))
	local fits = left:tag('div'):addClass('equip-fits-' .. ex)
	if ex == 'ex' then
		if edata.fits[2] == nil then
			fits:wikitext(xdata[edata.fits[1]][1])
		else fits:wikitext('多人专属') end
	else
		local types = tdata[edata.etype].fit_gun_type
		local gtypes = {'手枪', '冲锋枪', '狙击枪', '突击步枪', '机枪', '霰弹枪'}
		for _, v in ipairs(types) do fits:wikitext(string.format(
			'<abbr title="%s">[[File:反色图标平面-%s.png|link=]]</abbr>',
			(mw.ustring.gsub(gtypes[v], '狙击', '步')), gtypes[v]))
		end
	end
	return tostring(left)
end

local function addBanner()
	local banner = equip:tag('div'):addClass('equip-banner')
	local front = banner:tag('div'):addClass('equip-banner-front')
	front:wikitext(bannerLeft())
	front:tag('div'):addClass('equip-banner-sep')
	local right = front:tag('div'):addClass('equip-banner-right')
	right:tag('p'):wikitext(edata.intro)
	if edata.fits == nil then
		right:tag('div'):addClass('equip-note'):wikitext('*可能存在特殊人形不受枪种限制') end
	banner:tag('span'):addClass('equip-banner-back1'):wikitext('DATASHEET')
	banner:tag('span'):addClass('equip-banner-back2'):wikitext('装备详情')
end

local function addInfobox()
	local infobox = root:tag('div'):addClass('equip-infobox')
	local fitguns = {}
	if edata.fits ~= nil then
		for _, v in ipairs(edata.fits) do fitguns[#fitguns+1] = '<li>[[' .. xdata[v][1] .. ']]</li>' end
	end
	infobox:wikitext(makeCard(edata, mw.getCurrentFrame()))
	if #fitguns > 0 then
		infobox:tag('table')
			:tag('tr'):tag('th'):wikitext('适用人形'):done():done()
			:tag('tr'):tag('td'):tag('ul'):wikitext(table.concat(fitguns))
	end
end

local function _equipInfo(id)
	mid = id
	root = mw.html.create()
	edata = data[id]
	addInfobox()
	equip = root:tag('div'):addClass('equip')
	addBanner()
	addSpec()
	addObtain()
	addResources()
	setProperties()
	if edata.equip_group_id ~= nil then addSuits() else addRelated() end
	local f = mw.getCurrentFrame()
	local styles = f:extensionTag{
		name = 'templatestyles', args = { src = '模板:装备/styles.css' }
	}
	local cardstyles = f:extensionTag{
		name = 'templatestyles', args = { src = '模板:装备/card.css' }
	}
	return styles .. cardstyles .. tostring(root)
end

function p.equipInfo(frame)
	local args = frame == mw.getCurrentFrame() and frame:getParent().args or frame
	return _equipInfo(tonumber(args[1]))
end
return p