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

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

来自少前百科GFwiki
跳转至: 导航搜索
 
(未显示同一用户的75个中间版本)
第1行: 第1行:
 
local p = {}
 
local p = {}
 
local args = {}
 
local args = {}
local root
+
local super
 
local gundata
 
local gundata
local data = mw.loadData('Module:Gun info/data')
+
local mid
local infobox = require('Module:Infobox').infobox
+
local data
local guntype = { {'手枪', '冲锋枪', '步枪', '突击步枪', '机枪', '霰弹枪'},
+
local bdata = {}
 +
local etdata = mw.loadData('Module:Equip info/type data')
 +
local odata = mw.loadData('Module:Gun info/obtain data')
 +
local skindata = mw.loadData('Module:Gun info/skin data')
 +
local guntype = { {'手枪', '冲锋枪', '步枪', '突击步枪', '机枪', '霰弹枪', [0] = '所有枪种'},
 
{'HG', 'SMG', 'RF', 'AR', 'MG', 'SG'} }
 
{'HG', 'SMG', 'RF', 'AR', 'MG', 'SG'} }
local base_attr
+
local attrs = {'伤害', '射速', '命中', '回避', '暴击率', '技能冷却速度', '', '护甲'}
local basic = {16, 45, 5, 5}
+
local bonuses = {'pow', 'hit', 'dodge', 'speed', 'rate', 'critical_harm_rate',
local basic_lifearmors = {
+
'critical_percent', 'armor_piercing', 'armor', 'night_view_percent', 'bullet_number_up'}
{{55, 0.555}, {2, 0.161}},
+
local cardstyles = ''
{{96.283, 0.138}, {13.979, 0.04}}}
+
 
local grows = {
+
local function makeCard(d, f, p)
{{0.242, 0}, {0.181, 0}, {0.303, 0}, {0.303, 0}},
+
local cats = {'配件', '弹匣', '人形'}
{{0.06, 18.018}, {0.022, 15.741}, {0.075, 22.572}, {0.075, 22.572}}}
+
local typeinfo = etdata[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,
 +
['页面'] = p ~= nil and d.altname or d.name,
 +
['名称'] = d.name,
 +
['类别'] = cats[typeinfo.category],
 +
['类型'] = typeinfo.name,
 +
['描述'] = mw.ustring.gsub(desc, '<%%>', '<span>%</span>')
 +
}}
 +
end
 +
 
 +
local function putEquipments()
 +
local root = super:tag('div'):attr('id', 'equip-container')
 +
local function copy(t)
 +
local ret = {}
 +
for i, v in ipairs(t) do ret[i] = v end
 +
return ret
 +
end
 +
 +
local equips = {
 +
{{1, 4, 13, 16}, {2, 6}, {3,10}},
 +
{{3, 9, 10}, {2, 6}, {1, 1, 2, 3, 4, 13}},
 +
{{2, 5}, {1, 1, 2, 3, 13}, {3, 15}},
 +
{{1, 1, 2, 3, 4, 13}, {2, 8}, {3, 9, 10}},
 +
{{2, 5, 17}, {1, 1, 2, 3, 16}, {3, 14, 21}},
 +
{{3, 11}, {2, 7}, {1, 1, 2, 3, 4, 22}}
 +
}
 +
local defaults = equips[gundata.guntype]
 +
local catnames = {'配件', '弹匣', '人形'}
 +
root:newline():wikitext('=== 装备 ==='):newline()
 +
local edata = {}
 +
for i = 1,3 do edata[i] = gundata['equip' .. tostring(i)] and
 +
copy(gundata['equip' .. tostring(i)]) or defaults[i] end
 +
local equipTable = root:tag('table')
 +
for i = 1,3 do
 +
local tr = equipTable:tag('tr')
 +
for j = 1,3 do
 +
local td = tr:tag('td')
 +
if i == 1 then td:wikitext(
 +
'[[File:Equip_cat_' .. tostring(edata[j][1]) .. '.png|link=]]')
 +
elseif i == 2 then td:wikitext(catnames[edata[j][1]])
 +
else
 +
local etypes = {}
 +
for k = 2,#(edata[j]) do etypes[k-1] = etdata[edata[j][k]].name end
 +
td:wikitext('可装备', table.concat(etypes, '/'))
 +
end
 +
end
 +
end
 +
local ex = gundata.exclusives
 +
if ex[1] then
 +
local frame = mw.getCurrentFrame()
 +
cardstyles = frame:extensionTag{
 +
name = 'templatestyles', args = { src = '模板:装备/card.css' }
 +
}
 +
local eqdata = mw.loadData('Module:Equip info/data')
 +
local exTable = root:tag('table'):tag('tr')
 +
local cols = {}
 +
for i = 1,3 do cols[#cols+1] = exTable:tag('td') end
 +
for _,v in ipairs(ex) do
 +
local e = eqdata[v]
 +
cols[etdata[e.etype].category]:wikitext(makeCard(e, frame))
 +
end
 +
end
 +
end
 +
 
 +
local function serveSkillInfo(order, ismod)
 +
local root = mw.html.create()
 +
local id = (ismod and moddata or gundata)['skill' .. order]
 +
local group = math.floor(id/1e5) == 1 and '1' or 'other'
 +
if not bdata[group] then
 +
bdata[group] = mw.loadData('Module:Battle skill config/data ' .. group)
 +
end
 +
skilldata = bdata[group][id]
 +
local skill = root:tag('table'):attr{ class = 'skill-table',
 +
['data-cd'] = skilldata.cd_time,
 +
['data-cd-start'] = skilldata.start_cd_time }:addClass('skill' .. order)
 +
if skilldata.vals then skill:attr('data-val', skilldata.vals) end
 +
local signature = skill:tag('tr'):attr('class', 'skill-signature')
 +
local icon = signature:tag('td')
 +
icon:attr('rowspan', 2)
 +
:wikitext('[[File:IconSkill ' .. skilldata.code .. '.png|48px|link=]]')
 +
local skillname = signature:tag('td')
 +
skillname:wikitext(skilldata.name)
 +
if order == '2' then skillname:tag('span'):wikitext('改型2解锁')
 +
elseif ismod then skillname:tag('span'):wikitext('改型1强化')
 +
end
 +
local lvcd = skill:tag('tr'):tag('td'):attr('class', 'skill-lvcd')
 +
lvcd:tag('span'):wikitext('等级10')
 +
lvcd:wikitext('前置冷却<span></span>秒/冷却时间<span></span>秒')
 +
skill:tag('tr'):tag('td'):attr{class = 'lv-control', colspan = 2}
 +
local desc = skill:tag('tr'):tag('td'):attr('colspan', 2)
 +
if skilldata.desc then
 +
local descstr = string.gsub(skilldata.desc, '{}', '<span class="skill"></span>')
 +
descstr = string.gsub(descstr, '\n', '<br>')
 +
desc:wikitext(descstr)
 +
else for i, v in ipairs(skilldata.full_desc) do
 +
desc:tag('p'):wikitext((string.gsub(v, '\n', '<br>'))) end
 +
end
 +
return tostring(root)
 +
end
 +
 
 +
local function putSkills()
 +
local root = super:tag('div'):attr('id', 'skill-container')
 +
root:newline():wikitext('=== 技能 ==='):newline()
 +
root:wikitext(serveSkillInfo('1'))
 +
if gundata['mod'] then
 +
root:wikitext(serveSkillInfo('1', true))
 +
root:wikitext(serveSkillInfo('2', true))
 +
end
 +
end
 +
 
 +
local function addChibi()
 +
local root = mw.html.create()
 +
root:newline():wikitext('== 战斗形象 =='):newline()
 +
local div = root:tag('div'):addClass('dollSpineBox')
 +
local argTable = {'ChibiCostumeSwitcher', target = 'TDollChibiAnimation'}
 +
local guncode = string.gsub(gundata.code, ' ', '_')
 +
if moddata then argTable['costumes.mod'] = '心智升级' end
 +
for _, v in ipairs(gundata.skins) do
 +
local skin = skindata[v]
 +
if skin then
 +
local skincode = guncode .. '_' .. tostring(v)
 +
argTable['costumes.' .. skincode] = skin.name
 +
end
 +
end
 +
local frame = mw.getCurrentFrame()
 +
div:wikitext(frame:callParserFunction('#widget', argTable))
 +
div:tag('div'):addClass('tdoll_chibi'):attr{ id = 'TDollChibiAnimation',
 +
['data-tdoll-id'] = guncode }
 +
return tostring(root)
 +
end
  
 
local function addImages()
 
local function addImages()
root:wikitext('== 人形外观 ==')
+
local root = super:tag('div'):attr('id', 'image-container')
root:newline()
+
root:newline():wikitext('== 人形外观 =='):newline()
 
local guncode = string.gsub(gundata.code, ' ', '_')
 
local guncode = string.gsub(gundata.code, ' ', '_')
local skindata = mw.loadData('Module:Gun info/skin_data')
+
local classdata = mw.loadData('Module:Gun info/skinclass_data')
local showcase = root:tag('div'):attr('id', 'unit-image-showcase')
+
local control = root:tag('div'):attr('id', 'unit-showcase-control')
local menu = showcase:tag('ul'):attr('id', 'unit-image-selector')
+
control:tag('div'):attr('id', 'unit-image-selected')
showcase:tag('div'):attr('id', 'unit-image-display')
+
:tag('div'):wikitext('初始形象'):done():tag('div')
showcase:tag('div'):attr('id', 'state-toggle')
+
local menu = control:tag('ul'):attr('id', 'unit-image-selector'):css('display', 'none')
 +
control:tag('div'):attr('id', 'state-toggle'):done()
 +
:tag('div'):attr('id', 'live2d-toggle')
 
menu:tag('li'):attr('data-skincode', guncode):wikitext('初始形象')
 
menu:tag('li'):attr('data-skincode', guncode):wikitext('初始形象')
 
if moddata then
 
if moddata then
 
local moditem = menu:tag('li')
 
local moditem = menu:tag('li')
:attr('data-skincode', guncode .. 'Mod'):wikitext('心智升级')
+
:attr('data-skincode', guncode .. 'Mod')
 
local l2dmod = {[55] = 1, [56] = 1, [57] = 1, [65] = 1, [101] = 1,
 
local l2dmod = {[55] = 1, [56] = 1, [57] = 1, [65] = 1, [101] = 1,
 
[103] = 1, [122] = 1, [143] = 1}
 
[103] = 1, [122] = 1, [143] = 1}
if l2dmod[gundata.id] then moditem:addClass('live2d1') end
+
if l2dmod[gundata.id] then
 +
moditem:addClass('live2d1'):wikitext(
 +
'<div></div><div><span>心智升级</span></div><div class="live2d1"></div>')
 +
else moditem:wikitext('心智升级')
 +
end
 
end
 
end
 
for _, v in ipairs(gundata.skins) do
 
for _, v in ipairs(gundata.skins) do
skin = skindata[v]
+
local skin = skindata[v]
 
if skin then
 
if skin then
 
local skincode = guncode .. '_' .. tostring(v)
 
local skincode = guncode .. '_' .. tostring(v)
local item = menu:tag('li')
+
local skinclass = classdata[skin.class_id]
item:tag('span'):wikitext(skin.name)
+
local item = menu:tag('li'):attr('data-skincode', skincode)
item:tag('span'):wikitext(skindata.skin_classes[skin.class])
+
local tdiv = item:tag('div')
local skintype = skin['type']
+
if skinclass then tdiv:addClass('theme' .. tostring(skinclass.theme_type)) end
item:attr('data-skincode', skincode)
+
local scdiv = item:tag('div')
if skintype ~= 0 then
+
scdiv:tag('span'):wikitext(skin.name)
item:addClass('live2d' .. tostring(skintype))
+
if skinclass then scdiv:tag('span'):wikitext(skinclass.name) end
 +
local ldiv = item:tag('div')
 +
local skintype = tostring(skin['type'])
 +
if skintype ~= 'nil' then
 +
item:addClass('live2d' .. skintype)
 +
ldiv:addClass('live2d' .. skintype)
 
end
 
end
 
end
 
end
 
end
 
end
showcase:tag('div'):attr('id', 'live2d-control'):cssText('display:none')
+
local showcase = root:tag('div'):attr('id', 'unit-image-showcase')
root:newline()
+
showcase:tag('div'):attr('id', 'unit-image-display')
 +
:done():tag('div'):attr('id', 'live2d-control'):cssText('display:none')
 
end
 
end
  
第57行: 第219行:
 
effect_poses[i] = 3*(2 - (v - 1)%5) + math.floor((v - 1)/5) - 2 + self_pos
 
effect_poses[i] = 3*(2 - (v - 1)%5) + math.floor((v - 1)/5) - 2 + self_pos
 
end
 
end
 +
table.sort(effect_poses)
 
return self_pos, effect_poses
 
return self_pos, effect_poses
 
end
 
end
  
local function makeEffectTable(self_pos, effect_poses)
+
local function concatEffects(anames, avals, coeff)
local effect_table = root:tag('table')
+
local effects = {}
 +
for i = 1, #anames do
 +
local sign = avals[i] > 0 and '+' or ''
 +
table.insert(effects, string.format('%s<span class="effect-%s">%s%d%%</span>',
 +
anames[i],
 +
sign == '+' and 'positive' or 'negative',
 +
sign, math.floor(avals[i]*coeff)))
 +
end
 +
return table.concat(effects, ' ')
 +
end
 +
 
 +
local function makeEffectTable(self_pos, effect_poses, target, effect, parent)
 +
local effect_table = parent:tag('table'):addClass('effect-table'):tag('tr')
 +
local effect_grid = effect_table:tag('td'):tag('table'):addClass('effect-grid')
 
local index = 1
 
local index = 1
 
for i = 0, 2 do
 
for i = 0, 2 do
local tr = effect_table:tag('tr')
+
local tr = effect_grid:tag('tr')
 
for j = 1, 3 do
 
for j = 1, 3 do
 
local td = tr:tag('td')
 
local td = tr:tag('td')
第72行: 第248行:
 
elseif i*3 + j ==  self_pos then
 
elseif i*3 + j ==  self_pos then
 
td:addClass('self-cell')
 
td:addClass('self-cell')
index = index + 1
 
 
end
 
end
 
end
 
end
 
end
 
end
 +
local effect_text = effect_table:tag('td')
 +
effect_text:wikitext('<span class="effect-caption">影响格效果</span><br>')
 +
local targets = {}
 +
for _, v in ipairs(target) do targets[#targets+1] = guntype[1][v] end
 +
effect_text:wikitext(string.format('对%s有效', table.concat(targets, '、')))
 +
local anames, avals = {}, {}
 +
for i,v in ipairs(effect) do
 +
if i%2 == 1 then table.insert(anames, attrs[v])
 +
else table.insert(avals, v) end
 +
end
 +
effect_text:wikitext('<br>')
 +
effect_text:wikitext(concatEffects(anames, avals, 1))
 +
if gundata.guntype == 1 then for i = 1.25, 2, 0.25 do
 +
effect_text:wikitext('<br>')
 +
effect_text:wikitext(concatEffects(anames, avals, i)) end end
 +
end
 +
 +
local function r2fs(r)
 +
local f = math.floor(1500/r)
 +
return f, string.format('%.2g', f/30)
 
end
 
end
  
 
local function addCombatInfo()
 
local function addCombatInfo()
root:wikitext('== 战斗数据 ==')
+
local root = super:tag('div'):attr('id', 'stat-container')
root:newline()
+
local gtype = gundata.guntype
 +
local speeds = {15,12,7,10,4,6}
 +
local crits = {20,5,40,20,5,40}
 +
local targets = {{0}, {4}, {1}, {2}, {6}, {5}}
 +
root:newline():wikitext('== 战斗数据 =='):newline()
 
local ratios = { gundata.life, gundata.power, gundata.rate,
 
local ratios = { gundata.life, gundata.power, gundata.rate,
gundata.hit, gundata.dodge }
+
gundata.hit, gundata.dodge, gundata.armor or 0 }
local attrtable = root:tag('table'):attr{
+
local attrdataset = root:tag('div'):attr{
id = 'attr-table',
+
id = 'attr-dataset',
 +
['data-type'] = gtype,
 
['data-growing'] = table.concat(ratios, ','),
 
['data-growing'] = table.concat(ratios, ','),
 
['data-growth'] = gundata.growth
 
['data-growth'] = gundata.growth
 
}
 
}
local self_pos
 
local effect_poses
 
self_pos, effect_poses = getGridPositions(gundata.grid_center or 13, gundata.grid_pos)
 
makeEffectTable(self_pos, effect_poses)
 
 
if moddata then
 
if moddata then
local ratios = { moddata.life, moddata.power, moddata.rate,
+
ratios = { moddata.life, moddata.power, moddata.rate,
moddata.hit, moddata.dodge }
+
moddata.hit, moddata.dodge, moddata.armor or 0 }
attrtable:attr{
+
attrdataset:attr{
 
['data-growing-mod'] = table.concat(ratios, ','),
 
['data-growing-mod'] = table.concat(ratios, ','),
 
['data-growth-mod'] = moddata.growth
 
['data-growth-mod'] = moddata.growth
 
}
 
}
 +
end
 +
local attrtable = root:tag('div'):attr('id', 'attr-table')
 +
attrtable:newline():wikitext([[
 +
{|
 +
|+生命
 +
|-
 +
!×1!!×2!!×3!!×4!!×5
 +
|-id="hp-tr"
 +
| || || || ||
 +
|}]]):newline()
 +
local gtable = attrtable:tag('table'):attr('id', 'growing2')
 +
gtable:tag('tr'):tag('th'):attr{id = 'growth', colspan = 5}:wikitext'成长'
 +
gtable:tag('tr'):tag('td'):attr{id = 'grow-td', colspan = 5}
 +
local gaid1 = {1, 2, 3, 5, 9}
 +
local gaid2 = {1, 3, 4, 2, 8}
 +
local gthr = gtable:tag('tr')
 +
for i = 1, 5 do
 +
local gth = gthr:tag('th'):attr('id', bonuses[gaid1[i]]):wikitext(attrs[gaid2[i]])
 +
if i == 4 and gundata.max_rate then
 +
local f = mw.getCurrentFrame()
 +
gth:tag('span'):addClass('max-rate'):wikitext(f:expandTemplate{
 +
title='popup', args={['内容']=string.format(
 +
'射速上限:%d(攻击间隔%d帧/%s秒)',
 +
gundata.max_rate, r2fs(gundata.max_rate))
 +
}})
 +
end
 +
if i == 4 and moddata and moddata.max_rate then
 +
local f = mw.getCurrentFrame()
 +
gth:tag('span'):addClass('max-rate-mod'):wikitext(
 +
f:expandTemplate{title='popup', args={['内容']=string.format(
 +
'射速上限:%d(攻击间隔%d帧/%s秒)',
 +
moddata.max_rate, r2fs(moddata.max_rate))
 +
}
 +
}) end
 +
end
 +
local gtdr = gtable:tag('tr')
 +
for i = 1, 5 do gtdr:tag('td'):attr('id', bonuses[gaid1[i]] .. '-td') end
 +
attrtable:newline():wikitext(string.format([[
 +
{|
 +
!id="ap"|穿甲!!id="round"|弹量!!id="speed"|移速!!id="crit"|暴击!!id="critpow"|暴伤
 +
|-
 +
|15||data-attr="%d" data-mod="%d"|%s||%s||data-attr="%d" data-mod="%d"|%s%%||150%%
 +
|}]],
 +
gundata.round or 0,
 +
moddata and moddata.round or 0,
 +
tostring(gundata.round or '不适用'),
 +
tostring(speeds[gtype]),
 +
gundata.crit or crits[gtype],
 +
moddata and moddata.crit or crits[gtype],
 +
tostring(gundata.crit or crits[gtype])))
 +
local self_pos, effect_poses = getGridPositions(gundata.grid_center or 13, gundata.grid_pos)
 +
local container = moddata and root:tag('div'):attr('id', 'effects') or root
 +
makeEffectTable(self_pos, effect_poses, gundata.effect_target or targets[gtype], gundata.effect, container)
 +
if moddata then
 
self_pos, effect_poses = getGridPositions(moddata.grid_center or 13, moddata.grid_pos)
 
self_pos, effect_poses = getGridPositions(moddata.grid_center or 13, moddata.grid_pos)
makeEffectTable(self_pos, effect_poses)
+
makeEffectTable(self_pos, effect_poses, moddata.effect_target or targets[gtype], moddata.effect, container)
 
end
 
end
 
end
 
end
  
 
local function addInfobox()
 
local function addInfobox()
    local modrank = {'', '4', '4', '5', '6'}
+
local root = mw.html.create('div'):addClass('dollinfo')
root:wikitext(infobox{
+
local modrank = {'', '4', '4', '5', '6'}
above = gundata.name,
+
local orgdata = mw.loadData('Module:Gun info/org data')
label1 = '编号',
+
local org, org2 = orgdata[math.floor(gundata.org/100)], orgdata[gundata.org]
data1 = gundata.id,
+
local stars, rank = '', gundata.rank
label2 = '武器类型',
+
local isextra = mid > 1000
data2 = guntype[1][gundata['type']],
+
local weapon = guntype[1][gundata.guntype]
label3 = '稀有度',
+
if isextra then stars = '<span>★</span> EXTRA' else
data3 = tostring(gundata.rank) ..
+
for i = 1, rank do stars = stars .. '<span>★</span>' end
(moddata and '(心智升级:' .. modrank[gundata.rank] .. '' or '')
+
if moddata then for i = rank+1, modrank[rank] do
})
+
stars = '<span>☆</span>' .. stars end end end
    root:newline()
+
local obtains = {}
 +
for _, v in ipairs(gundata.obtain) do obtains[#obtains+1] = odata[v] end
 +
if gundata.obtain[1] == 1 or gundata.obtain[1] == 2 then
 +
obtains[#obtains+1] = '制造用时:' .. mw.getContentLanguage()
 +
:formatDuration(gundata.produce_time)
 +
end
 +
root:wikitext(string.format([=[
 +
<div id="dollnum">NO.%d</div><div id="dollrar">%s</div>
 +
<div id="dollwph">%s武器</div><div id="dollwpd">[[File:图标-%s.png|link=]]%s</div>
 +
<div id="dollpic"><div>[[File:Icon_No.%d%s.png|link=]]</div></div>
 +
<div id="dollilh">形象设计</div><div id="dollild">%s</div>
 +
<div id="dollcvh">配音</div><div id="dollcvd">%s</div>
 +
<div id="dolldph">部门</div><div id="dolldpd">%s</div>
 +
<div id="dollobh">入编渠道</div><div id="dollobd">%s</div>
 +
<div id="dollinh">介绍</div><div id="dollind">%s</div>]=],
 +
mid, stars,
 +
isextra and '' or '烙印', weapon, isextra and weapon or (args['武器'] or gundata.name),
 +
mid, moddata and '_Mod' or '',
 +
gundata.illu or '不明', gundata.cv or '不明',
 +
org and string.format('[[内部一览/%s|%s]]-%s', org, org, org2) or '无',
 +
table.concat(obtains, '<br>'), args['介绍'] or ''))
 +
return tostring(root)
 
end
 
end
  
 
local function _gunInfo()
 
local function _gunInfo()
gundata = data[tonumber(args[1])]
+
mid = tonumber(args[1])
 +
if mid < 1000 then
 +
data = mw.loadData('Module:Gun info/data')
 +
else
 +
data = mw.loadData('Module:Gun info/data extra')
 +
end
 +
gundata = data[mid]
 
if gundata == nil then
 
if gundata == nil then
 
return '<p style="color:red">未找到编号对应的战术人形信息,请检查编号是否正确及' ..
 
return '<p style="color:red">未找到编号对应的战术人形信息,请检查编号是否正确及' ..
 
'<a href="/w/Module:Gun_info/data">Module:Gun info/data</a>的数据是否为最新。</p>'
 
'<a href="/w/Module:Gun_info/data">Module:Gun info/data</a>的数据是否为最新。</p>'
 
end
 
end
moddata = data[tonumber(args[1])+20000]
+
if gundata['mod'] == 1 then
root = mw.html.create()
+
local moddataOrig = mw.loadData('Module:Gun info/data mod')[tonumber(args[1])+20000]
+
moddata = {}
addInfobox()
+
for k,v in pairs(moddataOrig) do moddata[k] = v end
 +
for k,v in pairs(gundata) do moddata[k] = moddata[k] or v end
 +
if gundata.max_rate and not moddata.max_rate then
 +
moddata.max_rate = gundata.max_rate end
 +
end
 +
local root = mw.html.create()
 +
root:wikitext(addInfobox())
 +
super = root:tag('div'):attr('id', 'doll-container')
 +
addImages()
 
addCombatInfo()
 
addCombatInfo()
addImages()
+
putSkills()
 +
putEquipments()
 +
root:wikitext(addChibi())
 
 
 
local templatestyles = mw.getCurrentFrame():extensionTag{
 
local templatestyles = mw.getCurrentFrame():extensionTag{
 
name = 'templatestyles', args = { src = '模板:战术人形信息/styles.css' }
 
name = 'templatestyles', args = { src = '模板:战术人形信息/styles.css' }
 
}
 
}
return templatestyles .. tostring(root)
+
return cardstyles .. templatestyles .. tostring(root)
 
end
 
end
  

2023年9月25日 (一) 21:59的最新版本

模块:Gun info及其子页面是一组主要用于存放和展示战术人形相关信息的模块,其各个部分的作用见下文。

组成部分

控制代码

数据


local p = {}
local args = {}
local super
local gundata
local mid
local data
local bdata = {}
local etdata = mw.loadData('Module:Equip info/type data')
local odata = mw.loadData('Module:Gun info/obtain data')
local skindata = mw.loadData('Module:Gun info/skin data')
local guntype = { {'手枪', '冲锋枪', '步枪', '突击步枪', '机枪', '霰弹枪', [0] = '所有枪种'},
	{'HG', 'SMG', 'RF', 'AR', 'MG', 'SG'} }
local attrs = {'伤害', '射速', '命中', '回避', '暴击率', '技能冷却速度', '', '护甲'}
local bonuses = {'pow', 'hit', 'dodge', 'speed', 'rate', 'critical_harm_rate',
	'critical_percent', 'armor_piercing', 'armor', 'night_view_percent', 'bullet_number_up'}
local cardstyles = ''

local function makeCard(d, f, p)
	local cats = {'配件', '弹匣', '人形'}
	local typeinfo = etdata[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,
		['页面'] = p ~= nil and d.altname or d.name,
		['名称'] = d.name,
		['类别'] = cats[typeinfo.category],
		['类型'] = typeinfo.name,
		['描述'] = mw.ustring.gsub(desc, '<%%>', '<span>%</span>')
	}}
end

local function putEquipments()
	local root = super:tag('div'):attr('id', 'equip-container')
	local function copy(t)
		local ret = {}
		for i, v in ipairs(t) do ret[i] = v end
		return ret
	end
	
	local equips = {
		{{1, 4, 13, 16}, {2, 6}, {3,10}},
		{{3, 9, 10}, {2, 6}, {1, 1, 2, 3, 4, 13}},
		{{2, 5}, {1, 1, 2, 3, 13}, {3, 15}},
		{{1, 1, 2, 3, 4, 13}, {2, 8}, {3, 9, 10}},
		{{2, 5, 17}, {1, 1, 2, 3, 16}, {3, 14, 21}},
		{{3, 11}, {2, 7}, {1, 1, 2, 3, 4, 22}}
	}
	local defaults = equips[gundata.guntype]
	local catnames = {'配件', '弹匣', '人形'}
	root:newline():wikitext('=== 装备 ==='):newline()
	local edata = {}
	for i = 1,3 do edata[i] = gundata['equip' .. tostring(i)] and
		copy(gundata['equip' .. tostring(i)]) or defaults[i] end
	local equipTable = root:tag('table')
	for i = 1,3 do
		local tr = equipTable:tag('tr')
		for j = 1,3 do
			local td = tr:tag('td')
			if i == 1 then td:wikitext(
				'[[File:Equip_cat_' .. tostring(edata[j][1]) .. '.png|link=]]')
			elseif i == 2 then td:wikitext(catnames[edata[j][1]])
			else
				local etypes = {}
				for k = 2,#(edata[j]) do etypes[k-1] = etdata[edata[j][k]].name end
				td:wikitext('可装备', table.concat(etypes, '/'))
			end
		end
	end
	local ex = gundata.exclusives
	if ex[1] then
		local frame = mw.getCurrentFrame()
		cardstyles = frame:extensionTag{
			name = 'templatestyles', args = { src = '模板:装备/card.css' }
		}
		local eqdata = mw.loadData('Module:Equip info/data')
		local exTable = root:tag('table'):tag('tr')
		local cols = {}
		for i = 1,3 do cols[#cols+1] = exTable:tag('td') end
		for _,v in ipairs(ex) do
			local e = eqdata[v]
			cols[etdata[e.etype].category]:wikitext(makeCard(e, frame))
		end
	end
end

local function serveSkillInfo(order, ismod)
	local root = mw.html.create()
	local id = (ismod and moddata or gundata)['skill' .. order]
	local group = math.floor(id/1e5) == 1 and '1' or 'other'
	if not bdata[group] then
		bdata[group] = mw.loadData('Module:Battle skill config/data ' .. group)
	end
	skilldata = bdata[group][id]
	local skill = root:tag('table'):attr{ class = 'skill-table',
		['data-cd'] = skilldata.cd_time,
		['data-cd-start'] = skilldata.start_cd_time }:addClass('skill' .. order)
	if skilldata.vals then skill:attr('data-val', skilldata.vals) end
	local signature = skill:tag('tr'):attr('class', 'skill-signature')
	local icon = signature:tag('td')
	icon:attr('rowspan', 2)
		:wikitext('[[File:IconSkill ' .. skilldata.code .. '.png|48px|link=]]')
	local skillname = signature:tag('td')
	skillname:wikitext(skilldata.name)
	if order == '2' then skillname:tag('span'):wikitext('改型2解锁')
	elseif ismod then skillname:tag('span'):wikitext('改型1强化')
	end
	local lvcd = skill:tag('tr'):tag('td'):attr('class', 'skill-lvcd')
	lvcd:tag('span'):wikitext('等级10')
	lvcd:wikitext('前置冷却<span></span>秒/冷却时间<span></span>秒')
	skill:tag('tr'):tag('td'):attr{class = 'lv-control', colspan = 2}
	local desc = skill:tag('tr'):tag('td'):attr('colspan', 2)
	if skilldata.desc then
		local descstr = string.gsub(skilldata.desc, '{}', '<span class="skill"></span>')
		descstr = string.gsub(descstr, '\n', '<br>')
		desc:wikitext(descstr)
	else for i, v in ipairs(skilldata.full_desc) do
		desc:tag('p'):wikitext((string.gsub(v, '\n', '<br>'))) end
	end
	return tostring(root)
end

local function putSkills()
	local root = super:tag('div'):attr('id', 'skill-container')
	root:newline():wikitext('=== 技能 ==='):newline()
	root:wikitext(serveSkillInfo('1'))
	if gundata['mod'] then
		root:wikitext(serveSkillInfo('1', true))
		root:wikitext(serveSkillInfo('2', true))
	end
end

local function addChibi()
	local root = mw.html.create()
	root:newline():wikitext('== 战斗形象 =='):newline()
	local div = root:tag('div'):addClass('dollSpineBox')
	local argTable = {'ChibiCostumeSwitcher', target = 'TDollChibiAnimation'}
	local guncode = string.gsub(gundata.code, ' ', '_')
	if moddata then argTable['costumes.mod'] = '心智升级' end
	for _, v in ipairs(gundata.skins) do
		local skin = skindata[v]
		if skin then
			local skincode = guncode .. '_' .. tostring(v)
			argTable['costumes.' .. skincode] = skin.name
		end
	end
	local frame = mw.getCurrentFrame()
	div:wikitext(frame:callParserFunction('#widget', argTable))
	div:tag('div'):addClass('tdoll_chibi'):attr{ id = 'TDollChibiAnimation',
		['data-tdoll-id'] = guncode }
	return tostring(root)
end

local function addImages()
	local root = super:tag('div'):attr('id', 'image-container')
	root:newline():wikitext('== 人形外观 =='):newline()
	local guncode = string.gsub(gundata.code, ' ', '_')
	local classdata = mw.loadData('Module:Gun info/skinclass_data')
	local control = root:tag('div'):attr('id', 'unit-showcase-control')
	control:tag('div'):attr('id', 'unit-image-selected')
		:tag('div'):wikitext('初始形象'):done():tag('div')
	local menu = control:tag('ul'):attr('id', 'unit-image-selector'):css('display', 'none')
	control:tag('div'):attr('id', 'state-toggle'):done()
		:tag('div'):attr('id', 'live2d-toggle')
	menu:tag('li'):attr('data-skincode', guncode):wikitext('初始形象')
	if moddata then
		local moditem = menu:tag('li')
			:attr('data-skincode', guncode .. 'Mod')
		local l2dmod = {[55] = 1, [56] = 1, [57] = 1, [65] = 1, [101] = 1,
			[103] = 1, [122] = 1, [143] = 1}
		if l2dmod[gundata.id] then
			moditem:addClass('live2d1'):wikitext(
				'<div></div><div><span>心智升级</span></div><div class="live2d1"></div>')
		else moditem:wikitext('心智升级')
		end
	end
	for _, v in ipairs(gundata.skins) do
		local skin = skindata[v]
		if skin then
			local skincode = guncode .. '_' .. tostring(v)
			local skinclass = classdata[skin.class_id]
			local item = menu:tag('li'):attr('data-skincode', skincode)
			local tdiv = item:tag('div')
			if skinclass then tdiv:addClass('theme' .. tostring(skinclass.theme_type)) end
			local scdiv = item:tag('div')
			scdiv:tag('span'):wikitext(skin.name)
			if skinclass then scdiv:tag('span'):wikitext(skinclass.name) end
			local ldiv = item:tag('div')
			local skintype = tostring(skin['type'])
			if skintype ~= 'nil' then
				item:addClass('live2d' .. skintype)
				ldiv:addClass('live2d' .. skintype)
			end
		end
	end
	local showcase = root:tag('div'):attr('id', 'unit-image-showcase')
	showcase:tag('div'):attr('id', 'unit-image-display')
		:done():tag('div'):attr('id', 'live2d-control'):cssText('display:none')
end

local function getGridPositions(center, pos)
	local self_pos = 4 - math.floor(center / 5) + 3 * (center % 5 - 2)
	local effect_poses = {}
	for i, v in ipairs(pos) do
		effect_poses[i] = 3*(2 - (v - 1)%5) + math.floor((v - 1)/5) - 2 + self_pos
	end
	table.sort(effect_poses)
	return self_pos, effect_poses
end

local function concatEffects(anames, avals, coeff)
	local effects = {}
	for i = 1, #anames do
		local sign = avals[i] > 0 and '+' or ''
		table.insert(effects, string.format('%s<span class="effect-%s">%s%d%%</span>',
			anames[i],
			sign == '+' and 'positive' or 'negative',
			sign, math.floor(avals[i]*coeff)))
	end
	return table.concat(effects, ' ')
end

local function makeEffectTable(self_pos, effect_poses, target, effect, parent)
	local effect_table = parent:tag('table'):addClass('effect-table'):tag('tr')
	local effect_grid = effect_table:tag('td'):tag('table'):addClass('effect-grid')
	local index = 1
	for i = 0, 2 do
		local tr = effect_grid:tag('tr')
		for j = 1, 3 do
			local td = tr:tag('td')
			if i*3 + j == effect_poses[index] then
				td:addClass('effect-cell')
				index = index + 1
			elseif i*3 + j ==  self_pos then
				td:addClass('self-cell')
			end
		end
	end
	local effect_text = effect_table:tag('td')
	effect_text:wikitext('<span class="effect-caption">影响格效果</span><br>')
	local targets = {}
	for _, v in ipairs(target) do targets[#targets+1] = guntype[1][v] end
	effect_text:wikitext(string.format('对%s有效', table.concat(targets, '、')))
	local anames, avals = {}, {}
	for i,v in ipairs(effect) do
		if i%2 == 1 then table.insert(anames, attrs[v])
		else table.insert(avals, v) end
	end
	effect_text:wikitext('<br>')
	effect_text:wikitext(concatEffects(anames, avals, 1))
	if gundata.guntype == 1 then for i = 1.25, 2, 0.25 do
		effect_text:wikitext('<br>')
		effect_text:wikitext(concatEffects(anames, avals, i)) end end
end

local function r2fs(r)
	local f = math.floor(1500/r)
	return f, string.format('%.2g', f/30)
end

local function addCombatInfo()
	local root = super:tag('div'):attr('id', 'stat-container')
	local gtype = gundata.guntype
	local speeds = {15,12,7,10,4,6}
	local crits = {20,5,40,20,5,40}
	local targets = {{0}, {4}, {1}, {2}, {6}, {5}}
	root:newline():wikitext('== 战斗数据 =='):newline()
	local ratios = { gundata.life, gundata.power, gundata.rate,
		gundata.hit, gundata.dodge, gundata.armor or 0 }
	local attrdataset = root:tag('div'):attr{
		id = 'attr-dataset',
		['data-type'] = gtype,
		['data-growing'] = table.concat(ratios, ','),
		['data-growth'] = gundata.growth
	}
	if moddata then
		ratios = { moddata.life, moddata.power, moddata.rate,
			moddata.hit, moddata.dodge, moddata.armor or 0 }
		attrdataset:attr{
			['data-growing-mod'] = table.concat(ratios, ','),
			['data-growth-mod'] = moddata.growth
		}
	end
	local attrtable = root:tag('div'):attr('id', 'attr-table')
	attrtable:newline():wikitext([[
{|
|+生命
|-
!×1!!×2!!×3!!×4!!×5
|-id="hp-tr"
| || || || ||
|}]]):newline()
	local gtable = attrtable:tag('table'):attr('id', 'growing2')
	gtable:tag('tr'):tag('th'):attr{id = 'growth', colspan = 5}:wikitext'成长'
	gtable:tag('tr'):tag('td'):attr{id = 'grow-td', colspan = 5}
	local gaid1 = {1, 2, 3, 5, 9}
	local gaid2 = {1, 3, 4, 2, 8}
	local gthr = gtable:tag('tr')
	for i = 1, 5 do
		local gth = gthr:tag('th'):attr('id', bonuses[gaid1[i]]):wikitext(attrs[gaid2[i]])
		if i == 4 and gundata.max_rate then
			local f = mw.getCurrentFrame()
			gth:tag('span'):addClass('max-rate'):wikitext(f:expandTemplate{
				title='popup', args={['内容']=string.format(
					'射速上限:%d(攻击间隔%d帧/%s秒)',
					gundata.max_rate, r2fs(gundata.max_rate))
			}})
		end
		if i == 4 and moddata and moddata.max_rate then
			local f = mw.getCurrentFrame()
			gth:tag('span'):addClass('max-rate-mod'):wikitext(
				f:expandTemplate{title='popup', args={['内容']=string.format(
					'射速上限:%d(攻击间隔%d帧/%s秒)',
					moddata.max_rate, r2fs(moddata.max_rate))
			}
		}) end
	end
	local gtdr = gtable:tag('tr')
	for i = 1, 5 do gtdr:tag('td'):attr('id', bonuses[gaid1[i]] .. '-td') end
	attrtable:newline():wikitext(string.format([[
{|
!id="ap"|穿甲!!id="round"|弹量!!id="speed"|移速!!id="crit"|暴击!!id="critpow"|暴伤
|-
|15||data-attr="%d" data-mod="%d"|%s||%s||data-attr="%d" data-mod="%d"|%s%%||150%%
|}]],
		gundata.round or 0,
		moddata and moddata.round or 0,
		tostring(gundata.round or '不适用'),
		tostring(speeds[gtype]),
		gundata.crit or crits[gtype],
		moddata and moddata.crit or crits[gtype],
		tostring(gundata.crit or crits[gtype])))
	local self_pos, effect_poses = getGridPositions(gundata.grid_center or 13, gundata.grid_pos)
	local container = moddata and root:tag('div'):attr('id', 'effects') or root
	makeEffectTable(self_pos, effect_poses, gundata.effect_target or targets[gtype], gundata.effect, container)
	if moddata then
		self_pos, effect_poses = getGridPositions(moddata.grid_center or 13, moddata.grid_pos)
		makeEffectTable(self_pos, effect_poses, moddata.effect_target or targets[gtype], moddata.effect, container)
	end
end

local function addInfobox()
	local root = mw.html.create('div'):addClass('dollinfo')
	local modrank = {'', '4', '4', '5', '6'}
	local orgdata = mw.loadData('Module:Gun info/org data')
	local org, org2 = orgdata[math.floor(gundata.org/100)], orgdata[gundata.org]
	local stars, rank = '', gundata.rank
	local isextra = mid > 1000
	local weapon = guntype[1][gundata.guntype]
	if isextra then stars = '<span>★</span> EXTRA' else
		for i = 1, rank do stars = stars .. '<span>★</span>' end
		if moddata then for i = rank+1, modrank[rank] do
			stars = '<span>☆</span>' .. stars end end end
	local obtains = {}
	for _, v in ipairs(gundata.obtain) do obtains[#obtains+1] = odata[v] end
	if gundata.obtain[1] == 1 or gundata.obtain[1] == 2 then
		obtains[#obtains+1] = '制造用时:' .. mw.getContentLanguage()
			:formatDuration(gundata.produce_time)
	end
	root:wikitext(string.format([=[
<div id="dollnum">NO.%d</div><div id="dollrar">%s</div>
<div id="dollwph">%s武器</div><div id="dollwpd">[[File:图标-%s.png|link=]]%s</div>
<div id="dollpic"><div>[[File:Icon_No.%d%s.png|link=]]</div></div>
<div id="dollilh">形象设计</div><div id="dollild">%s</div>
<div id="dollcvh">配音</div><div id="dollcvd">%s</div>
<div id="dolldph">部门</div><div id="dolldpd">%s</div>
<div id="dollobh">入编渠道</div><div id="dollobd">%s</div>
<div id="dollinh">介绍</div><div id="dollind">%s</div>]=],
		mid, stars,
		isextra and '' or '烙印', weapon, isextra and weapon or (args['武器'] or gundata.name),
		mid, moddata and '_Mod' or '',
		gundata.illu or '不明', gundata.cv or '不明',
		org and string.format('[[内部一览/%s|%s]]-%s', org, org, org2) or '无',
		table.concat(obtains, '<br>'), args['介绍'] or ''))
	return tostring(root)
end

local function _gunInfo()
	mid = tonumber(args[1])
	if mid < 1000 then
		data = mw.loadData('Module:Gun info/data')
	else
		data = mw.loadData('Module:Gun info/data extra')
	end
	gundata = data[mid]
	if gundata == nil then
		return '<p style="color:red">未找到编号对应的战术人形信息,请检查编号是否正确及' ..
			'<a href="/w/Module:Gun_info/data">Module:Gun info/data</a>的数据是否为最新。</p>'
	end
	if gundata['mod'] == 1 then
		local moddataOrig = mw.loadData('Module:Gun info/data mod')[tonumber(args[1])+20000]
		moddata = {}
		for k,v in pairs(moddataOrig) do moddata[k] = v end
		for k,v in pairs(gundata) do moddata[k] = moddata[k] or v end
		if gundata.max_rate and not moddata.max_rate then
			moddata.max_rate = gundata.max_rate end
	end
	local root = mw.html.create()
	root:wikitext(addInfobox())
	super = root:tag('div'):attr('id', 'doll-container')
	addImages()
	addCombatInfo()
	putSkills()
	putEquipments()
	root:wikitext(addChibi())
	
	local templatestyles = mw.getCurrentFrame():extensionTag{
		name = 'templatestyles', args = { src = '模板:战术人形信息/styles.css' }
	}
	return cardstyles .. templatestyles .. tostring(root)
end

function p.gunInfo(frame)
	if frame == mw.getCurrentFrame() then
		args = frame:getParent().args
	else
		args = frame
	end
	return _gunInfo()
end

return p