🌟現在、鉄壁 鉄壁ヘッドショットには対応済みです。
鉄壁HSは通常HSと同じダメージになります。LMG及びDMR、チャージライフル、ハンマーポイント弾を除き、すべてのダメージ値が一致していることを確認しています。

モジュール:Apex/STKCalculator

提供:Apex Data
2021年2月23日 (火) 15:44時点におけるMntone (トーク | 投稿記録)による版 (ページの作成:「local STKCalculator = {} local aw = require('Module:Utility/Library') local apex = require('Module:Utility/ApexLibrary') local STKCalculator = {} function STKCalcula…」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

このモジュールについての説明文ページを モジュール: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 damage = apex.calcDamageFromPartAndPassive(base, self:_getPartMultiplier(forcePart), passive, self.opts)
	while cond(points, damage) do
		points              = points - damage
		self.damageStack    = self.damageStack + damage
		self.currentPellets = self.currentPellets - 1
		
		self:_checkPellets()
		if not forcePart then
			self:_nextPart()
			damage = apex.calcDamageFromPartAndPassive(base, self:_getPartMultiplier(), passive, self.opts)
		end
	end
	
	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 > 0 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,
		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
	
	return STKCalculator.new(damage, {
		bodyshot = opts.bodyshot,
		headshot = damagestat.headshot,
		legsshot = damagestat.legshot,
		skyshot  = opts.skyshot,
		pattern  = opts.pattern,
		pellets  = opts.pellets,
		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