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

「モジュール:DamageTable」の版間の差分

提供:Apex Data
ナビゲーションに移動 検索に移動
(鉄壁の場合の丸め処理を修正)
(増幅バリケードを経由する場合の丸め演算が間違っていた問題の修正)
162行目: 162行目:
end
end


local function calcDamage(base, mul, part, useRound)
local function calcDamage(base, mul, part, amped, useRound)
if mul == 1 then
if mul == 1 then
return round(part * base)
return round(part * base)
elseif mul == 1.05 then
elseif mul == 1.05 and not amped then
return selectiveRound(mul * round(part * base), useRound)
return selectiveRound(mul * round(part * base), useRound)
else
else
197行目: 197行目:
local legMul = args.leg or 0.8
local legMul = args.leg or 0.8
local minCount = getShotCount(pellet * calcDamage(round(hopupsup * round(1.2 * math.max(damage, args.damagemax))), 1.05, math.max(headMul, skullpiercer), args.round), 100)
local minCount = getShotCount(pellet * calcDamage(round(hopupsup * round(1.2 * math.max(damage, args.damagemax))), 1.05, math.max(headMul, skullpiercer), true, args.round), 100)
local maxCount = math.max(
local maxCount = math.max(
getShotCount(pellet * calcDamage(damagemin, 0.85, legMul, args.round), 225),
getShotCount(pellet * calcDamage(damagemin, 0.85, legMul, false, args.round), 225),
getShotCount(pellet * damagemin, 50) + getShotCount(pellet * calcDamage(damagemin, 0.85, 1, args.round), 225))
getShotCount(pellet * damagemin, 50) + getShotCount(pellet * calcDamage(damagemin, 0.85, 1, false, args.round), 225))
local colspan, info
local colspan, info
if skullpiercer > 1 then
if skullpiercer > 1 then
274行目: 274行目:
table,
table,
skullpiercerHtml .. '(x' .. skullpiercer .. ')',
skullpiercerHtml .. '(x' .. skullpiercer .. ')',
calcDamage(baseDamage, mul, skullpiercer, args.round),
calcDamage(baseDamage, mul, skullpiercer, args.amped, args.round),
pellet, minCount, maxCount, info.level3top)
pellet, minCount, maxCount, info.level3top)
end
end
281行目: 281行目:
table,
table,
"頭 (x" .. headMul .. ")",
"頭 (x" .. headMul .. ")",
calcDamage(baseDamage, mul, headMul, args.round),
calcDamage(baseDamage, mul, headMul, args.amped, args.round),
pellet, minCount, maxCount, info.level1top)
pellet, minCount, maxCount, info.level1top)
289行目: 289行目:
table,
table,
skullpiercerHtml .. '<span class="text-rarity text-rarity-common">(x' .. skullpiercerLv1Mul .. ')</span>',
skullpiercerHtml .. '<span class="text-rarity text-rarity-common">(x' .. skullpiercerLv1Mul .. ')</span>',
calcDamage(baseDamage, mul, skullpiercerLv1Mul, args.round),
calcDamage(baseDamage, mul, skullpiercerLv1Mul, args.amped, args.round),
pellet, minCount, maxCount, info.level3)
pellet, minCount, maxCount, info.level3)
end
end
297行目: 297行目:
table,
table,
'<span class="text-rarity text-rarity-common">Lv.1 (x' .. hlmLv1Mul .. ')</span>',
'<span class="text-rarity text-rarity-common">Lv.1 (x' .. hlmLv1Mul .. ')</span>',
calcDamage(baseDamage, mul, hlmLv1Mul, args.round),
calcDamage(baseDamage, mul, hlmLv1Mul, args.amped, args.round),
pellet, minCount, maxCount, info.level2)
pellet, minCount, maxCount, info.level2)
305行目: 305行目:
table,
table,
skullpiercerHtml .. '<span class="text-rarity text-rarity-rare">(x' .. skullpiercerLv2Mul .. ')</span>',
skullpiercerHtml .. '<span class="text-rarity text-rarity-rare">(x' .. skullpiercerLv2Mul .. ')</span>',
calcDamage(baseDamage, mul, skullpiercerLv2Mul, args.round),
calcDamage(baseDamage, mul, skullpiercerLv2Mul, args.amped, args.round),
pellet, minCount, maxCount, info.level3)
pellet, minCount, maxCount, info.level3)
end
end
313行目: 313行目:
table,
table,
'<span class="text-rarity text-rarity-rare">Lv.2 (x' .. hlmLv2Mul .. ')</span>',
'<span class="text-rarity text-rarity-rare">Lv.2 (x' .. hlmLv2Mul .. ')</span>',
calcDamage(baseDamage, mul, hlmLv2Mul, args.round),
calcDamage(baseDamage, mul, hlmLv2Mul, args.amped, args.round),
pellet, minCount, maxCount, info.level2)
pellet, minCount, maxCount, info.level2)
321行目: 321行目:
table,
table,
skullpiercerHtml .. '<span class="text-rarity text-rarity-epic">(x' .. skullpiercerLv3Mul .. ')</span>',
skullpiercerHtml .. '<span class="text-rarity text-rarity-epic">(x' .. skullpiercerLv3Mul .. ')</span>',
calcDamage(baseDamage, mul, skullpiercerLv3Mul, args.round),
calcDamage(baseDamage, mul, skullpiercerLv3Mul, args.amped, args.round),
pellet, minCount, maxCount, info.level3)
pellet, minCount, maxCount, info.level3)
end
end
329行目: 329行目:
table,
table,
'<span class="text-rarity text-rarity-epic">Lv.3</span>/<span class="text-rarity text-rarity-legendary">4</span> <span class="text-rarity text-rarity-epic">(x' .. hlmLv3Mul .. ')</span>',
'<span class="text-rarity text-rarity-epic">Lv.3</span>/<span class="text-rarity text-rarity-legendary">4</span> <span class="text-rarity text-rarity-epic">(x' .. hlmLv3Mul .. ')</span>',
calcDamage(baseDamage, mul, hlmLv3Mul, args.round),
calcDamage(baseDamage, mul, hlmLv3Mul, args.amped, args.round),
pellet, minCount, maxCount, info.level2)
pellet, minCount, maxCount, info.level2)
local bodyDamage = calcDamage(baseDamage, mul, 1, args.round)
local bodyDamage = calcDamage(baseDamage, mul, 1, args.amped, args.round)
if legMul == 1 then
if legMul == 1 then
if mul == 0.85 then
if mul == 0.85 then
352行目: 352行目:
renderRow(
renderRow(
table, "脚 (x" .. legMul .. ")",
table, "脚 (x" .. legMul .. ")",
calcDamage(baseDamage, mul, legMul, args.round),
calcDamage(baseDamage, mul, legMul, args.amped, args.round),
pellet, minCount, maxCount, info.level1)
pellet, minCount, maxCount, info.level1)
end
end

2021年1月31日 (日) 23:59時点における版

このモジュールについての説明文ページを モジュール:DamageTable/doc に作成できます

local p = {}

local getArgs -- lazily initialized

local function round(num)
	return math.floor(tonumber(string.format("%.3f", num)) + 0.5)
end

local function roundover(num)
	return math.ceil(tonumber(string.format("%.3f", num)) - 0.5)
end

local function selectiveRound(num, useRound)
	useRound = useRound or false
	if useRound then
		return round(num)
	else
		return roundover(num)
	end
end

local function convertHslToRgb(hue, saturation, lightness)
	hue = math.max(0, math.min(1, hue))
	saturation = math.max(0, math.min(1, saturation))
	lightness = math.max(0, math.min(1, lightness))
	
	if saturation == 0 then
		return lightness, lightness, lightness
	else
		local function to(p, q, t)
			if t < 0 then t = t + 1 end
			if t > 1 then t = t - 1 end
			
			if t < 1/6 then
				return p + (q - p) * 6 * t
			elseif t < 3/6 then
				return q
			elseif t < 4/6 then
				return p + (q - p) * (2/3 - t) * 6
			else
				return p
			end
		end
		
		local q
		if lightness < 0.5 then
			q = lightness * (1 + saturation)
		else
			q = lightness + saturation - lightness * saturation
		end
		
		local p = 2 * lightness - q
		return to(p, q, hue + 1/3), to(p, q, hue), to(p, q, hue - 1/3)
	end
end

local function getColorAsString(hue)
	local r, g, b = convertHslToRgb(hue, 0.91, 0.89)
	return '#'
		.. string.format('%02X', 255 * r)
		.. string.format('%02X', 255 * g)
		.. string.format('%02X', 255 * b)
end

local function getShotCount(damage, health)
	return math.ceil(health / damage)
end

local function renderHeader(table, mul, colspan)
	local row = table:tag('tr')
	local cell = row:tag('th')
		:attr('colspan', colspan)
		:attr('rowspan', 2)
	if mul == 1 then
		cell:wikitext('部位')
	else
		cell:wikitext('部位 (x' .. mul .. ')')
	end
	row:tag('th')
		:attr('rowspan', 2)
		:wikitext('ダメージ')
	row:tag('th')
		:attr('colspan', 6)
		:wikitext('確殺数')
	
	row = table:tag('tr')
	row:tag('th'):wikitext('100<small> HP</small>')
	row:tag('th'):wikitext('<span class="text-rarity text-rarity-legendary">120<small> HP</small></span>')
	row:tag('th'):wikitext('<span class="text-rarity text-rarity-common">150<small> HP</small></span>')
	row:tag('th'):wikitext('<span class="text-rarity text-rarity-rare">175<small> HP</small></span>')
	row:tag('th'):wikitext('<span class="text-rarity text-rarity-epic">200<small> HP</small></span>')
	row:tag('th'):wikitext('<span class="text-rarity text-rarity-heirloom">225<small> HP</small></span>')
end

local function renderCell(row, allDamage, health, minCount, maxCount, offset)
	local shotCount = getShotCount(allDamage, health)
	local ratio = (shotCount + offset - minCount) / (maxCount - minCount)
	row:tag('td')
		:attr('align', 'right')
		:css('background-color', getColorAsString(0.85 * ratio))
		:wikitext(offset + shotCount)
end

local function renderRowForSTK(row, damage, pellet, minCount, maxCount, offset)
	offset = offset or 0
	
	local allDamage = pellet * damage
	renderCell(row, allDamage, 100, minCount, maxCount, offset)
	renderCell(row, allDamage, 120, minCount, maxCount, offset)
	renderCell(row, allDamage, 150, minCount, maxCount, offset)
	renderCell(row, allDamage, 175, minCount, maxCount, offset)
	renderCell(row, allDamage, 200, minCount, maxCount, offset)
	renderCell(row, allDamage, 225, minCount, maxCount, offset)
end

local function renderHeaderCell(row, name, rowinfo)
	for i = 1, #rowinfo do
		local cellinfo = rowinfo[i]
		local colspan = cellinfo.colspan or 1
		
		local cell = row:tag('th')
		if colspan > 1 then
			cell:attr('colspan', colspan)
		end
		if cellinfo.breaktop then
			cell:css('border-top', '0 none')
		end
		if cellinfo.breakbottom then
			cell:css('border-bottom', '0 none')
		end
		if i == #rowinfo then
			cell:wikitext(name)
		else
			cell:wikitext('&nbsp;&nbsp;')
		end
	end
end

local function renderRow(table, name, damage, pellet, minCount, maxCount, rowinfo)
	local row = table:tag('tr')
	renderHeaderCell(row, name, rowinfo)
	
	if pellet > 1 then
		row:tag('td'):attr('align', 'right'):wikitext((damage * pellet) .. ' <span style="white-space:nowrap"><small>(' .. damage .. ' × ' .. pellet .. ')</small></span>')  
	else
		row:tag('td'):attr('align', 'right'):wikitext(damage)
	end
	renderRowForSTK(row, damage, pellet, minCount, maxCount)
end

local function renderRowForGunShiled(table, damage, baseDamage, pellet, minCount, maxCount, rowinfo)
	local row = table:tag('tr')
	renderHeaderCell(row, '+ガンシールド', rowinfo)
	
	local countForGunShiled = getShotCount(pellet * baseDamage, 50)
	if pellet > 1 then
		row:tag('td'):attr('align', 'right'):wikitext((baseDamage * pellet) .. ' <span style="white-space:nowrap"><small>(' .. baseDamage .. ' × ' .. pellet .. ')</small></span>')  
	else
		row:tag('td'):attr('align', 'right'):wikitext(baseDamage)
	end
	renderRowForSTK(row, damage, pellet, minCount, maxCount, countForGunShiled)
end

local function calcDamage(base, mul, part, amped, useRound)
	if mul == 1 then
		return round(part * base)
	elseif mul == 1.05 and not amped then
		return selectiveRound(mul * round(part * base), useRound)
	else
		return round(mul * round(part * base))
	end
end

local function renderTable(args, frame)
	local hopup = args.hopup or 1
	local hopupsup
	if hopup == 1 then
		hopupsup = args.hopupsup or 1
	else
		hopupsup = hopup
	end
	
	local damage = args.damage or 20
	local damagemin = math.min(damage, args.damagemin)
	local rawDamage, baseDamage
	if args.amped then
		rawDamage = round(1.2 * damage)
	else
		rawDamage = damage
	end
	baseDamage = round(hopup * rawDamage)
	
	local pellet = args.pellet or 1
	local mul = args.mul or 1
	local skullpiercer = args.skullpiercer or 1
	local headMul = args.head or 2
	local legMul = args.leg or 0.8
	
	local minCount = getShotCount(pellet * calcDamage(round(hopupsup * round(1.2 * math.max(damage, args.damagemax))), 1.05, math.max(headMul, skullpiercer), true, args.round), 100)
	local maxCount = math.max(
		getShotCount(pellet * calcDamage(damagemin, 0.85, legMul, false, args.round), 225),
		getShotCount(pellet * damagemin, 50) + getShotCount(pellet * calcDamage(damagemin, 0.85, 1, false, args.round), 225))
	local colspan, info
	if skullpiercer > 1 then
		colspan = 3
		info = {
			level1 = {
				{ breaktop = false, breakbottom = false, colspan = 3 },
			},
			level1top = {
				{ breaktop = true, breakbottom = true, colspan = 3 },
			},
			level1gunshiled = {
				{ breaktop = false, breakbottom = true, colspan = 3 },
			},
			level2 = {
				{ breaktop = true, breakbottom = true },
				{ breaktop = true, breakbottom = false, colspan = 2 },
			},
			level2gunshiled = {
				{ breaktop = true, breakbottom = false },
				{ breaktop = false, breakbottom = false, colspan = 2 },
			},
			level3 = {
				{ breaktop = true, breakbottom = true },
				{ breaktop = false, breakbottom = true },
				{ breaktop = false, breakbottom = false },
			},
			level3top = {
				{ breaktop = false, breakbottom = true, colspan = 2 },
				{ breaktop = false, breakbottom = false },
			},
		}
	else
		colspan = 2
		info = {
			level1 = {
				{ breaktop = false, breakbottom = true, colspan = 2 },
			},
			level1gunshiled = {
				{ breaktop = false, breakbottom = true, colspan = 2 },
			},
			level2 = {
				{ breaktop = true, breakbottom = true },
				{ breaktop = false, breakbottom = false },
			},
			level2gunshiled = {
				{ breaktop = true, breakbottom = false },
				{ breaktop = false, breakbottom = false },
			},
		}
		info.level1top = info.level1
	end
	
	local skullpiercerHtml
	if frame ~= nil then
		skullpiercerHtml = frame:expandTemplate { title = 'Hopup', args = { "スカルピアサーライフリング" }} .. ' '
	else
		skullpiercerHtml = ''
	end
	
	local table = mw.html.create('table')
		:addClass('wikitable')
		:addClass('numbertable')
	if args.caption ~= nil then
		table:tag('caption')
			:wikitext(args.caption)
	end
	
	renderHeader(table, mul, colspan)
	
	if skullpiercer > 1 then
		renderRow(
			table,
			skullpiercerHtml .. '(x' .. skullpiercer .. ')',
			calcDamage(baseDamage, mul, skullpiercer, args.amped, args.round),
			pellet, minCount, maxCount, info.level3top)
	end
	
	renderRow(
		table,
		"頭 (x" .. headMul .. ")",
		calcDamage(baseDamage, mul, headMul, args.amped, args.round),
		pellet, minCount, maxCount, info.level1top)
	
	if skullpiercer > 1 then
		local skullpiercerLv1Mul = 0.2 + 0.8 * skullpiercer
		renderRow(
			table,
			skullpiercerHtml .. '<span class="text-rarity text-rarity-common">(x' .. skullpiercerLv1Mul .. ')</span>',
			calcDamage(baseDamage, mul, skullpiercerLv1Mul, args.amped, args.round),
			pellet, minCount, maxCount, info.level3)
	end
	
	local hlmLv1Mul = 0.2 + 0.8 * headMul
	renderRow(
		table,
		'<span class="text-rarity text-rarity-common">Lv.1 (x' .. hlmLv1Mul .. ')</span>',
		calcDamage(baseDamage, mul, hlmLv1Mul, args.amped, args.round),
		pellet, minCount, maxCount, info.level2)
	
	if skullpiercer > 1 then
		local skullpiercerLv2Mul = 0.4 + 0.6 * skullpiercer
		renderRow(
			table,
			skullpiercerHtml .. '<span class="text-rarity text-rarity-rare">(x' .. skullpiercerLv2Mul .. ')</span>',
			calcDamage(baseDamage, mul, skullpiercerLv2Mul, args.amped, args.round),
			pellet, minCount, maxCount, info.level3)
	end
	
	local hlmLv2Mul = 0.4 + 0.6 * headMul
	renderRow(
		table,
		'<span class="text-rarity text-rarity-rare">Lv.2 (x' .. hlmLv2Mul .. ')</span>',
		calcDamage(baseDamage, mul, hlmLv2Mul, args.amped, args.round),
		pellet, minCount, maxCount, info.level2)
	
	if skullpiercer > 1 then
		local skullpiercerLv3Mul = 0.5 + 0.5 * skullpiercer
		renderRow(
			table,
			skullpiercerHtml .. '<span class="text-rarity text-rarity-epic">(x' .. skullpiercerLv3Mul .. ')</span>',
			calcDamage(baseDamage, mul, skullpiercerLv3Mul, args.amped, args.round),
			pellet, minCount, maxCount, info.level3)
	end
	
	local hlmLv3Mul = 0.5 + 0.5 * headMul
	renderRow(
		table,
		'<span class="text-rarity text-rarity-epic">Lv.3</span>/<span class="text-rarity text-rarity-legendary">4</span> <span class="text-rarity text-rarity-epic">(x' .. hlmLv3Mul .. ')</span>',
		calcDamage(baseDamage, mul, hlmLv3Mul, args.amped, args.round),
		pellet, minCount, maxCount, info.level2)
	
	local bodyDamage = calcDamage(baseDamage, mul, 1, args.amped, args.round)
	if legMul == 1 then
		if mul == 0.85 then
			renderRow(table, "胴・脚", bodyDamage, pellet, minCount, maxCount, info.level1gunshiled)
			renderRowForGunShiled(table, bodyDamage, baseDamage, pellet, minCount, maxCount, info.level2gunshiled)
		else
			renderRow(table, "胴・脚", bodyDamage, pellet, minCount, maxCount, info.level1)
		end
	else
		if mul == 1.05 then
			renderRow(table, "胴・脚", bodyDamage, pellet, minCount, maxCount, info.level1)
		else
			if mul == 0.85 then
				renderRow(table, "胴", bodyDamage, pellet, minCount, maxCount, info.level1gunshiled)
				renderRowForGunShiled(table, bodyDamage, rawDamage, pellet, minCount, maxCount, info.level2gunshiled)
			else
				renderRow(table, "胴", bodyDamage, pellet, minCount, maxCount, info.level1)
			end
			renderRow(
				table, "脚 (x" .. legMul .. ")",
				calcDamage(baseDamage, mul, legMul, args.amped, args.round),
				pellet, minCount, maxCount, info.level1)
		end
	end
	
	return table
end

function p._main(args, frame)
	return tostring(renderTable(args, frame))
end

function p.main(frame)
	if not getArgs then
		getArgs = require('Module:Arguments').getArgs
	end
	args = getArgs(frame)
	
	-- fix arguments
	args.damage = tonumber(args.damage)
	args.damagemin = tonumber(args.damagemin)
	args.damagemax = tonumber(args.damagemax)
	args.pellet = tonumber(args.pellet)
	args.head = tonumber(args.head)
	args.leg = tonumber(args.leg)
	args.mul = tonumber(args.mul)
	args.round = args.round == 'true'
	args.amped = args.amped == 'true'
	args.skullpiercer = tonumber(args.skullpiercer)
	args.hopup = tonumber(args.hopup)
	args.hopupsup = tonumber(args.hopupsup)
	
	return p._main(args, frame)
end

return p