| 🌟 | 現在、 鉄壁HSは通常HSと同じダメージになります。LMG及びDMR、チャージライフル、ハンマーポイント弾を除き、すべてのダメージ値が一致していることを確認しています。 |
モジュール:Apex/STKCalculator
ナビゲーションに移動
検索に移動
このモジュールについての説明文ページを モジュール:Apex/STKCalculator/doc に作成できます
local STKCalculator = {}
local aw = require('Module:Utility/Library')
local apex = require('Module:Utility/ApexLibrary')
local STKCalculator = {}
function STKCalculator:reset()
self.damages = {}
self.damageStack = 0
self.currentPellets = self.pellets
self.patternIndex = 1
end
function STKCalculator:_getPartMultiplier(forcePart)
local part
if forcePart then
part = forcePart
elseif self.patternIndex <= #self.pattern.first then
part = self.pattern.first[self.patternIndex]
else
part = self.pattern.loop[self.patternIndex - #self.pattern.first]
end
local mul
if part == apex.BODY then
mul = self.bodyshot
elseif part == apex.LEGS then
mul = self.legsshot
elseif part == apex.SKY then
mul = self.skyshot
else
mul = apex.calcHeadshotMultiplier(self.headshot, part)
end
return mul
end
function STKCalculator:_nextPart()
if self.patternIndex == #self.pattern.first + #self.pattern.loop then
self.patternIndex = 1 + #self.pattern.first
else
self.patternIndex = self.patternIndex + 1
end
end
function STKCalculator:_checkPellets()
if self.currentPellets <= 0 then
self.currentPellets = self.pellets
table.insert(self.damages, self.damageStack)
self.damageStack = 0
end
end
function STKCalculator:_calcShotToKill(base, passive, points, cond, isLast, forcePart)
local partmul = self:_getPartMultiplier(forcePart)
local damage = apex.calcDamageFromPartAndPassive(base, partmul, passive, self.opts)
local hasBeam = self.beamdamage > 0 and self.beamticks > 0
local beamdamage
if hasBeam then
beamdamage = apex.calcDamageFromPartAndPassive(self.beamdamage, partmul, passive, self.opts)
else
beamdamage = 0
end
repeat
if hasBeam then
for t = 1, self.beamticks do
if not cond(points, damage) then
break
end
points = points - beamdamage
self.damageStack = self.damageStack + beamdamage
end
end
if not cond(points, damage) then
break
end
points = points - damage
self.damageStack = self.damageStack + damage
self.currentPellets = self.currentPellets - 1
self:_checkPellets()
if not forcePart then
self:_nextPart()
partmul = self:_getPartMultiplier(forcePart)
damage = apex.calcDamageFromPartAndPassive(base, partmul, passive, self.opts)
if hasBeam then
beamdamage = apex.calcDamageFromPartAndPassive(self.beamdamage, partmul, passive, self.opts)
end
end
until not cond(points, damage)
if isLast then
if self.damageStack > 0 then
self.currentPellets = self.pellets
table.insert(self.damages, self.damageStack)
self.damageStack = 0
end
end
return points
end
function STKCalculator:calcShotToKill(health, shield, gunshield, passive)
legend = legend or 1
-- ガンシールド
if gunshield > 0 then
local cond = function(points, _)
return points > 0
end
self:_calcShotToKill(self.damage, 1, gunshield, cond, true, apex.BODY)
end
-- ハンマーポイント弾
if self.hammerpointRounds > 1 then
-- シールド
local cond1 = function(points, damage)
return points >= damage
end
shield = self:_calcShotToKill(self.damage, passive, shield, cond1)
-- シールドと体力の混合
if shield > 0 then
local mergedDamage
if shield < self.damage then
mergedDamage = apex.calcDamageFromPartAndPassive(shield + math.floor(self.hammerpointRounds * (self.damage - shield)), self:_getPartMultiplier(), passive, self.opts)
else
mergedDamage = apex.calcDamageFromPartAndPassive(self.damage, self:_getPartMultiplier(), passive, self.opts)
end
health = health - (mergedDamage - shield)
self.damageStack = self.damageStack + mergedDamage
self.currentPellets = self.currentPellets - 1
self:_checkPellets()
self:_nextPart()
end
-- 体力
local cond2 = function(points, damage)
return points > 0
end
health = self:_calcShotToKill(math.floor(self.hammerpointRounds * self.damage), passive, health, cond2, true)
-- ボディーシールド
else
local cond = function(points, _)
return points > 0
end
self:_calcShotToKill(self.damage, passive, health + shield, cond, true)
end
end
function STKCalculator:getTable()
return self.damages
end
function STKCalculator:get()
return #self.damages
end
function STKCalculator:setPattern(pattern)
if pattern then
pattern.first = pattern.first or {}
pattern.loop = pattern.loop or {}
self.pattern = pattern
else
self.pattern = { first = {}, loop = { apex.BODY }}
end
end
function STKCalculator.new(damage, opts)
opts = opts or {}
if opts.pattern then
opts.pattern.first = opts.pattern.first or {}
opts.pattern.loop = opts.pattern.loop or {}
else
opts.pattern = { first = {}, loop = { apex.BODY }}
end
-- 増幅バリケードが有効
if opts.ampedCover then
damage = aw.round(1.2 * damage)
end
local obj = setmetatable({
damage = damage,
bodyshot = opts.bodyshot or 1,
headshot = opts.headshot or 2,
legsshot = opts.legsshot or 0.75,
skyshot = opts.skyshot or 0,
pattern = opts.pattern,
pellets = opts.pellets or 1,
beamdamage = opts.beamdamage or 0,
beamticks = opts.beamticks or 0,
hammerpointRounds = opts.hammerpointRounds or 0,
opts = {
ampedCover = opts.ampedCover or false,
round = opts.round or false,
},
}, { __index = STKCalculator })
obj:reset()
return obj
end
function STKCalculator.newFromStat(stat, opts)
local damagestat
if opts.useAnvilReceiver then
damagestat = stat.damage.anvil_receiver or stat.damage
else
damagestat = stat.damage
end
local damage
if opts.useAmpedMode then
damage = damegestat.amped or damegestat.base
else
damage = damegestat.base
end
local beamdamage, beamticks
if stat.beam then
beamdamage = stat.beam.base
if opts.ticks then
beamticks = math.min(opts.ticks, stat.beam.ticks)
else
beamticks = stat.beam.ticks
end
else
beamdamage = 0
beamticks = 0
end
return STKCalculator.new(damage, {
bodyshot = opts.bodyshot,
headshot = damagestat.headshot,
legsshot = damagestat.legshot,
skyshot = opts.skyshot,
pattern = opts.pattern,
pellets = opts.pellets,
beamdamage = beamdamage,
beamticks = beamticks,
hammerpoint_rounds = opts.useHammerpointRounds and damegestat.hammerpoint_rounds or 0,
})
end
function apex.calcShotCount(base, part, passive, health, shield, gunshield, opts)
opts = opts or {}
opts.ampedCover = opts.ampedCover or false
opts.bodyshot = part or opts.bodyshot or 1
opts.hammerpointRounds = opts.hammerpointRounds or 0
opts.pellets = opts.pellets or 1
opts.round = opts.round or false
local stkc = STKCalculator.new(base, opts)
stkc:calcShotToKill(health, shield, gunshield, passive)
return stkc:getTable()
end
return STKCalculator