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

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

提供:Apex Data
ナビゲーションに移動 検索に移動
(複数のヘッドショット倍率に対応)
(スターターキットによりヘルメットが必ず装着されているため、ヘルメット非装着時のダメージの非表示に対応)
168行目: 168行目:
end
end
cell:wikitext(name)
cell:wikitext(name)
elseif cellinfo.content then
cell:wikitext(cellinfo.content)
else
else
cell:wikitext('  ')
cell:wikitext('  ')
350行目: 352行目:


local function renderTable(args)
local function renderTable(args)
local shieldinfo = require('Module:Stat/Shield')[args.shieldpreset]
local shieldinfo = args.shieldinfo or require('Module:Stat/Shield')[args.shieldpreset]
local skullpiercer = args.skullpiercer or 1
local skullpiercer = args.skullpiercer or 1
local headMul = args.head or 2
local headMul = args.head or 2
405行目: 407行目:
}
}
local hideNoHelmets = shieldinfo.helmets.level0.disabled
local colspan, info
local colspan, info
if skullpiercer > 1 then
if skullpiercer > 1 then
428行目: 431行目:
level3 = {
level3 = {
{ breaktop = true, breakbottom = true },
{ breaktop = true, breakbottom = true },
{ breaktop = false, breakbottom = true },
{ breaktop = false, breakbottom = false },
},
level3first = {
{ breaktop = true, breakbottom = true, content = '頭' },
{ breaktop = false, breakbottom = true },
{ breaktop = false, breakbottom = true },
{ breaktop = false, breakbottom = false },
{ breaktop = false, breakbottom = false },
436行目: 444行目:
},
},
}
}
info.level2first = info.level2
else
else
colspan = 2
colspan = 2
447行目: 456行目:
level2 = {
level2 = {
{ breaktop = true, breakbottom = true },
{ breaktop = true, breakbottom = true },
{ breaktop = false, breakbottom = false },
},
level2first = {
{ breaktop = true, breakbottom = true, content = '頭' },
{ breaktop = false, breakbottom = false },
{ breaktop = false, breakbottom = false },
},
},
469行目: 482行目:
renderHeader(table, args.mul, colspan, shieldinfo.shields)
renderHeader(table, args.mul, colspan, shieldinfo.shields)
if skullpiercer > 1 then
if not hideNoHelmets then
if skullpiercer > 1 then
renderRow(
table,
skullpiercerPrefix .. '(x' .. skullpiercer .. ')',
nil,
skullpiercer, weaponinfo, info.level3top)
end
renderRow(
renderRow(
table,
table,
skullpiercerPrefix .. '(x' .. skullpiercer .. ')',
"頭 (x" .. headMul .. ")",
nil,
nil,
skullpiercer, weaponinfo, info.level3top)
headMul, weaponinfo, info.level1top)
end
end
renderRow(
table,
"頭 (x" .. headMul .. ")",
nil,
headMul, weaponinfo, info.level1top)
if skullpiercer > 1 then
if skullpiercer > 1 then
489行目: 504行目:
skullpiercerPrefix .. formatter:common('(x' .. skullpiercerLv1Mul .. ')'),
skullpiercerPrefix .. formatter:common('(x' .. skullpiercerLv1Mul .. ')'),
string.format(shieldinfo.helmets.level1.text, skullpiercer),
string.format(shieldinfo.helmets.level1.text, skullpiercer),
skullpiercerLv1Mul, weaponinfo, info.level3)
skullpiercerLv1Mul, weaponinfo, hideNoHelmets and info.level3first or info.level3)
end
end
497行目: 512行目:
formatter:common('Lv.1 (x' .. hlmLv1Mul .. ')'),
formatter:common('Lv.1 (x' .. hlmLv1Mul .. ')'),
string.format(shieldinfo.helmets.level1.text, headMul),
string.format(shieldinfo.helmets.level1.text, headMul),
hlmLv1Mul, weaponinfo, info.level2)
hlmLv1Mul, weaponinfo, hideNoHelmets and info.level2first or info.level2)
if skullpiercer > 1 then
if skullpiercer > 1 then
632行目: 647行目:
args.forcegunshield = aw.getAsBoolean(args.forcegunshield, false)
args.forcegunshield = aw.getAsBoolean(args.forcegunshield, false)
args.skullpiercerrarity = args.skullpiercerrarity or 'legendary'
args.skullpiercerrarity = args.skullpiercerrarity or 'legendary'
args.shieldpreset = args.shieldpreset or 'evoshieldonly'
args.shieldpreset = args.shieldpreset or 'removelowprofile'
return tostring(renderTable(args))
return tostring(renderTable(args))

2021年5月7日 (金) 12:41時点における版

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

require('Module:Utility/mw.html Extensions')

local p = {}

local aw = require('Module:Utility/Library')
local apex = require('Module:Utility/ApexLibrary')
local iu = require('Module:Utility/Image')
local STKCalculator = require('Module:Apex/STKCalculator')
local formatter -- lazily initialized
local getArgs -- lazily initialized

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(part, health, shield, info, gunshield)
	local damages = apex.calcShotCount(info.damage, part, info.mul, health, shield, gunshield or 0, {
		ampedCover = info.amped,
		beamdamage = info.beamdamage,
		beamticks  = info.ticks,
		disruptorRounds   = info.disruptor,
		hammerpointRounds = info.hammerpoint,
		gunshieldBleedthrough = info.bleedthrough,
		passthrough = info.passthrough,
		pellets = info.pellet,
		round = info.useRound,
	})
	return #damages, damages
end

local function renderHeader(tbl, mul, colspan, shields)
	tbl:tag('tr')
		:tag('th')
			:attr('colspan', colspan)
			:attr('rowspan', 2)
			:wikitextIf(
				mul == 1,
				'部位',
				function()
					return '部位 (x' .. mul .. ')'
				end)
			:done()
		:tag('th')
			:attr('rowspan', 2)
			:wikitext('ダメージ')
			:done()
		:tag('th')
			:attr('colspan', #shields)
			:wikitext('確殺数')
	
	local row = tbl:tag('tr')
	for _, shield in ipairs(shields) do
		row:tag('th')
			:attrIf(
				shield.tooltip ~= nil,
				{ ['data-tooltip'] = shield.tooltip })
			:wikitext(shield.label)
	end
end

local function renderCell(row, part, health, shield, info, gunshield)
	local shotCount, damages = getShotCount(part, health, shield, info, gunshield)
	local ratio = (shotCount - info.minCount) / (info.maxCount - info.minCount)
	local tooltip = { aw.stringifyRepeatingArray(damages, '→') }
	if info.ttkCalculator then
		local template = '<tr><th>%s&nbsp;</th><td class="cell-type-number" style="font-weight:bold">%d</td><td>&thinsp;ミリ秒</td></tr>'
		local ttkc = info.ttkCalculator
		local ttk0 = aw.round(1000 * ttkc:getAsLevel(shotCount, 0))
		local ttk1 = aw.round(1000 * ttkc:getAsLevel(shotCount, 1))
		local ttk2 = aw.round(1000 * ttkc:getAsLevel(shotCount, 2))
		local ttk3 = aw.round(1000 * ttkc:getAsLevel(shotCount, 3))
		
		if ttk2 ~= ttk3 then
			table.insert(tooltip, '<br><br>キルタイム:<table class="condensedtable listtable">')
			if ttk0 == ttk1 then
				table.insert(tooltip, string.format(template, 'なし・Lv.1', ttk0))
				table.insert(tooltip, string.format(template, 'Lv.2', ttk2))
			else
				table.insert(tooltip, string.format(template, 'なし', ttk0))
				table.insert(tooltip, string.format(template, 'Lv.1', ttk1))
				table.insert(tooltip, string.format(template, 'Lv.2', ttk2))
			end
			table.insert(tooltip, string.format(template, 'Lv.3', ttk3))
			table.insert(tooltip, '</table>')
		elseif ttk1 ~= ttk2 then
			table.insert(tooltip, '<br><br>キルタイム:<table class="condensedtable listtable">')
			if ttk0 == ttk1 then
				table.insert(tooltip, string.format(template, 'なし・Lv.1', ttk0))
			else
				table.insert(tooltip, string.format(template, 'なし', ttk0))
				table.insert(tooltip, string.format(template, 'Lv.1', ttk1))
			end
			table.insert(tooltip, string.format(template, 'Lv.2, 3', ttk2))
			table.insert(tooltip, '</table>')
		elseif ttk0 ~= ttk1 then
			table.insert(tooltip, '<br><br>キルタイム:<table class="condensedtable listtable">')
			table.insert(tooltip, string.format(template, 'なし', ttk0))
			table.insert(tooltip, string.format(template, 'Lv.1, 2, 3', ttk1))
			table.insert(tooltip, '</table>')
		else
			table.insert(tooltip, string.format('<br>キルタイム: <span class="text-style-number" style="font-weight:bold">%d</span>&thinsp;ミリ秒', ttk0))
		end
	end
	
	row:tag('td')
		:attr('data-tooltip', table.concat(tooltip))
		:css('background-color', getColorAsString(0.85 * ratio))
		:wikitext(shotCount)
end

local function renderHeaderCell(row, name, tooltip, 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
			if tooltip ~= nil then
				cell:attr('data-tooltip', tooltip)
			end
			cell:wikitext(name)
		elseif cellinfo.content then
			cell:wikitext(cellinfo.content)
		else
			cell:wikitext('&nbsp;&nbsp;')
		end
	end
end

local function renderRow(tbl, name, tooltip, part, weaponinfo, rowinfo, gunshield)
	local row = tbl:tag('tr')
	renderHeaderCell(row, name, tooltip, rowinfo)
	
	local opts = {
		ampedCover            = weaponinfo.amped,
		disruptorRounds       = weaponinfo.disruptor,
		hammerpointRounds     = weaponinfo.hammerpoint,
		gunshieldBleedthrough = weaponinfo.bleedthrough,
		passthrough           = weaponinfo.passthrough,
		round                 = weaponinfo.useRound,
	}
	
	local damage
	if gunshield then
		damage = apex.calcDamage(weaponinfo.damage, 1, 1, {
			ampedCover  = weaponinfo.amped,
			passthrough = weaponinfo.passthrough,
			round       = weaponinfo.useRound,
		})
	else
		damage = apex.calcDamage(weaponinfo.damage, part, weaponinfo.mul, opts)
	end
	
	local text
	if not gunshield and weaponinfo.disruptor > 1 then
		local defaultDamage = apex.calcDamage(weaponinfo.damage, part, weaponinfo.mul, {
			ampedCover  = weaponinfo.amped,
			passthrough = weaponinfo.passthrough,
			round       = weaponinfo.useRound,
		})
		if weaponinfo.pellet > 1 then
			text = string.format(
				'%s <small><span style="white-space:nowrap">(%s&thinsp;×&thinsp;%s)</span> → %s </small>',
				damage * weaponinfo.pellet,
				damage,
				weaponinfo.pellet,
				defaultDamage * weaponinfo.pellet)
		else
			text = string.format(
				'%s<small> → %s</small>',
				damage,
				defaultDamage)
		end
	elseif not gunshield and weaponinfo.hammerpoint > 1 then
		local defaultDamage = apex.calcDamage(weaponinfo.damage, part, weaponinfo.mul, {
			ampedCover  = weaponinfo.amped,
			passthrough = weaponinfo.passthrough,
			round       = weaponinfo.useRound,
		})
		if weaponinfo.pellet > 1 then
			text = string.format(
				'<small>%s → </small>%s <small><span style="white-space:nowrap">(%s&thinsp;×&thinsp;%s)</span></small>',
				defaultDamage * weaponinfo.pellet,
				damage * weaponinfo.pellet,
				damage,
				weaponinfo.pellet)
		else
			text = string.format(
				'<small>%s → </small>%s',
				defaultDamage,
				damage)
		end
	elseif weaponinfo.pellet > 1 then
		text = string.format(
			'%s <small><span style="white-space:nowrap">(%s&thinsp;×&thinsp;%s)</span></small>',
			damage * weaponinfo.pellet,
			damage,
			weaponinfo.pellet)
	elseif weaponinfo.ticks > 1 then
		local beamdamage = apex.calcDamageFromPartAndPassive(weaponinfo.beamdamage, part, weaponinfo.mul, opts)
		local alldamage = beamdamage * weaponinfo.ticks + damage
		text = string.format(
			'%s<small> <span style="white-space:nowrap">(%s&thinsp;×&thinsp;%s&thinsp;+&thinsp;%s)</span></small>',
			alldamage,
			beamdamage,
			weaponinfo.ticks,
			damage)
	else
		text = tostring(damage)
	end
	row:tag('td'):wikitext(text)
	
	for _, shield in ipairs(weaponinfo.shields) do
		renderCell(row, part, shield.health, shield.shield, weaponinfo, gunshield)
	end
end

local function getTTKCalculator(args)
	if args.rps <= 0 then
		return nil
	end
	
	-- 射撃レート
	local firerate
	if args.rpsratio1 > 1 then
		if args.rpsratio2 > args.rpsratio1 then
			if args.rpsratio3 > args.rpsratio2 then
				firerate = {
					args.rps,
					args.rpsratio1 * args.rps,
					args.rpsratio2 * args.rps,
					args.rpsratio3 * args.rps,
				}
			else
				local rps2 = args.rpsratio2 * args.rps
				firerate = {
					args.rps,
					args.rpsratio1 * args.rps,
					rps2,
					rps2,
				}
			end
		else
			local rps1 = args.rpsratio1 * args.rps
			firerate = {
				args.rps,
				rps1,
				rps1,
				rps1,
			}
		end
	else
		firerate = args.rps
	end
	
	-- 装填数
	local magazine
	if args.extmag0 > 0 then
		if args.extmag1 > args.extmag0 then
			if args.extmag2 > args.extmag1 then
				if args.extmag3 > args.extmag2 then
					magazine = { args.extmag0, args.extmag1, args.extmag2, args.extmag3 }
				else
					magazine = { args.extmag0, args.extmag1, args.extmag2, args.extmag2 }
				end
			else
				magazine = { args.extmag0, args.extmag1, args.extmag1, args.extmag1 }
			end
		else
			magazine = args.extmag0
		end
	else
		magazine = math.huge
	end
	
	-- リロード時間
	local reload
	if args.reloadratio2 > 0 and args.reloadratio2 < 1 then
		if args.reloadratio3 > 0 and args.reloadratio3 < args.reloadratio2 then
			reload = {
				args.reload,
				args.reload,
				args.reloadratio2 * args.reload,
				args.reloadratio3 * args.reload
			}
		else
			local reload2 = args.reloadratio2 * args.reload
			reload = {
				args.reload,
				args.reload,
				reload2,
				reload2
			}
		end
	else
		reload = args.reload
	end
	
	local ttkc = require('Module:Apex/TTKCalculator').new(firerate, magazine, reload, {
		raise = args.raise,
	})
	return ttkc
end

local function renderTable(args)
	local shieldinfo = args.shieldinfo or require('Module:Stat/Shield')[args.shieldpreset]
	local skullpiercer = args.skullpiercer or 1
	local headMul = args.head or 2
	
	local minCount, _ = getShotCount(
		args.headmax or headMul,
		100,
		0,
		{
			damage = math.max(args.damage, args.damagemax),
			beamdamage = math.max(args.beamdamage, args.beamdamagemax),
			ticks = args.ticks,
			mul = math.max(args.mul, args.mulmax),
			pellet = math.max(args.pellet, args.pelletmax),
			amped = true,
			disruptor = math.max(args.disruptor, args.disruptorsup),
			hammerpoint = math.max(args.hammerpoint, args.hammerpointsup),
			passthrough = 1,
		})
	local damagemin = math.min(args.damage, args.damagemin)
	local mininfo = {
		damage = damagemin,
		beamdamage = math.min(args.beamdamage, args.beamdamagemin),
		ticks = args.ticks,
		mul = math.min(args.mul, args.mulmin),
		pellet = math.min(args.pellet, args.pelletmin),
		amped = false,
		disruptor = 1,
		hammerpoint = 1,
		passthrough = math.min(args.passthrough, args.passthroughsup),
		bleedthrough = shieldinfo.gunshieldBleedthrough,
	}
	local maxshield = shieldinfo.shields[#shieldinfo.shields]
	local legCount, _ = getShotCount(math.min(args.leg, args.legmin), maxshield.health, maxshield.shield, mininfo)
	local bodyWithGunSheild, _ = getShotCount(1, maxshield.health, maxshield.shield, mininfo, shieldinfo.gunshield)
	local maxCount = math.max(legCount, bodyWithGunSheild)
	local ttkCalculator = getTTKCalculator(args)
	local weaponinfo = {
		damage = args.damage,
		beamdamage = args.beamdamage,
		ticks = args.ticks,
		mul = args.mul,
		pellet = args.pellet,
		amped = args.amped,
		disruptor = args.disruptor,
		hammerpoint = args.hammerpoint,
		passthrough = args.passthrough,
		bleedthrough = shieldinfo.gunshieldBleedthrough,
		useRound = args.round,
		minCount = minCount,
		maxCount = maxCount,
		shields = shieldinfo.shields,
		ttkCalculator = ttkCalculator,
	}
	
	local hideNoHelmets = shieldinfo.helmets.level0.disabled
	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 },
			},
			level3first = {
				{ breaktop = true, breakbottom = true, content = '頭' },
				{ breaktop = false, breakbottom = true },
				{ breaktop = false, breakbottom = false },
			},
			level3top = {
				{ breaktop = false, breakbottom = true, colspan = 2 },
				{ breaktop = false, breakbottom = false },
			},
		}
		info.level2first = info.level2
	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 },
			},
			level2first = {
				{ breaktop = true, breakbottom = true, content = '頭' },
				{ breaktop = false, breakbottom = false },
			},
			level2gunshiled = {
				{ breaktop = true, breakbottom = false },
				{ breaktop = false, breakbottom = false },
			},
		}
		info.level1top = info.level1
	end
	
	local skullpiercerPrefix = iu.hopup('skullpiercer_rifling', { rarity = args.skullpiercerrarity }) .. ' '
	local table = mw.html.create('table')
		:addClass('wikitable')
		:addClass('numbertable')
		:addClass('damagetable')
	if args.caption ~= nil then
		table:tag('caption')
			:wikitext(args.caption)
	end
	
	renderHeader(table, args.mul, colspan, shieldinfo.shields)
	
	if not hideNoHelmets then
		if skullpiercer > 1 then
			renderRow(
				table,
				skullpiercerPrefix .. '(x' .. skullpiercer .. ')',
				nil,
				skullpiercer, weaponinfo, info.level3top)
		end
		
		renderRow(
			table,
			"頭 (x" .. headMul .. ")",
			nil,
			headMul, weaponinfo, info.level1top)
	end
	
	if skullpiercer > 1 then
		local skullpiercerLv1Mul = shieldinfo.helmets.level1.func(skullpiercer)
		renderRow(
			table,
			skullpiercerPrefix .. formatter:common('(x' .. skullpiercerLv1Mul .. ')'),
			string.format(shieldinfo.helmets.level1.text, skullpiercer),
			skullpiercerLv1Mul, weaponinfo, hideNoHelmets and info.level3first or info.level3)
	end
	
	local hlmLv1Mul = shieldinfo.helmets.level1.func(headMul)
	renderRow(
		table,
		formatter:common('Lv.1 (x' .. hlmLv1Mul .. ')'),
		string.format(shieldinfo.helmets.level1.text, headMul),
		hlmLv1Mul, weaponinfo, hideNoHelmets and info.level2first or info.level2)
	
	if skullpiercer > 1 then
		local skullpiercerLv2Mul = shieldinfo.helmets.level2.func(skullpiercer)
		renderRow(
			table,
			skullpiercerPrefix .. formatter:rare('(x' .. skullpiercerLv2Mul .. ')'),
			string.format(shieldinfo.helmets.level2.text, skullpiercer),
			skullpiercerLv2Mul, weaponinfo, info.level3)
	end
	
	local hlmLv2Mul = shieldinfo.helmets.level2.func(headMul)
	renderRow(
		table,
		formatter:rare('Lv.2 (x' .. hlmLv2Mul .. ')'),
		string.format(shieldinfo.helmets.level2.text, headMul),
		hlmLv2Mul, weaponinfo, info.level2)
	
	if skullpiercer > 1 then
		local skullpiercerLv3Mul = shieldinfo.helmets.level3.func(skullpiercer)
		renderRow(
			table,
			skullpiercerPrefix .. formatter:epic('(x' .. skullpiercerLv3Mul .. ')'),
			string.format(shieldinfo.helmets.level3.text, skullpiercer),
			skullpiercerLv3Mul, weaponinfo, info.level3)
	end
	
	local hlmLv3Mul = shieldinfo.helmets.level3.func(headMul)
	renderRow(
		table,
		formatter:epic('Lv.3') .. '/' .. formatter:legendary('4') .. ' ' .. formatter:epic('(x' .. hlmLv3Mul .. ')'),
		string.format(shieldinfo.helmets.level3.text, headMul),
		hlmLv3Mul, weaponinfo, info.level2)
	
	if args.leg == 1 then
		if args.mul < 1 or args.forcegunshield then
			renderRow(table, "胴・脚", nil, 1, weaponinfo, info.level1gunshiled)
			renderRow(
				table,
				'+ガンシールド',
				shieldinfo.gunshieldLabel,
				1, weaponinfo, info.level2gunshiled, shieldinfo.gunshield)
		else
			renderRow(table, "胴・脚", nil, 1, weaponinfo, info.level1)
		end
	else
		if shieldinfo.legAsBodyOnLowProfile and args.mul == 1.05 then
			renderRow(table, "胴・脚", nil, 1, weaponinfo, info.level1)
		else
			if args.mul < 1 or args.forcegunshield then
				renderRow(table, "胴", nil, 1, weaponinfo, info.level1gunshiled)
				renderRow(
					table,
					'+ガンシールド',
					shieldinfo.gunshieldLabel,
					1, weaponinfo, info.level2gunshiled, shieldinfo.gunshield)
			else
				renderRow(table, "胴", nil, 1, weaponinfo, info.level1)
			end
			renderRow(table, "脚 (x" .. args.leg .. ")", nil, args.leg, weaponinfo, info.level1)
		end
	end
	
	return table
end

function p._main(args, frame)
	formatter = require('Module:Utility/Formatter').new(frame)
	
	-- init value
	local initValues = {
		damage = 20,
		damagemin = 1000,
		damagemax = 0,
		beamdamage = 0,
		beamdamagemin = 0,
		beamdamagemax = 0,
		ticks = 0,
		pellet = 1,
		pelletmin = 0,
		pelletmax = 0,
		head = 2,
		headmax = -1,
		leg = 0.8,
		legmin = 0,
		mul = 1,
		mulmin = 0.85,
		mulmax = 1.05,
		skullpiercer = 1,
		disruptor = 1,
		disruptorsup = 1,
		hammerpoint = 1,
		hammerpointsup = 1,
		passthrough = 1,
		passthroughsup = 1,
		rps = 0,
		rpsratio1 = 0,
		rpsratio2 = 0,
		rpsratio3 = 0,
		raise = 0,
		reload = 0,
		reloadratio2 = 0.95,
		reloadratio3 = 0.9,
		extmag0 = 0,
		extmag1 = 0,
		extmag2 = 0,
		extmag3 = 0,
	}
	
	-- fix arguments
	for key, value in pairs(initValues) do
		args[key] = aw.getAsNumber(args[key], value)
	end
	if args.pelletmin == 0 then
		args.pelletmin = args.pellet
	end
	if args.pelletmax == 0 then
		args.pelletmax = args.pellet
	end
	if args.headmax == -1 then
		args.headmax = math.max(args.head, args.skullpiercer)
	end
	if args.legmin == 0 then
		args.legmin = args.leg
	end
	if args.beamdamagemin == 0 then
		args.beamdamagemin = args.beamdamage
	end
	if args.beamdamagemax == 0 then
		args.beamdamagemax = args.beamdamage
	end
	args.round = aw.getAsBoolean(args.round, false)
	args.amped = aw.getAsBoolean(args.amped, false)
	args.forcegunshield = aw.getAsBoolean(args.forcegunshield, false)
	args.skullpiercerrarity = args.skullpiercerrarity or 'legendary'
	args.shieldpreset = args.shieldpreset or 'removelowprofile'
	
	return tostring(renderTable(args))
end

function p.main(frame)
	if not getArgs then
		getArgs = require('Module:Arguments').getArgs
	end
	args = getArgs(frame)
	
	return p._main(args, frame)
end

return p