| 🌟 | 現在、 鉄壁HSは通常HSと同じダメージになります。LMG及びDMR、チャージライフル、ハンマーポイント弾を除き、すべてのダメージ値が一致していることを確認しています。 |
「モジュール:WeaponInfobox」の版間の差分
ナビゲーションに移動
検索に移動
(condensedtableのスタイル適応条件の変更による変更) |
(改造ローダーとクイックドローホルスターの書式の変更) |
||
| 546行目: | 546行目: | ||
end | end | ||
elseif islmg then | elseif islmg then | ||
local | local text = string.format( | ||
reloadFormat .. ' 秒 <span class="text-separator">/</span> %s ' .. reloadFormat .. ' 秒', | |||
muls.level3 * reload.full, | |||
formatter:hopup('改造ローダー'), | |||
0.75 * muls.level3 * reload.full) | |||
renderRow(tbl, name, text) | |||
formatter:hopup('改造ローダー') | |||
else | else | ||
local time | local time | ||
| 647行目: | 640行目: | ||
end | end | ||
local text | |||
if quickdraw_holster > 0 then | if quickdraw_holster > 0 then | ||
text = string.format( | |||
drawFormat .. ' 秒 <span class="text-separator">/</span> %s ' .. drawFormat .. ' 秒', | |||
time, | |||
iu.hopup('クイックドローホルスター'), | |||
quickdraw_holster * time) | |||
iu.hopup('クイックドローホルスター') | |||
else | else | ||
text = string.format(drawFormat .. ' 秒', time) | |||
end | end | ||
renderRow(tbl, name, text) | |||
elseif quickdraw_holster > 0 then | elseif quickdraw_holster > 0 then | ||
local intable = createCellInRow(tbl, name) | local intable = createCellInRow(tbl, name) | ||
2021年2月16日 (火) 20:59時点における版
このモジュールについての説明文ページを モジュール:WeaponInfobox/doc に作成できます
require('Module:Utility/mw.html Extensions')
local p = {}
local aw = require('Module:Utility/Library')
local iu = require('Module:Utility/Image')
local formatter -- lazily initialized
local getArgs -- lazily initialized
local function stringStarts(str, start)
return string.sub(str, 1, string.len(start)) == start
end
local function createCellInRow(tbl, name)
return tbl:tag('tr')
:tag('th')
:wikitext(name)
:done()
:tag('td')
end
local function renderRow(tbl, name, item)
createCellInRow(tbl, name):wikitext(item)
end
local function renderFormatRow(tbl, name, default, common, rare, epic, opts)
opts = opts or {}
opts.separator = opts.separator or ' - '
local row = tbl:tag('tr')
:addClassIf(opts.class and type(opts.class) == 'string', opts.class)
if name ~= nil then
row:tag('th')
:attrIf(opts.headerAlign and type(opts.headerAlign) == 'string', { align = opts.headerAlign })
:wikitext(name)
end
row:tag('td')
:addClass('cell-type-number')
:wikitext(default)
if common ~= nil then
row:tag('td'):wikitext(opts.separator):done()
:tag('td')
:addClass('cell-type-number')
:wikitext(formatter:common(common))
end
if rare ~= nil then
row:tag('td'):wikitext(opts.separator):done()
:tag('td')
:addClass('cell-type-number')
:wikitext(formatter:rare(rare))
end
if epic ~= nil then
row:tag('td'):wikitext(opts.separator):done()
:tag('td')
:addClass('cell-type-number')
:wikitext(formatter:epic(epic))
end
if opts.footer ~= nil then
row:tag('td'):wikitext(opts.footer)
end
return row
end
local CategoryDict = {
assault_rifle = "アサルトライフル",
sub_machine_gun = "サブマシンガン",
light_machine_gun = "ライトマシンガン",
sniper = "スナイパーライフル",
shotgun = "ショットガン",
pistol = "ピストル",
}
local function renderCategory(tbl, name, stat)
local category = CategoryDict[stat]
local item = string.format('[[武器#%s|%s]][[Category:%s]]', category, category, category)
renderRow(tbl, name, item)
end
local AmmoDict = {
light = "ライトアモ",
heavy = "ヘビーアモ",
energy = "エネルギーアモ",
sniper = "スナイパーアモ",
shotgun = "ショットガンアモ",
special_light = "専用ライトアモ",
special_heavy = "専用ヘビーアモ",
special_energy = "専用エネルギーアモ",
special_sniper = "専用スナイパーアモ",
special_shotgun = "専用ショットガンアモ",
}
local function renderAmmo(tbl, name, stat)
local ammo = AmmoDict[stat]
local page = '弾薬#' .. ammo
local item = formatter:ammo(ammo, 28, page)
.. string.format(' [[%s|%s]][[Category:%s]]', page, ammo, ammo)
renderRow(tbl, name, item)
end
local function convertDecimalToFractional(num)
local integer = math.floor(num)
local decimal = tonumber(string.format("%.3f", num - integer))
local decimalText
if decimal == 0.125 then
decimalText = '⅛'
elseif decimal == 0.2 then
decimalText = '⅕'
elseif decimal == 0.25 then
decimalText = '¼'
elseif decimal == 1/3 then
decimalText = '⅓'
elseif decimal == 0.375 then
decimalText = '⅜'
elseif decimal == 0.4 then
decimalText = '⅖'
elseif decimal == 0.5 then
decimalText = '½'
elseif decimal == 0.6 then
decimalText = '⅗'
elseif decimal == 0.625 then
decimalText = '⅝'
elseif decimal == 2/3 then
decimalText = '⅔'
elseif decimal == 0.75 then
decimalText = '¾'
elseif decimal == 0.8 then
decimalText = '⅘'
elseif decimal == 0.875 then
decimalText = '⅞'
else
decimalText = ''
end
if decimalText == '' then
return tostring(num)
elseif integer == 0 then
return decimalText
else
return tostring(integer) .. decimalText
end
end
local function renderMode(tbl, name, stat)
local mode = nil
if stat.burst > 1 then
mode = stat.burst .. '点バースト'
end
if stat.auto then
if mode == nil then
mode = 'オート'
else
mode = mode .. '・オート'
end
end
if stat.single then
if mode == nil then
mode = '単発'
else
mode = mode .. '・単発'
end
end
renderRow(tbl, name, mode)
end
local function renderDamage(tbl, name, stat, ammo, pellet)
local base = stat.base
local typename = type(base)
if pellet ~= nil then
local item = tostring(base) .. ' × ' .. tostring(pellet) .. '片'
renderRow(tbl, name, item)
elseif typename == 'table' then
renderRow(tbl, name, table.concat(base, ' - '))
elseif typename == 'number' then
local damageText
if stat.anvil_receiver ~= nil then
damageText = base .. ' - '
.. iu.hopup('アンビルレシーバー')
.. ' ' .. formatter:legendary(stat.anvil_receiver.base)
else
damageText = tostring(base)
end
renderRow(tbl, name, damageText)
else
return
end
local head = convertDecimalToFractional(stat.headshot)
local hlm1 = convertDecimalToFractional(0.2 + 0.8 * stat.headshot)
local hlm2 = convertDecimalToFractional(0.4 + 0.6 * stat.headshot)
local hlm3 = convertDecimalToFractional(0.5 + 0.5 * stat.headshot)
local leg = convertDecimalToFractional(stat.legshot)
local sprm = stat.skullpiercer_rifling or 1
local cattext = '[[Category:ヘッドショット倍率が' .. stat.headshot .. '倍の武器]]'
local ul = mw.html.create('ul')
if sprm > 1 then
local spr0 = convertDecimalToFractional(sprm)
local spr1 = convertDecimalToFractional(0.2 + 0.8 * sprm)
local spr2 = convertDecimalToFractional(0.4 + 0.6 * sprm)
local spr3 = convertDecimalToFractional(0.5 + 0.5 * sprm)
local intable = ul:tag('li')
:tag('table')
:addClass('condensedtable')
renderFormatRow(
intable,
'頭',
head, hlm1, hlm2, hlm3,
{ footer = '倍' .. cattext })
renderFormatRow(
intable,
iu.hopup('スカルピアサーライフリング') .. ' ',
spr0, spr1, spr2, spr3,
{ footer = '倍' })
else
local headText = '頭 ' .. formatter:format(head, hlm1, hlm2, hlm3, '倍', ' - ') .. cattext
ul:tag('li'):wikitext(headText)
end
local legText
if stat.anvil_receiver ~= nil then
local anvilleg = convertDecimalToFractional(stat.anvil_receiver.legshot)
legText = '脚 ' .. leg .. ' - '
.. iu.hopup('アンビルレシーバー')
.. ' ' .. formatter:legendary(anvilleg) .. '倍'
else
legText = '脚 ' .. leg .. '倍'
end
ul:tag('li'):wikitext(legText)
tbl:tag('tr')
:tag('td')
:attr('colspan', 2)
:node(ul)
end
local rpsFormat = '%.2f'
local rpmFormat = '%.0f'
local function renderFirerate(tbl, name, firerate, mode)
if firerate == nil then
return
end
local cell = createCellInRow(tbl, name)
local rps
if mode.auto then
if mode.single then
if firerate.anvil_receiver then
local ul = tbl:tag('tr'):tag('td'):attr('colspan', 2):tag('ul')
ul:tag('li'):wikitext('オート: ' .. firerate.auto .. ' rps <small>(' .. (60 * firerate.auto) .. ' rpm)</small>')
if firerate.auto ~= firerate.single then
ul:tag('li'):wikitext('単発: ' .. firerate.single .. ' rps <small>(' .. (60 * firerate.single) .. ' rpm)</small>')
end
if firerate.anvil_receiver then
ul:tag('li')
:wikitext(
iu.hopup('アンビルレシーバー')
.. ': ' .. firerate.anvil_receiver .. ' rps <small>(' .. (60 * firerate.anvil_receiver) .. ' rpm)</small>')
end
elseif firerate.auto ~= firerate.single then
tbl:tag('tr')
:tag('td')
:attr('colspan', 2)
:tag('ul')
:tag('li')
:wikitext('オート: ' .. firerate.auto .. ' rps <small>(' .. (60 * firerate.auto) .. ' rpm)</small>')
:done()
:tag('li')
:wikitext('単発: ' .. firerate.single .. ' rps <small>(' .. (60 * firerate.single) .. ' rpm)</small>')
else
local rps = firerate.auto
cell:wikitext(rps .. ' rps <small>(' .. (60 * rps) .. ' rpm)</small>')
end
return
else
rps = firerate.auto
end
elseif mode.single then
rps = firerate.single
else
return
end
if type(rps) == 'table' then
local intable = cell:tag('table'):addClass('condensedtable')
renderFormatRow(
intable,
nil,
string.format(rpsFormat, rps[1]),
string.format(rpsFormat, rps[2]),
string.format(rpsFormat, rps[3]),
string.format(rpsFormat, rps[4]),
{ separator = ' - ', footer = ' rps' })
renderFormatRow(
intable,
nil,
string.format(rpmFormat, 60 * rps[1]),
string.format(rpmFormat, 60 * rps[2]),
string.format(rpmFormat, 60 * rps[3]),
string.format(rpmFormat, 60 * rps[4]),
{ separator = ' - ', footer = ' rpm' })
else
cell:wikitext(string.format(
rpsFormat .. ' rps <small>(' .. rpmFormat .. ' rpm)</small>',
rps,
60 * rps))
end
end
local function renderRowDPS(tbl, name, leg, body, head, skullpiercer, tag)
tag = tag or 'td'
local row = tbl:tag('tr')
row:tag('th'):wikitext(name)
if leg == '' then
row:tag(tag)
:attr('align', 'center')
:addClass('disabled')
:wikitext('–')
elseif leg ~= nil and leg ~= body then
row:tag(tag):wikitext(leg)
end
row
:tag(tag):wikitext(body):done()
:tag(tag):wikitext(head)
if skullpiercer ~= nil then
row:tag(tag):wikitext(skullpiercer)
end
end
local function toDPSText(dps)
return string.format("%.1f", dps)
end
local function renderDPSTable(cell, name, pellet, base, damages, firerate, useRound)
local headDamage = aw.round(damages.headshot * base)
local legDamage = aw.round(damages.legshot * base)
local skullpiercer = damages.skullpiercer_rifling
local skullpiercerHeader = nil
local commonSkullpiercerDPS = nil
local lowprofileSkullpiercerDPS = nil
local fortifiedSkullpiercerDPS = nil
if skullpiercer ~= nil then
skullpiercerHeader = iu.hopup('スカルピアサーライフリング')
local skullpiercerDamage = aw.round(skullpiercer * base)
commonSkullpiercerDPS = toDPSText(pellet * skullpiercerDamage * firerate)
lowprofileSkullpiercerDPS = toDPSText(pellet * aw.selectiveRound(1.05 * skullpiercerDamage, useRound) * firerate)
fortifiedSkullpiercerDPS = toDPSText(pellet * aw.round(0.85 * skullpiercerDamage) * firerate)
end
if type(firerate) == 'table' then
firerate = firerate[1]
end
local intable = cell:tag('table')
:addClass('intable')
:addClass('numbertable')
local lowprofileLegDamagePlaceholder
if damages.legshot == 1 then
lowprofileLegDamagePlaceholder = nil
renderRowDPS(intable, name, nil, '胴', '頭', skullpiercerHeader, 'th')
else
lowprofileLegDamagePlaceholder = ''
renderRowDPS(intable, name, '脚', '胴', '頭', skullpiercerHeader, 'th')
end
renderRowDPS(
intable,
'通常',
toDPSText(pellet * legDamage * firerate),
toDPSText(pellet * base * firerate),
toDPSText(pellet * headDamage * firerate),
commonSkullpiercerDPS)
renderRowDPS(
intable,
'小柄',
lowprofileLegDamagePlaceholder,
toDPSText(pellet * aw.selectiveRound(1.05 * base, useRound) * firerate),
toDPSText(pellet * aw.selectiveRound(1.05 * headDamage, useRound) * firerate),
lowprofileSkullpiercerDPS)
renderRowDPS(
intable,
'鉄壁',
toDPSText(pellet * aw.round(0.85 * legDamage) * firerate),
toDPSText(pellet * aw.round(0.85 * base) * firerate),
toDPSText(pellet * aw.round(0.85 * headDamage) * firerate),
fortifiedSkullpiercerDPS)
end
local function renderDPS(tbl, name, stat)
if stat.firerate == nil then
return
end
local damage = stat.damage.base
renderRow(tbl, name, '')
local pellet = stat.pellet or 1
local useRound = stat.damage.round or false
local cell = tbl:tag('tr'):tag('td'):attr('colspan', 2)
if type(damage) == 'table' then
for _, damage in ipairs(damage) do
if stat.mode.single then
renderDPSTable(
cell,
'',
pellet,
damage,
stat.damage,
stat.firerate.single,
useRound)
end
end
else
if stat.mode.auto then
renderDPSTable(
cell,
'',
pellet,
stat.damage.base,
stat.damage,
stat.firerate.auto,
useRound)
end
if stat.mode.single and stat.firerate.auto ~= stat.firerate.single then
renderDPSTable(
cell,
'',
pellet,
stat.damage.base,
stat.damage,
stat.firerate.single,
useRound)
end
if stat.damage.anvil_receiver and stat.firerate.anvil_receiver then
renderDPSTable(
cell,
iu.hopup('アンビルレシーバー'),
pellet,
stat.damage.anvil_receiver.base,
stat.damage.anvil_receiver,
stat.firerate.anvil_receiver,
useRound)
end
end
end
local function renderMagazine(table, name, stat, islmg)
local typename = type(stat)
if typename == 'table' then
if islmg then
local intable = createCellInRow(table, name)
:tag('table')
:addClass('condensedtable')
renderFormatRow(
intable,
'',
stat[1], stat[2], stat[3], stat[4], { footer = ' 発' })
renderFormatRow(
intable,
formatter:hopup('改造ローダー') .. ' ',
aw.round(1.15 * stat[1]),
aw.round(1.15 * stat[2]),
aw.round(1.15 * stat[3]),
aw.round(1.15 * stat[4]),
{ footer = ' 発' })
else
local text = formatter:format(stat[1], stat[2], stat[3], stat[4], ' 発', ' - ')
renderRow(table, name, text)
end
elseif typename == 'number' then
if stat == math.huge then
renderRow(table, name, '∞')
else
renderRow(table, name, stat)
end
else
return
end
end
local reloadFormat = '%.2f'
local function renderReload(tbl, name, reload, attachments, ammo, islmg)
if reload.full == nil then
return
end
local muls
if ammo == 'heavy' or ammo == 'special_heavy' then
muls = { level2 = 0.92, level3 = 0.87 }
else
muls = { level2 = 0.95, level3 = 0.9 }
end
local incompatible = not attachments.extended_mag_or_shotgun_bolt
if incompatible or ammo == 'shotgun' or stringStarts(ammo, "special_") then
if reload.tactical ~= nil and reload.tactical ~= reload.full then
local tacticalText, fullText
if incompatible or ammo == 'special_sniper' then
tacticalText = tostring(reload.tactical)
fullText = tostring(reload.full)
else
tacticalText = tostring(muls.level3 * reload.tactical)
fullText = tostring(muls.level3 * reload.full)
end
local intable = createCellInRow(tbl, name)
:tag('table')
:addClass('condensedtable')
:addClass('listtable')
renderFormatRow(
intable,
'タクティカル ',
string.format(reloadFormat, reload.tactical),
nil, nil, nil, { footer = ' 秒' })
if islmg then
renderFormatRow(
intable,
formatter:hopup('改造ローダー') .. ' ',
string.format(reloadFormat, 0.75 * reload.tactical),
nil, nil, nil, { class = 'no-list-style', headerAlign = 'right', footer = ' 秒' })
end
renderFormatRow(
intable,
'フル',
string.format(reloadFormat, reload.full),
nil, nil, nil, { footer = ' 秒' })
if islmg then
renderFormatRow(
intable,
formatter:hopup('改造ローダー') .. ' ',
string.format(reloadFormat, 0.75 * reload.full),
nil, nil, nil, { class = 'no-list-style', headerAlign = 'right', footer = ' 秒' })
end
elseif islmg then
local text = string.format(
reloadFormat .. ' 秒 <span class="text-separator">/</span> %s ' .. reloadFormat .. ' 秒',
muls.level3 * reload.full,
formatter:hopup('改造ローダー'),
0.75 * muls.level3 * reload.full)
renderRow(tbl, name, text)
else
local time
if incompatible or ammo == 'special_sniper' then
time = reload.full
else
time = muls.level3 * reload.full
end
renderRow(tbl, name, string.format(reloadFormat .. ' 秒', time))
end
elseif reload.tactical ~= nil and reload.tactical ~= reload.full then
renderRow(tbl, name, '')
local intable = tbl:tag('tr')
:tag('td')
:attr('colspan', 2)
:tag('table')
:addClass('condensedtable')
:addClass('listtable')
renderFormatRow(
intable,
'タクティカル ',
string.format(reloadFormat, reload.tactical),
nil,
string.format(reloadFormat, muls.level2 * reload.tactical),
string.format(reloadFormat, muls.level3 * reload.tactical),
{ footer = ' 秒' })
if islmg then
renderFormatRow(
intable,
formatter:hopup('改造ローダー') .. ' ',
string.format(reloadFormat, 0.75 * reload.tactical),
nil,
string.format(reloadFormat, 0.75 * muls.level2 * reload.tactical),
string.format(reloadFormat, 0.75 * muls.level3 * reload.tactical),
{ class = 'no-list-style', headerAlign = 'right', footer = ' 秒' })
end
renderFormatRow(
intable,
'フル',
string.format(reloadFormat, reload.full),
nil,
string.format(reloadFormat, muls.level2 * reload.full),
string.format(reloadFormat, muls.level3 * reload.full),
{ footer = ' 秒' })
if islmg then
renderFormatRow(
intable,
formatter:hopup('改造ローダー') .. ' ',
string.format(reloadFormat, 0.75 * reload.full),
nil,
string.format(reloadFormat, 0.75 * muls.level2 * reload.full),
string.format(reloadFormat, 0.75 * muls.level3 * reload.full),
{ class = 'no-list-style', headerAlign = 'right', footer = ' 秒' })
end
else
local text = formatter:format(
string.format(reloadFormat, reload.full),
nil,
string.format(reloadFormat, muls.level2 * reload.full),
string.format(reloadFormat, muls.level3 * reload.full),
' 秒', ' - ')
renderRow(tbl, name, text)
end
end
local drawFormat = '%.2f'
local function renderDraw(tbl, name, draw, quickdraw_holster, attachments, ammo)
if draw == nil then
return
end
local muls
if ammo == 'heavy' or ammo == 'special_heavy' then
muls = { level2 = 0.92, level3 = 0.87 }
else
muls = { level2 = 0.95, level3 = 0.9 }
end
local incompatible = not attachments.stock
if incompatible or stringStarts(ammo, "special_") then
local time
if incompatible or ammo == 'special_sniper' then
time = draw
else
time = 0.75 * draw
end
local text
if quickdraw_holster > 0 then
text = string.format(
drawFormat .. ' 秒 <span class="text-separator">/</span> %s ' .. drawFormat .. ' 秒',
time,
iu.hopup('クイックドローホルスター'),
quickdraw_holster * time)
else
text = string.format(drawFormat .. ' 秒', time)
end
renderRow(tbl, name, text)
elseif quickdraw_holster > 0 then
local intable = createCellInRow(tbl, name)
:tag('table')
:addClass('condensedtable')
renderFormatRow(
intable,
'',
string.format(reloadFormat, draw),
string.format(reloadFormat, 0.85 * draw),
string.format(reloadFormat, 0.80 * draw),
string.format(reloadFormat, 0.75 * draw),
{ footer = ' 秒' })
renderFormatRow(
intable,
iu.hopup('クイックドローホルスター') .. ' ',
string.format(reloadFormat, quickdraw_holster * draw),
string.format(reloadFormat, 0.85 * quickdraw_holster * draw),
string.format(reloadFormat, 0.80 * quickdraw_holster * draw),
string.format(reloadFormat, 0.75 * quickdraw_holster * draw),
{ footer = ' 秒' })
else
local text = formatter:format(
string.format(drawFormat, draw),
string.format(drawFormat, 0.85 * draw),
string.format(drawFormat, 0.80 * draw),
string.format(drawFormat, 0.75 * draw),
' 秒', ' - ')
renderRow(tbl, name, text)
end
end
local function renderReleaseDate(tbl, name, release)
local r = os.date("*t", release)
local releaseText = string.format(
'<time datetime="%04d-%02d-%02dT%02d:00:00.000+0900">%d年%d月%d日 %d時</time>~',
r.year, r.month, r.day, r.hour, r.year, r.month, r.day, r.hour)
renderRow(tbl, name, releaseText)
end
local function renderTable(args, stat)
stat = stat or mw.loadData('Module:Stat/Weapon')[args.name]
local category = stat.category
local islmg = category == 'light_machine_gun'
local table = mw.html.create('table')
renderReleaseDate(table, 'リリース日', stat.release)
renderCategory(table, '種類', category)
renderAmmo(table, '弾薬', stat.ammo)
renderMode(table, '射撃モード', stat.mode)
renderDamage(table, 'ダメージ', stat.damage, stat.ammo, stat.pellet)
renderDPS(table, 'DPS', stat)
renderFirerate(table, '射撃速度', stat.firerate, stat.mode)
renderMagazine(table, '装填数', stat.magazine, islmg)
if stat.time then
if stat.time.draw then
renderDraw(table, '据銃時間', stat.time.draw, stat.time.quickdraw_holster or 0, stat.attachments, stat.ammo)
end
if stat.time.reload then
renderReload(table, 'リロード', stat.time.reload, stat.attachments, stat.ammo, islmg)
end
end
return table
end
function p.getNode(stat, formatter2)
formatter = formatter2 or require('Module:Utility/Formatter').new()
return renderTable(nil, stat)
end
function p._main(args, frame)
formatter = require('Module:Utility/Formatter').new(frame)
return tostring(renderTable(args))
end
function p.main(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
args = getArgs(frame)
return p._main(args, frame)
end
return p