| 🌟 | 現在、 鉄壁HSは通常HSと同じダメージになります。LMG及びDMR、チャージライフル、ハンマーポイント弾を除き、すべてのダメージ値が一致していることを確認しています。 |
「モジュール:Apex/TTKCalculator」の版間の差分
ナビゲーションに移動
検索に移動
(ターボチャージャーに対応) |
(ディヴォーションLMGの可変レートに対応) |
||
| 95行目: | 95行目: | ||
return ttk | return ttk | ||
end | end | ||
function TTKCalculator:_getVariableFirerateTtkInOneMagazine(left) | |||
local ttk = 0 | |||
-- The first | |||
left = left - 1 | |||
-- To the last | |||
while left > 0 do | |||
left = left - 1 | |||
local current = self.start + (self.firerate - self.start) * math.min(1, ttk / self.duration) | |||
local time = 1 / current | |||
ttk = ttk + time | |||
end | |||
return ttk | |||
end | |||
function TTKCalculator:get(shot) | function TTKCalculator:get(shot) | ||
| 112行目: | 130行目: | ||
local shotTTK = self:_getBurstTtkInOneMagazine(shot, true) | local shotTTK = self:_getBurstTtkInOneMagazine(shot, true) | ||
ttk = ttk + self.raise + shotTTK | |||
-- 可変オート | |||
elseif self.start > 0 and self.duration > 0 then | |||
if magazine > 0 then | |||
while shot > magazine do | |||
local shotTTK = self:_getVariableFirerateTtkInOneMagazine(magazine) | |||
ttk = ttk + self.raise + shotTTK + self.reload | |||
shot = shot - magazine | |||
end | |||
end | |||
local shotTTK = self:_getVariableFirerateTtkInOneMagazine(shot) | |||
ttk = ttk + self.raise + shotTTK | ttk = ttk + self.raise + shotTTK | ||
| 138行目: | 169行目: | ||
raise = opts.raise or 0, | raise = opts.raise or 0, | ||
start = opts.start or 0, | |||
duration = opts.duration or 0, | |||
burst = opts.burst or 1, | burst = opts.burst or 1, | ||
burstDelay = opts.burstDelay or 0, | burstDelay = opts.burstDelay or 0, | ||
| 165行目: | 198行目: | ||
elseif stat.mode.auto and (mode == TTKCalculator.AUTO or not stat.mode.single) then | elseif stat.mode.auto and (mode == TTKCalculator.AUTO or not stat.mode.single) then | ||
firerate = stat.firerate.auto | firerate = stat.firerate.auto | ||
opts.raise = opts2.useTurbocharger and stat.firerate.auto_raise_turbocharger or stat.firerate.auto_raise or 0 | opts.raise = opts2.useTurbocharger and stat.firerate.auto_raise_turbocharger or stat.firerate.auto_raise or 0 | ||
opts.start = opts2.useTurbocharger and stat.firerate.auto_start_turbocharger or stat.firerate.auto_start or 0 | |||
opts.duration = opts2.useTurbocharger and stat.firerate.auto_duration_turbocharger or stat.firerate.auto_duration or 0 | |||
opts.roundsPerShot = stat.rounds_per_shot and stat.rounds_per_shot.auto or 1 | opts.roundsPerShot = stat.rounds_per_shot and stat.rounds_per_shot.auto or 1 | ||
2021年2月28日 (日) 13:36時点における版
このモジュールについての説明文ページを モジュール: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:_getVariableFirerateTtkInOneMagazine(left)
local ttk = 0
-- The first
left = left - 1
-- To the last
while left > 0 do
left = left - 1
local current = self.start + (self.firerate - self.start) * math.min(1, ttk / self.duration)
local time = 1 / current
ttk = ttk + time
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
-- 可変オート
elseif self.start > 0 and self.duration > 0 then
if magazine > 0 then
while shot > magazine do
local shotTTK = self:_getVariableFirerateTtkInOneMagazine(magazine)
ttk = ttk + self.raise + shotTTK + self.reload
shot = shot - magazine
end
end
local shotTTK = self:_getVariableFirerateTtkInOneMagazine(shot)
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:getAsLevel(shot, level)
self:setLevel(level)
return self:get(shot)
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,
start = opts.start or 0,
duration = opts.duration 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
opts2 = opts2 or {}
local firerate, magazine, reload
local opts = {}
local isModdedLoader = stat.category == 'light_machine_gun' and opts2.useModdedLoader
-- バースト
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 = opts2.useTurbocharger and stat.firerate.auto_raise_turbocharger or stat.firerate.auto_raise or 0
opts.start = opts2.useTurbocharger and stat.firerate.auto_start_turbocharger or stat.firerate.auto_start or 0
opts.duration = opts2.useTurbocharger and stat.firerate.auto_duration_turbocharger or stat.firerate.auto_duration 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