🌟 | 現在、 鉄壁ヘッドショットには対応済みです。 鉄壁HSは通常HSと同じダメージになります。LMG及びDMR、チャージライフル、ハンマーポイント弾を除き、すべてのダメージ値が一致していることを確認しています。 |
「モジュール:Apex/TTKCalculator」の版間の差分
ナビゲーションに移動
検索に移動
(デフォルトの装填数設定を∞に設定) |
(levelのoffsetの基準を変更) |
||
14行目: | 14行目: | ||
local type = type(firerates) | local type = type(firerates) | ||
if type == 'table' then | if type == 'table' then | ||
self.firerate = firerates[self.level] | self.firerate = firerates[1 + self.level] | ||
elseif type == 'string' then | elseif type == 'string' then | ||
self.firerate = tonumber(firerates) | self.firerate = tonumber(firerates) | ||
32行目: | 32行目: | ||
local type = type(magazines) | local type = type(magazines) | ||
if type == 'table' then | if type == 'table' then | ||
self.magazine = magazines[self.level] | self.magazine = magazines[1 + self.level] | ||
elseif type == 'string' then | elseif type == 'string' then | ||
self.magazine = tonumber(magazines) | self.magazine = tonumber(magazines) | ||
50行目: | 50行目: | ||
local type = type(reloads) | local type = type(reloads) | ||
if type == 'table' then | if type == 'table' then | ||
self.reload = reloads[self.level] | self.reload = reloads[1 + self.level] | ||
elseif type == 'string' then | elseif type == 'string' then | ||
self.reload = tonumber(reloads) | self.reload = tonumber(reloads) | ||
136行目: | 136行目: | ||
burstDelay = opts.burstDelay or 0, | burstDelay = opts.burstDelay or 0, | ||
roundsPerShot = opts.roundsPerShot or 1, | roundsPerShot = opts.roundsPerShot or 1, | ||
level = opts.level or | level = opts.level or 0, | ||
}, { __index = TTKCalculator }) | }, { __index = TTKCalculator }) | ||
obj:_load() | obj:_load() |
2021年2月24日 (水) 23:35時点における版
このモジュールについての説明文ページを モジュール:Apex/TTKCalculator/doc に作成できます
local TTKCalculator = {} local aw = require('Module:Utility/Library') -- モード TTKCalculator.BURST = 0 TTKCalculator.AUTO = 100 TTKCalculator.SINGLE = 200 TTKCalculator.SINGLE_ANVIL_RECEIVER = 201 -- [prop] 発射レート function TTKCalculator:_loadFirerates() local firerates = self.firerates local type = type(firerates) if type == 'table' then self.firerate = firerates[1 + self.level] elseif type == 'string' then self.firerate = tonumber(firerates) else self.firerate = firerates end end function TTKCalculator:setFirerates(firerates) self.firerates = firerates or 1 self:_loadFirerates() end -- [prop] 装填数 function TTKCalculator:_loadMagazines() local magazines = self.magazines local type = type(magazines) if type == 'table' then self.magazine = magazines[1 + self.level] elseif type == 'string' then self.magazine = tonumber(magazines) else self.magazine = magazines end end function TTKCalculator:setMagazines(magazines) self.magazines = magazines or 20 self:_loadMagazines() end -- [prop] リロード時間 function TTKCalculator:_loadReloads() local reloads = self.reloads local type = type(reloads) if type == 'table' then self.reload = reloads[1 + self.level] elseif type == 'string' then self.reload = tonumber(reloads) else self.reload = reloads end end function TTKCalculator:setReloads(reloads) self.reloads = reloads or 0 self:_loadReloads() end -- [prop] レベル function TTKCalculator:_load() self:_loadFirerates() self:_loadMagazines() self:_loadReloads() end function TTKCalculator:setLevel(level) self.level = level self:_load() end -- [func] TTK算出関数 function TTKCalculator:_getBurstTtkInOneMagazine(left, skipLastDelay) local ttk = 0 while left > 0 do local current = math.min(self.burst, left) left = left - current if current > 1 then ttk = ttk + (current - 1) / self.firerate end if left == 0 and skipLastDelay then break end if current == self.burst then ttk = ttk + self.burstDelay end end return ttk end function TTKCalculator:get(shot) local ttk = 0 local magazine = math.floor(self.magazine / self.roundsPerShot) -- バースト if self.burst > 1 and self.burst <= magazine then local function getTtkInOneMag(left, burst, burstDelay, firerate) end while shot > magazine do local shotTTK = self:_getBurstTtkInOneMagazine(magazine) ttk = ttk + self.raise + shotTTK + self.reload shot = shot - magazine end local shotTTK = self:_getBurstTtkInOneMagazine(shot, true) ttk = ttk + self.raise + shotTTK -- 非バースト (オート・単発) else while shot > magazine do ttk = ttk + self.raise + (magazine - 1) / self.firerate + self.reload shot = shot - magazine end ttk = ttk + self.raise + (shot - 1) / self.firerate end return ttk end -- コンストラクター function TTKCalculator.new(firerates, magazines, reloads, opts) local obj = setmetatable({ firerates = firerates or 1, magazines = magazines or math.huge, reloads = reloads or 0, raise = opts.raise or 0, burst = opts.burst or 1, burstDelay = opts.burstDelay or 0, roundsPerShot = opts.roundsPerShot or 1, level = opts.level or 0, }, { __index = TTKCalculator }) obj:_load() return obj end function TTKCalculator.newFromStat(stat, mode, opts2) mode = mode or TTKCalculator.AUTO local firerate, magazine, reload local opts = {} local isModdedLoader = stat.category == 'light_machine_gun' and opts2 and opts2.moddedLoader -- バースト if stat.mode.burst > 1 and mode == TTKCalculator.BURST then firerate = stat.firerate.burst opts.burst = stat.mode.burst opts.burstDelay = stat.firerate.burst_delay opts.roundsPerShot = stat.rounds_per_shot and stat.rounds_per_shot.burst or 1 -- オート elseif stat.mode.auto and (mode == TTKCalculator.AUTO or not stat.mode.single) then firerate = stat.firerate.auto opts.raise = stat.firerate.auto_raise or 0 opts.roundsPerShot = stat.rounds_per_shot and stat.rounds_per_shot.auto or 1 -- 単発 elseif stat.mode.single then -- アンビルレシーバー if mode == TTKCalculator.SINGLE_ANVIL_RECEIVER then firerate = stat.firerate.anvil_receiver opts.roundsPerShot = stat.rounds_per_shot and stat.rounds_per_shot.anvil_receiver or 1 -- 通常の単発 else firerate = stat.firerate.single opts.roundsPerShot = stat.rounds_per_shot and stat.rounds_per_shot.single or 1 end -- プレースホルダー else firerate = 1 opts.roundsPerShot = 1 end -- 装填数 if isModdedLoader then if type(stat.magazine) == 'table' then magazine = { aw.round(1.15 * stat.magazine[1]), aw.round(1.15 * stat.magazine[2]), aw.round(1.15 * stat.magazine[3]), aw.round(1.15 * stat.magazine[4]), } elseif stat.magazine == math.huge then if aw.isNumberAndGreaterThanZero(stat.overheat) then magazine = 1 + math.floor(1.15 * stat.overheat * firerate) else magazine = math.huge -- dummy end else magazine = aw.round(1.15 * stat.magazine) end -- L-スターEMG elseif stat.magazine == math.huge then if aw.isNumberAndGreaterThanZero(stat.overheat) then magazine = 1 + math.floor(stat.overheat * firerate) else magazine = math.huge -- dummy end -- 拡張マガジンがつかない場合 else magazine = stat.magazine end -- ショットガンまたは拡張マガジンがつかない if stat.ammo == 'shotgun' or stat.ammo == 'special_shotgun' or not stat.attachments.extended_mag_or_shotgun_bolt then reload = stat.time.reload.full -- 投下物資 (ヘビーアモ) elseif stat.ammo == 'special_heavy' then reload = 0.87 * stat.time.reload.full -- 投下物資 (その他) elseif aw.stringstarts(stat.ammo, 'special_') then reload = 0.9 * stat.time.reload.full -- ヘビー elseif stat.ammo == 'heavy' then local base = stat.time.reload.full if isModdedLoader then base = 0.75 * base end reload = { base, base, 0.92 * base, 0.87 * base, } -- その他 else local base = stat.time.reload.full if isModdedLoader then base = 0.75 * base end reload = { base, base, 0.95 * base, 0.9 * base, } end return TTKCalculator.new(firerate, magazine, reload, opts) end function TTKCalculator._test(name, count, opts) local stat = mw.loadData('Module:Stat/Weapon')[name] local mode = stat.mode.auto and TTKCalculator.AUTO or TTKCalculator.SINGLE local ttkc = TTKCalculator.newFromStat(stat, mode, opts) return ttkc:get(count) end return TTKCalculator