本站文本内容除另有声明外,转载时均必须注明出处,并遵守CC BY-NC-SA 3.0协议。(转载须知
本站是中文Minecraft Wiki的镜像站,与Mojang Studios、Weird Gloop没有从属关系。(免责声明

全站通知:

模块:Breaking table

来自我的世界地下城WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

该模块用于实现{{Breaking table}}

该模块(曾用名Breaking row)的旧实现见Module:Breaking table/legacy

依赖项


lzh:Module:Breaking table

local p = {}

local Autovalue = require( [[Module:Autovalue]] )
local Autolink = require( [[Module:Autolink]] )
local Sprite = require( [[Module:Sprite]] )
local Reverselink = require( [[Module:Reverselink]] )
local ProcessArgs = require( [[Module:ProcessArgs]] )

local function ComputeBreakingTime( hardness, breakingRate, rateFactor )
	return math.max(
		1,
		math.ceil( ( hardness * 30 / rateFactor ) / breakingRate )
	) / 20
end

local localStrings = {
	['ref_group'] = '挖掘',
	['category_missing_hardness'] = '缺失硬度',
	['table_data_description'] = '挖掘时间',
	['note_breakingtime'] = '根据受影响因素修正前的基础挖掘速度计算出的挖掘时间,单位:秒。更多信息详见[[挖掘#挖掘速度]]。',
	['note_unbreakable'] = '硬度为负数的方块不可通过挖掘来破坏。',
	['header_breakingtime'] = '[[挖掘]]时间',
	['header_blocks'] = '方块',
	['header_hardness'] = '硬度',
	['header_breaking_tool'] = '合适挖掘工具',
	['header_breakingtime_notool'] = '<abbr title="包含空手或使用错误种类的工具">徒手</abbr>',
	['header_breakingtime_sword'] = '剑',
	['header_breakingtime_shears'] = '剪刀',
	['header_breakingtime_tier_wooden'] = '木质',
	['header_breakingtime_tier_stone'] = '石质',
	['header_breakingtime_tier_iron'] = '铁质',
	['header_breakingtime_tier_diamond'] = '钻石质',
	['header_breakingtime_tier_netherite'] = '下界合金质',
	['header_breakingtime_tier_golden'] = '金质',
}

local breakingTimeHeader
local function getBreakingTimeHeader()
    if breakingTimeHeader == nil then
        breakingTimeHeader = localStrings.header_breakingtime .. mw.getCurrentFrame():callParserFunction {
        	name = '#tag:ref',
        	args = {
        		localStrings.note_breakingtime,
        		name = 'breakingtimenote',
        		group = localStrings.ref_group
        	}
        }
    end
    return breakingTimeHeader
end

local function ParseLineHeaderToTableCell( lineName, horizontal, onlyFlag, SwordJEandSwordBESame, toolsColspan )
	if lineName == 'blockname' then
		if horizontal then
			return '! '..localStrings.header_blocks
		else
			return '! rowspan = "2" | '..localStrings.header_blocks
		end
	elseif lineName == 'hardness' then
		if horizontal then
			return '! '..localStrings.header_hardness
		else
			return '! rowspan = "2" | '..localStrings.header_hardness
		end
	elseif lineName == 'breaking_tool' then
		if horizontal then
			return '! '..localStrings.header_breaking_tool
		else
			return '! rowspan = "2" | '..localStrings.header_breaking_tool
		end
	elseif lineName == 'notool' then
		return table.concat({
			'! colspan="'..toolsColspan..'" | '..getBreakingTimeHeader(),
			'|-',
			'! '..localStrings.header_breakingtime_notool
			}, '\n')
	elseif lineName == 'swordJE' then
		if onlyFlag == 'je' or SwordJEandSwordBESame then
			return '! '..localStrings.header_breakingtime_sword
		else
			return '! '..localStrings.header_breakingtime_sword..mw.getCurrentFrame():expandTemplate { title = 'Only', args = { 'je' } }
		end
	elseif lineName == 'swordBE' then
		if onlyFlag == 'be' or SwordJEandSwordBESame then
			return '! '..localStrings.header_breakingtime_sword
		else
			return '! '..localStrings.header_breakingtime_sword..mw.getCurrentFrame():expandTemplate { title = 'Only', args = { 'be' } }
		end
	elseif lineName == 'shears' then
		return '! '..localStrings.header_breakingtime_shears
	elseif lineName == 'tierWooden' then
		return '! '..localStrings.header_breakingtime_tier_wooden
	elseif lineName == 'tierStone' then
		return '! '..localStrings.header_breakingtime_tier_stone
	elseif lineName == 'tierIron' then
		return '! '..localStrings.header_breakingtime_tier_iron
	elseif lineName == 'tierDiamond' then
		return '! '..localStrings.header_breakingtime_tier_diamond
	elseif lineName == 'tierNetherite' then
		return '! '..localStrings.header_breakingtime_tier_netherite
	elseif lineName == 'tierGolden' then
		return '! '..localStrings.header_breakingtime_tier_golden
	else
		return '! ??????'
	end
end

local function ParseLineToTableCell(lineName, breakingDataEntry, onlyFlag)
	if lineName == 'blockname' then
		local blocklinks = {}
		local categories = {}
		for i, blockId in ipairs( breakingDataEntry.blockIds ) do
			local only = ''
			local blocklink, spriteCat = Sprite.link({
				Reverselink.xlink(blockId.blockId),
				['data'] = 'BlockSprite'
			})
			if blockId.hasJE and not blockId.hasBE then
				if onlyFlag ~= 'je' then
					only = mw.getCurrentFrame():expandTemplate { title = 'Only', args = { 'je' } }
				end
			elseif blockId.hasBE and not blockId.hasJE then
				if onlyFlag ~= 'be' then
					only = mw.getCurrentFrame():expandTemplate { title = 'Only', args = { 'be' } }
				end
			end
			table.insert( blocklinks, blocklink..only )
			table.insert( categories, spriteCat )
		end
		return '! '..table.concat(blocklinks, '<br>')..table.concat(categories)
	end
	if lineName == 'breaking_tool' then
		if type(breakingDataEntry.breaking_tool) == 'table' then
			local valueTable = {}
			local frame = mw.getCurrentFrame()
			for k, v in pairs( breakingDataEntry.breaking_tool ) do
				table.insert(valueTable, frame:expandTemplate { title = 'BreakingToolTooltip', args = { v } })
			end
			if #valueTable <= 0 then
				return '| '..frame:expandTemplate { title = 'BreakingToolTooltip', args = { 'none' } }
			end
			return '| '..table.concat(valueTable)
		end
		return '| ?'
	end
	if lineName == 'hardness' then
		local note = ''
		local attrible = ''
		if type(breakingDataEntry.hardness) == 'number' and breakingDataEntry.hardness < 0 then
			attrible = 'data-sort-value="999999999" | '
			local frame = mw.getCurrentFrame()
			if frame:callParserFunction( '#dplvar', 'unbreakable note' ) == '' then
				note = frame:callParserFunction { name = '#tag:ref', args = { localStrings.note_unbreakable, name = 'unbreakable', group = localStrings.ref_group } }
				frame:callParserFunction( '#dplvar:set', 'unbreakable note', '1' )
			else
				note = frame:callParserFunction { name = '#tag:ref', args = { '', name = 'unbreakable', group = localStrings.ref_group } }
			end
		end
		return '| '..attrible..breakingDataEntry.hardness..note
	end
	if lineName == 'notool'
	or lineName == 'tierWooden'
	or lineName == 'tierStone'
	or lineName == 'tierIron'
	or lineName == 'tierDiamond'
	or lineName == 'tierNetherite'
	or lineName == 'tierGolden'
	or lineName == 'swordJE'
	or lineName == 'swordBE'
	or lineName == 'shears'
	then
		if breakingDataEntry[lineName] then
			local att = ''
			if breakingDataEntry[lineName] == '∞' then
				att = 'data-sort-value="999999999" '
			end
			local choose
			if breakingDataEntry.reds[lineName] then
				choose = 'class="tc-no" |' --mw.getCurrentFrame():expandTemplate{ title = 'Table Choice', args = { 'no', '' } }
			else
				choose = 'class="tc-yes" |' --mw.getCurrentFrame():expandTemplate{ title = 'Table Choice', args = { 'yes', '' } }
			end
			return '| '..att..choose..' '..breakingDataEntry[lineName]
		else
			return '| —'
		end
	else
		return '| ?????????'
	end
end

local function GenerateDataLines(breakingData, onlyFlag)
	local SwordJEandNotoolSame = true
	local SwordBEandNotoolSame = true
	local SwordJEandSwordBESame = true
	local hasSwrodJE = false
	local hasSwrodBE = false
	local hasShears = false
	local hasTier = false
	for i, breakingDataEntry in ipairs( breakingData ) do
		if breakingDataEntry.tierDiamond then
			hasTier = true
		end
		if breakingDataEntry.swordJE then
			hasSwrodJE = true
		end
		if breakingDataEntry.swordBE then
			hasSwrodBE = true
		end
		if breakingDataEntry.shears then
			hasShears = true
		end
		if breakingDataEntry.swordJE ~= nil and breakingDataEntry.swordJE ~= breakingDataEntry.notool then
			SwordJEandNotoolSame = false
		end
		if breakingDataEntry.swordBE ~= nil and breakingDataEntry.swordBE ~= breakingDataEntry.notool then
			SwordBEandNotoolSame = false
		end
		if breakingDataEntry.swordJE ~= breakingDataEntry.swordBE then
			SwordJEandSwordBESame = false
		end
	end
	
	local lines = {}
	table.insert(lines, 'blockname')
	table.insert(lines, 'hardness')
	table.insert(lines, 'breaking_tool')
	table.insert(lines, 'notool')
	if hasTier then
		table.insert(lines, 'tierWooden')
		table.insert(lines, 'tierStone')
		table.insert(lines, 'tierIron')
		table.insert(lines, 'tierDiamond')
		table.insert(lines, 'tierNetherite')
		table.insert(lines, 'tierGolden')
	end
	if hasSwrodJE and not SwordJEandNotoolSame then
		table.insert(lines, 'swordJE')
	end
	if hasSwrodBE and not SwordBEandNotoolSame and not SwordJEandSwordBESame then
		table.insert(lines, 'swordBE')
	end
	if hasShears then
		table.insert(lines, 'shears')
	end
	
	local dataLines = {}
	for i, breakingDataEntry in ipairs( breakingData ) do
		local dataLine = {}
		for i, line in ipairs( lines ) do
			dataLine[line]=ParseLineToTableCell(line, breakingDataEntry, onlyFlag)
		end
		table.insert(dataLines, dataLine)
	end
	return lines, dataLines, SwordJEandSwordBESame
end

local function BreakingDataToVerticalTable(breakingData, onlyFlag)
	local lines, dataLines, SwordJEandSwordBESame = GenerateDataLines(breakingData, onlyFlag)
	local finalTableStrings = {}
	table.insert(finalTableStrings, ' {| class="wikitable sortable" style="text-align:center;" data-sort-type="number" data-description="'..localStrings.table_data_description..'"')
	for i, line in ipairs( lines ) do
		table.insert(finalTableStrings, ParseLineHeaderToTableCell(line, false, onlyFlag, SwordJEandSwordBESame, #lines + -3) )
	end
	table.insert(finalTableStrings, '|-')
	for i, dataLine in ipairs( dataLines ) do
		for i, line in ipairs( lines ) do
			table.insert(finalTableStrings, dataLine[line] )
		end
		table.insert(finalTableStrings, '|-')
	end
	table.insert(finalTableStrings, '|}')
	table.insert(finalTableStrings, mw.getCurrentFrame():callParserFunction { name = '#tag:references', args = { '', group = localStrings.ref_group } })
	mw.getCurrentFrame():callParserFunction( '#dplvar:set', 'unbreakable note', '' )
	
	return table.concat(finalTableStrings, '\n')
end

local function BreakingDataToHorizontalTable(breakingData, onlyFlag)
	local lines, dataLines, SwordJEandSwordBESame = GenerateDataLines(breakingData, onlyFlag)
	local finalTableStrings = {}
	table.insert(finalTableStrings, ' {| class="wikitable" style="text-align:center;" data-description="'..localStrings.table_data_description..'"')
	for i, line in ipairs( lines ) do
		table.insert(finalTableStrings, ParseLineHeaderToTableCell(line, true, onlyFlag, SwordJEandSwordBESame, #dataLines + 1) )
		for i, dataLine in ipairs( dataLines ) do
			table.insert(finalTableStrings, dataLine[line] )
		end
		table.insert(finalTableStrings, '|-')
	end
	table.insert(finalTableStrings, '|}')
	table.insert(finalTableStrings, mw.getCurrentFrame():callParserFunction { name = '#tag:references', args = { '', group = localStrings.ref_group } })
	mw.getCurrentFrame():callParserFunction( '#dplvar:set', 'unbreakable note', '' )
	
	return table.concat(finalTableStrings, '\n')
end

local ToolType = {
	['pickaxe'] = 'pickaxe',
	['wooden pickaxe'] = 'pickaxe',
	['stone pickaxe'] = 'pickaxe',
	['iron pickaxe'] = 'pickaxe',
	['diamond pickaxe'] = 'pickaxe',
	['netherite pickaxe'] = 'pickaxe',
	['shovel'] = 'shovel',
	['wooden shovel'] = 'shovel',
	['axe'] = 'axe',
	['wooden axe'] = 'axe',
	['hoe'] = 'hoe',
	['sword'] = 'sword',
	['wooden sword'] = 'sword',
	['shears'] = 'shears',
	['shears required'] = 'shears',
	['null required'] = 'none',
	['none'] = 'none',
}
local ToolTier = {
	['pickaxe'] = 0,
	['wooden pickaxe'] = 1,
	['stone pickaxe'] = 2,
	['iron pickaxe'] = 3,
	['diamond pickaxe'] = 4,
	['netherite pickaxe'] = 5,
	['shovel'] = 0,
	['wooden shovel'] = 1,
	['axe'] = 0,
	['wooden axe'] = 1,
	['hoe'] = 0,
	['sword'] = 0,
	['wooden sword'] = 0.5,
	['shears'] = 0,
	['shears required'] = 0.5,
	['null required'] = 1,
	['none'] = 0,
}

local function ParseBreakingDatas(breakingStats)
	local hardness = breakingStats.hardness
	local breaking_tool = breakingStats.breaking_tool
	local swordRateJE = breakingStats.swordRateJE
	local swordRateBE = breakingStats.swordRateBE
	local shearsRate = breakingStats.shearsRate
	
	local result = {}
    result.reds = {}
	local broken = false
	result.hardness = hardness
	result.breaking_tool = breaking_tool
    if hardness == nil then
		result.hardness = '?[[Category:'..localStrings.category_missing_hardness..']]'
		broken = true
    end
    if breaking_tool == nil then
		result.breaking_tool = {'?'}
		broken = true
    end
    if broken then
		return result
	end
	
	local tool = 'none'
	local tier = 0
	local hasShears = false
	local hasSword = false
	
    for i, tooltext in ipairs(breaking_tool) do
        if ToolType[tooltext] == 'shears' then
            hasShears = true
        elseif ToolType[tooltext] == 'sword' then
            hasSword = true
        elseif ToolType[tooltext] ~= 'none' then
        	tool = ToolType[tooltext]
        end
        tier = ToolTier[tooltext]
    end

    if hardness < 0 then
    	result.notool = '∞'
    	result.reds.notool = true
		return result
    end
    
    local notoolRatio = 1
    local swordRatio = 1
    local tierWoodenRatio = 1
    local tierStoneRatio = 1
    local tierIronRatio = 1
    local tierDiamondRatio = 1
    local tierNetheriteRatio = 1
    local tierGoldenRatio = 1
    
    if tier > 0 then
    	notoolRatio = 0.3
    	result.reds.notool = true
    end
    if tier > 0.5 then
    	swordRatio = 0.3
    	result.reds.swordJE = true
    	result.reds.swordBE = true
    end
    if tier > 1 then
    	tierWoodenRatio = 0.3
    	tierGoldenRatio = 0.3
    	result.reds.tierWooden = true
    	result.reds.tierGolden = true
    end
    if tier > 2 then
    	tierStoneRatio = 0.3
    	result.reds.tierStone = true
    end
    if tier > 3 then
    	tierIronRatio = 0.3
    	result.reds.tierIron = true
    end
    if tier > 4 then
    	tierDiamondRatio = 0.3
    	result.reds.tierDiamond = true
    end
    if tier > 5 then
    	tierNetheriteRatio = 0.3
    	result.reds.tierNetherite = true
    end
    
    result.notool = ComputeBreakingTime(hardness, 1, notoolRatio)
    if tool ~= 'none' then
	    result.tierWooden = ComputeBreakingTime(hardness, 2, tierWoodenRatio)
	    result.tierStone = ComputeBreakingTime(hardness, 4, tierStoneRatio)
	    result.tierIron = ComputeBreakingTime(hardness, 6, tierIronRatio)
	    result.tierDiamond = ComputeBreakingTime(hardness, 8, tierDiamondRatio)
	    result.tierNetherite = ComputeBreakingTime(hardness, 9, tierNetheriteRatio)
	    result.tierGolden = ComputeBreakingTime(hardness, 12, tierGoldenRatio)
    end
    if swordRateJE then
	    result.swordJE = ComputeBreakingTime(hardness, swordRateJE, swordRatio)
    end
    if swordRateBE then
	    result.swordBE = ComputeBreakingTime(hardness, swordRateBE, swordRatio)
    end
    if hasShears then
	    result.shears = ComputeBreakingTime(hardness, shearsRate, 1)
    end
	
	return result
end

local function tableHasValue (targetTable, targetValue)
    for index, value in ipairs(targetTable) do
        if value == targetValue then
            return true
        end
    end
    return false
end

local function IsSameTool(tools1, tools2)
	if tools1 == nil and tools2 == nil then
		return true
	end
	if tools1 == nil or tools2 == nil then
		return false
	end
	for i, tool1 in pairs( tools1 ) do
		if not tableHasValue(tools2, tool1) then
			return false
		end
	end
	for i, tool2 in pairs( tools2 ) do
		if not tableHasValue(tools1, tool2) then
			return false
		end
	end
	return true
end

local function GenBreakingStats(blockId, onlyBE)
	return {
		['hardness'] = Autovalue.getRawValue(blockId, 'hardness', onlyBE),
		['breaking_tool'] = Autovalue.getRawValue(blockId, 'breaking tool', onlyBE),
	}
end

local function IsSameBreakingStats(breakingStats1, breakingStats2)
	return (
	 breakingStats1.hardness == breakingStats2.hardness
	 and breakingStats1.swordRateJE == breakingStats2.swordRateJE
	 and breakingStats1.swordRateBE == breakingStats2.swordRateBE
	 and breakingStats1.shearsRate == breakingStats2.shearsRate
	 and IsSameTool(breakingStats1.breaking_tool, breakingStats2.breaking_tool) )
end

local function GetSwordRate(blockId, breakingStats, onlyBE)
	if blockId == "蜘蛛网" then
		return 15
	elseif blockId == "竹子" then
		return 1000000000
	elseif onlyBE then
		return 1.5
	elseif breakingStats and breakingStats.breaking_tool and (tableHasValue (breakingStats.breaking_tool, 'sword') or tableHasValue (breakingStats.breaking_tool, 'wooden sword')) then
		return 1.5
	else
		return 1
	end
end
local function GetShearsRate(blockId, breakingStats, onlyBE)
	if blockId == "蜘蛛网" then
		return 15
	elseif string.find(blockId,"树叶$") then
		return 15
	elseif blockId == "羊毛" then
		return 5
	elseif breakingStats and breakingStats.breaking_tool and (tableHasValue (breakingStats.breaking_tool, 'shears') or tableHasValue (breakingStats.breaking_tool, 'shears requird')) then
		return 2
	else
		return 1
	end
end

local ExclusiveBE = {
	'平滑石砖',
	'物品展示框',
	'荧光物品展示框',
	'下界反应核',
	'发光的黑曜石',
	'切石机(MATTIS)',
	'reserved6',
	'客户端请求占位符方块',
	'数据更新方块',
	'未知',
	'未知方块',
	'隐形基岩',
	'允许方块',
	'拒绝方块',
	'边界',
	'相机',
	'紫色火把',
	'蓝色火把',
	'绿色火把',
	'红色火把',
	'彩色火把',
	'化合物创建器',
	'元素',
	'元素构造器',
	'强化玻璃',
	'染色强化玻璃',
	'强化玻璃板',
	'染色强化玻璃板',
	'实验台',
	'材料分解器',
	'化学仪器',
	'加热块',
	'水下火把',
	'水下TNT',
	'黑板',
}

local function BreakingDataBuilder(blockIds, onlyFlag, enableGrouping)
	local groupedBlockData = {}
	for i, blockId in ipairs( blockIds ) do
		local breakingStatsList = {}
		local localOnlyFlag = onlyFlag
		if localOnlyFlag ~= 'je' and localOnlyFlag ~= 'be' then
			if tableHasValue (ExclusiveBE, blockId) then
				localOnlyFlag = 'be'
			end
		end
		if localOnlyFlag == 'je' then
			local breakingStats = GenBreakingStats(blockId, false)
			breakingStats.hasJE = true
			breakingStats.shearsRate = GetShearsRate(blockId, breakingStats)
			breakingStats.swordRateJE = GetSwordRate(blockId, breakingStats, false)
			table.insert(breakingStatsList, breakingStats)
		elseif localOnlyFlag == 'be' then
			local breakingStats = GenBreakingStats(blockId, true)
			breakingStats.hasBE = true
			breakingStats.shearsRate = GetShearsRate(blockId, breakingStats)
			breakingStats.swordRateBE = GetSwordRate(blockId, breakingStats, true)
			table.insert(breakingStatsList, breakingStats)
		else
			local breakingStatsJE = GenBreakingStats(blockId, false)
			local breakingStatsBE = GenBreakingStats(blockId, true)
			breakingStatsJE.shearsRate = GetShearsRate(blockId, breakingStatsJE)
			breakingStatsBE.shearsRate = GetShearsRate(blockId, breakingStatsBE)
			if IsSameBreakingStats(breakingStatsJE, breakingStatsBE) then
				breakingStatsJE.hasJE = true
				breakingStatsJE.hasBE = true
				breakingStatsJE.swordRateJE = GetSwordRate(blockId, breakingStatsJE, false)
				breakingStatsJE.swordRateBE = GetSwordRate(blockId, breakingStatsJE, true)
				table.insert(breakingStatsList, breakingStatsJE)
			else
				breakingStatsJE.hasJE = true
				breakingStatsBE.hasBE = true
				breakingStatsJE.swordRateJE = GetSwordRate(blockId, breakingStatsJE, false)
				breakingStatsBE.swordRateBE = GetSwordRate(blockId, breakingStatsBE, true)
				table.insert(breakingStatsList, breakingStatsJE)
				table.insert(breakingStatsList, breakingStatsBE)
			end
		end
		for i, breakingStats in ipairs( breakingStatsList ) do
			local mergeTargetNotFound = true
			if enableGrouping then
				for i, blockDataGroup in ipairs( groupedBlockData ) do
					if IsSameBreakingStats(blockDataGroup.breakingStats, breakingStats) then
						table.insert(blockDataGroup.blockIds, {
							['blockId'] = blockId,
							['hasJE'] = breakingStats.hasJE,
							['hasBE'] = breakingStats.hasBE,
							} )
						mergeTargetNotFound = false
						break
					end
				end
			end
			if mergeTargetNotFound then
				table.insert(groupedBlockData, {
					['blockIds'] = { {
						['blockId'] = blockId,
						['hasJE'] = breakingStats.hasJE,
						['hasBE'] = breakingStats.hasBE,
						} },
					['breakingStats'] = breakingStats,
				})
			end
		end
	end
	return groupedBlockData
end

local function ParseGroupedBlockDatasToTableEntries (groupedBlockData)
	local tableEntries = {}
	for i, blockDataGroup in ipairs( groupedBlockData ) do
		local tableEntry = ParseBreakingDatas(blockDataGroup.breakingStats)
		tableEntry.blockIds = blockDataGroup.blockIds
		table.insert(tableEntries, tableEntry)
	end
	return tableEntries
end

local function StripSpaceAndLineAtBothEnds(str)
	return (string.gsub(str, '^[%s\n]*(.-)[%s\n]*$', '%1'))
end

local function StringToArray (str, splitter)
	local rawSplit = mw.text.split(str, splitter)
	local results = {}
	for i,value in ipairs( rawSplit ) do
		local stripped = StripSpaceAndLineAtBothEnds( value )
		if stripped ~= '' then
			table.insert(results,  stripped)
		end
	end
	return results
end

function p.genBreakingTable(f)
	local args = f
	local frame = mw.getCurrentFrame()
	if f == frame then
		args = require('Module:ProcessArgs').merge(true)
	end
	local targetNames = {}
	local argTargetNames
	if args[1] then
		argTargetNames = mw.text.trim(args[1])
	else
		local titleName = mw.text.trim(mw.title.getCurrentTitle().rootText)
		if tableHasValue (ExclusiveBE, titleName)
		or require( [[Module:Block id values]] )[titleName]
		or require( [[Module:Autovalue/groups]] )[titleName]
		then
			argTargetNames = titleName
		end
	end
	if argTargetNames then
		targetNames = Autovalue.expandGroups(StringToArray(argTargetNames, ','))
	end
	local argOnly = StripSpaceAndLineAtBothEnds( args.only or '' )
	if argOnly == 'java' then argOnly = 'je' end
	if argOnly == 'bedrock' then argOnly = 'be' end
	if args.vertical then
		return BreakingDataToVerticalTable(
			ParseGroupedBlockDatasToTableEntries(
				BreakingDataBuilder(
					targetNames,
					argOnly,
					false
					)
				),
			argOnly
			)
	else
		return BreakingDataToHorizontalTable(
			ParseGroupedBlockDatasToTableEntries(
				BreakingDataBuilder(
					targetNames,
					argOnly,
					true
					)
				),
			argOnly
			)
	end
end

return p