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

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

提供:Apex Data
ナビゲーションに移動 検索に移動
(DPS表生成の不具合を修正)
(intable変数を定義していない不具合の修正)
294行目: 294行目:
end
end
cell:tag('table')
local intable = cell:tag('table')
:addClass('intable')
:addClass('intable')
:addClass('numbertable')
:addClass('numbertable')

2021年2月3日 (水) 18:50時点における版

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

local p = {}

local aw = require('Module:Utility/Library')
local formatter -- lazily initialized
local getArgs -- lazily initialized

local function renderRow(table, name, item)
	table:tag('tr')
		:tag('th')
			:wikitext(name)
			:done()
		:tag('td')
			:wikitext(item)
end

local function createCellInRow(tbl, name)
	return tbl:tag('tr')
		:tag('th')
			:wikitext(name)
			:done()
		:tag('td')
end

local CategoryDict = {
	assault_rifle = "アサルトライフル",
	sub_machine_gun = "サブマシンガン",
	light_machine_gun = "ライトマシンガン",
	sniper = "スナイパーライフル",
	shotgun = "ショットガン",
	pistol = "ピストル",
}
local function renderCategory(table, name, stat)
	local category = CategoryDict[stat]
	renderRow(table, name, '[[武器#' .. category .. '|' .. category .. ']]')
end

local AmmoDict = {
	light = "ライト",
	heavy = "ヘビー",
	energy = "エネルギー",
	sniper = "スナイパー",
	shotgun = "ショットガン",
	special_light = "専用ライト",
	special_heavy = "専用ヘビー",
	special_energy = "専用エネルギー",
	special_sniper = "専用スナイパー",
	special_shotgun = "専用ショットガン",
}
local function renderAmmo(table, name, stat)
	local ammo = AmmoDict[stat]
	local page = '弾による武器一覧#' .. ammo .. 'アモ'
	local item = formatter:ammo(ammo, 28, page)
		.. ' [[' .. page .. '|' .. ammo .. 'アモ]]'
	renderRow(table, name, item)
end

local function convertDecimalToFractional(num)
	local integer = math.floor(num)
	local decimal = tonumber(string.format("%.3f", num - integer))
	local decimalText
	if decimal == 0.125 then
		decimalText = '⅛'
	elseif decimal == 0.2 then
		decimalText = '⅕'
	elseif decimal == 0.25 then
		decimalText = '¼'
	elseif decimal == 1/3 then
		decimalText = '⅓'
	elseif decimal == 0.375 then
		decimalText = '⅜'
	elseif decimal == 0.4 then
		decimalText = '⅖'
	elseif decimal == 0.5 then
		decimalText = '½'
	elseif decimal == 0.6 then
		decimalText = '⅗'
	elseif decimal == 0.625 then
		decimalText = '⅝'
	elseif decimal == 2/3 then
		decimalText = '⅔'
	elseif decimal == 0.75 then
		decimalText = '¾'
	elseif decimal == 0.8 then
		decimalText = '⅘'
	elseif decimal == 0.875 then
		decimalText = '⅞'
	else
		decimalText = ''
	end
	
	if decimalText == '' then
		return tostring(num)
	elseif integer == 0 then
		return decimalText
	else
		return tostring(integer) .. decimalText
	end
end

local function renderMode(table, name, stat)
	local mode = nil
	if stat.burst > 1 then
		mode = stat.burst .. '点バースト'
	end
	
	if stat.auto then
		if mode == nil then
			mode = 'オート'
		else
			mode = mode .. '・オート'
		end
	end
	
	if stat.single then
		if mode == nil then
			mode = '単発'
		else
			mode = mode .. '・単発'
		end
	end
	
	renderRow(table, name, mode)
end

local function renderDamage(tbl, name, stat, ammo, pellet)
	local base = stat.base
	local typename = type(base)
	if pellet ~= nil then
		local item = tostring(base) .. ' × ' .. tostring(pellet) .. '片'
		renderRow(tbl, name, item)
	elseif typename == 'table' then
		renderRow(tbl, name, table.concat(base, ' - '))
	elseif typename == 'number' then
		local damageText
		if stat.anvil_receiver ~= nil then
			damageText = base .. ' - '
			.. formatter:hopup('アンビルレシーバー', nil, 'ホップアップによる武器一覧#アンビルレシーバー')
			.. ' ' .. formatter:legendary(stat.anvil_receiver.base)
		else
			damageText = tostring(base)
		end
		renderRow(tbl, name, damageText)
	else
		return
	end
	
	local head = convertDecimalToFractional(stat.headshot)
	local hlm1 = convertDecimalToFractional(0.2 + 0.8 * stat.headshot)
	local hlm2 = convertDecimalToFractional(0.4 + 0.6 * stat.headshot)
	local hlm3 = convertDecimalToFractional(0.5 + 0.5 * stat.headshot)
	local leg = convertDecimalToFractional(stat.legshot)
	local sprm = stat.skullpiercer_rifling or 1
	
	local ul = mw.html.create('ul')
	if sprm > 1 then
		local spr0 = convertDecimalToFractional(sprm)
		local spr1 = convertDecimalToFractional(0.2 + 0.8 * sprm)
		local spr2 = convertDecimalToFractional(0.4 + 0.6 * sprm)
		local spr3 = convertDecimalToFractional(0.5 + 0.5 * sprm)
		
		local intable = ul:tag('li')
			:tag('table')
				:addClass('condensedtable')
		local row1 = intable:tag('tr')
		row1:tag('td'):wikitext('頭')
		row1:tag('td'):wikitext(head)
 		row1:tag('td'):wikitext(' - ')
		row1:tag('td'):wikitext(formatter:common(hlm1))
 		row1:tag('td'):wikitext(' - ')
		row1:tag('td'):wikitext(formatter:rare(hlm2))
 		row1:tag('td'):wikitext(' - ')
		row1:tag('td'):wikitext(formatter:epic(hlm3))
		row1:tag('td'):wikitext('倍')
		
		local row2 = intable:tag('tr')
		row2:tag('td'):wikitext(formatter:hopup('スカルピアサーライフリング', nil, 'ホップアップによる武器一覧#スカルピアサーライフリング') .. ' ')
		row2:tag('td'):wikitext(spr0)
 		row2:tag('td'):wikitext(' - ')
		row2:tag('td'):wikitext(formatter:common(spr1))
 		row2:tag('td'):wikitext(' - ')
		row2:tag('td'):wikitext(formatter:rare(spr2))
 		row2:tag('td'):wikitext(' - ')
		row2:tag('td'):wikitext(formatter:epic(spr3))
		row2:tag('td'):wikitext('倍')
	else
		local headText = '頭 ' .. formatter:format(head, hlm1, hlm2, hlm3, '倍', ' - ')
		ul:tag('li'):wikitext(headText)
	end
	
	local legText
	if stat.anvil_receiver ~= nil then
		local anvilleg = convertDecimalToFractional(stat.anvil_receiver.legshot)
		legText = '脚 ' .. leg .. ' - '
			.. formatter:hopup('アンビルレシーバー', nil, 'ホップアップによる武器一覧#アンビルレシーバー')
			.. ' ' .. formatter:legendary(anvilleg) .. '倍'
	else
		legText = '脚 ' .. leg .. '倍'
	end
	ul:tag('li'):wikitext(legText)
	tbl:tag('tr')
		:tag('td')
			:attr('colspan', 2)
			:node(ul)
end

local function renderFirerate(tbl, name, firerate, mode)
	if firerate == nil then
		return
	end
	
	local cell = createCellInRow(tbl, name)
	if mode.auto then
		if mode.single then
			if firerate.anvil_receiver then
				local ul = tbl:tag('tr'):tag('td'):attr('colspan', 2):tag('ul')
				ul:tag('li'):wikitext('オート: ' .. firerate.auto .. ' rps <small>(' .. (60 * firerate.auto) .. ' rpm)</small>')
				
				if firerate.auto ~= firerate.single then
					ul:tag('li'):wikitext('単発: ' .. firerate.single .. ' rps <small>(' .. (60 * firerate.single) .. ' rpm)</small>')
				end
				
				if firerate.anvil_receiver then
					ul:tag('li')
						:wikitext(
							formatter:hopup('アンビルレシーバー', nil, 'ホップアップによる武器一覧#アンビルレシーバー')
							.. ': ' .. firerate.anvil_receiver .. ' rps <small>(' .. (60 * firerate.anvil_receiver) .. ' rpm)</small>')
				end
			elseif firerate.auto ~= firerate.single then
				tbl:tag('tr')
					:tag('td')
						:attr('colspan', 2)
						:tag('ul')
							:tag('li')
								:wikitext('オート: ' .. firerate.auto .. ' rps <small>(' .. (60 * firerate.auto) .. ' rpm)</small>')
								:done()
							:tag('li')
								:wikitext('単発: ' .. firerate.single .. ' rps <small>(' .. (60 * firerate.single) .. ' rpm)</small>')
			else
				local rps = firerate.auto
				cell:wikitext(rps .. ' rps <small>(' .. (60 * rps) .. ' rpm)</small>')
			end
		else
			local rps = firerate.auto
			cell:wikitext(rps .. ' rps <small>(' .. (60 * rps) .. ' rpm)</small>')
		end
	elseif mode.single then
		local rps = firerate.single
		cell:wikitext(rps .. ' rps <small>(' .. (60 * rps) .. ' rpm)</small>')
	end
end

local function renderRowDPS(tbl, name, leg, body, head, skullpiercer, tag)
	tag = tag or 'td'
	
	local row = tbl:tag('tr')
	row:tag('th'):wikitext(name)
	if leg == '' then
		row:tag(tag)
			:attr('align', 'center')
			:addClass('disabled')
			:wikitext('–')
	elseif leg ~= nil and leg ~= body then
		row:tag(tag):wikitext(leg)
	end
	row
		:tag(tag):wikitext(body):done()
		:tag(tag):wikitext(head)
	if skullpiercer ~= nil then
		row:tag(tag):wikitext(skullpiercer)
	end
end

local function toDPSText(dps)
	return string.format("%.1f", dps)
end

local function renderDPSTable(cell, name, pellet, damages, firerate, useRound)
	local damage = damages.base
	local headDamage = aw.round(damages.headshot * damage)
	local legDamage = aw.round(damages.legshot * damage)
	local skullpiercer = damages.skullpiercer_rifling
	
	local skullpiercerHeader = nil
	local commonSkullpiercerDPS = nil
	local lowprofileSkullpiercerDPS = nil
	local fortifiedSkullpiercerDPS = nil
	if skullpiercer ~= nil then
		skullpiercerHeader = formatter:hopup('スカルピアサーライフリング', nil, 'ホップアップによる武器一覧#スカルピアサーライフリング')
		
		local skullpiercerDamage = aw.round(skullpiercer * damage)
		commonSkullpiercerDPS = toDPSText(pellet * skullpiercerDamage * firerate)
		lowprofileSkullpiercerDPS = toDPSText(pellet * aw.selectiveRound(1.05 * skullpiercerDamage, useRound) * firerate)
		fortifiedSkullpiercerDPS = toDPSText(pellet * aw.round(0.85 * skullpiercerDamage) * firerate)
	end
	
	local intable = cell:tag('table')
		:addClass('intable')
		:addClass('numbertable')
	local lowprofileLegDamagePlaceholder
	if damages.legshot == 1 then
		lowprofileLegDamagePlaceholder = nil
		renderRowDPS(intable, '', nil, '胴', '頭', skullpiercerHeader, 'th')
	else
		lowprofileLegDamagePlaceholder = ''
		renderRowDPS(intable, '', '脚', '胴', '頭', skullpiercerHeader, 'th')
	end
	renderRowDPS(
		intable,
		'通常',
		toDPSText(pellet * legDamage * firerate),
		toDPSText(pellet * damage * firerate),
		toDPSText(pellet * headDamage * firerate),
		commonSkullpiercerDPS)
	renderRowDPS(
		intable,
		'小柄',
		lowprofileLegDamagePlaceholder,
		toDPSText(pellet * aw.selectiveRound(1.05 * damage, useRound) * firerate),
		toDPSText(pellet * aw.selectiveRound(1.05 * headDamage, useRound) * firerate),
		lowprofileSkullpiercerDPS)
	renderRowDPS(
		intable,
		'鉄壁',
		toDPSText(pellet * aw.round(0.85 * legDamage) * firerate),
		toDPSText(pellet * aw.round(0.85 * damage) * firerate),
		toDPSText(pellet * aw.round(0.85 * headDamage) * firerate),
		fortifiedSkullpiercerDPS)
end

local function renderDPS(tbl, name, stat)
	if stat.firerate == nil then
		return
	end
	
	local damage = stat.damage.base
	local typename = type(damage)
	if typename == 'table' then
		renderRow(tbl, name, table.concat(damage, ' - '))
	elseif typename == 'number' then
		renderRow(tbl, name, '')
		
		local pellet = stat.pellet or 1
		local useRound = stat.damage.round or false
		local cell = tbl:tag('tr'):tag('td'):attr('colspan', 2)
		if stat.mode.auto then
			renderDPSTable(cell, '', pellet, stat.damage, stat.firerate.auto, useRound)
		end
		
		if stat.mode.single and stat.firerate.auto ~= stat.firerate.single then
			renderDPSTable(cell, '', pellet, stat.damage, stat.firerate.single, useRound)
		end
		
		if stat.damage.anvil_receiver and stat.firerate.anvil_receiver then
			renderDPSTable(
				cell,
				formatter:hopup('アンビルレシーバー', nil, 'ホップアップによる武器一覧#アンビルレシーバー'),
				pellet,
				stat.damage.anvil_receiver,
				stat.firerate.anvil_receiver,
				useRound)
		end
	end
end

local function renderMagazine(table, name, stat, category)
	local typename = type(stat)
	if typename == 'table' then
		if category == 'light_machine_gun' then
			local intable = table:tag('tr')
				:tag('th')
					:wikitext(name)
					:done()
				:tag('td')
					:tag('table')
						:addClass('condensedtable')
			
			local row1 = intable:tag('tr')
			row1:tag('td'):wikitext('')
			row1:tag('td'):wikitext(stat[1])
	 		row1:tag('td'):wikitext('&nbsp;-&nbsp;')
			row1:tag('td'):wikitext(formatter:common(stat[2]))
	 		row1:tag('td'):wikitext('&nbsp;-&nbsp;')
			row1:tag('td'):wikitext(formatter:rare(stat[3]))
	 		row1:tag('td'):wikitext('&nbsp;-&nbsp;')
			row1:tag('td'):wikitext(formatter:epic(stat[4]))
			
			local row2 = intable:tag('tr')
			row2:tag('td'):wikitext(formatter:hopup('改造ローダー') .. '&nbsp;')
			row2:tag('td'):wikitext(stat['modded0'])
	 		row2:tag('td'):wikitext('&nbsp;-&nbsp;')
			row2:tag('td'):wikitext(formatter:common(stat['modded1']))
	 		row2:tag('td'):wikitext('&nbsp;-&nbsp;')
			row2:tag('td'):wikitext(formatter:rare(stat['modded2']))
	 		row2:tag('td'):wikitext('&nbsp;-&nbsp;')
			row2:tag('td'):wikitext(formatter:epic(stat['modded3']))
		else
			local text = formatter:format(stat[1], stat[2], stat[3], stat[4], '', ' - ')
			renderRow(table, name, text)
		end
	elseif typename == 'number' then
		if stat == math.huge then
			renderRow(table, name, '∞')
		else
			renderRow(table, name, stat)
		end
	else
		return
	end
end

local function renderTable(args, stat)
	stat = stat or require('Module:Stat/Weapon')[args.name]
	
	local category = stat.category
	local table = mw.html.create('table')
	renderCategory(table, '種類', category)
	renderAmmo(table, '弾薬', stat.ammo)
	renderMode(table, '射撃モード', stat.mode)
	renderDamage(table, 'ダメージ', stat.damage, stat.ammo, stat.pellet)
	renderFirerate(table, '射撃速度', stat.firerate, stat.mode)
	renderDPS(table, 'DPS', stat)
	renderMagazine(table, '装填数', stat.magazine, category)
	return table
end

function p.getNode(stat, formatter2)
	formatter = formatter2 or require('Module:Utility/Formatter').new()
	return renderTable(nil, stat)
end

function p._main(args, frame)
	formatter = require('Module:Utility/Formatter').new(frame)
	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