| 🌟 | 現在、 鉄壁HSは通常HSと同じダメージになります。LMG及びDMR、チャージライフル、ハンマーポイント弾を除き、すべてのダメージ値が一致していることを確認しています。 |
「モジュール:DamageTable」の版間の差分
ナビゲーションに移動
検索に移動
(一部の表示形態で位置がずれる問題の修正) |
(胴体の確定数の計算がおかしなことになる不具合の修正) |
||
| 357行目: | 357行目: | ||
scale_hed2 = headLv2Scale, | scale_hed2 = headLv2Scale, | ||
scale_hed3 = headLv3Scale, | scale_hed3 = headLv3Scale, | ||
scale_body = 1, | |||
scale_legs = legsScale, | scale_legs = legsScale, | ||
} | } | ||
2021年9月12日 (日) 12:59時点における版
このモジュールについての説明文ページを モジュール:DamageTable/doc に作成できます
require('Module:Utility/mw.html Extensions')
local p = {}
local table = require('Module:TableExtensions')
local aw = require('Module:Utility/Library')
local apex = require('Module:Utility/ApexLibrary')
local STKCalculator = require('Module:Apex/STKCalculator')
local getArgs -- lazily initialized
local function convertHslToRgb(hue, saturation, lightness)
hue = math.max(0, math.min(1, hue))
saturation = math.max(0, math.min(1, saturation))
lightness = math.max(0, math.min(1, lightness))
if saturation == 0 then
return lightness, lightness, lightness
else
local function to(p, q, t)
if t < 0 then t = t + 1 end
if t > 1 then t = t - 1 end
if t < 1/6 then
return p + (q - p) * 6 * t
elseif t < 3/6 then
return q
elseif t < 4/6 then
return p + (q - p) * (2/3 - t) * 6
else
return p
end
end
local q
if lightness < 0.5 then
q = lightness * (1 + saturation)
else
q = lightness + saturation - lightness * saturation
end
local p = 2 * lightness - q
return to(p, q, hue + 1/3), to(p, q, hue), to(p, q, hue - 1/3)
end
end
local function getColorAsString(hue)
local r, g, b = convertHslToRgb(hue, 0.91, 0.89)
return string.format('#%02X%02X%02X', 255 * r, 255 * g, 255 * b)
end
local function getShotCount(part, health, shield, info, gunshield)
local damages = apex.calcShotCount(info.damage, part, info.mul, health, shield, gunshield or 0, info.opts)
return #damages, damages
end
local function renderHeader(tbl, mul, colspan, shields, res)
tbl:tag('tr')
:tag('th')
:attr('colspan', colspan)
:attr('rowspan', 2)
:wikitextIf(
mul == 1,
res.targets.caption,
function()
return string.format(res.targets.caption_format, mul)
end)
:done()
:tag('th')
:attr('rowspan', 2)
:wikitext(res.damages.caption)
:done()
:tag('th')
:attr('colspan', #shields)
:wikitext(res.shotstokill)
local row = tbl:tag('tr')
for _, shield in ipairs(shields) do
row:tag('th')
:attrIf(
shield.tooltip ~= nil,
{ ['data-tooltip'] = shield.tooltip })
:wikitext(shield.label)
end
end
local function renderCell(row, part, health, shield, info, gunshield, rowspan)
local shotCount, damages = getShotCount(part, health, shield, info, gunshield)
local ratio = (shotCount - info.minCount) / info.diffCount
local tooltip = { aw.stringifyRepeatingArray(damages, '→') }
if info.ttkCalculator then
local template = '<tr><th>%s </th><td class="cell-type-number" style="font-weight:bold">%d</td><td> ミリ秒</td></tr>'
local ttkc = info.ttkCalculator
local ttk0 = aw.round(1000 * ttkc:getAsLevel(shotCount, 0))
local ttk1 = aw.round(1000 * ttkc:getAsLevel(shotCount, 1))
local ttk2 = aw.round(1000 * ttkc:getAsLevel(shotCount, 2))
local ttk3 = aw.round(1000 * ttkc:getAsLevel(shotCount, 3))
if ttk2 ~= ttk3 then
table.insert(tooltip, '<br><br>キルタイム:<table class="condensedtable listtable">')
if ttk0 == ttk1 then
table.insert(tooltip, string.format(template, 'なし・Lv.1', ttk0))
table.insert(tooltip, string.format(template, 'Lv.2', ttk2))
else
table.insert(tooltip, string.format(template, 'なし', ttk0))
table.insert(tooltip, string.format(template, 'Lv.1', ttk1))
table.insert(tooltip, string.format(template, 'Lv.2', ttk2))
end
table.insert(tooltip, string.format(template, 'Lv.3', ttk3))
table.insert(tooltip, '</table>')
elseif ttk1 ~= ttk2 then
table.insert(tooltip, '<br><br>キルタイム:<table class="condensedtable listtable">')
if ttk0 == ttk1 then
table.insert(tooltip, string.format(template, 'なし・Lv.1', ttk0))
else
table.insert(tooltip, string.format(template, 'なし', ttk0))
table.insert(tooltip, string.format(template, 'Lv.1', ttk1))
end
table.insert(tooltip, string.format(template, 'Lv.2, 3', ttk2))
table.insert(tooltip, '</table>')
elseif ttk0 ~= ttk1 then
table.insert(tooltip, '<br><br>キルタイム:<table class="condensedtable listtable">')
table.insert(tooltip, string.format(template, 'なし', ttk0))
table.insert(tooltip, string.format(template, 'Lv.1, 2, 3', ttk1))
table.insert(tooltip, '</table>')
else
table.insert(tooltip, string.format('<br>キルタイム: <span class="text-style-number" style="font-weight:bold">%d</span> ミリ秒', ttk0))
end
end
row:tag('td')
:attrIf(rowspan > 1, { rowspan = rowspan })
:attr('data-tooltip', table.concat(tooltip))
:css('background-color', getColorAsString((info.diffCount < 5 and 0.65 or 0.85) * ratio))
:wikitext(shotCount)
end
local function renderHeaderCell(row, name, tooltip, rowinfo)
for i = 1, #rowinfo do
local cellinfo = rowinfo[i]
local colspan = cellinfo.colspan or 1
local rowspan = cellinfo.rowspan or 1
local cell = row:tag('th')
if colspan > 1 then
cell:attr('colspan', colspan)
end
if rowspan > 1 then
cell:attr('rowspan', rowspan)
end
if cellinfo.breaktop then
cell:css('border-top', '0 none transparent')
end
if cellinfo.breakbottom then
cell:css('border-bottom', '0 none transparent')
end
--if cellinfo.showbottom then
-- cell:css({
-- ['border-bottom-style'] = 'solid',
-- ['border-bottom-width'] = '1px',
-- })
--end
if cellinfo.verticalAlign then
cell:css('vertical-align', cellinfo.verticalAlign)
end
if i == #rowinfo then
if tooltip ~= nil then
cell:attr('data-tooltip', tooltip)
end
cell:wikitext(name)
elseif cellinfo.content then
cell:wikitext(cellinfo.content)
else
cell:wikitext(' ')
end
end
end
local function renderRow(tbl, name, tooltip, part, weaponinfo, rowinfo, res, gunshield)
local row = tbl:tag('tr')
renderHeaderCell(row, name, tooltip, rowinfo)
local damage
local opts2 = aw.shallowCopy(weaponinfo.opts)
table.removeKey(opts2, 'beamdamage')
table.removeKey(opts2, 'beamticks')
if gunshield then
table.removeKey(opts2, 'disruptorRounds')
table.removeKey(opts2, 'hammerpointRounds')
damage = apex.calcDamage(weaponinfo.damage, 1, 1, opts2)
else
damage = apex.calcDamage(weaponinfo.damage, part, weaponinfo.mul, opts2)
end
local text
if not gunshield and weaponinfo.opts.disruptorRounds > 1 then
local optsD = aw.shallowCopy(weaponinfo.opts)
table.removeKey(optsD, 'disruptorRounds')
local defaultDamage = apex.calcDamage(weaponinfo.damage, part, weaponinfo.mul, optsD)
if weaponinfo.opts.pellets > 1 then
text = string.format(
res.damages.pelletsWithDisruptor,
damage * weaponinfo.opts.pellets,
damage,
weaponinfo.opts.pellets,
defaultDamage * weaponinfo.opts.pellets)
else
text = string.format(res.damages.disruptor, damage, defaultDamage)
end
elseif not gunshield and weaponinfo.opts.hammerpointRounds > 1 then
local optsH = aw.shallowCopy(weaponinfo.opts)
table.removeKey(optsH, 'hammerpointRounds')
local defaultDamage = apex.calcDamage(weaponinfo.damage, part, weaponinfo.mul, optsH)
if weaponinfo.opts.pellets > 1 then
text = string.format(
res.damages.pelletsWithHammerpoint,
defaultDamage * weaponinfo.opts.pellets,
damage * weaponinfo.opts.pellets,
damage,
weaponinfo.opts.pellets)
else
text = string.format(res.damages.hammerpoint, defaultDamage, damage)
end
elseif weaponinfo.opts.pellets > 1 then
text = string.format(
res.damages.pellets,
damage * weaponinfo.opts.pellets,
damage,
weaponinfo.opts.pellets)
elseif weaponinfo.opts.beamticks > 1 then
local beamdamage = apex.calcDamageFromPartAndPassive(weaponinfo.opts.beamdamage, part, weaponinfo.mul, opts2)
local alldamage = beamdamage * weaponinfo.opts.beamticks + damage
text = string.format(
res.damages.ticks,
alldamage,
beamdamage,
weaponinfo.opts.beamticks,
damage)
else
text = tostring(damage)
end
row:tag('td'):wikitext(text)
for _, shield in ipairs(weaponinfo.shields) do
renderCell(row, part, shield.health, shield.shield, weaponinfo, gunshield, 1)
end
end
local function getTTKCalculator(args)
if args.rps <= 0 then
return nil
end
-- 射撃レート
local firerate
if args.rpsratio1 > 1 then
if args.rpsratio2 > args.rpsratio1 then
if args.rpsratio3 > args.rpsratio2 then
firerate = {
args.rps,
args.rpsratio1 * args.rps,
args.rpsratio2 * args.rps,
args.rpsratio3 * args.rps,
}
else
local rps2 = args.rpsratio2 * args.rps
firerate = {
args.rps,
args.rpsratio1 * args.rps,
rps2,
rps2,
}
end
else
local rps1 = args.rpsratio1 * args.rps
firerate = {
args.rps,
rps1,
rps1,
rps1,
}
end
else
firerate = args.rps
end
-- 装填数
local magazine
if args.extmag0 > 0 then
if args.extmag1 > args.extmag0 then
if args.extmag2 > args.extmag1 then
if args.extmag3 > args.extmag2 then
magazine = { args.extmag0, args.extmag1, args.extmag2, args.extmag3 }
else
magazine = { args.extmag0, args.extmag1, args.extmag2, args.extmag2 }
end
else
magazine = { args.extmag0, args.extmag1, args.extmag1, args.extmag1 }
end
else
magazine = args.extmag0
end
else
magazine = math.huge
end
-- リロード時間
local reload
if args.reloadratio2 > 0 and args.reloadratio2 < 1 then
if args.reloadratio3 > 0 and args.reloadratio3 < args.reloadratio2 then
if args.reloadratio1 > 0 and args.reloadratio1 < 1 and args.reloadratio1 > args.reloadratio2 then
reload = {
args.reload,
args.reloadratio1 * args.reload,
args.reloadratio2 * args.reload,
args.reloadratio3 * args.reload
}
else
reload = {
args.reload,
args.reload,
args.reloadratio2 * args.reload,
args.reloadratio3 * args.reload
}
end
else
local reload2 = args.reloadratio2 * args.reload
reload = {
args.reload,
args.reload,
reload2,
reload2
}
end
else
reload = args.reload
end
local ttkc = require('Module:Apex/TTKCalculator').new(firerate, magazine, reload, {
raiseTime = args.raise,
})
return ttkc
end
local function getContentLanguage(lang)
local language = lang or mw.language.getContentLanguage().code
return language == 'en' and 'en' or 'ja'
end
-- Calc all base damages
local function calcBaseDamages(damage, headScale, legsScale, helmets, opts)
local headLv1Scale = helmets.level1.func(headScale)
local headLv2Scale = helmets.level2.func(headScale)
local headLv3Scale = helmets.level3.func(headScale)
local ret = {
scale_hed0 = headScale,
scale_hed1 = headLv1Scale,
scale_hed2 = headLv2Scale,
scale_hed3 = headLv3Scale,
scale_body = 1,
scale_legs = legsScale,
}
if opts.beamdamage > 0 then
ret.dschrg_hed0 = aw.round(headScale * opts.beamdamage)
ret.dschrg_hed1 = aw.round(headLv1Scale * opts.beamdamage)
ret.dschrg_hed2 = aw.round(headLv2Scale * opts.beamdamage)
ret.dschrg_hed3 = aw.round(headLv3Scale * opts.beamdamage)
ret.dschrg_body = opts.beamdamage
if legsScale < 1 then
ret.dschrg_legs = aw.round(legsScale * opts.beamdamage)
else
ret.dschrg_legs = opts.beamdamage
end
end
-- Amped Cover
if opts.ampedCover then
damage = aw.round(1.2 * damage)
end
-- Additional Scale
if opts.charged > 1 then
damage = aw.round(opts.charged * damage)
end
-- Unshield Scale
if opts.hammerpointRounds > 1 then
local shieldDamage = damage
local unshldDamage = apex.calcHammerpointDamage(damage, opts.hammerpointRounds)
-- Passthrough
if opts.passthrough < 1 then
shieldDamage = apex.calcPassthroughDamage(shieldDamage, opts.passthrough)
unshldDamage = apex.calcPassthroughDamage(unshldDamage, opts.passthrough)
end
local shieldLegs, unshldLegs
if legsScale < 1 then
shieldLegs = aw.round(legsScale * shieldDamage)
unshldLegs = aw.round(legsScale * unshldDamage)
else
shieldLegs = shieldDamage
unshldLegs = unshldDamage
end
ret.shield_hed0 = aw.round(headScale * shieldDamage)
ret.shield_hed1 = aw.round(headLv1Scale * shieldDamage)
ret.shield_hed2 = aw.round(headLv2Scale * shieldDamage)
ret.shield_hed3 = aw.round(headLv3Scale * shieldDamage)
ret.shield_body = shieldDamage
ret.shield_legs = shieldLegs
ret.unshld_hed0 = aw.round(headScale * unshldDamage)
ret.unshld_hed1 = aw.round(headLv1Scale * unshldDamage)
ret.unshld_hed2 = aw.round(headLv2Scale * unshldDamage)
ret.unshld_hed3 = aw.round(headLv3Scale * unshldDamage)
ret.unshld_body = unshldDamage
ret.unshld_legs = unshldLegs
-- Other
else
-- Passthrough
if opts.passthrough < 1 then
damage = apex.calcPassthroughDamage(damage, opts.passthrough)
end
local legs
if legsScale < 1 then
legs = aw.round(legsScale * damage)
else
legs = damage
end
ret.shield_hed0 = aw.round(headScale * damage)
ret.shield_hed1 = aw.round(headLv1Scale * damage)
ret.shield_hed2 = aw.round(headLv2Scale * damage)
ret.shield_hed3 = aw.round(headLv3Scale * damage)
ret.shield_body = damage
ret.shield_legs = legs
ret.unshld_hed0 = ret.shield_hed0
ret.unshld_hed1 = ret.shield_hed1
ret.unshld_hed2 = ret.shield_hed2
ret.unshld_hed3 = ret.shield_hed3
ret.unshld_body = ret.shield_body
ret.unshld_legs = ret.shield_legs
end
return ret
end
-- Apply perk/shield scale to damages
local function applyPerkAndShieldScaleToDamages(damages, perkScale, opts)
if perkScale ~= 1 then
if opts.disruptorRounds > 1 then
return table.map(damages, function(key, val)
if aw.stringstarts(key, 'shield_') or aw.stringstarts(key, 'unshld_') or aw.stringstarts(key, 'dschrg_') then
local perkedDamage = apex.calcPassiveDamage(val, perkScale, { round = opts.round })
if aw.stringstarts(key, 'shield_') then
return apex.calcDisruptorDamage(perkedDamage, opts.disruptorRounds)
else
return perkedDamage
end
else
return val
end
end)
else
return table.map(damages, function(key, val)
if aw.stringstarts(key, 'shield_') or aw.stringstarts(key, 'unshld_') or aw.stringstarts(key, 'dschrg_') then
return apex.calcPassiveDamage(val, perkScale, { round = opts.round })
else
return val
end
end)
end
elseif opts.disruptorRounds > 1 then
return table.map(damages, function(key, val)
if aw.stringstarts(key, 'shield_') then
return apex.calcDisruptorDamage(val, opts.disruptorRounds)
else
return val
end
end)
else
return damages
end
end
-- Compare damage
local function equalPartDamage(damages, part0, part1)
if damages['dschrg_' .. part0] and damages['dschrg_' .. part1] then
return damages['shield_' .. part0] == damages['shield_' .. part1] and damages['unshld_' .. part0] == damages['unshld_' .. part1] and damages['dschrg_' .. part0] == damages['dschrg_' .. part1]
else
return damages['shield_' .. part0] == damages['shield_' .. part1] and damages['unshld_' .. part0] == damages['unshld_' .. part1]
end
end
-- Render the damage row
local function renderRow2(tbl, name, tooltip, damages, partname, weaponinfo, rowinfo, res, rowspan, gunshield)
rowspan = rowspan or 1
local scale = damages['scale_' .. partname]
local shieldDamage = damages['shield_' .. partname]
local unshldDamage = damages['unshld_' .. partname]
local dschrgDamage = damages['dschrg_' .. partname]
local row = tbl:tag('tr')
renderHeaderCell(row, name, tooltip, rowinfo)
local text
if shieldDamage > unshldDamage then
if weaponinfo.opts.pellets > 1 then
text = string.format(
res.damages.pelletsWithDisruptor,
shieldDamage * weaponinfo.opts.pellets,
shieldDamage,
weaponinfo.opts.pellets,
unshldDamage * weaponinfo.opts.pellets)
else
text = string.format(res.damages.disruptor, shieldDamage, unshldDamage)
end
elseif shieldDamage < unshldDamage then
if weaponinfo.opts.pellets > 1 then
text = string.format(
res.damages.pelletsWithHammerpoint,
shieldDamage * weaponinfo.opts.pellets,
unshldDamage * weaponinfo.opts.pellets,
unshldDamage,
weaponinfo.opts.pellets)
else
text = string.format(res.damages.hammerpoint, shieldDamage, unshldDamage)
end
elseif dschrgDamage and weaponinfo.opts.beamticks >= 1 then
text = string.format(
res.damages.ticks,
dschrgDamage * weaponinfo.opts.beamticks + shieldDamage,
dschrgDamage,
weaponinfo.opts.beamticks,
shieldDamage)
else
if weaponinfo.opts.pellets > 1 then
text = string.format(
res.damages.pellets,
shieldDamage * weaponinfo.opts.pellets,
shieldDamage,
weaponinfo.opts.pellets)
else
text = tostring(shieldDamage)
end
end
row:tag('td')
:attr('rowspan', rowspan)
:wikitext(text)
for _, shield in ipairs(weaponinfo.shields) do
renderCell(row, scale, shield.health, shield.shield, weaponinfo, gunshield, rowspan)
end
end
-- Render the helmet damage
local function renderHelmetSection(tbl, damages, res, weaponinfo, helmets, info)
local skipLvl1 = false
local skipLvl2 = false
local hed1Label = string.format(res.targets.helmet1, damages.scale_hed1)
local hed2Label = string.format(res.targets.helmet2, damages.scale_hed2)
local hed3Label = string.format(res.targets.helmet3, damages.scale_hed3)
local hed1Tooltip = string.format(helmets.level1.text, damages.scale_hed1)
local hed2Tooltip = string.format(helmets.level2.text, damages.scale_hed2)
local hed3Tooltip = string.format(helmets.level3.text, damages.scale_hed3)
if not helmets.level0.disabled then
local hed0Rowspan
if equalPartDamage(damages, 'hed0', 'hed1') then
if equalPartDamage(damages, 'hed0', 'hed2') then
if equalPartDamage(damages, 'hed0', 'hed3') then
hed0Rowspan = 4
else
hed0Rowspan = 3
end
else
hed0Rowspan = 2
end
else
hed0Rowspan = 1
end
local hed0Label = string.format(res.targets.head_format, damages.scale_hed0)
renderRow2(tbl, hed0Label, nil, damages, 'hed0', weaponinfo, info.level1top, res, hed0Rowspan)
if hed0Rowspan >= 4 then
renderHeaderCell(tbl:tag('tr'), hed1Label, hed1Tooltip, info.level2first)
renderHeaderCell(tbl:tag('tr'), hed2Label, hed2Tooltip, info.level2)
renderHeaderCell(tbl:tag('tr'), hed3Label, hed3Tooltip, info.level2)
return
elseif hed0Rowspan == 3 then
renderHeaderCell(tbl:tag('tr'), hed1Label, hed1Tooltip, info.level2first)
renderHeaderCell(tbl:tag('tr'), hed2Label, hed2Tooltip, info.level2)
skipLvl1 = true
skipLvl2 = true
elseif hed0Rowspan == 2 then
renderHeaderCell(tbl:tag('tr'), hed1Label, hed1Tooltip, info.level2first)
skipLvl1 = true
end
end
-- Lvl 1
if not skipLvl1 then
local hed1Rowspan
if equalPartDamage(damages, 'hed1', 'hed2') then
if equalPartDamage(damages, 'hed1', 'hed3') then
hed1Rowspan = 3
else
hed1Rowspan = 2
end
else
hed1Rowspan = 1
end
renderRow2(tbl, hed1Label, hed1Tooltip, damages, 'hed1', weaponinfo, info.level2first, res, hed1Rowspan)
if hed1Rowspan >= 3 then
renderHeaderCell(tbl:tag('tr'), hed2Label, hed2Tooltip, info.level2)
renderHeaderCell(tbl:tag('tr'), hed3Label, hed3Tooltip, info.level2)
return
elseif hed1Rowspan == 2 then
renderHeaderCell(tbl:tag('tr'), hed2Label, hed2Tooltip, info.level2)
skipLvl2 = true
end
end
-- Lvl 2
if not skipLvl2 then
local hed2Rowspan
if equalPartDamage(damages, 'hed2', 'hed3') then
hed2Rowspan = 2
else
hed2Rowspan = 1
end
renderRow2(tbl, hed2Label, hed2Tooltip, damages, 'hed2', weaponinfo, info.level2, res, hed2Rowspan)
if hed2Rowspan >= 2 then
renderHeaderCell(tbl:tag('tr'), hed3Label, hed3Tooltip, info.level2)
return
end
end
-- Lvl 3
renderRow2(tbl, hed3Label, hed3Tooltip, damages, 'hed3', weaponinfo, info.level2, res, 1)
end
local function renderTable(args)
local lang = getContentLanguage(args.lang)
local res = mw.loadData('Module:DamageTable/configuration')[lang]
local shieldinfo = args.shieldinfo or require('Module:Stat/Shield')[args.shieldpreset]
local skullpiercer = args.skullpiercer or 1
local headMul = args.head or 2
local hideNoHelmets = shieldinfo.helmets.level0.disabled
local minHead
if hideNoHelmets then
minHead = shieldinfo.helmets.level1.func(args.headmax)
else
minHead = args.headmax
end
local minCount, _ = getShotCount(
minHead,
100,
0,
{
damage = math.max(args.damage, args.damagemax),
mul = math.max(args.mul, args.mulmax),
opts = {
ampedCover = true,
beamdamage = math.max(args.beamdamage, args.beamdamagemax),
beamticks = math.max(args.ticks, args.ticksmax),
charged = math.max(args.charged, args.chargedmax),
disruptorRounds = math.max(args.disruptor, args.disruptorsup),
gunshieldBleedthrough = shieldinfo.gunshieldBleedthrough,
hammerpointRounds = math.max(args.hammerpoint, args.hammerpointsup),
passthrough = 1,
pellets = math.max(args.pellet, args.pelletmax),
round = args.round,
}
})
local damagemin = math.min(args.damage, args.damagemin)
local mininfo = {
damage = damagemin,
mul = math.min(args.mul, args.mulmin),
opts = {
ampedCover = false,
beamdamage = math.min(args.beamdamage, args.beamdamagemin),
beamticks = math.min(args.ticks, args.ticksmin),
charged = 1,
disruptorRounds = 1,
gunshieldBleedthrough = shieldinfo.gunshieldBleedthrough,
hammerpointRounds = 1,
passthrough = math.min(args.passthrough, args.passthroughsup),
pellets = math.min(args.pellet, args.pelletmin),
round = args.round,
}
}
local maxshield = shieldinfo.shields[#shieldinfo.shields]
local legCount, _ = getShotCount(math.min(args.leg, args.legmin), maxshield.health, maxshield.shield, mininfo)
local bodyWithGunSheild, _ = getShotCount(1, maxshield.health, maxshield.shield, mininfo, shieldinfo.gunshield)
local maxCount = math.max(legCount, bodyWithGunSheild)
local ttkCalculator = getTTKCalculator(args)
-- Define weapon info
local weaponinfo = {
damage = args.damage,
mul = args.mul,
minCount = minCount,
diffCount = maxCount - minCount,
shields = shieldinfo.shields,
helmets = shieldinfo.helmets,
ttkCalculator = ttkCalculator,
opts = {
ampedCover = args.amped,
beamdamage = args.beamdamage,
beamticks = args.ticks,
charged = args.charged,
disruptorRounds = args.disruptor,
gunshieldBleedthrough = shieldinfo.gunshieldBleedthrough,
hammerpointRounds = args.hammerpoint,
passthrough = args.passthrough,
pellets = args.pellet,
round = args.round,
},
}
local colspan, info
if skullpiercer > 1 then
colspan = 3
info = {
level1 = {
{ breaktop = false, breakbottom = false, colspan = 3 },
},
level1top = {
{ breaktop = true, breakbottom = true, colspan = 3 },
},
level1gunshiled = {
{ breaktop = false, breakbottom = true, colspan = 3 },
},
level2 = {
{ breaktop = true, breakbottom = false, colspan = 2 },
},
level2gunshiled = {
{ breaktop = true, breakbottom = false },
{ breaktop = false, breakbottom = false, colspan = 2 },
},
level3 = {
{ breaktop = false, breakbottom = true },
{ breaktop = false, breakbottom = false, showbottom = true },
},
level3first = {
hideNoHelmets and { breaktop = false, breakbottom = false, rowspan = 6, content = res.targets.head, verticalAlign = 'top' } or { breaktop = true, breakbottom = false, rowspan = 6 },
{ breaktop = false, breakbottom = true },
{ breaktop = false, breakbottom = false, showbottom = true },
},
level3top = {
{ breaktop = false, breakbottom = true, colspan = 2 },
{ breaktop = false, breakbottom = false, showbottom = true },
},
}
info.level2first = info.level2
else
colspan = 2
info = {
level1 = {
{ breaktop = false, breakbottom = false, colspan = 2 },
},
level1gunshiled = {
{ breaktop = false, breakbottom = true, colspan = 2 },
},
level2 = {
{ breaktop = false, breakbottom = false },
},
level2first = {
hideNoHelmets and { breaktop = false, breakbottom = false, rowspan = 3, content = res.targets.head, verticalAlign = 'top' } or { breaktop = true, breakbottom = false, rowspan = 3 },
{ breaktop = false, breakbottom = false },
},
level2gunshiled = {
{ breaktop = true, breakbottom = false },
{ breaktop = false, breakbottom = false },
},
}
info.level1top = info.level1gunshiled
end
local table = mw.html.create('table')
:addClass('wikitable')
:addClass('numbertable')
:addClass('damagetable')
if args.caption ~= nil then
table:tag('caption')
:wikitext(args.caption)
end
local baseDamages = calcBaseDamages(weaponinfo.damage, headMul, args.leg, weaponinfo.helmets, weaponinfo.opts)
local perkedDamages = applyPerkAndShieldScaleToDamages(baseDamages, weaponinfo.mul, weaponinfo.opts)
renderHeader(table, args.mul, colspan, shieldinfo.shields, res)
-- Headshot damage
if headMul > 1 then
-- w/Skullpiercer Rifling
if skullpiercer > 1 then
if not hideNoHelmets then
renderRow(
table,
string.format(res.targets.skullpiercer0, args.skullpiercerrarity, skullpiercer),
nil,
skullpiercer, weaponinfo, info.level3top, res)
renderRow2(
table,
string.format(res.targets.head_format, perkedDamages.scale_hed0),
nil,
perkedDamages,
'hed0',
weaponinfo, info.level1top, res)
end
local skullpiercerLv1Mul = shieldinfo.helmets.level1.func(skullpiercer)
renderRow(
table,
string.format(res.targets.skullpiercer1, args.skullpiercerrarity, skullpiercerLv1Mul),
string.format(shieldinfo.helmets.level1.text, skullpiercer),
skullpiercerLv1Mul, weaponinfo, info.level3first, res)
renderRow2(
table,
string.format(res.targets.helmet1, perkedDamages.scale_hed1),
string.format(shieldinfo.helmets.level1.text, headMul),
perkedDamages,
'hed1',
weaponinfo, info.level2first, res)
local skullpiercerLv2Mul = shieldinfo.helmets.level2.func(skullpiercer)
renderRow(
table,
string.format(res.targets.skullpiercer2, args.skullpiercerrarity, skullpiercerLv2Mul),
string.format(shieldinfo.helmets.level2.text, skullpiercer),
skullpiercerLv2Mul, weaponinfo, info.level3, res)
renderRow2(
table,
string.format(res.targets.helmet2, perkedDamages.scale_hed2),
string.format(shieldinfo.helmets.level2.text, headMul),
perkedDamages,
'hed2',
weaponinfo, info.level2, res)
local skullpiercerLv3Mul = shieldinfo.helmets.level3.func(skullpiercer)
renderRow(
table,
string.format(res.targets.skullpiercer3, args.skullpiercerrarity, skullpiercerLv3Mul),
string.format(shieldinfo.helmets.level3.text, skullpiercer),
skullpiercerLv3Mul, weaponinfo, info.level3, res)
renderRow2(
table,
string.format(res.targets.helmet3, perkedDamages.scale_hed3),
string.format(shieldinfo.helmets.level3.text, headMul),
perkedDamages,
'hed3',
weaponinfo, info.level2, res)
-- w/o Skullpiercer Rifling
else
renderHelmetSection(table, perkedDamages, res, weaponinfo, shieldinfo.helmets, info)
end
end
-- Body & legs shot damage
if perkedDamages.scale_legs >= 1 then
if args.mul < 1 or args.forcegunshield then
renderRow2(table, res.targets.bodylegs, nil, perkedDamages, 'body', weaponinfo, info.level1gunshiled, res)
renderRow(
table,
res.targets.gunshield,
shieldinfo.gunshieldLabel,
1, weaponinfo, info.level2gunshiled, res, shieldinfo.gunshield)
else
renderRow2(table, res.targets.bodylegs, nil, perkedDamages, 'body', weaponinfo, info.level1, res)
end
else
if shieldinfo.legAsBodyOnLowProfile and args.mul > 1 then
renderRow2(table, res.targets.bodylegs, nil, perkedDamages, 'body', weaponinfo, info.level1, res)
else
if args.mul < 1 or args.forcegunshield then
renderRow2(table, res.targets.body, nil, perkedDamages, 'body', weaponinfo, info.level1gunshiled, res)
renderRow(
table,
res.targets.gunshield,
shieldinfo.gunshieldLabel,
1, weaponinfo, info.level2gunshiled, res, shieldinfo.gunshield)
else
renderRow2(table, res.targets.body, nil, perkedDamages, 'body', weaponinfo, info.level1, res)
end
local legsLabel = string.format(res.targets.legs, args.leg)
renderRow2(table, legsLabel, nil, perkedDamages, 'legs', weaponinfo, info.level1, res)
end
end
return table
end
function p._main(args, frame)
-- init value
local initValues = {
damage = 20,
damagemin = 1000,
damagemax = 0,
beamdamage = 0,
beamdamagemin = 0,
beamdamagemax = 0,
ticks = 0,
ticksmin = math.huge,
ticksmax = 0,
pellet = 1,
pelletmin = 0,
pelletmax = 0,
head = 2,
headmax = -1,
leg = 0.8,
legmin = 0,
mul = 1,
mulmin = 0.85,
mulmax = 1,
charged = 1,
chargedmax = 1,
skullpiercer = 1,
disruptor = 1,
disruptorsup = 1,
hammerpoint = 1,
hammerpointsup = 1,
passthrough = 1,
passthroughsup = 1,
rps = 0,
rpsratio1 = 0,
rpsratio2 = 0,
rpsratio3 = 0,
raise = 0,
reload = 0,
reloadratio1 = 0.963,
reloadratio2 = 0.933,
reloadratio3 = 0.9,
extmag0 = 0,
extmag1 = 0,
extmag2 = 0,
extmag3 = 0,
}
-- fix arguments
for key, value in pairs(initValues) do
args[key] = aw.getAsNumber(args[key], value)
end
if args.pelletmin == 0 then
args.pelletmin = args.pellet
end
if args.pelletmax == 0 then
args.pelletmax = args.pellet
end
if args.headmax == -1 then
args.headmax = math.max(args.head, args.skullpiercer)
end
if args.legmin == 0 then
args.legmin = args.leg
end
if args.beamdamagemin == 0 then
args.beamdamagemin = args.beamdamage
end
if args.beamdamagemax == 0 then
args.beamdamagemax = args.beamdamage
end
args.round = aw.getAsBoolean(args.round, false)
args.amped = aw.getAsBoolean(args.amped, false)
args.forcegunshield = aw.getAsBoolean(args.forcegunshield, false)
args.rarity = args.rarity or 'epic'
args.skullpiercerrarity = args.skullpiercerrarity or 'legendary'
args.shieldpreset = args.shieldpreset or 'removelowprofile'
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