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

モジュール:WeaponInfobox/Spread

提供:Apex Data
< モジュール:WeaponInfobox
2022年8月12日 (金) 16:06時点におけるMntone (トーク | 投稿記録)による版 (レーザーサイトに対応)
ナビゲーションに移動 検索に移動

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

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

local p = {}
local cfg = mw.loadData('Module:WeaponInfobox/configuration')

local aw = require('Module:Utility/Library')
local iu = require('Module:Utility/Image')

local function isAllKickOnFireZero(k)
	return k.stand_hip == 0
		and k.stand_ads == 0
		and k.crouch_hip == 0
		and k.crouch_ads == 0
		and k.air_hip == 0
		and k.air_ads == 0
end

local function isAllSpreadSame(k)
	return k.stand_hip_run == k.stand_hip
		and k.stand_hip_sprint == k.stand_hip
		and k.stand_ads == k.stand_hip
		and k.crouch_hip == k.stand_hip
		and k.crouch_ads == k.stand_hip
		and k.air_hip == k.stand_hip
		and k.air_ads == k.stand_hip
end

local function hasSecondDecimalPlace(num)
	return math.floor(10 * num) ~= 10 * num
end

local function getFormatString1(num)
	return string.format('%.1f°', num)
end

local function getFormatString2(num)
	return string.format('%.2f°', num)
end

local function getDiffFormatString1(num)
	if num <= 0 then
		return '-'
	else
		return string.format('%+.1f°', num)
	end
end

local function getDiffFormatString2(num)
	if num == 0 then
		return '-'
	else
		return string.format('%+.2f°', num)
	end
end

local function getFormatStringFunction(stat, qkdw, hasHipfire)
	if (qkdw and hasSecondDecimalPlace(qkdw.stand_hip))
	or (qkdw and hasSecondDecimalPlace(qkdw.stand_hip_run))
	or (hasHipfire and hasSecondDecimalPlace(stat.stand_hip))
	or (hasHipfire and hasSecondDecimalPlace(stat.stand_hip_run))
	or (hasHipfire and hasSecondDecimalPlace(stat.stand_hip_sprint))
	or hasSecondDecimalPlace(stat.stand_ads)
	or (hasHipfire and hasSecondDecimalPlace(stat.crouch_hip))
	or hasSecondDecimalPlace(stat.crouch_ads)
	or (hasHipfire and hasSecondDecimalPlace(stat.air_hip))
	or hasSecondDecimalPlace(stat.air_ads)
	or (hasHipfire and hasSecondDecimalPlace(stat.max_kick.stand_hip))
	or hasSecondDecimalPlace(stat.max_kick.stand_ads)
	or (hasHipfire and hasSecondDecimalPlace(stat.max_kick.crouch_hip))
	or hasSecondDecimalPlace(stat.max_kick.crouch_ads)
	or (hasHipfire and hasSecondDecimalPlace(stat.max_kick.air_hip))
	or hasSecondDecimalPlace(stat.max_kick.air_ads) then
		return getFormatString2
	else
		return getFormatString1
	end
end

local function getDiffFormatStringFunction(stat, hasHipfire)
	if (hasHipfire and hasSecondDecimalPlace(stat.kick_on_fire.stand_hip))
	or hasSecondDecimalPlace(stat.kick_on_fire.stand_ads)
	or (hasHipfire and hasSecondDecimalPlace(stat.kick_on_fire.crouch_hip))
	or hasSecondDecimalPlace(stat.kick_on_fire.crouch_ads)
	or (hasHipfire and hasSecondDecimalPlace(stat.kick_on_fire.air_hip))
	or hasSecondDecimalPlace(stat.kick_on_fire.air_ads) then
		return getDiffFormatString2
	else
		return getDiffFormatString1
	end
end

local function renderKickOnFireCell(row, stat, target, env)
	local base = stat[target]
	row:tag('td')
		:addClass('cell-type-number')
		:attr('align', 'right')
		:wikitext(env.getFormatString(stat[target]))
	
	if not env.hideKickOnFire then
		local incr = stat.kick_on_fire[target]
		if incr == 0 then
			row:tag('td')
				:addClass('disabled')
				:attr('align', 'center')
				:attr('colspan', 2)
				:wikitext(env.cfg.na)
		else
			row
				:tag('td')
					:addClass('cell-type-number')
					:attr('align', 'right')
					:wikitext(env.getDiffFormatString(incr))
				:tag('td')
					:addClass('cell-type-number')
					:attr('align', 'right')
					:wikitext(env.getFormatString(base + stat.max_kick[target]))
		end
	end
end

local lazerSightRatio = { 0.8, 0.6, 0.4 }
local function renderLazerRow(tbl, stat, level, colspan, env, target, target2)
	local mul = lazerSightRatio[level]
	local lazerhip = tbl:tag('tr')
		:tag('th')
			:css('border-top', '0 none transparent')
			:wikitext('&nbsp;&nbsp;')
			:done()
		:tag('th')
			:attrIf(colspan > 1, { colspan = colspan })
			:wikitext(iu.attachment('レーザーサイト', level))
			:done()
		:tag('td')
			:addClass('cell-type-number')
			:attr('align', 'right')
			:wikitext(env.getFormatString(mul * stat[target]))
			:done()
	if not env.hideKickOnFire then
		lazerhip
			:tag('td')
				:addClass('cell-type-number')
				:attr('align', 'right')
				:wikitext(env.getDiffFormatString(mul * stat.kick_on_fire[target2 or target]))
			:tag('td')
				:addClass('cell-type-number')
				:attr('align', 'right')
				:wikitext(env.getFormatString(mul * (stat[target] + stat.max_kick[target2 or target])))
	end
end
local function renderLazerRows(tbl, stat, colspan, env, target, target2)
	renderLazerRow(tbl, stat, 1, colspan, env, target, target2)
	renderLazerRow(tbl, stat, 2, colspan, env, target, target2)
	renderLazerRow(tbl, stat, 3, colspan, env, target, target2)
end

function p.renderSpread(stat, lazer_sight, quickdraw_holster, lang)
	local spread = cfg[lang].spread
	local hasHipfire = aw.isNumberAndGreaterThanOrEqualToZero(stat.stand_hip)
	local getFormatString = getFormatStringFunction(stat, quickdraw_holster, hasHipfire)
	local getDiffFormatString = getDiffFormatStringFunction(stat, hasHipfire)
	local layout
	if lazer_sight then
		layout = {
			state_colspan  = 4,
			hip_rowspan    = 20,
			stand_rowspan  = 12,
			hipads_colspan = 3,
			concat_incr    = false,
		}
	elseif quickdraw_holster then
		layout = {
			state_colspan  = 4,
			hip_rowspan    = 7,
			stand_rowspan  = 5,
			hipads_colspan = 3,
			concat_incr    = true,
		}
	else
		layout = {
			state_colspan  = 3,
			hip_rowspan    = 5,
			stand_rowspan  = 3,
			hipads_colspan = 2,
			concat_incr    = true,
		}
	end
	local hideKickOnFire = isAllKickOnFireZero(stat.kick_on_fire)
	local env = {
		cfg                 = spread,
		hideKickOnFire      = hideKickOnFire,
		getFormatString     = getFormatString,
		getDiffFormatString = getDiffFormatString,
	}
	
	if hideKickOnFire and isAllSpreadSame(stat) then
		return mw.html.create('span')
			:wikitext(getFormatString(stat.stand_hip))
	end
	
	local tbl = mw.html.create('table')
		:addClass('intable')
	
	local header = tbl:tag('tr')
		:tag('th')
			:attr('colspan', layout.state_colspan)
			:wikitext(spread.state.name)
			:done()
		:tag('th')
			:wikitext(spread.first_shot)
			:done()
	
	if not hideKickOnFire then
		header:tag('th')
				:wikitext(spread.increment)
				:done()
			:tag('th')
				:wikitext(spread.maximum)
	end
	
	-- Hipfire
	if hasHipfire then
		local hipfire = tbl:tag('tr')
			:tag('th')
				:addClass(spread.state.hip_class)
				:attr('rowspan', layout.hip_rowspan)
				:tag('span')
					:wikitext(spread.state.hip)
					:done()
				:done()
			:tag('th')
				:addClass(spread.state.stand_class)
				:attr('rowspan', layout.stand_rowspan)
				:tag('span')
					:wikitext(spread.state.stand)
					:done()
				:done()
			:tag('th')
				:attrIf(lazer_sight or quickdraw_holster, { colspan = 2 })
				:wikitext(spread.state.still)
				:done()
			:tag('td')
				:addClass('cell-type-number')
				:attr('align', 'right')
				:wikitext(getFormatString(stat.stand_hip))
				:done()
		if not hideKickOnFire then
			hipfire
				:tag('td')
					:addClass('cell-type-number')
					:attr('align', 'right')
					:attrIf(layout.concat_incr, { rowspan = layout.stand_rowspan })
					:wikitext(getDiffFormatString(stat.kick_on_fire.stand_hip))
					:done()
				:tag('td')
					:addClass('cell-type-number')
					:attr('align', 'right')
					:wikitext(getFormatString(stat.stand_hip + stat.max_kick.stand_hip))
		end
		
		if lazer_sight then
			renderLazerRows(tbl, stat, 1, env, 'stand_hip')
		elseif quickdraw_holster then
			local quickhip = tbl:tag('tr')
				:tag('th')
					:css('border-top', '0 none transparent')
					:wikitext('&nbsp;&nbsp;')
					:done()
				:tag('th')
					:wikitext(iu.hopup('quickdraw_holster'))
					:done()
				:tag('td')
					:addClass('cell-type-number')
					:attr('align', 'right')
					:wikitext(getFormatString(quickdraw_holster.stand_hip))
					:done()
			if not hideKickOnFire then
				if not layout.concat_incr then
					quickhip:tag('td')
						:addClass('cell-type-number')
						:attr('align', 'right')
						:wikitext(getDiffFormatString(stat.kick_on_fire.stand_hip))
				end
				quickhip:tag('td')
					:addClass('cell-type-number')
					:attr('align', 'right')
					:wikitext(getFormatString(quickdraw_holster.stand_hip + stat.max_kick.stand_hip))
			end
		end
		
		local run = tbl:tag('tr')
			:tag('th')
				:attrIf(lazer_sight or quickdraw_holster, { colspan = 2 })
				:wikitext(spread.state.run)
				:done()
			:tag('td')
				:addClass('cell-type-number')
				:attr('align', 'right')
				:wikitext(getFormatString(stat.stand_hip_run))
				:done()
		if not hideKickOnFire then
			if not layout.concat_incr then
				run:tag('td')
					:addClass('cell-type-number')
					:attr('align', 'right')
					:wikitext(getDiffFormatString(stat.kick_on_fire.stand_hip))
			end
			run:tag('td')
				:addClass('cell-type-number')
				:attr('align', 'right')
				:wikitext(getFormatString(stat.stand_hip_run + stat.max_kick.stand_hip))
		end
		
		if lazer_sight then
			renderLazerRows(tbl, stat, 1, env, 'stand_hip_run', 'stand_hip')
		elseif quickdraw_holster then
			local quickrun = tbl:tag('tr')
				:tag('th')
					:css('border-top', '0 none transparent')
					:wikitext('&nbsp;&nbsp;')
					:done()
				:tag('th')
					:wikitext(iu.hopup('quickdraw_holster'))
					:done()
				:tag('td')
					:addClass('cell-type-number')
					:attr('align', 'right')
					:wikitext(getFormatString(quickdraw_holster.stand_hip_run))
					:done()
			if not hideKickOnFire then
				if not layout.concat_incr then
					quickrun:tag('td')
						:addClass('cell-type-number')
						:attr('align', 'right')
						:wikitext(getDiffFormatString(stat.kick_on_fire.stand_hip))
				end
				quickrun:tag('td')
					:addClass('cell-type-number')
					:attr('align', 'right')
					:wikitext(getFormatString(quickdraw_holster.stand_hip_run + stat.max_kick.stand_hip))
			end
		end
		
		local sprint = tbl:tag('tr')
			:tag('th')
				:attrIf(lazer_sight or quickdraw_holster, { colspan = 2 })
				:wikitext(spread.state.sprint)
				:done()
			:tag('td')
				:addClass('cell-type-number')
				:attr('align', 'right')
				:wikitext(getFormatString(stat.stand_hip_sprint))
				:done()
		if not hideKickOnFire then
			if not layout.concat_incr then
				sprint:tag('td')
					:addClass('cell-type-number')
					:attr('align', 'right')
					:wikitext(getDiffFormatString(stat.kick_on_fire.stand_hip))
			end
			sprint:tag('td')
				:addClass('cell-type-number')
				:attr('align', 'right')
				:wikitext(getFormatString(stat.stand_hip_sprint + stat.max_kick.stand_hip))
		end
		
		if lazer_sight then
			renderLazerRows(tbl, stat, 1, env, 'stand_hip_sprint', 'stand_hip')
		end
		
		-- Hipfire while crouching
		local crouch = tbl:tag('tr')
			:tag('th')
				:attr('colspan', layout.hipads_colspan)
				:wikitext(spread.state.crouch)
				:done()
		renderKickOnFireCell(crouch, stat, 'crouch_hip', env)
		
		if lazer_sight then
			renderLazerRows(tbl, stat, layout.hipads_colspan - 1, env, 'crouch_hip')
		end
		
		-- Hipfire in the air
		local air = tbl:tag('tr')
			:tag('th')
				:attr('colspan', layout.hipads_colspan)
				:wikitext(spread.state.air)
				:done()
		renderKickOnFireCell(air, stat, 'air_hip', env)
		
		if lazer_sight then
			renderLazerRows(tbl, stat, layout.hipads_colspan - 1, env, 'air_hip')
		end
	end
	
	-- ADS
	if stat.stand_ads == stat.crouch_ads
		and stat.kick_on_fire.stand_ads == stat.kick_on_fire.crouch_ads
		and stat.max_kick.stand_ads == stat.max_kick.crouch_ads then
		local ads = tbl:tag('tr')
			:tag('th')
				:addClass(spread.state.ads_class)
				:attr('rowspan', 3)
				:tag('span')
					:wikitext(spread.state.ads)
					:done()
				:done()
			:tag('th')
				:attr('colspan', layout.hipads_colspan)
				:wikitext(spread.state.standcrouch)
				:done()
		renderKickOnFireCell(ads, stat, 'stand_ads', env)
	else
		local hipads = tbl:tag('tr')
			:tag('th')
				:addClass(spread.state.ads_class)
				:attr('rowspan', 3)
				:tag('span')
					:wikitext(spread.state.ads)
					:done()
				:done()
			:tag('th')
				:attr('colspan', layout.hipads_colspan)
				:wikitext(spread.state.stand)
				:done()
		renderKickOnFireCell(hipads, stat, 'stand_ads', env)
		
		-- ADS while crouching
		local crouchads = tbl:tag('tr')
			:tag('th')
				:attr('colspan', layout.hipads_colspan)
				:wikitext(spread.state.crouch)
				:done()
		renderKickOnFireCell(crouchads, stat, 'crouch_ads', env)
	end
	
	-- ADS in the air
	local airads = tbl:tag('tr')
		:tag('th')
			:attr('colspan', layout.hipads_colspan)
			:wikitext(spread.state.air)
			:done()
	renderKickOnFireCell(airads, stat, 'air_ads', env)
	
	return tbl
end

function p._main(name, lang)
	lang = lang or 'ja'
	
	local stat = mw.loadData('Module:Stat/Weapon')[name]
	local lsrs = stat.attachments.laser_sight
	local qkdw = stat.quickdraw_holster and stat.quickdraw_holster.spread
	local node = p.renderSpread(stat.spread, lsrs, qkdw, lang)
	return tostring(node)
end

return p