| 🌟 | 現在、 鉄壁HSは通常HSと同じダメージになります。LMG及びDMR、チャージライフル、ハンマーポイント弾を除き、すべてのダメージ値が一致していることを確認しています。 |
「モジュール:MultipleStatTable」の版間の差分
ナビゲーションに移動
検索に移動
(ページの作成:「require('Module:Utility/mw.html Extensions') local p = {} local aw = require('Module:Utility/Library') local apex = require('Module:Utility/ApexLibrary') local iu = req…」) |
(可変レート武器における最高速スタートのTTKが表示されていない不具合の修正) |
||
| (同じ利用者による、間の64版が非表示) | |||
| 7行目: | 7行目: | ||
local iu = require('Module:Utility/Image') | local iu = require('Module:Utility/Image') | ||
local nu = require('Module:Utility/Name') | local nu = require('Module:Utility/Name') | ||
local inu = require('Module:Utility/ImageWithName') | |||
local Hopup = mw.loadData('Module:Stat/Hopup') | |||
local formatter -- lazily initialized | local formatter -- lazily initialized | ||
local getArgs -- lazily initialized | local getArgs -- lazily initialized | ||
| 17行目: | 21行目: | ||
end | end | ||
cache.moddedLoader = | cache.moddedLoader = iu.passive('modded_loader') .. ' <span class="text-desktoponly">改造ローダー</span>' | ||
return cache.moddedLoader | return cache.moddedLoader | ||
end | end | ||
| 28行目: | 32行目: | ||
cache.ampedMode = iu.item('シールドセル') .. ' <span class="text-desktoponly">増幅モード</span>' | cache.ampedMode = iu.item('シールドセル') .. ' <span class="text-desktoponly">増幅モード</span>' | ||
return cache.ampedMode | return cache.ampedMode | ||
end | |||
local function getRevvedUpMode() | |||
if cache.revvedUpMode then | |||
return cache.revvedUpMode | |||
end | |||
cache.revvedUpMode = iu.grenade('テルミットグレネード') .. ' <span class="text-desktoponly">連射速度上昇モード</span>' | |||
return cache.revvedUpMode | |||
end | |||
local function getDisruptorRounds() | |||
if cache.disruptorRounds then | |||
return cache.disruptorRounds | |||
end | |||
cache.disruptorRounds = inu.hopup('disruptor_rounds', { desktopOnly = true }) | |||
return cache.disruptorRounds | |||
end | end | ||
| 35行目: | 57行目: | ||
end | end | ||
cache.hammerpointRounds = | cache.hammerpointRounds = inu.hopup('hammerpoint_rounds', { desktopOnly = true }) | ||
return cache.hammerpointRounds | return cache.hammerpointRounds | ||
end | |||
local function getShatterCaps() | |||
if cache.shatterCaps then | |||
return cache.shatterCaps | |||
end | |||
cache.shatterCaps = inu.hopup('shatter_caps', { desktopOnly = true }) | |||
return cache.shatterCaps | |||
end | |||
local function getDeadeyesTempo() | |||
if cache.deadeyesTempo then | |||
return cache.deadeyesTempo | |||
end | |||
cache.deadeyesTempo = inu.hopup('deadeyes_tempo', { desktopOnly = true }) | |||
return cache.deadeyesTempo | |||
end | end | ||
| 44行目: | 84行目: | ||
end | end | ||
cache.anvilReceiver = | cache.anvilReceiver = inu.hopup('anvil_receiver', { desktopOnly = true }) | ||
return cache.anvilReceiver | return cache.anvilReceiver | ||
end | |||
local function getTurbocharger() | |||
if cache.turbocharger then | |||
return cache.turbocharger | |||
end | |||
cache.turbocharger = inu.hopup('turbocharger', { desktopOnly = true }) | |||
return cache.turbocharger | |||
end | |||
local function getBoostedLoader() | |||
if cache.boostedLoader then | |||
return cache.boostedLoader | |||
end | |||
cache.boostedLoader = inu.hopup('boosted_loader', { desktopOnly = true }) | |||
return cache.boostedLoader | |||
end | end | ||
| 51行目: | 109行目: | ||
if not force and level == 0 then | if not force and level == 0 then | ||
return '' | return '' | ||
end | |||
if aw.stringstarts(ammo, 'special_') then | |||
ammo = string.sub(ammo, 9) | |||
end | end | ||
| 58行目: | 120行目: | ||
if cache[ammo] and cache[ammo][1 + level] then | if cache[ammo] and cache[ammo][1 + level] then | ||
return cache[ammo][1 + level] | return cache[ammo][1 + level] | ||
end | end | ||
if ammo == 'shotgun' then | if ammo == 'shotgun' then | ||
cache[ammo][1 + level] = | cache[ammo][1 + level] = inu.bolt(level, { desktopOnly = true }) | ||
else | else | ||
cache[ammo][1 + level] = | cache[ammo][1 + level] = inu.extmag(ammo, level, { desktopOnly = true }) | ||
end | end | ||
return cache[ammo][1 + level] | return cache[ammo][1 + level] | ||
end | end | ||
-- | local getEmphasizableText = aw.getEmphasizableTextFunc('%s', '<span class="text-desktoponly">%s</span>', '<span class="text-desktoponly">%s</span>') | ||
local function | local function getWeaponLink(name, ammo, shortname) | ||
local classSuffix = aw.stringstarts(ammo, 'special_') and 'special' or ammo | |||
local suitableName = getEmphasizableText(name, shortname) | |||
return string.format('[[%s|<span class="text-ammo-%s">%s</span>]]', name, classSuffix, suitableName) | |||
end | end | ||
-- [[ 設定 ]] | |||
local columns = { '通常', '鉄壁', '+ガンシールド' } | |||
local columnCount = #columns | |||
local config = { | |||
-- 通常 | |||
{ | |||
gunshield = 0, | |||
passive = 1, | |||
}, | |||
-- 小柄 | |||
--{ | |||
-- gunshield = 0, | |||
-- passive = 1.05, | |||
--}, | |||
-- 鉄壁 | |||
{ | |||
gunshield = 0, | |||
passive = 0.85, | |||
}, | |||
-- +ガンシールド | |||
{ | |||
gunshield = 50, | |||
passive = 0.85, | |||
}, | |||
} | |||
-- [[ テーブル生成 ]] | |||
local function passthrough(num) | local function passthrough(num) | ||
return num | return num | ||
| 114行目: | 195行目: | ||
local tbl = mw.html.create('table') | local tbl = mw.html.create('table') | ||
:addClass('numbertable') | :addClass('numbertable') | ||
:addClass(' | :addClass('st') | ||
:addClass('sortable') | :addClass('sortable') | ||
local header = tbl:tag('tr') | local header = tbl:tag('tr') | ||
:addClass('row-sticky') | |||
:tag('th') | |||
:addClass('st-desktop') | |||
:css('width', '36px') | |||
:done() | |||
:tag('th') | :tag('th') | ||
:addClass(' | :addClass('st-mobile-first') | ||
:attrIf(slots > 2, { colspan = slots - 1 }) | |||
:attrIf(slots > | |||
:wikitext('武器名') | :wikitext('武器名') | ||
:done() | :done() | ||
for _, item in ipairs(headers) do | for _, item in ipairs(headers) do | ||
header:tag('th') | header:tag('th') | ||
: | :css('min-width', '60px') | ||
:wikitext(item) | :wikitext(item) | ||
end | end | ||
local rank = 1 | local rank = 1 | ||
local max | local max = 0 | ||
for i = 1, #data do | |||
local value = math.max(unpack(data[i].values)) | |||
if value ~= math.huge then | |||
max = math.max(max, value) | |||
end | end | ||
end | end | ||
| 160行目: | 229行目: | ||
if slots > 1 then | if slots > 1 then | ||
for i = 1, slots do | for i = 1, slots do | ||
local classname | |||
if i == 1 then | |||
classname = 'st-desktop' | |||
elseif i == 2 then | |||
classname = 'st-mobile-first st-dashed-right st-mobile-none-right st-mobile-padding0-right' | |||
elseif i == slots then | |||
classname = 'st-dashed-left st-mobile-none-left st-mobile-padding0-both' | |||
else | |||
classname = 'st-dashed-both st-mobile-none-both st-mobile-padding0-both' | |||
end | |||
row:tag('td') | row:tag('td') | ||
:addClass( | :addClass(classname) | ||
: | :attrIf(i == 1, { align = 'center' }) | ||
:wikitext(obj[i]) | :wikitext(obj[i]) | ||
:attr('align', 'left') | :attr('align', 'left') | ||
| 170行目: | 248行目: | ||
else | else | ||
row:tag('td') | row:tag('td') | ||
:wikitext(obj.name) | :wikitext(obj.name) | ||
:attr('align', 'left') | :attr('align', 'left') | ||
| 180行目: | 256行目: | ||
local graph = string.format('linear-gradient(to right, #A7D7F9 %s%%, transparent %s%%)', percentage, percentage) | local graph = string.format('linear-gradient(to right, #A7D7F9 %s%%, transparent %s%%)', percentage, percentage) | ||
row:tag('td') | row:tag('td') | ||
:addClass(' | :addClass('st-graph') | ||
:addClass(' | :addClass('st-textshadow') | ||
:addClass(' | :addClass('st-line') | ||
:addClass(' | :addClass('st-line-h12') | ||
:attr('align', 'right') | :attr('align', 'right') | ||
:css('background-image', graph .. ' !important') | :css('background-image', graph .. ' !important') | ||
| 210行目: | 286行目: | ||
-- [[ キルタイム ]] | -- [[ キルタイム ]] | ||
local function | local function getSTKs(stat, opts, health, shield, STKCalculator) | ||
local ret = {} | |||
local stkc = STKCalculator.newFromStat(stat, opts) | local stkc = STKCalculator.newFromStat(stat, opts) | ||
for passive = 1, #config do | |||
local c = config[passive] | |||
stkc:calcShotToKill(health, shield, c.gunshield, c.passive) | |||
table.insert(ret, stkc:get()) | |||
stkc:reset() | |||
end | |||
return ret | |||
end | |||
local ttkc = TTKCalculator.newFromStat(stat, | local function getTTKs(stat, stks, opts, TTKCalculator) | ||
local ttkc = TTKCalculator.newFromStat(stat, opts) | |||
{ | local ret = {} | ||
ttkc:getAsLevel( | for _, stk in ipairs(stks) do | ||
ttkc:getAsLevel( | local obj = { | ||
ttkc:getAsLevel( | ttkc:getAsLevel(stk, 0), | ||
ttkc:getAsLevel( | ttkc:getAsLevel(stk, 1), | ||
} | ttkc:getAsLevel(stk, 2), | ||
ttkc:getAsLevel(stk, 3), | |||
} | |||
table.insert(ret, obj) | |||
end | |||
return ret | |||
end | |||
local function isDiffTTKs(ttks, a, b) | |||
for passive = 1, columnCount do | |||
if 0.0001 * aw.round(10000 * ttks[passive][a]) ~= 0.0001 * aw.round(10000 * ttks[passive][b]) then | |||
return true | |||
end | |||
end | |||
return false | |||
end | |||
local function compareTTKs(ttks1, ttks2) | |||
for passive = 1, columnCount do | |||
for level = 1, 4 do | |||
local ttk1 = 0.0001 * aw.round(10000 * ttks1[passive][level]) | |||
local ttk2 = 0.0001 * aw.round(10000 * ttks2[passive][level]) | |||
if ttk1 ~= ttk2 then | |||
return false | |||
end | |||
end | |||
end | |||
return true | |||
end | end | ||
local function repackTTKs(ttks, level) | local function repackTTKs(ttks, level) | ||
local ret = {} | |||
for _, ttk in ipairs(ttks) do | |||
table.insert(ret, ttk[level]) | |||
end | |||
return ret | |||
end | end | ||
local function addFromTTKs(ammo, data, basename, hopup, ttks) | local function addFromTTKs(ammo, data, ammoname, basename, hopup, ttks) | ||
if ttks | if isDiffTTKs(ttks, 3, 4) then | ||
add(data, { basename, getMagazineLabel(ammo, 3), hopup }, repackTTKs(ttks, 4)) | add(data, { ammoname, basename, getMagazineLabel(ammo, 3), hopup }, repackTTKs(ttks, 4)) | ||
add(data, { basename, getMagazineLabel(ammo, 2), hopup }, repackTTKs(ttks, 3)) | add(data, { ammoname, basename, getMagazineLabel(ammo, 2), hopup }, repackTTKs(ttks, 3)) | ||
if ttks | if isDiffTTKs(ttks, 1, 2) then | ||
add(data, { basename, getMagazineLabel(ammo, 1), hopup }, repackTTKs(ttks, 2)) | add(data, { ammoname, basename, getMagazineLabel(ammo, 1), hopup }, repackTTKs(ttks, 2)) | ||
add(data, { basename, getMagazineLabel(ammo, 0, true), hopup }, repackTTKs(ttks, 1)) | add(data, { ammoname, basename, getMagazineLabel(ammo, 0, true), hopup }, repackTTKs(ttks, 1)) | ||
else | else | ||
add(data, { basename, getMagazineLabel(ammo, 0, true) .. '<br>' .. getMagazineLabel(ammo, 1), hopup }, repackTTKs(ttks, 1)) | add(data, { ammoname, basename, getMagazineLabel(ammo, 0, true) .. '<br>' .. getMagazineLabel(ammo, 1), hopup }, repackTTKs(ttks, 1)) | ||
end | end | ||
elseif ttks | elseif isDiffTTKs(ttks, 2, 3) then | ||
add(data, { basename, getMagazineLabel(ammo, 2) .. '<br>' .. getMagazineLabel(ammo, 3), hopup }, repackTTKs(ttks, 3)) | add(data, { ammoname, basename, getMagazineLabel(ammo, 2) .. '<br>' .. getMagazineLabel(ammo, 3), hopup }, repackTTKs(ttks, 3)) | ||
if ttks | if isDiffTTKs(ttks, 1, 2) then | ||
add(data, { basename, getMagazineLabel(ammo, 1), hopup }, repackTTKs(ttks, 2)) | add(data, { ammoname, basename, getMagazineLabel(ammo, 1), hopup }, repackTTKs(ttks, 2)) | ||
add(data, { basename, getMagazineLabel(ammo, 0, true), hopup }, repackTTKs(ttks, 1)) | add(data, { ammoname, basename, getMagazineLabel(ammo, 0, true), hopup }, repackTTKs(ttks, 1)) | ||
else | else | ||
add(data, { basename, getMagazineLabel(ammo, 0, true) .. '<br>' .. getMagazineLabel(ammo, 1), hopup }, repackTTKs(ttks, 1)) | add(data, { ammoname, basename, getMagazineLabel(ammo, 0, true) .. '<br>' .. getMagazineLabel(ammo, 1), hopup }, repackTTKs(ttks, 1)) | ||
end | end | ||
elseif ttks | elseif isDiffTTKs(ttks, 1, 2) then | ||
add(data, { basename, getMagazineLabel(ammo, 1) .. '<br>' .. getMagazineLabel(ammo, 2) .. '<br>' .. getMagazineLabel(ammo, 3), hopup }, repackTTKs(ttks, 2)) | add(data, { ammoname, basename, getMagazineLabel(ammo, 1) .. '<br>' .. getMagazineLabel(ammo, 2) .. '<br>' .. getMagazineLabel(ammo, 3), hopup }, repackTTKs(ttks, 2)) | ||
add(data, { basename, getMagazineLabel(ammo, 0, true), hopup }, repackTTKs(ttks, 1)) | add(data, { ammoname, basename, getMagazineLabel(ammo, 0, true), hopup }, repackTTKs(ttks, 1)) | ||
else | else | ||
add(data, { basename, '', hopup }, repackTTKs(ttks, 1)) | add(data, { ammoname, basename, '', hopup }, repackTTKs(ttks, 1)) | ||
end | end | ||
end | |||
local function parsePattern(str) | |||
local type = type(str) | |||
if type == 'table' then | |||
return str | |||
elseif str == nil or type ~= 'string' then | |||
return nil | |||
end | |||
local pattern = {} | |||
local head = false | |||
for i = 1, #str do | |||
local c = string.sub(str, i, i) | |||
local cont = false | |||
if head then | |||
head = false | |||
if c == '1' then | |||
table.insert(pattern, apex.HEAD_HLMLV1) | |||
cont = true | |||
elseif c == '2' then | |||
table.insert(pattern, apex.HEAD_HLMLV2) | |||
cont = true | |||
elseif c == '3' then | |||
table.insert(pattern, apex.HEAD_HLMLV3) | |||
cont = true | |||
elseif c == '0' then | |||
table.insert(pattern, apex.HEAD_NOHLM) | |||
cont = true | |||
else | |||
table.insert(pattern, apex.HEAD_NOHLM) | |||
end | |||
end | |||
if not cont then | |||
if c == 'H' then | |||
head = true | |||
elseif c == 'L' then | |||
table.insert(pattern, apex.LEGS) | |||
elseif c == 'S' then | |||
table.insert(pattern, apex.SKY) | |||
elseif c == ',' or c == ' ' then | |||
if head then | |||
head = false | |||
table.insert(pattern, apex.HEAD_NOHLM) | |||
end | |||
else | |||
table.insert(pattern, apex.BODY) | |||
end | |||
end | |||
end | |||
if head then | |||
table.insert(pattern, apex.HEAD_NOHLM) | |||
end | |||
return pattern | |||
end | end | ||
| 287行目: | 433行目: | ||
args.shield = aw.getAsNumber(args.shield, 125) | args.shield = aw.getAsNumber(args.shield, 125) | ||
local opts = { | |||
pattern = { | |||
first = parsePattern(args.firstPattern), | |||
loop = parsePattern(args.loopPattern), | |||
}, | |||
} | |||
local STKCalculator = require('Module:Apex/STKCalculator') | local STKCalculator = require('Module:Apex/STKCalculator') | ||
local TTKCalculator = require('Module:Apex/TTKCalculator') | local TTKCalculator = require('Module:Apex/TTKCalculator') | ||
local tbl = createStatTable('キルタイム [s]', | local tbl = createStatTable('キルタイム [s]', 4, columns, function(data, name, stat) | ||
if | if stat.time == nil or (not aw.isNumber(stat.time.reloadempty or stat.time.reload)) then | ||
return | return | ||
end | end | ||
local ammo = stat.ammo | local ammo = stat.ammo | ||
local | local ammoname = iu.ammo(ammo, { size = 20 }) | ||
if stat. | local basename = getWeaponLink(name, ammo, stat.localization['Japanese_Short']) | ||
local special = aw.stringstarts(ammo, 'special_') | |||
local stks = getSTKs(stat, opts, args.health, args.shield, STKCalculator) | |||
addFromTTKs(ammo, data, basename .. ' ( | local ttks = getTTKs(stat, stks, opts, TTKCalculator) | ||
if not stat.attachments.disruptor_rounds_only then | |||
addFromTTKs(ammo, data, ammoname, basename, '', ttks) | |||
end | |||
-- ライトマシンガン (ディヴォーションLMG・M600スピットファイア・L-スターEMG) | |||
if stat.category == 'light_machine_gun' then | |||
local opts2 = aw.shallowCopy(opts) | |||
opts2.useModdedLoader = true | |||
local ttks2 = getTTKs(stat, stks, opts2, TTKCalculator) | |||
if not compareTTKs(ttks, ttks2) then | |||
addFromTTKs(ammo, data, ammoname, basename, getModdedLoader(), ttks2) | |||
end | |||
end | |||
if stat.altfire and aw.isNumber(stat.altfire.firerate) and stat.altfire.firerate ~= stat.firerate then | |||
local altname | |||
if stat.altfire.is_semi_auto or stat.is_semi_auto then | |||
altname = basename .. ' (単発)' | |||
else | else | ||
altname = basename .. ' (オート)' | |||
end | end | ||
local ttks = getTTKs(stat, TTKCalculator. | local altopts = aw.shallowCopy(opts) | ||
addFromTTKs(ammo, data, basename .. ' ( | altopts.useAltfire = true | ||
local | local ttks = getTTKs(stat, stks, altopts, TTKCalculator) | ||
local | addFromTTKs(ammo, data, ammoname, altname, '', ttks) | ||
addFromTTKs(ammo, data, basename, '', | |||
-- ブーステッドローダー (ヘムロックバーストAR) | |||
if Hopup.boosted_loader.enabled and stat.boosted_loader and type(stat.boosted_loader.magazine) == 'table' then | |||
altopts.useBoostedLoader = true | |||
local burstttks2 = getTTKs(stat, stks, altopts, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, altname, getBoostedLoader(), burstttks2) | |||
end | |||
end | |||
-- 最高速から | |||
local ttksmax = nil | |||
if aw.isNumberAndGreaterThanZero(stat.firerate_maximum_duration) then | |||
local maxname = basename .. ' (最高速)' | |||
local opts2 = aw.shallowCopy(opts) | |||
opts2.startMaximum = true | |||
ttksmax = getTTKs(stat, stks, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, maxname, '', ttksmax) | |||
if stat.category == 'light_machine_gun' then | |||
local opts3 = aw.shallowCopy(opts2) | |||
opts3.useModdedLoader = true | |||
local ttks3 = getTTKs(stat, stks, opts3, TTKCalculator) | |||
if not compareTTKs(ttksmax, ttks3) then | |||
addFromTTKs(ammo, data, ammoname, maxname, getModdedLoader(), ttks3) | |||
end | |||
end | |||
end | |||
-- センチネルの増幅モード | |||
if aw.isNumberAndGreaterThanZero(stat.damage.amped) then | |||
local ampedammoname = iu.ammo(ammo .. '_amped', { size = 20 }) | |||
local ampedname = string.format('%s (%s)', basename, getAmpedMode()) | |||
local opts2 = aw.shallowCopy(opts) | |||
opts2.useAmpedMode = true | |||
local stksAmped = getSTKs(stat, opts2, args.health, args.shield, STKCalculator) | |||
local ttksAmped = getTTKs(stat, stksAmped, opts2, TTKCalculator) | |||
if not compareTTKs(ttks, ttksAmped) then | |||
addFromTTKs(ammo, data, ampedammoname, ampedname, '', ttksAmped) | |||
end | |||
-- デッドアイズテンポ | |||
if Hopup.deadeyes_tempo.enabled and stat.deadeyes_tempo then | |||
opts2.useDeadeyesTempo = true | |||
local ttksTempo = getTTKs(stat, stksAmped, opts2, TTKCalculator) | |||
if not compareTTKs(ttksAmped, ttksTempo) then | |||
addFromTTKs(ammo, data, ampedammoname, ampedname, getDeadeyesTempo(), ttksTempo) | |||
end | |||
-- 最高速 | |||
if aw.isNumberAndGreaterThanOrEqualToX(stat.deadeyes_tempo.firerate_maximum_count, 1) then | |||
local ampedmaxname = string.format('%s (最高速・%s)', basename, getAmpedMode()) | |||
opts2.startMaximum = true | |||
local stksTempoMax = getSTKs(stat, opts2, args.health, args.shield, STKCalculator) | |||
local ttksTempoMax = getTTKs(stat, stksTempoMax, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ampedammoname, ampedmaxname, getDeadeyesTempo(), ttksTempoMax) | |||
end | |||
end | |||
end | |||
-- ランページの連射速度上昇モード | |||
if aw.isNumberAndGreaterThanZero(stat.firerate_revvedup) then | |||
local revvedupammoname = iu.ammo(ammo .. '_revved_up', { size = 20 }) | |||
local revvedupname = string.format('%s (%s)', basename, getRevvedUpMode()) | |||
local opts2 = aw.shallowCopy(opts) | |||
opts2.useRevvedUpMode = true | |||
local ttksRevvedUp = getTTKs(stat, stks, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, revvedupammoname, revvedupname, '', ttksRevvedUp) | |||
end | |||
-- フルチャージ (30-30リピーター・ボセックコンパウンドボウ) | |||
if aw.isNumberAndGreaterThanZero(stat.damage.charged) then | |||
local chargedname = basename .. ' (最大溜め)' | |||
local opts2 = aw.shallowCopy(opts) | |||
opts2.useCharged = true | |||
local stks2 = getSTKs(stat, opts2, args.health, args.shield, STKCalculator) | |||
local ttks2 = getTTKs(stat, stks2, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, chargedname, '', ttks2) | |||
-- デッドアイズテンポ | |||
if Hopup.deadeyes_tempo.enabled and stat.deadeyes_tempo then | |||
opts2.useDeadeyesTempo = true | |||
local ttksTempo = getTTKs(stat, stks2, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, chargedname, getDeadeyesTempo(), ttksTempo) | |||
-- 最高速 | |||
if aw.isNumberAndGreaterThanOrEqualToX(stat.deadeyes_tempo.firerate_maximum_count, 1) then | |||
local chargedmaxname = basename .. ' (最高速・最大溜め)' | |||
opts2.startMaximum = true | |||
local stksTempoMax = getSTKs(stat, opts2, args.health, args.shield, STKCalculator) | |||
local ttksTempoMax = getTTKs(stat, stksTempoMax, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, chargedmaxname, getDeadeyesTempo(), ttksTempoMax) | |||
end | |||
end | |||
end | |||
-- ディスラプター弾 (オルタネーターSMG・RE-45オート) | |||
if (Hopup.disruptor_rounds.enabled or special) and aw.isNumber(stat.damage.disruptor_rounds) and stat.damage.disruptor_rounds > 1 then | |||
local opts2 = aw.shallowCopy(opts) | |||
opts2.useDisruptorRounds = true | |||
local stks2 = getSTKs(stat, opts2, args.health, args.shield, STKCalculator) | |||
local ttks2 = getTTKs(stat, stks2, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, basename, getDisruptorRounds(), ttks2) | |||
end | |||
-- ハンマーポイント弾 (モザンビーク・P2020) | |||
if Hopup.hammerpoint_rounds.enabled and aw.isNumber(stat.damage.hammerpoint_rounds) and stat.damage.hammerpoint_rounds > 1 then | |||
local opts2 = aw.shallowCopy(opts) | |||
opts2.useHammerpointRounds = true | |||
local stks2 = getSTKs(stat, opts2, args.health, args.shield, STKCalculator) | |||
local ttks2 = getTTKs(stat, stks2, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, basename, getHammerpointRounds(), ttks2) | |||
end | |||
-- アンビルレシーバー (VK-47フラットライン・R-301カービン) | |||
if Hopup.anvil_receiver.enabled and stat.anvil_receiver then | |||
local opts2 = aw.shallowCopy(opts) | |||
opts2.useAnvilReceiver = true | |||
local stks2 = getSTKs(stat, opts2, args.health, args.shield, STKCalculator) | |||
local ttks2 = getTTKs(stat, stks2, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, basename, getAnvilReceiver(), ttks2) | |||
end | |||
-- ブーステッドローダー (ヘムロックバーストAR・ウィングマン) | |||
if Hopup.boosted_loader.enabled and stat.boosted_loader and type(stat.boosted_loader.magazine) == 'table' then | |||
local opts2 = aw.shallowCopy(opts) | |||
opts2.useBoostedLoader = true | |||
local ttks2 = getTTKs(stat, stks, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, basename, getBoostedLoader(), ttks2) | |||
end | |||
-- シャッターキャップ (30-30リピーター・ボセックコンポウンドボウ) | |||
if Hopup.shatter_caps.enabled and stat.shatter_caps then | |||
local label = getShatterCaps() | |||
local opts2 = aw.shallowCopy(opts) | |||
opts2.useShatterCaps = true | |||
local stks2 = getSTKs(stat, opts2, args.health, args.shield, STKCalculator) | |||
local ttks2 = getTTKs(stat, stks2, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, basename, label, ttks2) | |||
if aw.isNumberAndGreaterThanZero(stat.shatter_caps.damage.charged) then | |||
if aw. | local chargedname = basename .. ' (最大溜め)' | ||
local | opts2.useCharged = true | ||
addFromTTKs(ammo, data, basename, | local stks3 = getSTKs(stat, opts2, args.health, args.shield, STKCalculator) | ||
local ttks3 = getTTKs(stat, stks3, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, chargedname, label, ttks3) | |||
-- デッドアイズテンポ (ボセックコンパウンドボウ) | |||
if Hopup.deadeyes_tempo.enabled and stat.deadeyes_tempo then | |||
label = label .. '<br>' .. getDeadeyesTempo() | |||
opts2.useDeadeyesTempo = true | |||
local ttksTempo = getTTKs(stat, stks3, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, chargedname, label, ttksTempo) | |||
-- 最高速 | |||
if aw.isNumberAndGreaterThanOrEqualToX(stat.deadeyes_tempo.firerate_maximum_count, 1) then | |||
local chargedmaxname = basename .. ' (最高速・最大溜め)' | |||
opts2.startMaximum = true | |||
local stksTempoMax = getSTKs(stat, opts2, args.health, args.shield, STKCalculator) | |||
local ttksTempoMax = getTTKs(stat, stksTempoMax, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, chargedmaxname, label, ttksTempoMax) | |||
end | |||
end | |||
end | |||
end | |||
-- デッドアイズテンポ (センチネル) | |||
if Hopup.deadeyes_tempo.enabled and stat.deadeyes_tempo and (not aw.isNumberAndGreaterThanZero(stat.damage.charged)) then | |||
local opts2 = aw.shallowCopy(opts) | |||
opts2.useDeadeyesTempo = true | |||
local ttksTempo = getTTKs(stat, stks, opts2, TTKCalculator) | |||
if not compareTTKs(ttks, ttksTempo) then | |||
addFromTTKs(ammo, data, ammoname, basename, getDeadeyesTempo(), ttksTempo) | |||
end | end | ||
-- 最高速 | |||
if aw.isNumberAndGreaterThanOrEqualToX(stat.deadeyes_tempo.firerate_maximum_count, 1) then | |||
local maxname = basename .. ' (最高速)' | |||
opts2.startMaximum = true | |||
local stksTempoMax = getSTKs(stat, opts2, args.health, args.shield, STKCalculator) | |||
local ttksTempoMax = getTTKs(stat, stksTempoMax, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, maxname, getDeadeyesTempo(), ttksTempoMax) | |||
end | |||
end | |||
-- ターボチャージャー (ハボックライフル・ディヴォーションLMG) | |||
if stat.turbocharger then | |||
local opts2 = aw.shallowCopy(opts) | |||
opts2.useTurbocharger = true | |||
local ttks2 = getTTKs(stat, stks, opts2, TTKCalculator) | |||
addFromTTKs(ammo, data, ammoname, basename, getTurbocharger(), ttks2) | |||
-- | -- 最高速から | ||
if aw. | if aw.isNumberAndGreaterThanZero(stat.turbocharger.firerate_maximum_duration) then | ||
local | local maxname = basename .. ' (最高速)' | ||
local opts3 = aw.shallowCopy(opts2) | |||
opts3.startMaximum = true | |||
local ttks3 = getTTKs(stat, stks, opts3, TTKCalculator) | |||
if ttksmax ~= nil and not compareTTKs(ttksmax, ttks3) then | |||
addFromTTKs(ammo, data, ammoname, maxname, getTurbocharger(), ttks3) | |||
end | |||
if stat.category == 'light_machine_gun' then | |||
local opts4 = aw.shallowCopy(opts3) | |||
opts4.useModdedLoader = true | |||
local ttks4 = getTTKs(stat, stks, opts4, TTKCalculator) | |||
if not compareTTKs(ttks3, ttks4) then | |||
addFromTTKs(ammo, data, ammoname, maxname, getTurbocharger() .. '<br>' .. getModdedLoader(), ttks4) | |||
end | |||
end | |||
end | end | ||
-- | -- ライトマシンガン (ディヴォーションLMG) | ||
if stat. | if stat.category == 'light_machine_gun' then | ||
local | local opts3 = aw.shallowCopy(opts2) | ||
addFromTTKs(ammo, data, basename, | opts3.useModdedLoader = true | ||
local ttks3 = getTTKs(stat, stks, opts3, TTKCalculator) | |||
if not compareTTKs(ttks2, ttks3) then | |||
addFromTTKs(ammo, data, ammoname, basename, getTurbocharger() .. '<br>' .. getModdedLoader(), ttks3) | |||
end | |||
end | end | ||
end | end | ||
2022年4月24日 (日) 15:02時点における最新版
このモジュールについての説明文ページを モジュール:MultipleStatTable/doc に作成できます
require('Module:Utility/mw.html Extensions')
local p = {}
local aw = require('Module:Utility/Library')
local apex = require('Module:Utility/ApexLibrary')
local iu = require('Module:Utility/Image')
local nu = require('Module:Utility/Name')
local inu = require('Module:Utility/ImageWithName')
local Hopup = mw.loadData('Module:Stat/Hopup')
local formatter -- lazily initialized
local getArgs -- lazily initialized
-- [[ リソース キャッシュ ]]
local cache = {}
local function getModdedLoader()
if cache.moddedLoader then
return cache.moddedLoader
end
cache.moddedLoader = iu.passive('modded_loader') .. ' <span class="text-desktoponly">改造ローダー</span>'
return cache.moddedLoader
end
local function getAmpedMode()
if cache.ampedMode then
return cache.ampedMode
end
cache.ampedMode = iu.item('シールドセル') .. ' <span class="text-desktoponly">増幅モード</span>'
return cache.ampedMode
end
local function getRevvedUpMode()
if cache.revvedUpMode then
return cache.revvedUpMode
end
cache.revvedUpMode = iu.grenade('テルミットグレネード') .. ' <span class="text-desktoponly">連射速度上昇モード</span>'
return cache.revvedUpMode
end
local function getDisruptorRounds()
if cache.disruptorRounds then
return cache.disruptorRounds
end
cache.disruptorRounds = inu.hopup('disruptor_rounds', { desktopOnly = true })
return cache.disruptorRounds
end
local function getHammerpointRounds()
if cache.hammerpointRounds then
return cache.hammerpointRounds
end
cache.hammerpointRounds = inu.hopup('hammerpoint_rounds', { desktopOnly = true })
return cache.hammerpointRounds
end
local function getShatterCaps()
if cache.shatterCaps then
return cache.shatterCaps
end
cache.shatterCaps = inu.hopup('shatter_caps', { desktopOnly = true })
return cache.shatterCaps
end
local function getDeadeyesTempo()
if cache.deadeyesTempo then
return cache.deadeyesTempo
end
cache.deadeyesTempo = inu.hopup('deadeyes_tempo', { desktopOnly = true })
return cache.deadeyesTempo
end
local function getAnvilReceiver()
if cache.anvilReceiver then
return cache.anvilReceiver
end
cache.anvilReceiver = inu.hopup('anvil_receiver', { desktopOnly = true })
return cache.anvilReceiver
end
local function getTurbocharger()
if cache.turbocharger then
return cache.turbocharger
end
cache.turbocharger = inu.hopup('turbocharger', { desktopOnly = true })
return cache.turbocharger
end
local function getBoostedLoader()
if cache.boostedLoader then
return cache.boostedLoader
end
cache.boostedLoader = inu.hopup('boosted_loader', { desktopOnly = true })
return cache.boostedLoader
end
local function getMagazineLabel(ammo, level, force)
if not force and level == 0 then
return ''
end
if aw.stringstarts(ammo, 'special_') then
ammo = string.sub(ammo, 9)
end
if not cache[ammo] then
cache[ammo] = {}
end
if cache[ammo] and cache[ammo][1 + level] then
return cache[ammo][1 + level]
end
if ammo == 'shotgun' then
cache[ammo][1 + level] = inu.bolt(level, { desktopOnly = true })
else
cache[ammo][1 + level] = inu.extmag(ammo, level, { desktopOnly = true })
end
return cache[ammo][1 + level]
end
local getEmphasizableText = aw.getEmphasizableTextFunc('%s', '<span class="text-desktoponly">%s</span>', '<span class="text-desktoponly">%s</span>')
local function getWeaponLink(name, ammo, shortname)
local classSuffix = aw.stringstarts(ammo, 'special_') and 'special' or ammo
local suitableName = getEmphasizableText(name, shortname)
return string.format('[[%s|<span class="text-ammo-%s">%s</span>]]', name, classSuffix, suitableName)
end
-- [[ 設定 ]]
local columns = { '通常', '鉄壁', '+ガンシールド' }
local columnCount = #columns
local config = {
-- 通常
{
gunshield = 0,
passive = 1,
},
-- 小柄
--{
-- gunshield = 0,
-- passive = 1.05,
--},
-- 鉄壁
{
gunshield = 0,
passive = 0.85,
},
-- +ガンシールド
{
gunshield = 50,
passive = 0.85,
},
}
-- [[ テーブル生成 ]]
local function passthrough(num)
return num
end
local function createStatTable(itemname, slots, headers, fn, numformat, isdesc, zero)
numformat = numformat or passthrough
if isdesc == nil then
isdesc = true
end
zero = zero or 0
local stat = mw.loadData('Module:Stat/Weapon')
local data = {}
for key, value in pairs(stat) do
fn(data, key, value)
end
if isdesc then
table.sort(data, function(a, b)
return a.values[1] > b.values[1]
end)
else
table.sort(data, function(a, b)
return a.values[1] < b.values[1]
end)
end
local tbl = mw.html.create('table')
:addClass('numbertable')
:addClass('st')
:addClass('sortable')
local header = tbl:tag('tr')
:addClass('row-sticky')
:tag('th')
:addClass('st-desktop')
:css('width', '36px')
:done()
:tag('th')
:addClass('st-mobile-first')
:attrIf(slots > 2, { colspan = slots - 1 })
:wikitext('武器名')
:done()
for _, item in ipairs(headers) do
header:tag('th')
:css('min-width', '60px')
:wikitext(item)
end
local rank = 1
local max = 0
for i = 1, #data do
local value = math.max(unpack(data[i].values))
if value ~= math.huge then
max = math.max(max, value)
end
end
local current = max
for i, obj in ipairs(data) do
local row = tbl:tag('tr')
if slots > 1 then
for i = 1, slots do
local classname
if i == 1 then
classname = 'st-desktop'
elseif i == 2 then
classname = 'st-mobile-first st-dashed-right st-mobile-none-right st-mobile-padding0-right'
elseif i == slots then
classname = 'st-dashed-left st-mobile-none-left st-mobile-padding0-both'
else
classname = 'st-dashed-both st-mobile-none-both st-mobile-padding0-both'
end
row:tag('td')
:addClass(classname)
:attrIf(i == 1, { align = 'center' })
:wikitext(obj[i])
:attr('align', 'left')
end
else
row:tag('td')
:wikitext(obj.name)
:attr('align', 'left')
end
for _, value in ipairs(obj.values) do
local percentage = 0.001 * aw.round(100000 * (value - zero) / (1.05 * max - zero))
local graph = string.format('linear-gradient(to right, #A7D7F9 %s%%, transparent %s%%)', percentage, percentage)
row:tag('td')
:addClass('st-graph')
:addClass('st-textshadow')
:addClass('st-line')
:addClass('st-line-h12')
:attr('align', 'right')
:css('background-image', graph .. ' !important')
:wikitext(numformat(value))
end
end
return tbl
end
local function add(data, name, values)
if values == nil or type(values) == 'number' then
error(string.format('The "%s" value is nil or number', name))
end
if type(name) == 'table' then
name.values = values
table.insert(data, name)
else
local obj = {
name = name,
values = values,
}
table.insert(data, obj)
end
end
-- [[ キルタイム ]]
local function getSTKs(stat, opts, health, shield, STKCalculator)
local ret = {}
local stkc = STKCalculator.newFromStat(stat, opts)
for passive = 1, #config do
local c = config[passive]
stkc:calcShotToKill(health, shield, c.gunshield, c.passive)
table.insert(ret, stkc:get())
stkc:reset()
end
return ret
end
local function getTTKs(stat, stks, opts, TTKCalculator)
local ttkc = TTKCalculator.newFromStat(stat, opts)
local ret = {}
for _, stk in ipairs(stks) do
local obj = {
ttkc:getAsLevel(stk, 0),
ttkc:getAsLevel(stk, 1),
ttkc:getAsLevel(stk, 2),
ttkc:getAsLevel(stk, 3),
}
table.insert(ret, obj)
end
return ret
end
local function isDiffTTKs(ttks, a, b)
for passive = 1, columnCount do
if 0.0001 * aw.round(10000 * ttks[passive][a]) ~= 0.0001 * aw.round(10000 * ttks[passive][b]) then
return true
end
end
return false
end
local function compareTTKs(ttks1, ttks2)
for passive = 1, columnCount do
for level = 1, 4 do
local ttk1 = 0.0001 * aw.round(10000 * ttks1[passive][level])
local ttk2 = 0.0001 * aw.round(10000 * ttks2[passive][level])
if ttk1 ~= ttk2 then
return false
end
end
end
return true
end
local function repackTTKs(ttks, level)
local ret = {}
for _, ttk in ipairs(ttks) do
table.insert(ret, ttk[level])
end
return ret
end
local function addFromTTKs(ammo, data, ammoname, basename, hopup, ttks)
if isDiffTTKs(ttks, 3, 4) then
add(data, { ammoname, basename, getMagazineLabel(ammo, 3), hopup }, repackTTKs(ttks, 4))
add(data, { ammoname, basename, getMagazineLabel(ammo, 2), hopup }, repackTTKs(ttks, 3))
if isDiffTTKs(ttks, 1, 2) then
add(data, { ammoname, basename, getMagazineLabel(ammo, 1), hopup }, repackTTKs(ttks, 2))
add(data, { ammoname, basename, getMagazineLabel(ammo, 0, true), hopup }, repackTTKs(ttks, 1))
else
add(data, { ammoname, basename, getMagazineLabel(ammo, 0, true) .. '<br>' .. getMagazineLabel(ammo, 1), hopup }, repackTTKs(ttks, 1))
end
elseif isDiffTTKs(ttks, 2, 3) then
add(data, { ammoname, basename, getMagazineLabel(ammo, 2) .. '<br>' .. getMagazineLabel(ammo, 3), hopup }, repackTTKs(ttks, 3))
if isDiffTTKs(ttks, 1, 2) then
add(data, { ammoname, basename, getMagazineLabel(ammo, 1), hopup }, repackTTKs(ttks, 2))
add(data, { ammoname, basename, getMagazineLabel(ammo, 0, true), hopup }, repackTTKs(ttks, 1))
else
add(data, { ammoname, basename, getMagazineLabel(ammo, 0, true) .. '<br>' .. getMagazineLabel(ammo, 1), hopup }, repackTTKs(ttks, 1))
end
elseif isDiffTTKs(ttks, 1, 2) then
add(data, { ammoname, basename, getMagazineLabel(ammo, 1) .. '<br>' .. getMagazineLabel(ammo, 2) .. '<br>' .. getMagazineLabel(ammo, 3), hopup }, repackTTKs(ttks, 2))
add(data, { ammoname, basename, getMagazineLabel(ammo, 0, true), hopup }, repackTTKs(ttks, 1))
else
add(data, { ammoname, basename, '', hopup }, repackTTKs(ttks, 1))
end
end
local function parsePattern(str)
local type = type(str)
if type == 'table' then
return str
elseif str == nil or type ~= 'string' then
return nil
end
local pattern = {}
local head = false
for i = 1, #str do
local c = string.sub(str, i, i)
local cont = false
if head then
head = false
if c == '1' then
table.insert(pattern, apex.HEAD_HLMLV1)
cont = true
elseif c == '2' then
table.insert(pattern, apex.HEAD_HLMLV2)
cont = true
elseif c == '3' then
table.insert(pattern, apex.HEAD_HLMLV3)
cont = true
elseif c == '0' then
table.insert(pattern, apex.HEAD_NOHLM)
cont = true
else
table.insert(pattern, apex.HEAD_NOHLM)
end
end
if not cont then
if c == 'H' then
head = true
elseif c == 'L' then
table.insert(pattern, apex.LEGS)
elseif c == 'S' then
table.insert(pattern, apex.SKY)
elseif c == ',' or c == ' ' then
if head then
head = false
table.insert(pattern, apex.HEAD_NOHLM)
end
else
table.insert(pattern, apex.BODY)
end
end
end
if head then
table.insert(pattern, apex.HEAD_NOHLM)
end
return pattern
end
function p.bytimetokill(frame, args)
formatter = require('Module:Utility/Formatter').new(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
args = args or getArgs(frame)
args.health = aw.getAsNumber(args.health, 100)
args.shield = aw.getAsNumber(args.shield, 125)
local opts = {
pattern = {
first = parsePattern(args.firstPattern),
loop = parsePattern(args.loopPattern),
},
}
local STKCalculator = require('Module:Apex/STKCalculator')
local TTKCalculator = require('Module:Apex/TTKCalculator')
local tbl = createStatTable('キルタイム [s]', 4, columns, function(data, name, stat)
if stat.time == nil or (not aw.isNumber(stat.time.reloadempty or stat.time.reload)) then
return
end
local ammo = stat.ammo
local ammoname = iu.ammo(ammo, { size = 20 })
local basename = getWeaponLink(name, ammo, stat.localization['Japanese_Short'])
local special = aw.stringstarts(ammo, 'special_')
local stks = getSTKs(stat, opts, args.health, args.shield, STKCalculator)
local ttks = getTTKs(stat, stks, opts, TTKCalculator)
if not stat.attachments.disruptor_rounds_only then
addFromTTKs(ammo, data, ammoname, basename, '', ttks)
end
-- ライトマシンガン (ディヴォーションLMG・M600スピットファイア・L-スターEMG)
if stat.category == 'light_machine_gun' then
local opts2 = aw.shallowCopy(opts)
opts2.useModdedLoader = true
local ttks2 = getTTKs(stat, stks, opts2, TTKCalculator)
if not compareTTKs(ttks, ttks2) then
addFromTTKs(ammo, data, ammoname, basename, getModdedLoader(), ttks2)
end
end
if stat.altfire and aw.isNumber(stat.altfire.firerate) and stat.altfire.firerate ~= stat.firerate then
local altname
if stat.altfire.is_semi_auto or stat.is_semi_auto then
altname = basename .. ' (単発)'
else
altname = basename .. ' (オート)'
end
local altopts = aw.shallowCopy(opts)
altopts.useAltfire = true
local ttks = getTTKs(stat, stks, altopts, TTKCalculator)
addFromTTKs(ammo, data, ammoname, altname, '', ttks)
-- ブーステッドローダー (ヘムロックバーストAR)
if Hopup.boosted_loader.enabled and stat.boosted_loader and type(stat.boosted_loader.magazine) == 'table' then
altopts.useBoostedLoader = true
local burstttks2 = getTTKs(stat, stks, altopts, TTKCalculator)
addFromTTKs(ammo, data, ammoname, altname, getBoostedLoader(), burstttks2)
end
end
-- 最高速から
local ttksmax = nil
if aw.isNumberAndGreaterThanZero(stat.firerate_maximum_duration) then
local maxname = basename .. ' (最高速)'
local opts2 = aw.shallowCopy(opts)
opts2.startMaximum = true
ttksmax = getTTKs(stat, stks, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, maxname, '', ttksmax)
if stat.category == 'light_machine_gun' then
local opts3 = aw.shallowCopy(opts2)
opts3.useModdedLoader = true
local ttks3 = getTTKs(stat, stks, opts3, TTKCalculator)
if not compareTTKs(ttksmax, ttks3) then
addFromTTKs(ammo, data, ammoname, maxname, getModdedLoader(), ttks3)
end
end
end
-- センチネルの増幅モード
if aw.isNumberAndGreaterThanZero(stat.damage.amped) then
local ampedammoname = iu.ammo(ammo .. '_amped', { size = 20 })
local ampedname = string.format('%s (%s)', basename, getAmpedMode())
local opts2 = aw.shallowCopy(opts)
opts2.useAmpedMode = true
local stksAmped = getSTKs(stat, opts2, args.health, args.shield, STKCalculator)
local ttksAmped = getTTKs(stat, stksAmped, opts2, TTKCalculator)
if not compareTTKs(ttks, ttksAmped) then
addFromTTKs(ammo, data, ampedammoname, ampedname, '', ttksAmped)
end
-- デッドアイズテンポ
if Hopup.deadeyes_tempo.enabled and stat.deadeyes_tempo then
opts2.useDeadeyesTempo = true
local ttksTempo = getTTKs(stat, stksAmped, opts2, TTKCalculator)
if not compareTTKs(ttksAmped, ttksTempo) then
addFromTTKs(ammo, data, ampedammoname, ampedname, getDeadeyesTempo(), ttksTempo)
end
-- 最高速
if aw.isNumberAndGreaterThanOrEqualToX(stat.deadeyes_tempo.firerate_maximum_count, 1) then
local ampedmaxname = string.format('%s (最高速・%s)', basename, getAmpedMode())
opts2.startMaximum = true
local stksTempoMax = getSTKs(stat, opts2, args.health, args.shield, STKCalculator)
local ttksTempoMax = getTTKs(stat, stksTempoMax, opts2, TTKCalculator)
addFromTTKs(ammo, data, ampedammoname, ampedmaxname, getDeadeyesTempo(), ttksTempoMax)
end
end
end
-- ランページの連射速度上昇モード
if aw.isNumberAndGreaterThanZero(stat.firerate_revvedup) then
local revvedupammoname = iu.ammo(ammo .. '_revved_up', { size = 20 })
local revvedupname = string.format('%s (%s)', basename, getRevvedUpMode())
local opts2 = aw.shallowCopy(opts)
opts2.useRevvedUpMode = true
local ttksRevvedUp = getTTKs(stat, stks, opts2, TTKCalculator)
addFromTTKs(ammo, data, revvedupammoname, revvedupname, '', ttksRevvedUp)
end
-- フルチャージ (30-30リピーター・ボセックコンパウンドボウ)
if aw.isNumberAndGreaterThanZero(stat.damage.charged) then
local chargedname = basename .. ' (最大溜め)'
local opts2 = aw.shallowCopy(opts)
opts2.useCharged = true
local stks2 = getSTKs(stat, opts2, args.health, args.shield, STKCalculator)
local ttks2 = getTTKs(stat, stks2, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, chargedname, '', ttks2)
-- デッドアイズテンポ
if Hopup.deadeyes_tempo.enabled and stat.deadeyes_tempo then
opts2.useDeadeyesTempo = true
local ttksTempo = getTTKs(stat, stks2, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, chargedname, getDeadeyesTempo(), ttksTempo)
-- 最高速
if aw.isNumberAndGreaterThanOrEqualToX(stat.deadeyes_tempo.firerate_maximum_count, 1) then
local chargedmaxname = basename .. ' (最高速・最大溜め)'
opts2.startMaximum = true
local stksTempoMax = getSTKs(stat, opts2, args.health, args.shield, STKCalculator)
local ttksTempoMax = getTTKs(stat, stksTempoMax, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, chargedmaxname, getDeadeyesTempo(), ttksTempoMax)
end
end
end
-- ディスラプター弾 (オルタネーターSMG・RE-45オート)
if (Hopup.disruptor_rounds.enabled or special) and aw.isNumber(stat.damage.disruptor_rounds) and stat.damage.disruptor_rounds > 1 then
local opts2 = aw.shallowCopy(opts)
opts2.useDisruptorRounds = true
local stks2 = getSTKs(stat, opts2, args.health, args.shield, STKCalculator)
local ttks2 = getTTKs(stat, stks2, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, basename, getDisruptorRounds(), ttks2)
end
-- ハンマーポイント弾 (モザンビーク・P2020)
if Hopup.hammerpoint_rounds.enabled and aw.isNumber(stat.damage.hammerpoint_rounds) and stat.damage.hammerpoint_rounds > 1 then
local opts2 = aw.shallowCopy(opts)
opts2.useHammerpointRounds = true
local stks2 = getSTKs(stat, opts2, args.health, args.shield, STKCalculator)
local ttks2 = getTTKs(stat, stks2, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, basename, getHammerpointRounds(), ttks2)
end
-- アンビルレシーバー (VK-47フラットライン・R-301カービン)
if Hopup.anvil_receiver.enabled and stat.anvil_receiver then
local opts2 = aw.shallowCopy(opts)
opts2.useAnvilReceiver = true
local stks2 = getSTKs(stat, opts2, args.health, args.shield, STKCalculator)
local ttks2 = getTTKs(stat, stks2, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, basename, getAnvilReceiver(), ttks2)
end
-- ブーステッドローダー (ヘムロックバーストAR・ウィングマン)
if Hopup.boosted_loader.enabled and stat.boosted_loader and type(stat.boosted_loader.magazine) == 'table' then
local opts2 = aw.shallowCopy(opts)
opts2.useBoostedLoader = true
local ttks2 = getTTKs(stat, stks, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, basename, getBoostedLoader(), ttks2)
end
-- シャッターキャップ (30-30リピーター・ボセックコンポウンドボウ)
if Hopup.shatter_caps.enabled and stat.shatter_caps then
local label = getShatterCaps()
local opts2 = aw.shallowCopy(opts)
opts2.useShatterCaps = true
local stks2 = getSTKs(stat, opts2, args.health, args.shield, STKCalculator)
local ttks2 = getTTKs(stat, stks2, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, basename, label, ttks2)
if aw.isNumberAndGreaterThanZero(stat.shatter_caps.damage.charged) then
local chargedname = basename .. ' (最大溜め)'
opts2.useCharged = true
local stks3 = getSTKs(stat, opts2, args.health, args.shield, STKCalculator)
local ttks3 = getTTKs(stat, stks3, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, chargedname, label, ttks3)
-- デッドアイズテンポ (ボセックコンパウンドボウ)
if Hopup.deadeyes_tempo.enabled and stat.deadeyes_tempo then
label = label .. '<br>' .. getDeadeyesTempo()
opts2.useDeadeyesTempo = true
local ttksTempo = getTTKs(stat, stks3, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, chargedname, label, ttksTempo)
-- 最高速
if aw.isNumberAndGreaterThanOrEqualToX(stat.deadeyes_tempo.firerate_maximum_count, 1) then
local chargedmaxname = basename .. ' (最高速・最大溜め)'
opts2.startMaximum = true
local stksTempoMax = getSTKs(stat, opts2, args.health, args.shield, STKCalculator)
local ttksTempoMax = getTTKs(stat, stksTempoMax, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, chargedmaxname, label, ttksTempoMax)
end
end
end
end
-- デッドアイズテンポ (センチネル)
if Hopup.deadeyes_tempo.enabled and stat.deadeyes_tempo and (not aw.isNumberAndGreaterThanZero(stat.damage.charged)) then
local opts2 = aw.shallowCopy(opts)
opts2.useDeadeyesTempo = true
local ttksTempo = getTTKs(stat, stks, opts2, TTKCalculator)
if not compareTTKs(ttks, ttksTempo) then
addFromTTKs(ammo, data, ammoname, basename, getDeadeyesTempo(), ttksTempo)
end
-- 最高速
if aw.isNumberAndGreaterThanOrEqualToX(stat.deadeyes_tempo.firerate_maximum_count, 1) then
local maxname = basename .. ' (最高速)'
opts2.startMaximum = true
local stksTempoMax = getSTKs(stat, opts2, args.health, args.shield, STKCalculator)
local ttksTempoMax = getTTKs(stat, stksTempoMax, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, maxname, getDeadeyesTempo(), ttksTempoMax)
end
end
-- ターボチャージャー (ハボックライフル・ディヴォーションLMG)
if stat.turbocharger then
local opts2 = aw.shallowCopy(opts)
opts2.useTurbocharger = true
local ttks2 = getTTKs(stat, stks, opts2, TTKCalculator)
addFromTTKs(ammo, data, ammoname, basename, getTurbocharger(), ttks2)
-- 最高速から
if aw.isNumberAndGreaterThanZero(stat.turbocharger.firerate_maximum_duration) then
local maxname = basename .. ' (最高速)'
local opts3 = aw.shallowCopy(opts2)
opts3.startMaximum = true
local ttks3 = getTTKs(stat, stks, opts3, TTKCalculator)
if ttksmax ~= nil and not compareTTKs(ttksmax, ttks3) then
addFromTTKs(ammo, data, ammoname, maxname, getTurbocharger(), ttks3)
end
if stat.category == 'light_machine_gun' then
local opts4 = aw.shallowCopy(opts3)
opts4.useModdedLoader = true
local ttks4 = getTTKs(stat, stks, opts4, TTKCalculator)
if not compareTTKs(ttks3, ttks4) then
addFromTTKs(ammo, data, ammoname, maxname, getTurbocharger() .. '<br>' .. getModdedLoader(), ttks4)
end
end
end
-- ライトマシンガン (ディヴォーションLMG)
if stat.category == 'light_machine_gun' then
local opts3 = aw.shallowCopy(opts2)
opts3.useModdedLoader = true
local ttks3 = getTTKs(stat, stks, opts3, TTKCalculator)
if not compareTTKs(ttks2, ttks3) then
addFromTTKs(ammo, data, ammoname, basename, getTurbocharger() .. '<br>' .. getModdedLoader(), ttks3)
end
end
end
end, function(num)
return 0.001 * aw.round(1000 * num)
end, false, -0.1)
return tostring(tbl)
end
return p