| 🌟 | 現在、 鉄壁HSは通常HSと同じダメージになります。LMG及びDMR、チャージライフル、ハンマーポイント弾を除き、すべてのダメージ値が一致していることを確認しています。 |
モジュール:WeaponInfobox/DPS
ナビゲーションに移動
検索に移動
このモジュールについての説明文ページを モジュール:WeaponInfobox/DPS/doc に作成できます
require('Module:Utility/mw.html Extensions')
local p = {}
local cfg = mw.loadData('Module:WeaponInfobox/configuration')
local aw = require('Module:Utility/Library')
local apex = require('Module:Utility/ApexLibrary')
local iu = require('Module:Utility/Image')
local proto = require('Module:Utility/Prototypes')
-- Constants
local leftBorder = {
['border-left-width'] = '1px',
['border-left-style'] = 'solid',
}
local leftBorderWithoutTopRightBorder = {
['border-top'] = '0 none transparent',
['border-right'] = '0 none transparent',
['border-left-width'] = '1px',
['border-left-style'] = 'solid',
}
-- Protos
local MinMaxProto = {
proto.NumberRange(0),
proto.NumberRange(0),
}
local MultipleFirerateProto = {
proto.NumberRange(0),
proto.NumberRange(0),
proto.NumberRange(0),
proto.NumberRange(0),
}
local AnvilReceiverProto = {
damage = {
base = proto.NumberRange(1),
headshot = proto.NumberRange(1, 10),
legshot = proto.NumberRange(0, 1),
},
firerate = {
single = proto.NumberRange(0),
},
}
local ShatterCapsProto = {
damage = {
base = proto.NumberRange(1),
headshot = proto.NumberRange(1, 10),
legshot = proto.NumberRange(0, 1),
},
pellet = proto.NumberRange(1),
}
local DeadeyesTempoWithRechamberProto = {
firerate = {
single_rechamber = proto.NumberRange(0),
},
}
local function calcBurstRPS(stat, delay)
delay = delay or stat.firerate.burst_delay
return stat.mode.burst / ((stat.mode.burst - 1) / stat.firerate.burst + delay)
end
local function calcRechamberRPS(firerate, rechamber)
rechamber = rechamber or firerate.single_rechamber
return 1 / (1 / firerate.single + rechamber)
end
local function getStats(stat1, stat2)
local ret
if stat2 then
ret = {
base = stat2.damage.base or stat1.damage.base,
head = stat2.damage.headshot or stat1.damage.headshot or 1.75,
legs = stat2.damage.legshot or stat1.damage.legshot or 0.75,
}
else
ret = {
base = stat1.damage.base,
head = stat1.damage.headshot or 1.75,
legs = stat1.damage.legshot or 0.75,
}
end
return ret
end
local function getDamages(stat, helmets)
local helmet = helmets.level0.disabled and helmets.level1 or helmets.level0
local ret
if stat.legs > 0 and stat.legs < 1 then
ret = {
aw.round(stat.legs * stat.base),
stat.base,
{
aw.round(helmets.level3.func(stat.head) * stat.base),
aw.round(helmet.func(stat.head) * stat.base),
},
}
else
ret = {
stat.base,
{
aw.round(helmets.level3.func(stat.head) * stat.base),
aw.round(helmet.func(stat.head) * stat.base),
},
}
end
return ret
end
local function getDPSs(damages, perk, pellets, firerate, useRound)
local ret = {}
for _, damage in ipairs(damages) do
if proto.validateTypes(damage, MinMaxProto) then
local minPerked = apex.calcPassiveDamage(damage[1], perk, { round = useRound })
local maxPerked = apex.calcPassiveDamage(damage[2], perk, { round = useRound })
table.insert(ret, { minPerked * firerate, pellets * maxPerked * firerate })
elseif pellets > 1 then
local perked = apex.calcPassiveDamage(damage, perk, { round = useRound })
table.insert(ret, { perked * firerate, pellets * perked * firerate })
else
local perked = apex.calcPassiveDamage(damage, perk, { round = useRound })
table.insert(ret, pellets * perked * firerate)
end
end
return ret
end
local function toDPSText(value, format)
if proto.validateTypes(value, MinMaxProto) then
return string.format(format, string.format("%.1f", value[1]), string.format("%.1f", value[2]))
else
return string.format("%.1f", value)
end
end
local function renderDPSRow(tbl, name, format, data, opts)
local row = tbl:tag('tr')
if aw.isNumberAndGreaterThanZero(opts.offset) then
for i = 1, opts.offset do
local hasLeftBorder = opts.offsetStyles and opts.offsetStyles[i] and opts.offsetStyles[i].leftBorder
if hasLeftBorder then
row:tag('th')
:css(leftBorderWithoutTopRightBorder)
:wikitext(' ')
else
row:tag('th')
:css('border', '0 none transparent')
:wikitext(' ')
end
end
end
row:tag('th')
:attrIf(aw.isNumber(opts.colspan), { colspan = opts.colspan })
:cssIf(aw.isNumberAndGreaterThanZero(opts.offset), leftBorder)
:wikitext(name)
if #data >= 3 then
if data[1] == nil then
row:tag('td')
:attr('align', 'center')
:addClass('disabled')
:wikitext('–')
else
row:tag('td')
:addClass('cell-type-number')
:attr('align', 'right')
:wikitext(toDPSText(data[1], format))
end
row
:tag('td')
:addClass('cell-type-number')
:attr('align', 'right')
:wikitext(toDPSText(data[2], format))
:done()
:tag('td')
:attr('align', 'right')
:wikitext(toDPSText(data[3], format))
else
row
:tag('td')
:addClass('cell-type-number')
:attr('align', 'right')
:attrIf(opts.hideLegs, { colspan = 2 })
:wikitext(toDPSText(data[1], format))
:done()
:tag('td')
:attr('align', 'right')
:wikitext(toDPSText(data[2], format))
end
end
function p.renderDPS(stat, shieldinfo, lang)
local cfg = cfg[lang].dps
local basic = getStats(stat)
local damages = getDamages(basic, shieldinfo.helmets)
local pellet = aw.getAsNumber(stat.pellet, 1)
local useRound = aw.getAsBoolean(stat.damage.round, false)
local hasAnvil = proto.validateTypes(stat.anvil_receiver, AnvilReceiverProto)
local hasShat = proto.validateTypes(stat.shatter_caps, ShatterCapsProto)
local hasTempo = proto.validateTypes(stat.deadeyes_tempo, DeadeyesTempoWithRechamberProto)
local hasHopup = hasAnvil or hasShat or hasTempo
local hasAmped = aw.isNumberAndGreaterThanZero(stat.damage.amped)
local hasChgd = aw.isNumberAndGreaterThanZero(stat.damage.charged)
local hasExtra = hasAmped or hasChgd
-- Load firerate
local firerate
if aw.isNumber(stat.mode.burst) and stat.mode.burst > 1 then
firerate = calcBurstRPS(stat)
elseif stat.mode.auto then
firerate = stat.firerate.auto
elseif stat.mode.single then
if aw.isNumberAndGreaterThanZero(stat.firerate.single_rechamber) then
firerate = calcRechamberRPS(stat.firerate)
elseif proto.validateTypes(stat.firerate.single_rechamber, MultipleFirerateProto) then
firerate = {
calcRechamberRPS(stat.firerate, stat.firerate.single_rechamber[1]),
calcRechamberRPS(stat.firerate, stat.firerate.single_rechamber[2]),
calcRechamberRPS(stat.firerate, stat.firerate.single_rechamber[3]),
calcRechamberRPS(stat.firerate, stat.firerate.single_rechamber[4]),
}
else
firerate = stat.firerate.single
end
else
return nil
end
local hasMultiple = proto.validateTypes(firerate, MultipleFirerateProto)
local headerColspan
local defopts, mpopts, huopts, exopts, ex2opts
if hasMultiple then
if hasExtra then
headerColspan = 3
defopts = { colspan = 3 }
muopts = { offset = 1, colspan = 2 }
exopts = { offset = 2 }
ex2opts = { offset = 2, offsetStyles = { nil, { leftBorder = true } } }
else
headerColspan = 2
defopts = { colspan = 2 }
muopts = { offset = 1 }
exopts = {}
ex2opts = {}
end
huopts = {}
elseif hasHopup then
if hasExtra then
local hideLegs = damages.legs ~= 1
headerColspan = 3
defopts = { colspan = 3 }
huopts = { offset = 1, colspan = 2, hideLegs = hideLegs }
exopts = { offset = 2 }
ex2opts = { offset = 2, offsetStyles = { nil, { leftBorder = true } }, hideLegs = hideLegs }
else
headerColspan = 2
defopts = { colspan = 2 }
huopts = { offset = 1, hideLegs = damages.legs ~= 1 }
exopts = {}
ex2opts = {}
end
muopts = {}
elseif hasExtra then
headerColspan = 1
defopts = { colspan = 2 }
muopts = {}
huopts = {}
exopts = {}
ex2opts = { offset = 1 }
else
headerColspan = 1
defopts = {}
muopts = {}
huopts = {}
exopts = {}
ex2opts = {}
end
-- Hop-ups
local damages2, pellet2, firerate2, label
if hasAnvil then
local anvil = getStats(stat, stat.anvil_receiver)
damages2 = getDamages(anvil, shieldinfo.helmets)
pellet2 = pellet
firerate2 = stat.anvil_receiver.firerate.single
label = iu.hopup('anvil_receiver')
elseif hasShat then
local shat = getStats(stat, stat.shatter_caps)
damages2 = getDamages(shat, shieldinfo.helmets)
pellet2 = stat.shatter_caps.pellet
firerate2 = firerate
label = iu.hopup('shatter_caps')
elseif hasTempo then
damages2 = damages
pellet2 = pellet
firerate2 = calcRechamberRPS(stat.firerate, stat.deadeyes_tempo.firerate.single_rechamber)
label = string.format(cfg.hopup.deadeyes_tempo, iu.hopup('deadeyes_tempo'))
end
-- Extra damages
local damagesE, labelE, damages2E
if hasAmped then
local extra = aw.shallowCopy(basic)
extra.base = stat.damage.amped
damagesE = getDamages(extra, shieldinfo.helmets)
labelE = iu.item('シールドセル')
elseif hasChgd then
local extra = aw.shallowCopy(basic)
extra.base = stat.damage.charged
damagesE = getDamages(extra, shieldinfo.helmets)
labelE = iu.scope('スロット')
if hasShat then
local shat2 = getStats(stat, stat.shatter_caps)
shat2.base = stat.shatter_caps.damage.charged
if aw.isNumberAndGreaterThanZero(stat.shatter_caps.damage.headshot_charged) then
shat2.head = stat.shatter_caps.damage.headshot_charged
end
if aw.isNumberAndGreaterThanZero(stat.shatter_caps.damage.legshot_charged) then
local legs = stat.shatter_caps.damage.legshot_charged
shat2.legs = legs
if legs == 1 then
ex2opts.hideLegs = true
end
end
damages2E = getDamages(shat2, shieldinfo.helmets)
end
end
local tbl = mw.html.create('table'):addClass('intable')
-- Header
local header = tbl:tag('tr'):tag('th')
:attrIf(headerColspan > 1, { colspan = headerColspan })
:wikitext('')
:done()
if #damages >= 3 then
header
:tag('th')
:wikitext(cfg.part.legs)
:tag('th')
:wikitext(cfg.part.body)
else
header:tag('th')
:wikitext(cfg.part.bodylegs)
end
header:tag('th')
:wikitext(cfg.part.head)
-- Normal
if hasMultiple then
local normalDPS0 = getDPSs(damages, 1, pellet, firerate[1], useRound)
local normalDPS1 = getDPSs(damages, 1, pellet, firerate[2], useRound)
local normalDPS2 = getDPSs(damages, 1, pellet, firerate[3], useRound)
local normalDPS3 = getDPSs(damages, 1, pellet, firerate[4], useRound)
renderDPSRow(tbl, cfg.perk.normal, cfg.complex, normalDPS0, defopts)
renderDPSRow(tbl, iu.attachment('ショットガンボルト', 1), cfg.complex, normalDPS1, muopts)
renderDPSRow(tbl, iu.attachment('ショットガンボルト', 2), cfg.complex, normalDPS2, muopts)
renderDPSRow(tbl, iu.attachment('ショットガンボルト', 3), cfg.complex, normalDPS3, muopts)
else
local normalDPS = getDPSs(damages, 1, pellet, firerate, useRound)
renderDPSRow(tbl, cfg.perk.normal, cfg.complex, normalDPS, defopts)
end
--- Extra
if hasExtra then
local extraDPS = getDPSs(damagesE, 1, pellet, firerate, useRound)
renderDPSRow(tbl, labelE, cfg.complex, extraDPS, exopts)
end
--- Hop-up
if hasHopup then
local hopupDPS = getDPSs(damages2, 1, pellet2, firerate2, useRound)
renderDPSRow(tbl, label, cfg.complex, hopupDPS, huopts)
---- Extra
if hasTempo and hasAmped then
local tempoExtraDPS = getDPSs(damagesE, 1, pellet2, firerate2, useRound)
renderDPSRow(tbl, labelE, cfg.complex, tempoExtraDPS, ex2opts)
elseif hasShat and hasChgd then
local shatChargedDPS = getDPSs(damages2E, 1, pellet2, firerate2, useRound)
renderDPSRow(tbl, labelE, cfg.complex, shatChargedDPS, ex2opts)
end
end
-- Low Profile
if aw.isNumber(shieldinfo.lowprofile) and shieldinfo.lowprofile > 1 then
if hasMultiple then
local normalDPS0 = getDPSs(damages, shieldinfo.lowprofile, pellet, firerate[1], useRound)
local normalDPS1 = getDPSs(damages, shieldinfo.lowprofile, pellet, firerate[2], useRound)
local normalDPS2 = getDPSs(damages, shieldinfo.lowprofile, pellet, firerate[3], useRound)
local normalDPS3 = getDPSs(damages, shieldinfo.lowprofile, pellet, firerate[4], useRound)
renderDPSRow(tbl, cfg.perk.lowprofile, cfg.complex, normalDPS0, defopts)
renderDPSRow(tbl, iu.attachment('ショットガンボルト', 1), cfg.complex, normalDPS1, muopts)
renderDPSRow(tbl, iu.attachment('ショットガンボルト', 2), cfg.complex, normalDPS2, muopts)
renderDPSRow(tbl, iu.attachment('ショットガンボルト', 3), cfg.complex, normalDPS3, muopts)
else
local lowprofileDPS = getDPSs(damages, shieldinfo.lowprofile, pellet, firerate, useRound)
renderDPSRow(tbl, cfg.perk.lowprofile, cfg.complex, lowprofileDPS, defopts)
end
--- Extra
if hasExtra then
local extraLowProfileDPS = getDPSs(damagesE, shieldinfo.lowprofile, pellet, firerate, useRound)
renderDPSRow(tbl, labelE, cfg.complex, extraLowProfileDPS, exopts)
end
--- Hop-up
if hasHopup then
local hopupLowProfileDPS = getDPSs(damages2, shieldinfo.lowprofile, pellet2, firerate2, useRound)
renderDPSRow(tbl, label, cfg.complex, hopupLowProfileDPS, huopts)
---- Extra
if hasTempo and hasAmped then
local tempoAmpedLowProfileDPS = getDPSs(damagesE, shieldinfo.lowprofile, pellet2, firerate2, useRound)
renderDPSRow(tbl, labelE, cfg.complex, tempoAmpedLowProfileDPS, ex2opts)
elseif hasShat and hasChgd then
local shatChargedLowProfileDPS = getDPSs(damages2E, shieldinfo.lowprofile, pellet2, firerate2, useRound)
renderDPSRow(tbl, labelE, cfg.complex, shatChargedLowProfileDPS, ex2opts)
end
end
end
-- Fortified
if aw.isNumber(shieldinfo.fortified) and shieldinfo.fortified < 1 then
if hasMultiple then
local normalDPS0 = getDPSs(damages, shieldinfo.fortified, pellet, firerate[1], useRound)
local normalDPS1 = getDPSs(damages, shieldinfo.fortified, pellet, firerate[2], useRound)
local normalDPS2 = getDPSs(damages, shieldinfo.fortified, pellet, firerate[3], useRound)
local normalDPS3 = getDPSs(damages, shieldinfo.fortified, pellet, firerate[4], useRound)
renderDPSRow(tbl, cfg.perk.fortified, cfg.complex, normalDPS0, defopts)
renderDPSRow(tbl, iu.attachment('ショットガンボルト', 1), cfg.complex, normalDPS1, muopts)
renderDPSRow(tbl, iu.attachment('ショットガンボルト', 2), cfg.complex, normalDPS2, muopts)
renderDPSRow(tbl, iu.attachment('ショットガンボルト', 3), cfg.complex, normalDPS3, muopts)
else
local lowprofileDPS = getDPSs(damages, shieldinfo.fortified, pellet, firerate, useRound)
renderDPSRow(tbl, cfg.perk.fortified, cfg.complex, lowprofileDPS, defopts)
end
--- Extra
if hasExtra then
local extraFortifiedDPS = getDPSs(damagesE, shieldinfo.fortified, pellet, firerate, useRound)
renderDPSRow(tbl, labelE, cfg.complex, extraFortifiedDPS, exopts)
end
--- Hop-up
if hasHopup then
local hopupFortifiedDPS = getDPSs(damages2, shieldinfo.fortified, pellet2, firerate2, useRound)
renderDPSRow(tbl, label, cfg.complex, hopupFortifiedDPS, huopts)
---- Extra
if hasTempo and hasAmped then
local tempoAmpedFortifiedDPS = getDPSs(damagesE, shieldinfo.fortified, pellet2, firerate2, useRound)
renderDPSRow(tbl, labelE, cfg.complex, tempoAmpedFortifiedDPS, ex2opts)
elseif hasShat and hasChgd then
local shatChargedFortifiedDPS = getDPSs(damages2E, shieldinfo.fortified, pellet2, firerate2, useRound)
renderDPSRow(tbl, labelE, cfg.complex, shatChargedFortifiedDPS, ex2opts)
end
end
end
return tbl
end
function p._main(name, lang)
lang = lang or 'ja'
local stat = mw.loadData('Module:Stat/Weapon')[name]
local sld = require('Module:Stat/Shield')['removelowprofile']
local node = p.renderDPS(stat, sld, lang)
local div = mw.html.create('div')
:addClass('tpl-infobox-right')
:addClass('tpl-weapon')
if aw.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(name .. iu.ammo(stat.ammo, { size = 40 }))
:done()
:tag('table')
:tag('tr')
:tag('th'):wikitext('DPS'):done()
:tag('td'):done()
:tag('tr')
:tag('td'):attr('colspan', 2):node(node)
return tostring(div)
end
return p