🌟 | 現在、 鉄壁ヘッドショットには対応済みです。 鉄壁HSは通常HSと同じダメージになります。LMG及びDMR、チャージライフル、ハンマーポイント弾を除き、すべてのダメージ値が一致していることを確認しています。 |
「モジュール:WeaponInfobox」の版間の差分
ナビゲーションに移動
検索に移動
(弾薬や種類のUI生成をLuaライブラリーの使用に切り替え) |
(センチネルの増幅モード記述変更による実装の変更) |
||
182行目: | 182行目: | ||
iu.hopup('アンビルレシーバー'), | iu.hopup('アンビルレシーバー'), | ||
formatter:legendary(stat.anvil_receiver.base)) | formatter:legendary(stat.anvil_receiver.base)) | ||
elseif stat.amped then | |||
damageText = string.format( | |||
'%s <span class="text-separator">/</span> %s %s', | |||
base, | |||
iu.item('シールドセル'), | |||
stat.amped) | |||
else | else | ||
damageText = tostring(base) | damageText = tostring(base) |
2021年2月19日 (金) 21:25時点における版
このモジュールについての説明文ページを モジュール:WeaponInfobox/doc に作成できます
require('Module:Utility/mw.html Extensions') local p = {} local cfg = mw.loadData('Module:WeaponInfobox/configuration') local aw = require('Module:Utility/Library') local iu = require('Module:Utility/Image') local nu = require('Module:Utility/Name') 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 calcBurstAverageRPS(stat, delay) delay = delay or stat.firerate.burst_delay return stat.mode.burst / ((stat.mode.burst - 1) / stat.firerate.burst + delay) 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 function renderReleaseDate(tbl, cfg, 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, cfg.name, releaseText) end local function renderCategory(tbl, cfg, stat) local category = nu.type(stat) local item = string.format('[[武器#%s|%s]][[Category:%s]]', category, category, category) renderRow(tbl, cfg.name, item) end local function renderAmmo(tbl, cfg, stat) local ammo = nu.ammo(stat) local item = string.format( '%s [[弾薬#%s|%s]][[Category:%s]]', iu.ammo(stat, { size = 24 }), ammo, ammo, ammo) renderRow(tbl, cfg.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, cfg, stat) local mode = nil if stat.burst > 1 then mode = string.format(cfg.burst, stat.burst) .. cfg.burst_category end if stat.auto then if mode == nil then mode = cfg.auto .. cfg.auto_category else mode = mode .. cfg.separator .. cfg.auto .. cfg.auto_category end end if stat.single then if mode == nil then mode = cfg.single .. cfg.single_category else mode = mode .. cfg.separator .. cfg.single .. cfg.single_category end end renderRow(tbl, cfg.name, mode) end local function renderDamage(tbl, cfg, stat, ammo, pellet) local base = stat.base local typename = type(base) local damageText if pellet ~= nil then damageText = string.format(cfg.shotgun, base, pellet) elseif typename == 'table' then damageText = table.concat(base, ' - ') elseif typename == 'number' then if stat.anvil_receiver ~= nil then damageText = string.format( '%s <span class="text-separator">/</span> %s %s', base, iu.hopup('アンビルレシーバー'), formatter:legendary(stat.anvil_receiver.base)) elseif stat.amped then damageText = string.format( '%s <span class="text-separator">/</span> %s %s', base, iu.item('シールドセル'), stat.amped) else damageText = tostring(base) end else return end renderRow(tbl, cfg.name, damageText) 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 = string.format(cfg.head_category, stat.headshot) local ul = tbl:tag('tr') :tag('td') :attr('colspan', 2) :tag('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, cfg.head, head, hlm1, hlm2, hlm3, { footer = cfg.unit .. cattext }) renderFormatRow( intable, iu.hopup('スカルピアサーライフリング') .. ' ', spr0, spr1, spr2, spr3, { footer = cfg.unit }) else local headText = cfg.head .. formatter:format(head, hlm1, hlm2, hlm3, cfg.unit, ' - ') .. cattext ul:tag('li'):wikitext(headText) end local legText if stat.anvil_receiver ~= nil then local anvilleg = convertDecimalToFractional(stat.anvil_receiver.legshot) legText = string.format( cfg.legs .. ' %s' .. cfg.unit .. ' <span class="text-separator">/</span> %s %s', leg, iu.hopup('アンビルレシーバー'), formatter:legendary(anvilleg .. cfg.unit)) else legText = cfg.legs .. ' ' .. leg .. cfg.unit end ul:tag('li'):wikitext(legText) end local function renderFirerateRow(intbl, name, cfg, rps, opts) opts = opts or {} intbl:tag('tr') :addClassIf(opts.class and type(opts.class) == 'string', opts.class) :tag('th') :wikitext(name) :done() :tag('td') :addClass('cell-type-number') :attr('align', 'right') :wikitext(string.format(cfg.rps.format, rps)) :done() :tag('td') :wikitext(cfg.rps.unit) :done() :tag('td') :tag('small') :addClass('text-secondary') :wikitext(cfg.rpm.name) :done() :done() :tag('td') :addClass('cell-type-number') :attr('align', 'right') :tag('small') :addClass('text-secondary') :wikitext(aw.comma(60 * rps)) :done() :done() :tag('td') :tag('small') :addClass('text-secondary') :wikitext(cfg.rpm.unit) end local function renderFirerateCell(cell, cfg, rps, opts) opts = opts or {} opts.header = opts.header or '' cell:wikitext(string.format( opts.header .. '<span class="text-type-number">' .. cfg.rps.format .. '</span>' .. cfg.rps.unit .. '<span class="text-secondary"><small>(<span class="text-type-number">%s</span>' .. cfg.rpm.unit .. '</small></span>', rps, aw.comma(60 * rps))) end local function renderFirerate(tbl, cfg, stat) local firerate = stat.firerate if firerate == nil then return end local mode = stat.mode local cell = createCellInRow(tbl, cfg.name) local rps if mode.auto then if mode.single then if firerate.anvil_receiver then local intbl = cell:tag('table') :addClass('condensedtable') :addClass('listtable') renderFirerateRow(intbl, cfg.auto, cfg, firerate.auto) if firerate.auto ~= firerate.single then renderFirerateRow(intbl, cfg.single, cfg, firerate.single) end if firerate.anvil_receiver then renderFirerateRow(intbl, iu.hopup('アンビルレシーバー'), cfg, firerate.anvil_receiver) end return elseif firerate.auto ~= firerate.single then local intbl = cell:tag('table') :addClass('condensedtable') :addClass('listtable') if firerate.burst then renderFirerateRow(intbl, cfg.burst, cfg, firerate.burst) end renderFirerateRow(intbl, cfg.auto, cfg, firerate.auto) renderFirerateRow(intbl, cfg.single, cfg, firerate.single) return end elseif mode.burst > 1 then if type(firerate.auto) == 'table' then local newcell = tbl:tag('tr') :tag('td') :attr('colspan', 2) renderFirerateCell(newcell:tag('ul'):tag('li'), cfg, firerate.burst, { header = cfg.burst }) intbl = newcell:tag('table') :addClass('condensedtable') :addClass('listtable') local average1 = 0.01 * aw.round(100 * calcBurstAverageRPS(stat, firerate.burst_delay[1])) local average2 = 0.01 * aw.round(100 * calcBurstAverageRPS(stat, firerate.burst_delay[2])) local average3 = 0.01 * aw.round(100 * calcBurstAverageRPS(stat, firerate.burst_delay[3])) local average4 = 0.01 * aw.round(100 * calcBurstAverageRPS(stat, firerate.burst_delay[4])) renderFormatRow( intbl, cfg.burst_average .. cfg.rps.name, string.format(cfg.rps.format, average1), string.format(cfg.rps.format, average2), string.format(cfg.rps.format, average3), string.format(cfg.rps.format, average4), { class = 'no-list-style', separator = cfg.rps.separator, footer = cfg.rps.unit }) renderFormatRow( intbl, cfg.rpm.name, string.format(cfg.rpm.format, 60 * average1), string.format(cfg.rpm.format, 60 * average2), string.format(cfg.rpm.format, 60 * average3), string.format(cfg.rpm.format, 60 * average4), { class = 'all-secondary no-list-style', headerAlign = 'right', separator = cfg.rpm.separator, footer = cfg.rpm.unit }) renderFormatRow( intbl, cfg.auto .. cfg.rps.name, string.format(cfg.rps.format, firerate.auto[1]), string.format(cfg.rps.format, firerate.auto[2]), string.format(cfg.rps.format, firerate.auto[3]), string.format(cfg.rps.format, firerate.auto[4]), { separator = cfg.rps.separator, footer = cfg.rps.unit }) renderFormatRow( intbl, cfg.rpm.name, string.format(cfg.rpm.format, 60 * firerate.auto[1]), string.format(cfg.rpm.format, 60 * firerate.auto[2]), string.format(cfg.rpm.format, 60 * firerate.auto[3]), string.format(cfg.rpm.format, 60 * firerate.auto[4]), { class = 'all-secondary no-list-style', headerAlign = 'right', separator = cfg.rpm.separator, footer = cfg.rpm.unit }) else local intbl = cell:tag('table') :addClass('condensedtable') :addClass('listtable') local average = 0.01 * aw.round(100 * calcBurstAverageRPS(stat)) renderFirerateRow(intbl, cfg.burst, cfg, firerate.burst) renderFirerateRow(intbl, cfg.burst_average, cfg, average, { class = 'no-list-style' }) renderFirerateRow(intbl, cfg.auto, cfg, firerate.auto) end return end rps = firerate.auto elseif mode.single then if mode.burst > 1 then local intbl = cell:tag('table') :addClass('condensedtable') :addClass('listtable') local average = 0.01 * aw.round(100 * calcBurstAverageRPS(stat)) renderFirerateRow(intbl, cfg.burst, cfg, firerate.burst) renderFirerateRow(intbl, cfg.burst_average, cfg, average, { class = 'no-list-style' }) renderFirerateRow(intbl, cfg.single, cfg, firerate.single) return end rps = firerate.single else return end if type(rps) == 'table' then local intable = cell:tag('table'):addClass('condensedtable') renderFormatRow( intable, cfg.rps.name, string.format(cfg.rps.format, rps[1]), string.format(cfg.rps.format, rps[2]), string.format(cfg.rps.format, rps[3]), string.format(cfg.rps.format, rps[4]), { separator = cfg.rps.separator, footer = cfg.rps.unit }) renderFormatRow( intable, cfg.rpm.name, string.format(cfg.rpm.format, 60 * rps[1]), string.format(cfg.rpm.format, 60 * rps[2]), string.format(cfg.rpm.format, 60 * rps[3]), string.format(cfg.rpm.format, 60 * rps[4]), { class = 'all-secondary', separator = cfg.rpm.separator, footer = cfg.rpm.unit }) else renderFirerateCell(cell, cfg, 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.burst and stat.mode.burst > 1 then local average if type(stat.firerate.burst_delay) == 'table' then average = calcBurstAverageRPS(stat, stat.firerate.burst_delay[1]) else average = calcBurstAverageRPS(stat) end renderDPSTable( cell, '', pellet, stat.damage.base, stat.damage, average, useRound) end 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(tbl, cfg, stat, islmg) local typename = type(stat) if typename == 'table' then if islmg then local intable = createCellInRow(tbl, cfg.name) :tag('table') :addClass('condensedtable') renderFormatRow( intable, '', stat[1], stat[2], stat[3], stat[4], { footer = cfg.units }) 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 = cfg.units }) else local text = formatter:format(stat[1], stat[2], stat[3], stat[4], cfg.units, ' - ') renderRow(tbl, cfg.name, text) end elseif typename == 'number' then local text if stat == math.huge then text = cfg.infinity else text = stat .. cfg.unit end renderRow(tbl, cfg.name, text) end end local function renderReload(tbl, cfg, 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, cfg.name) :tag('table') :addClass('condensedtable') :addClass('listtable') renderFormatRow( intable, cfg.tactical.name .. ' ', string.format(cfg.tactical.format, reload.tactical), nil, nil, nil, { footer = cfg.tactical.unit }) if islmg then renderFormatRow( intable, formatter:hopup('改造ローダー') .. ' ', string.format(cfg.tactical.format, 0.75 * reload.tactical), nil, nil, nil, { class = 'no-list-style', headerAlign = 'right', footer = cfg.tactical.unit }) end renderFormatRow( intable, cfg.full.name .. ' ', string.format(cfg.full.format, reload.full), nil, nil, nil, { footer = cfg.full.unit }) if islmg then renderFormatRow( intable, formatter:hopup('改造ローダー') .. ' ', string.format(cfg.full.format, 0.75 * reload.full), nil, nil, nil, { class = 'no-list-style', headerAlign = 'right', footer = cfg.full.unit }) end elseif islmg then local text = string.format( cfg.full.format .. cfg.full.unit .. ' <span class="text-separator">/</span> %s ' .. cfg.full.format .. cfg.full.unit, muls.level3 * reload.full, formatter:hopup('改造ローダー'), 0.75 * muls.level3 * reload.full) renderRow(tbl, cfg.name, text) else local time if incompatible or ammo == 'special_sniper' then time = reload.full else time = muls.level3 * reload.full end renderRow(tbl, cfg.name, string.format(cfg.full.format, time) .. cfg.full.unit) end elseif reload.tactical ~= nil and reload.tactical ~= reload.full then renderRow(tbl, cfg.name, '') local intable = tbl:tag('tr') :tag('td') :attr('colspan', 2) :tag('table') :addClass('condensedtable') :addClass('listtable') renderFormatRow( intable, cfg.tactical.name .. ' ', string.format(cfg.tactical.format, reload.tactical), nil, string.format(cfg.tactical.format, muls.level2 * reload.tactical), string.format(cfg.tactical.format, muls.level3 * reload.tactical), { footer = cfg.tactical.unit }) if islmg then renderFormatRow( intable, formatter:hopup('改造ローダー') .. ' ', string.format(cfg.tactical.format, 0.75 * reload.tactical), nil, string.format(cfg.tactical.format, 0.75 * muls.level2 * reload.tactical), string.format(cfg.tactical.format, 0.75 * muls.level3 * reload.tactical), { class = 'no-list-style', headerAlign = 'right', footer = cfg.tactical.unit }) end renderFormatRow( intable, cfg.full.name .. ' ', string.format(cfg.full.format, reload.full), nil, string.format(cfg.full.format, muls.level2 * reload.full), string.format(cfg.full.format, muls.level3 * reload.full), { footer = cfg.full.unit }) if islmg then renderFormatRow( intable, formatter:hopup('改造ローダー') .. ' ', string.format(cfg.full.format, 0.75 * reload.full), nil, string.format(cfg.full.format, 0.75 * muls.level2 * reload.full), string.format(cfg.full.format, 0.75 * muls.level3 * reload.full), { class = 'no-list-style', headerAlign = 'right', footer = cfg.full.unit }) end else local text = formatter:format( string.format(cfg.full.format, reload.full), nil, string.format(cfg.full.format, muls.level2 * reload.full), string.format(cfg.full.format, muls.level3 * reload.full), cfg.full.unit, ' - ') renderRow(tbl, cfg.name, text) end end local function renderDraw(tbl, cfg, 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( cfg.format .. cfg.unit .. ' <span class="text-separator">/</span> %s ' .. formatter:epic(cfg.format .. cfg.unit), time, iu.hopup('クイックドローホルスター'), quickdraw_holster * time) else text = string.format(cfg.format, time) .. cfg.unit end renderRow(tbl, cfg.name, text) elseif quickdraw_holster > 0 then local intable = createCellInRow(tbl, cfg.name) :tag('table') :addClass('condensedtable') renderFormatRow( intable, '', string.format(cfg.format, draw), string.format(cfg.format, 0.85 * draw), string.format(cfg.format, 0.80 * draw), string.format(cfg.format, 0.75 * draw), { footer = cfg.unit }) renderFormatRow( intable, iu.hopup('クイックドローホルスター') .. ' ', string.format(cfg.format, quickdraw_holster * draw), string.format(cfg.format, 0.85 * quickdraw_holster * draw), string.format(cfg.format, 0.80 * quickdraw_holster * draw), string.format(cfg.format, 0.75 * quickdraw_holster * draw), { footer = cfg.unit }) else local text = formatter:format( string.format(cfg.format, draw), string.format(cfg.format, 0.85 * draw), string.format(cfg.format, 0.80 * draw), string.format(cfg.format, 0.75 * draw), cfg.unit, ' - ') renderRow(tbl, cfg.name, text) end end local function createTable(cfg, stat) local islmg = stat.category == 'light_machine_gun' local tbl = mw.html.create('table') renderReleaseDate(tbl, cfg.release, stat.release) renderCategory(tbl, cfg.category, stat.category) renderAmmo(tbl, cfg.ammo, stat.ammo) renderMode(tbl, cfg.mode, stat.mode) renderDamage(tbl, cfg.damage, stat.damage, stat.ammo, stat.pellet) renderDPS(tbl, 'DPS', stat) renderFirerate(tbl, cfg.firerate, stat) renderMagazine(tbl, cfg.magazine, stat.magazine, islmg) if stat.time then if stat.time.draw then renderDraw(tbl, cfg.draw, stat.time.draw, stat.time.quickdraw_holster or 0, stat.attachments, stat.ammo) end if stat.time.reload then renderReload(tbl, cfg.reload, stat.time.reload, stat.attachments, stat.ammo, islmg) end end return tbl end local function renderInfobox(args) local cfglang = cfg[args and args.lang or 'ja'] local stat = mw.loadData('Module:Stat/Weapon')[args.name] local div = mw.html.create('div') :addClass('tpl-infobox-right') :addClass('tpl-weapon') if stringStarts(stat.ammo, "special_") then div:addClass('tpl-weapon-special') else div:addClass('tpl-weapon-' .. stat.ammo) end div:tag('div') :addClass('tpl-weapon-header') :wikitext(args.name .. iu.ammo(stat.ammo, { size = 40 })) div:node(createTable(cfglang, stat)) return div end function p._main(args, frame) formatter = require('Module:Utility/Formatter').new(frame) return tostring(renderInfobox(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