🌟 | 現在、 鉄壁ヘッドショットには対応済みです。 鉄壁HSは通常HSと同じダメージになります。LMG及びDMR、チャージライフル、ハンマーポイント弾を除き、すべてのダメージ値が一致していることを確認しています。 |
モジュール:StatTable/ShotTime
ナビゲーションに移動
検索に移動
このモジュールについての説明文ページを モジュール:StatTable/ShotTime/doc に作成できます
local aw = require('Module:Utility/Library') local apex = require('Module:Utility/ApexLibrary') local iu = require('Module:Utility/Image') local tableutil = require('Module:Utility/TableUtil/Apex') local TTKCalculator = require('Module:Apex/TTKCalculator') local Hopup = mw.loadData('Module:Stat/Hopup') local configuration = mw.loadData('Module:StatTable/configuration') local getArgs -- lazily initialized local function calcBurstDuration(data, firerate, magazine, delay) local groupCount = math.floor(math.floor(magazine / data.ammopershot) / data.burstcount) local duration = groupCount * ((data.burstcount - 1) / firerate + delay) - delay return duration end local function calcDurationBase(data, firerate, shotCount, rechamber) local duration = shotCount / firerate if data.raise > 0 then if data.semiauto then duration = duration + shotCount * data.raise else duration = duration + data.raise end end if data.charge > 0 then duration = duration + shotCount * data.charge end if rechamber > 0 then duration = duration + shotCount * rechamber end return duration end local function calcDuration(data, firerate, magazine, rechamber) local shotCount = math.floor(magazine / data.ammopershot) - 1 if aw.isNumberAndGreaterThanOrEqualToX(data.tempomaxcount, 1) and shotCount > data.tempomaxcount and aw.isNumberAndGreaterThanZero(data.temporechamber) then local duration = calcDurationBase(data, firerate, data.tempomaxcount, rechamber) duration = duration + calcDurationBase(data, firerate, shotCount - data.tempomaxcount, data.temporechamber) return duration else return calcDurationBase(data, firerate, shotCount, rechamber) end end local function addFlatData(dataset, data, special) local fireratesType = type(data.firerates) local magazinesType = type(data.magazines) local rechambersType = type(data.rechambers) -- バーストの場合 if aw.isNumberAndGreaterThanOrEqualToX(data.burstcount, 2) and fireratesType == 'number' then local delaysType = type(data.burstdelay) -- ショットガンボルトがつく場合(バースト遅延が可変) if delaysType == 'table' then if special then data.duration = calcBurstDuration(data, data.firerates, data.magazines, data.burstdelay[4]) table.insert(dataset, data) else for level, delay in ipairs(data.burstdelay) do local data2 = aw.shallowCopy(data) data2.duration = calcBurstDuration(data, data.firerates, data.magazines, delay) data2.level = level - 1 table.insert(dataset, data2) end end elseif delaysType == 'number' and data.burstdelay > 0 then -- 拡張マガジンがつく場合 if magazinesType == 'table' then if special then data.duration = calcBurstDuration(data, data.firerates, data.magazines[4], data.burstdelay) table.insert(dataset, data) else for level, magazine in ipairs(data.magazines) do local data2 = aw.shallowCopy(data) data2.duration = calcBurstDuration(data, data.firerates, magazine, data.burstdelay) data2.level = level - 1 table.insert(dataset, data2) end end else data.duration = calcBurstDuration(data, data.firerates, data.magazines, data.burstdelay) table.insert(dataset, data) end end -- ショットガンボルトがつく場合 (ファイアレートが可変) elseif fireratesType == 'table' and magazinesType == 'number' then if special then data.duration = calcDuration(data, data.firerates[4], data.magazines, data.rechambers) table.insert(dataset, data) else for level, firerate in ipairs(data.firerates) do local data2 = aw.shallowCopy(data) data2.duration = calcDuration(data, firerate, data.magazines, data.rechambers) data2.level = level - 1 table.insert(dataset, data2) end end -- ショットガンボルトがつく場合 (リチャンバーが可変) elseif fireratesType == 'number' and magazinesType == 'number' and rechambersType == 'table' then if special then data.duration = calcDuration(data, data.firerates, data.magazines, data.rechambers[4]) table.insert(dataset, data) else for level, rechamber in ipairs(data.rechambers) do local data2 = aw.shallowCopy(data) data2.duration = calcDuration(data, data.firerates, data.magazines, rechamber) data2.level = level - 1 table.insert(dataset, data2) end end -- 拡張マガジンがつく場合 elseif fireratesType == 'number' and magazinesType == 'table' then if special then data.duration = calcDuration(data, data.firerates, data.magazines[4], data.rechambers) table.insert(dataset, data) else for level, magazine in ipairs(data.magazines) do local data2 = aw.shallowCopy(data) data2.duration = calcDuration(data, data.firerates, magazine, data.rechambers) data2.level = level - 1 table.insert(dataset, data2) end end -- 拡張マガジンとショットガンボルトの両方ともがつかない場合 elseif fireratesType == 'number' and magazinesType == 'number' then data.duration = calcDuration(data, data.firerates, data.magazines, data.rechambers) table.insert(dataset, data) end end local function createDataset(dataset, stats, res, addData, __debug) for name, stat in pairs(stats) do local baseData = { ammo = stat.ammo, ammoicon = stat.ammo, ammopershot = stat.ammo_per_shot or 1, charge = -1, duration = -1, firerates = stat.firerate, level = -1, magazines = stat.magazine, name = name, semiauto = stat.is_semi_auto, raise = stat.raise or 0, rechambers = stat.rechamber or 0, shortname = stat.localization['Japanese_Short'], } local special = aw.stringstarts(stat.ammo, 'special_') -- Use TTKCalculator if name == 'ディヴォーションLMG' then local ttkc = TTKCalculator.newFromStat(stat) for level, magazine in ipairs(stat.magazine) do local data2 = aw.shallowCopy(baseData) data2.duration = ttkc:getAsLevel(magazine, level - 1) data2.level = level - 1 table.insert(dataset, data2) end ttkc = TTKCalculator.newFromStat(stat, { useTurbocharger = true }) for level, magazine in ipairs(stat.magazine) do local data2 = aw.shallowCopy(baseData) data2.duration = ttkc:getAsLevel(magazine, level - 1) data2.hopup = { 'turbocharger' } data2.level = level - 1 table.insert(dataset, data2) end local moddedLoaderMagazines = apex.getMagazineWithModdedLoader(stat.magazine) ttkc = TTKCalculator.newFromStat(stat, { useModdedLoader = true }) for level, magazine in ipairs(moddedLoaderMagazines) do local data2 = aw.shallowCopy(baseData) data2.duration = ttkc:getAsLevel(magazine, level - 1) data2.hopup = { 'modded_loader' } data2.level = level - 1 table.insert(dataset, data2) end ttkc = TTKCalculator.newFromStat(stat, { useTurbocharger = true, useModdedLoader = true }) for level, magazine in ipairs(moddedLoaderMagazines) do local data2 = aw.shallowCopy(baseData) data2.duration = ttkc:getAsLevel(magazine, level - 1) data2.hopup = { 'turbocharger', 'modded_loader' } data2.level = level - 1 table.insert(dataset, data2) end -- Mag is inf elseif stat.magazine == math.huge then local overheatsType = type(stat.overheat) if overheatsType == 'table' then local virtualMagazines = { math.ceil(stat.overheat[1] * stat.firerate), math.ceil(stat.overheat[2] * stat.firerate), math.ceil(stat.overheat[3] * stat.firerate), math.ceil(stat.overheat[4] * stat.firerate), } baseData.magazines = virtualMagazines addData(dataset, baseData, special) -- Modded Loader if stat.category == 'light_machine_gun' then local moddedLoaderVirtualMagazines = { math.ceil(1.15 * stat.overheat[1] * stat.firerate), math.ceil(1.15 * stat.overheat[2] * stat.firerate), math.ceil(1.15 * stat.overheat[3] * stat.firerate), math.ceil(1.15 * stat.overheat[4] * stat.firerate), } local moddedLoaderData = aw.shallowCopy(baseData) moddedLoaderData.hopup = { 'modded_loader' } moddedLoaderData.magazines = moddedLoaderVirtualMagazines addData(dataset, moddedLoaderData, special) end elseif overheatsType == 'number' then baseData.magazines = math.ceil(stat.overheat * stat.firerate) addData(dataset, baseData, special) -- Modded Loader if stat.category == 'light_machine_gun' then local moddedLoaderData = aw.shallowCopy(baseData) moddedLoaderData.hopup = { 'modded_loader' } moddedLoaderData.magazines = math.ceil(1.15 * stat.overheat * stat.firerate) addData(dataset, moddedLoaderData, special) end end -- Other else -- Altfire mode if type(stat.altfire) == 'table' and aw.isNumberAndGreaterThanZero(stat.altfire.firerate) then local burstfireData = aw.shallowCopy(baseData) burstfireData.burstcount = stat.burst_count burstfireData.burstdelay = stat.burst_delay burstfireData.option = res.burst addData(dataset, burstfireData, special) local altfireData = aw.shallowCopy(baseData) altfireData.firerates = stat.altfire.firerate altfireData.semiauto = stat.altfire.is_semi_auto == nil and stat.is_semi_auto or stat.altfire.is_semi_auto altfireData.option = altfireData.semiauto and res.single or res.auto addData(dataset, altfireData, special) -- Burst mode elseif aw.isNumberAndGreaterThanOrEqualToX(stat.burst_count, 2) then local burstfireData = aw.shallowCopy(baseData) burstfireData.burstcount = stat.burst_count burstfireData.burstdelay = stat.burst_delay addData(dataset, burstfireData, special) -- Chargefire elseif aw.isNumberAndGreaterThanZero(stat.charge) then baseData.option = res.mincharge addData(dataset, baseData, special) local maxData = aw.shallowCopy(baseData) maxData.charge = stat.charge maxData.option = res.maxcharge addData(dataset, maxData, special) -- Charge Rifle elseif aw.isNumberAndGreaterThanZero(stat.sustained_discharge_duration) then baseData.raise = stat.sustained_discharge_duration addData(dataset, baseData, special) -- Other else addData(dataset, baseData, special) end -- Modded Loader if stat.category == 'light_machine_gun' or stat.ammo == 'minigun' then local moddedLoaderData = aw.shallowCopy(baseData) moddedLoaderData.hopup = { 'modded_loader' } moddedLoaderData.magazines = apex.getMagazineWithModdedLoader(stat.magazine) addData(dataset, moddedLoaderData, special) -- Revved Up mode if aw.isNumberAndGreaterThanOrEqualToX(stat.firerate_revvedup, stat.firerate) then local revvedUpData = aw.shallowCopy(baseData) revvedUpData.ammoicon = stat.ammo .. '_revved_up' revvedUpData.firerates = stat.firerate_revvedup revvedUpData.option = res.revvedup addData(dataset, revvedUpData, special) local moddedLoaderRevvedUpData = aw.shallowCopy(moddedLoaderData) moddedLoaderRevvedUpData.ammoicon = stat.ammo .. '_revved_up' moddedLoaderRevvedUpData.firerates = stat.firerate_revvedup moddedLoaderRevvedUpData.option = res.revvedup addData(dataset, moddedLoaderRevvedUpData, special) end end -- Turbocharger if (__debug or Hopup.turbocharger.enabled) and type(stat.turbocharger) == 'table' and aw.isNumberAndGreaterThanZero(stat.turbocharger.raise) then local turbochargerData = aw.shallowCopy(baseData) turbochargerData.hopup = { 'turbocharger' } turbochargerData.raise = stat.turbocharger.raise or stat.raise or 0 addData(dataset, turbochargerData, special) end -- Selectfire Receiver if (__debug or Hopup.selectfire_receiver.enabled) and type(stat.selectfire_receiver) == 'table' and aw.isNumberAndGreaterThanZero(stat.selectfire_receiver.firerate) then local semiauto if stat.selectfire_receiver.semiauto then semiauto = stat.selectfire_receiver.semiauto else semiauto = stat.semiauto end local selectfireReceiverData = aw.shallowCopy(baseData) selectfireReceiverData.ammopershot = stat.selectfire_receiver.ammo_per_shot or stat.ammo_per_shot or 1 selectfireReceiverData.firerates = stat.selectfire_receiver.firerate selectfireReceiverData.hopup = { 'selectfire_receiver' } selectfireReceiverData.raise = stat.selectfire_receiver.raise or stat.raise or 0 selectfireReceiverData.semiauto = semiauto addData(dataset, selectfireReceiverData, special) end -- Anvil Receiver if (__debug or Hopup.anvil_receiver.enabled) and type(stat.anvil_receiver) == 'table' and aw.isNumberAndGreaterThanZero(stat.anvil_receiver.firerate) then local anvilReceiverData = aw.shallowCopy(baseData) anvilReceiverData.ammopershot = stat.anvil_receiver.ammo_per_shot or 2 anvilReceiverData.firerates = stat.anvil_receiver.firerate anvilReceiverData.hopup = { 'anvil_receiver' } addData(dataset, anvilReceiverData, special) end -- Double Tap Trigger if (__debug or Hopup.double_tap_trigger.enabled) and type(stat.double_tap_trigger) == 'table' and aw.isNumberAndGreaterThanOrEqualToX(stat.double_tap_trigger.burst_count, 2) then local doubleTapTriggerData = aw.shallowCopy(baseData) doubleTapTriggerData.burstcount = stat.double_tap_trigger.burst_count doubleTapTriggerData.burstdelay = stat.double_tap_trigger.burst_delay doubleTapTriggerData.firerates = stat.double_tap_trigger.firerate doubleTapTriggerData.hopup = { 'double_tap_trigger' } addData(dataset, doubleTapTriggerData, special) end -- Deadeye's Tempo if (__debug or Hopup.deadeyes_tempo.enabled) and type(stat.deadeyes_tempo) == 'table' and aw.isNumberAndGreaterThanZero(stat.deadeyes_tempo.rechamber) then local deadeyesTempoData = aw.shallowCopy(baseData) deadeyesTempoData.hopup = { 'deadeyes_tempo' } deadeyesTempoData.tempomaxcount = stat.deadeyes_tempo.firerate_maximum_count deadeyesTempoData.temporechamber = stat.deadeyes_tempo.rechamber addData(dataset, deadeyesTempoData, special) end -- Boosted Loader if (__debug or Hopup.boosted_loader.enabled) and type(stat.boosted_loader) == 'table' then if type(stat.altfire) == 'table' and aw.isNumberAndGreaterThanZero(stat.altfire.firerate) then local boostedLoaderData = aw.shallowCopy(baseData) boostedLoaderData.burstcount = stat.burst_count boostedLoaderData.burstdelay = stat.burst_delay boostedLoaderData.hopup = { 'boosted_loader' } boostedLoaderData.magazines = stat.boosted_loader.magazine boostedLoaderData.option = res.burst addData(dataset, boostedLoaderData, special) local altfireBoostedLoaderData = aw.shallowCopy(baseData) altfireBoostedLoaderData.firerates = stat.altfire.firerate altfireBoostedLoaderData.hopup = { 'boosted_loader' } altfireBoostedLoaderData.magazines = stat.boosted_loader.magazine altfireBoostedLoaderData.semiauto = stat.altfire.is_semi_auto == nil and stat.is_semi_auto or stat.altfire.is_semi_auto altfireBoostedLoaderData.option = altfireBoostedLoaderData.semiauto and res.single or res.auto addData(dataset, altfireBoostedLoaderData, special) else local boostedLoaderData = aw.shallowCopy(baseData) boostedLoaderData.hopup = { 'boosted_loader' } boostedLoaderData.magazines = stat.boosted_loader.magazine addData(dataset, boostedLoaderData, special) end end end end end local p = {} function p._main(args, __debug) args = args or {} if __debug == nil then __debug = true end local lang = args.lang or 'ja' local res = configuration[lang] local stats = mw.loadData('Module:Stat/Weapon') local dataset = {} createDataset(dataset, stats, res, addFlatData, __debug) local metadata = { tableutil.RankCell.new('', 'duration', true), tableutil.AmmoCell.new('', 'ammoicon', { attributes = { align = 'center' }, cellClass = 'st-desktop', footerClass = 'st-desktop', headerClass = 'st-desktop', headerStyle = { width = '36px' }, }), tableutil.WeaponNameCell.new(res.weaponname, 'name', { ammoIndex = 'ammo', attributes = { align = 'left' }, cellClass = 'st-dashed-right st-mobile-none-right st-mobile-padding0-right', headerColspan = 3, optionIndex = 'option', shortnameIndex = 'shortname', }), tableutil.MagazineCell.new(res.mag, 'level', { ammoIndex = 'ammo', attributes = { align = 'left' }, cellClass = 'st-dashed-right st-mobile-none-right st-mobile-padding0-both', headerColspan = 0, }), tableutil.HopupCell.new(res.hopup, 'hopup', { attributes = { align = 'left' }, cellClass = 'st-mobile-padding0-both', headerColspan = 0, }), tableutil.LineValueCell.new(res.duration, 'duration', { cellClass = 'st-mobile-graph st-mobile-medium st-mobile-textshadow st-mobile-last', footerClass = 'st-mobile-axis st-mobile-last', format = function(val) if val >= 10 then return string.format('%.2f', val) else return string.format('%.3f', val) end end, headerClass = 'st-mobile-last', headerStyle = { ['min-width'] = '50px', ['max-width'] = '6em', }, preferredGridCount = 3, }), tableutil.LineCell.new(res.graph, 'duration', { cellClass = 'st-desktop st-desktop-graph', footerClass = 'st-desktop', headerClass = 'st-desktop', headerStyle = { ['min-width'] = '200px', }, }), } local node = tableutil.createTable(dataset, metadata) return tostring(node) --mw.logObject(dataset) --return dataset end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end args = getArgs(frame) return p._main(args, false) end return p