Minecraft Wiki

除另有声明,转载时均必须注明出处若簡繁轉換出錯,請以遊戲內為準请勇于扩充与修正内容有兴趣逛逛我们的微博沟通交流,欢迎到社区专页需要协助,请在告示板留言

了解更多

Minecraft Wiki
(Revert)
无编辑摘要
 
(未显示6个用户的69个中间版本)
第1行: 第1行:
 
local p = {}
 
local p = {}
  +
local Autolink = require( [[Module:Autolink]] )
p.value = function( f )
 
  +
local args = f
 
  +
--为维护分类提供名称。
if f == mw.getCurrentFrame() then
 
  +
local categoryMapping = {
args = require( 'Module:ProcessArgs' ).merge( true )
 
  +
-- 方块数据
  +
['breaking tool'] = '合适挖掘工具',
  +
['blast resistance'] = '爆炸抗性',
  +
['hardness'] = '硬度',
  +
['material'] = '材料', -- JE
  +
['material BE'] = '基岩版材料', -- BE
  +
['suffocating'] = '窒息生物',
  +
['redstone conductor'] = '红石导体',
  +
['flame odds'] = '引燃几率',
  +
['burn odds'] = '烧毁几率',
  +
['lava flammable'] = '熔岩可燃性',
  +
['push reaction'] = '活塞推动行为',
  +
-- 物品数据
  +
['maxstack'] = '最大堆叠',
  +
['rarity'] = '稀有度',
  +
['creative tab'] = '创造标签页', -- JE
  +
['creative category'] = '创造分类', -- BE
  +
}
  +
  +
-- 是否有对应的values BE数据表。
  +
local hasBeData = {
  +
['breaking tool'] = true,
  +
['blast resistance'] = true,
  +
['hardness'] = true,
  +
['maxstack'] = true,
  +
['rarity'] = true,
  +
['suffocating'] = true,
  +
['redstone conductor'] = true,
  +
['flame odds'] = true,
  +
['burn odds'] = true,
  +
['lava flammable'] = true,
  +
['push reaction'] = true,
  +
}
  +
  +
local function ValueTypeExist(valueType)
  +
return not not categoryMapping[valueType]
  +
end
  +
  +
-- 从值列表按照键值获得值,找不到则返回键值。
  +
local function MappingValue(mappingName, value)
  +
local mapping = mw.loadData('Module:Autovalue/' .. mappingName .. ' mapping')
  +
if mapping[value] then
  +
return mapping[value]
  +
else
  +
return value
 
end
 
end
  +
end
local block = mw.text.trim( args[1] or ''):lower()
 
local type = args.type
 
   
  +
-- 从值列表按照键值获得值,有去除末尾s,有__fallback,找不到则返回nil。
-- Most of these transforms are unnecessary, but are kept for compatibility with original template
 
  +
local function ValueFromValuesByKey(values, key)
 
  +
local value = values[key]
-- Strip trailing "s" on everything but these
 
local keepS = {
+
if value == nil then
  +
value = values[key:gsub('s$', '')]
glass = true,
 
steps = true, stairs = true,
 
bars = true,
 
cactus = true,
 
leaves = true,
 
grass = true,
 
potatoes = true
 
}
 
if not keepS[block:match( '%w+$' )] then
 
block = block:gsub( 's$', '' )
 
 
end
 
end
  +
if value == nil then
 
  +
value = values['__fallback']
-- Other transforms
 
  +
end
block = block
 
  +
return value
:gsub( 'wooden', 'wood' )
 
  +
end
:gsub( 'mossy', 'moss' )
 
  +
:gsub( 'steps', 'stairs' )
 
  +
-- 值获取方法,不设置则直接使用ValueFromValuesByKey。
:gsub( "['%(%)%-%s]+", '' )
 
  +
local valueGettingMethod = {
 
  +
['breaking tool'] = (function (values, key, onlyBE)
local value = mw.loadData( 'Module:' .. type .. ' values' )[block]
 
  +
local value = ValueFromValuesByKey(values, key)
  +
if type(value) ~= 'table' then
  +
return value
  +
end
  +
local hardnessValues
  +
if onlyBE then
  +
hardnessValues = mw.loadData('Module:hardness values BE')
  +
else
  +
hardnessValues = mw.loadData('Module:hardness values')
  +
end
  +
if ValueFromValuesByKey(hardnessValues, key) == 0 then
  +
local result = {}
  +
for i,breakingTool in ipairs(value) do
  +
if breakingTool == 'pickaxe'
  +
or breakingTool == 'shovel'
  +
or breakingTool == 'axe'
  +
or breakingTool == 'hoe'
  +
or breakingTool == 'sword'
  +
or breakingTool == 'shears'
  +
then
  +
-- Skip.
  +
else
  +
table.insert(result, breakingTool)
  +
end
  +
end
  +
return result;
  +
else
  +
return value
  +
end
  +
end),
  +
}
  +
  +
-- 将true和false分别转换为'是'和'否'。
  +
local function TrueFalueMapping (value)
  +
if value == true then
  +
return '是'
  +
elseif value == false then
  +
return '否'
  +
else
  +
return value
  +
end
  +
end
  +
  +
-- 为数字添加逗号分隔符。
  +
local function FormatNumber (value)
  +
if type(value) == 'number' then
  +
local i, j, minus, int, fraction = tostring(value):find('([-]?)(%d+)([.]?%d*)')
  +
int = int:reverse():gsub("(%d%d%d)", "%1,")
  +
return minus .. int:reverse():gsub("^,", "") .. fraction
  +
else
  +
return value
  +
end
  +
end
  +
  +
-- 值映射方法,不设置则输出原值。
  +
local valueMappingMethod = {
  +
['blast resistance'] = FormatNumber,
  +
['hardness'] = FormatNumber,
  +
['maxstack'] = FormatNumber,
  +
['flame odds'] = FormatNumber,
  +
['burn odds'] = FormatNumber,
  +
['suffocating'] = TrueFalueMapping,
  +
['redstone conductor'] = TrueFalueMapping,
  +
['lava flammable'] = TrueFalueMapping,
  +
['breaking tool'] = (function (value)
  +
if type(value) == 'table' then
  +
local valueTable = {}
  +
local frame = mw.getCurrentFrame()
  +
for k, v in pairs( value ) 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 value
  +
end),
  +
['creative tab'] = (function (value)
  +
if type(value) == 'table' then
  +
local valueTable = {}
  +
for k, v in pairs( value ) do
  +
table.insert(valueTable, MappingValue('creative tab', v))
  +
end
  +
if #valueTable <= 0 then
  +
return "''无''"
  +
end
  +
return table.concat(valueTable, ",")
  +
end
  +
return value
  +
end),
  +
['creative category'] = (function (value)
  +
return MappingValue('creative category', value)
  +
end),
  +
['material'] = (function (value)
  +
return MappingValue('material', value)
  +
end),
  +
['material BE'] = (function (value)
  +
return MappingValue('material BE', value)
  +
end),
  +
['push reaction'] = (function (value)
  +
return MappingValue('push reaction', value)
  +
end),
  +
}
  +
  +
-- 提供值列表、类型名称、键值名称来获取值。返回原始数据类型。
  +
local function tryGetRawValue(values, valueType, targetName, onlyBE)
  +
local value
  +
if type(valueGettingMethod[valueType]) == 'function' then
  +
value = valueGettingMethod[valueType](values, targetName, onlyBE)
  +
else
  +
value = ValueFromValuesByKey(values, targetName)
  +
end
  +
return value
  +
end
  +
  +
-- 提供值列表、类型名称、键值名称来获取值。返回值应当是字符串。
  +
local function tryGetValue(values, valueType, targetName, onlyBE)
  +
local value = tryGetRawValue(values, valueType, targetName, onlyBE)
  +
if type(valueMappingMethod[valueType]) == 'function' then
  +
return valueMappingMethod[valueType](value)
  +
else
  +
return value
  +
end
  +
end
  +
  +
-- 获取值。
  +
local function GetValue(targetName, argType, argMode, nocat)
  +
if not ValueTypeExist(argType) then
  +
return '?[[Category:未知自动值类型]]'
  +
end
  +
  +
local frame = mw.getCurrentFrame()
  +
local values
  +
local valuesBE
  +
local onlyBE = false
  +
if hasBeData[argType] then
  +
if argMode == 'infobox'
  +
or argMode == 'content' then
  +
values = mw.loadData('Module:' .. argType .. ' values')
  +
valuesBE = mw.loadData('Module:' .. argType .. ' values BE')
  +
elseif argMode == 'onlyBE' then
  +
values = mw.loadData('Module:' .. argType .. ' values BE')
  +
onlyBE = true
  +
else
  +
values = mw.loadData('Module:' .. argType .. ' values')
  +
end
  +
else
  +
values = mw.loadData('Module:' .. argType .. ' values')
  +
end
  +
local value
  +
local valueBE
 
local category = ''
 
local category = ''
  +
local result
if not value then
 
  +
if values then
value = '[[Template:' .. type .. ' values#缺失的值|?]]'
 
  +
value = tryGetValue(values, argType, targetName, onlyBE)
local title = mw.title.getCurrentTitle()
 
if not args.nocat and title.namespace == 0 and not title.isSubpage then
+
if value == nil and argMode == 'onlyBE' then
category = '[[Category:缺失 ' .. type:lower() .. ']]'
+
values = mw.loadData('Module:' .. argType .. ' values')
  +
value = tryGetValue(values, argType, targetName, false)
  +
end
  +
if value == nil then
  +
value = '[[Template:' .. argType .. ' values#缺失值|?]]'
  +
local title = mw.title.getCurrentTitle()
  +
if not nocat and title.namespace == 0 and not title.isSubpage then
  +
category = '[[Category:缺失' .. (categoryMapping[argType:lower()] or argType:lower()) .. ']]'
  +
end
 
end
 
end
 
end
 
end
  +
if valuesBE then
return value .. category
 
  +
valueBE = tryGetValue(valuesBE, argType, targetName, true) or value
  +
end
  +
if valueBE then
  +
if argMode == 'infobox' then
  +
result = "'''" .. frame:expandTemplate { title = 'el', args = { 'je' } } .. ":'''" .. value .. "<br>'''" .. frame:expandTemplate { title = 'el', args = { 'be' } } .. ":'''" .. valueBE
  +
else
  +
result = value .. frame:expandTemplate { title = 'only', args = { 'je' } } .. "或" .. valueBE .. frame:expandTemplate { title = 'only', args = { 'be' } }
  +
end
  +
else
  +
result = value
  +
end
  +
result = result .. category
  +
return result
 
end
 
end
  +
  +
-- 去除参数字符串头尾的空格和换行符。
  +
local function StripSpaceAndLineAtBothEnds(str)
  +
return string.gsub(str, '^[%s\n]*(.-)[%s\n]*$', '%1')
  +
end
  +
  +
-- 将字符串转换为键值对表。
  +
local function LoadKeyValuePairsFromString(str)
  +
local strTable = {}
  +
local resultTable = {}
  +
local lastPoint = 0
  +
while true do
  +
local point1,point2 = string.find(str, "[^;]+", lastPoint + 1)
  +
if point1 == nil then
  +
break
  +
end
  +
lastPoint = point2
  +
table.insert(strTable, string.sub(str, point1, point2))
  +
end
  +
for i,strInTable in ipairs(strTable) do
  +
local key, value
  +
local point = string.find(strInTable, ":", 1)
  +
if point ~= nil then
  +
key = StripSpaceAndLineAtBothEnds(string.sub(strInTable, 1, point - 1))
  +
value = StripSpaceAndLineAtBothEnds(string.sub(strInTable, point + 1, string.len(strInTable)))
  +
else
  +
key = StripSpaceAndLineAtBothEnds(strInTable)
  +
end
  +
table.insert(resultTable, {key = key, value = value})
  +
end
  +
return resultTable
  +
end
  +
  +
-- 外部模块调用此函数。
  +
function p.getRawValue(targetName, valueType, onlyBE)
  +
local values
  +
if hasBeData[valueType] and onlyBE then
  +
values = mw.loadData('Module:' .. valueType .. ' values BE')
  +
else
  +
values = mw.loadData('Module:' .. valueType .. ' values')
  +
onlyBE = false
  +
end
  +
local value = tryGetRawValue(values, valueType, targetName, onlyBE)
  +
if value == nil and onlyBE then
  +
return p.getValue(targetName, valueType, false)
  +
end
  +
return value
  +
end
  +
  +
-- 外部模块调用此函数。
  +
function p.getValue(argTargetNames, argType, argMode, argNocat, doNotMerge)
  +
local targetNames = LoadKeyValuePairsFromString(mw.text.trim(argTargetNames or ''):lower())
  +
local argOriginalMode = argMode
  +
  +
if #targetNames < 1 then
  +
return GetValue('', argType, argMode, argNocat)
  +
end
  +
if #targetNames == 1 and targetNames.value == nil then
  +
return GetValue(targetNames[1].key, argType, argMode, argNocat)
  +
end
  +
  +
if argMode == 'infobox' then
  +
argMode = 'content'
  +
end
  +
  +
local resultEntries = {}
  +
  +
for i,keyValuePair in ipairs(targetNames) do
  +
local entryName = keyValuePair.value or Autolink.invlink( keyValuePair.key, 'nolink' )
  +
local entryValue = GetValue(keyValuePair.key, argType, argMode, argNocat)
  +
  +
local targetResultEntryFound = false
  +
if doNotMerge and doNotMerge ~= true then
  +
for i,resultEntry in ipairs(resultEntries) do
  +
if resultEntry.value == entryValue then
  +
targetResultEntryFound = true
  +
table.insert(resultEntry.names, entryName)
  +
break
  +
end
  +
end
  +
end
  +
if not targetResultEntryFound then
  +
table.insert(resultEntries, {
  +
names = { entryName },
  +
value = entryValue
  +
})
  +
end
  +
end
  +
  +
local resultStringTable = {}
  +
for i,targetResultEntry in ipairs(resultEntries) do
  +
local rowNames = {}
  +
for i,entryName in ipairs(targetResultEntry.names) do
  +
table.insert(rowNames, "'''"..entryName.."'''")
  +
end
  +
local rowName = table.concat(rowNames, '、')
  +
local rowValue = targetResultEntry.value
  +
table.insert(resultStringTable, rowName..":"..rowValue)
  +
end
  +
  +
if #resultStringTable == 1 then
  +
if argOriginalMode == 'infobox' and hasBeData[argType] then
  +
return GetValue(targetNames[1].key, argType, 'infobox', argNocat)
  +
else
  +
return resultEntries[1].value
  +
end
  +
else
  +
return table.concat(resultStringTable, "<br>")
  +
end
  +
end
  +
  +
-- 模板调用此函数。
  +
function p.value(f)
  +
local args = f
  +
local frame = mw.getCurrentFrame()
  +
if f == frame then
  +
args = require('Module:ProcessArgs').merge(true)
  +
end
  +
local argTargetNames = mw.text.trim(args[1] or ''):lower()
  +
local argType = args.type
  +
local argMode = args.mode or 'onlyJE'
  +
local argNocat = args.nocat
  +
local argNoMergeSameValues = args['autovalue-do-not-merge-rows']
  +
local doNotMerge = type(argNoMergeSameValues) == 'string' and #argNoMergeSameValues > 0
  +
  +
return p.getValue(argTargetNames, argType, argMode, argNocat, doNotMerge )
  +
end
  +
 
return p
 
return p

2023年11月10日 (五) 13:55的最新版本

本模块用于实现值提供器模板。

用法

此模块对外公开了以下方法:

  • p.value(f):模板使用的方法,会解析模板被传入的参数。
  • p.getValue(argTargetNames, argType, argMode, argNocat):其他模块可以使用的易于调用的方法。
  • p.getRawValue(targetName, valueType, onlyBE):直接返回原始数据类型、不进行转换为字符串的方法。每次调用只能处理单个目标名称。
参数
名称 p.value p.getValue
目标名称 1 argTargetNames
目标类型 type argType
数据模式 mode argMode
停用分类 nocat argNocat

目标名称

需要解析的一系列目标名称。

每一个目标名称应当是一个Reverselink的英文名称,之间使用;作为分割,分隔符之间可以插入空格、制表符和换行符。模块会自动从Module:Autolink获取名称,但可以通过目标名称:可读名称来覆盖。

{{Hardness values|
Structure Void;
Crafting Table;
Beehive;
Bee nest;
Chest:大箱子;
}}

结构空位:0[仅Java版]或-1[仅基岩版]
工作台:2.5[仅Java版]或2.5[仅基岩版]
蜂箱:0.6[仅Java版]或0.6[仅基岩版]
蜂巢:0.3[仅Java版]或0.3[仅基岩版]
大箱子:2.5[仅Java版]或2.5[仅基岩版]

目标类型

目标值的类型。

* 合适挖掘工具:{{#invoke: Autovalue | value
| Crafting Table
| type = breaking tool
}}
* 硬度:{{#invoke: Autovalue | value
| Crafting Table
| type = hardness
}}
* 爆炸抗性:{{#invoke: Autovalue | value
| Crafting Table
| type = blast resistance
}}
  • 合适挖掘工具:
  • 硬度:2.5
  • 爆炸抗性:2.5

数据模式

影响模块在数据于JE和BE有不同值时的输出方式。若没有JE和BE使用不同值的情况,模式对输出没有影响。

模式 输出 说明
onlyJE 0 只输出JE值。
content 0[仅Java版]或-1[仅基岩版] 适用于文内插入的使用{{only}}的叙述。
infobox Java版0
基岩版-1
适用于插入信息框的纵列叙述。
onlyBE -1 只输出BE值。

停用分类

指定后不再添加缺失值的维护分类。

依赖项

另见

实现
主要用途
分类
数据
数据名称 模板 数据模块 缺失值的维护分类 覆盖自动值的追踪分类
合适挖掘工具
breaking tool
{{Breaking tool values}} Module:Breaking tool values
Module:Breaking tool values BE
Category:缺失合适挖掘工具 Category:覆写合适挖掘工具的页面
硬度
hardness
{{Hardness values}} Module:Hardness values
Module:Hardness values BE
Category:缺失硬度 Category:覆写硬度的页面
爆炸抗性
blast resistance
{{Blast resistance values}} Module:Blast resistance values
Module:Blast resistance values BE
Category:缺失爆炸抗性 Category:覆写爆炸抗性的页面
材料
material
{{Material values}} Module:Autovalue/material mapping
Module:Material values
Category:缺失材料 Category:覆写材料的页面
基岩版材料
material BE
{{Material BE values}} Module:Autovalue/material BE mapping
Module:Material BE values
Category:缺失基岩版材料 Category:覆写基岩版材料的页面
最大堆叠
maxstack
{{Maxstack values}} Module:Maxstack values
Module:Maxstack values BE
Category:缺失最大堆叠 Category:覆写最大堆叠的页面
稀有度
rarity
{{Rarity values}} Module:Rarity values
Module:Rarity values BE
Category:覆写稀有度的页面
创造标签页
creative tab
{{Creative tab values}} Module:Autovalue/creative tab mapping
Module:Creative tab values
Category:缺失创造标签页 Category:覆写创造标签页的页面
创造分类
creative category
{{Creative category values}} Module:Autovalue/creative category mapping
Module:Creative category values
Category:缺失创造分类 Category:覆写创造分类的页面
窒息生物
suffocating
{{Suffocating values}} Module:Suffocating values
Module:Suffocating values BE
Category:缺失窒息生物 Category:覆写窒息生物的页面
红石导体
redstone conductor
{{Redstone conductor values}} Module:Redstone conductor values
Module:Redstone conductor values BE
Category:缺失红石导体 Category:覆写红石导体的页面
可替代
replaceable
{{Replaceable values}} Module:Replaceable values
Module:Replaceable values BE
Category:缺失可替代 Category:覆写可替代的页面
引燃几率
flame odds
{{Flame odds values}} Module:Flame odds values
Module:Flame odds values BE
Category:缺失引燃几率 Category:覆写引燃几率的页面
烧毁几率
burn odds
{{Burn odds values}} Module:Burn odds values
Module:Burn odds values BE
Category:缺失烧毁几率 Category:覆写烧毁几率的页面
熔岩可燃性
lava flammable
{{Lava flammable values}} Module:Lava flammable values
Module:Lava flammable values BE
Category:缺失熔岩可燃性 Category:覆写熔岩可燃性的页面
活塞推动行为
push reaction
{{Push reaction values}} Module:Autovalue/push reaction mapping
Module:Push reaction values
Module:Push reaction values BE
Category:缺失活塞推动行为 Category:覆写活塞推动行为的页面


语言
local p = {}
local Autolink = require( [[Module:Autolink]] )

--为维护分类提供名称。
local categoryMapping = {
	-- 方块数据
	['breaking tool'] = '合适挖掘工具',
	['blast resistance'] = '爆炸抗性',
	['hardness'] = '硬度',
	['material'] = '材料', -- JE
	['material BE'] = '基岩版材料', -- BE
	['suffocating'] = '窒息生物',
	['redstone conductor'] = '红石导体',
	['flame odds'] = '引燃几率',
	['burn odds'] = '烧毁几率',
	['lava flammable'] = '熔岩可燃性',
	['push reaction'] = '活塞推动行为',
	-- 物品数据
	['maxstack'] = '最大堆叠',
	['rarity'] = '稀有度',
	['creative tab'] = '创造标签页', -- JE
	['creative category'] = '创造分类', -- BE
}

-- 是否有对应的values BE数据表。
local hasBeData = {
	['breaking tool'] = true,
	['blast resistance'] = true,
	['hardness'] = true,
	['maxstack'] = true,
	['rarity'] = true,
	['suffocating'] = true,
	['redstone conductor'] = true,
	['flame odds'] = true,
	['burn odds'] = true,
	['lava flammable'] = true,
	['push reaction'] = true,
}

local function ValueTypeExist(valueType)
	return not not categoryMapping[valueType]
end

-- 从值列表按照键值获得值,找不到则返回键值。
local function MappingValue(mappingName, value)
	local mapping = mw.loadData('Module:Autovalue/' .. mappingName .. ' mapping')
	if mapping[value] then
		return mapping[value]
	else
		return value
	end
end

-- 从值列表按照键值获得值,有去除末尾s,有__fallback,找不到则返回nil。
local function ValueFromValuesByKey(values, key)
	local value = values[key]
	if value == nil then
		value = values[key:gsub('s$', '')]
	end
	if value == nil then
		value = values['__fallback']
	end
	return value
end

-- 值获取方法,不设置则直接使用ValueFromValuesByKey。
local valueGettingMethod = {
	['breaking tool'] = (function (values, key, onlyBE)
		local value = ValueFromValuesByKey(values, key)
		if type(value) ~= 'table' then
			return value
		end
		local hardnessValues
		if onlyBE then
			hardnessValues = mw.loadData('Module:hardness values BE')
		else
			hardnessValues = mw.loadData('Module:hardness values')
		end
		if ValueFromValuesByKey(hardnessValues, key) == 0 then
			local result = {}
			for i,breakingTool in ipairs(value) do
				if breakingTool == 'pickaxe'
				or breakingTool == 'shovel'
				or breakingTool == 'axe'
				or breakingTool == 'hoe'
				or breakingTool == 'sword'
				or breakingTool == 'shears'
				then
					-- Skip.
				else
					table.insert(result, breakingTool)
				end
			end
			return result;
		else
			return value
		end
	end),
}

-- 将true和false分别转换为'是'和'否'。
local function TrueFalueMapping (value)
	if value == true then
		return '是'
	elseif value == false then
		return '否'
	else
		return value
	end
end

-- 为数字添加逗号分隔符。
local function FormatNumber (value)
	if type(value) == 'number' then
		local i, j, minus, int, fraction = tostring(value):find('([-]?)(%d+)([.]?%d*)')
		int = int:reverse():gsub("(%d%d%d)", "%1,")
		return minus .. int:reverse():gsub("^,", "") .. fraction
	else
		return value
	end
end

-- 值映射方法,不设置则输出原值。
local valueMappingMethod = {
	['blast resistance'] = FormatNumber,
	['hardness'] = FormatNumber,
	['maxstack'] = FormatNumber,
	['flame odds'] = FormatNumber,
	['burn odds'] = FormatNumber,
	['suffocating'] = TrueFalueMapping,
	['redstone conductor'] = TrueFalueMapping,
	['lava flammable'] = TrueFalueMapping,
	['breaking tool'] = (function (value)
		if type(value) == 'table' then
			local valueTable = {}
			local frame = mw.getCurrentFrame()
			for k, v in pairs( value ) 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 value
	end),
	['creative tab'] = (function (value)
		if type(value) == 'table' then
			local valueTable = {}
			for k, v in pairs( value ) do
				table.insert(valueTable, MappingValue('creative tab', v))
			end
			if #valueTable <= 0 then
				return "''无''"
			end
			return table.concat(valueTable, ",")
		end
		return value
	end),
	['creative category'] = (function (value)
		return MappingValue('creative category', value)
	end),
	['material'] = (function (value)
		return MappingValue('material', value)
	end),
	['material BE'] = (function (value)
		return MappingValue('material BE', value)
	end),
	['push reaction'] = (function (value)
		return MappingValue('push reaction', value)
	end),
}

-- 提供值列表、类型名称、键值名称来获取值。返回原始数据类型。
local function tryGetRawValue(values, valueType, targetName, onlyBE)
	local value
	if type(valueGettingMethod[valueType]) == 'function' then
		value = valueGettingMethod[valueType](values, targetName, onlyBE)
	else
		value = ValueFromValuesByKey(values, targetName)
	end
	return value
end

-- 提供值列表、类型名称、键值名称来获取值。返回值应当是字符串。
local function tryGetValue(values, valueType, targetName, onlyBE)
	local value = tryGetRawValue(values, valueType, targetName, onlyBE)
	if type(valueMappingMethod[valueType]) == 'function' then
		return valueMappingMethod[valueType](value)
	else
		return value
	end
end

-- 获取值。
local function GetValue(targetName, argType, argMode, nocat)
	if not ValueTypeExist(argType) then
		return '?[[Category:未知自动值类型]]'
	end

	local frame = mw.getCurrentFrame()
	local values
	local valuesBE
	local onlyBE = false
	if hasBeData[argType] then
		if argMode == 'infobox'
		or argMode == 'content' then
			values = mw.loadData('Module:' .. argType .. ' values')
			valuesBE = mw.loadData('Module:' .. argType .. ' values BE')
		elseif argMode == 'onlyBE' then
			values = mw.loadData('Module:' .. argType .. ' values BE')
			onlyBE = true
		else
			values = mw.loadData('Module:' .. argType .. ' values')
		end
	else
		values = mw.loadData('Module:' .. argType .. ' values')
	end
	local value
	local valueBE
	local category = ''
	local result
	if values then
		value = tryGetValue(values, argType, targetName, onlyBE)
		if value == nil and argMode == 'onlyBE' then
			values = mw.loadData('Module:' .. argType .. ' values')
			value = tryGetValue(values, argType, targetName, false)
		end
		if value == nil then
			value = '[[Template:' .. argType .. ' values#缺失值|?]]'
			local title = mw.title.getCurrentTitle()
			if not nocat and title.namespace == 0 and not title.isSubpage then
				category = '[[Category:缺失' .. (categoryMapping[argType:lower()] or argType:lower()) .. ']]'
			end
		end
	end
	if valuesBE then
		valueBE = tryGetValue(valuesBE, argType, targetName, true) or value
	end
	if valueBE then
		if argMode == 'infobox' then
			result = "'''" .. frame:expandTemplate { title = 'el', args = { 'je' } } .. ":'''" .. value .. "<br>'''" .. frame:expandTemplate { title = 'el', args = { 'be' } } .. ":'''" .. valueBE
		else
			result = value .. frame:expandTemplate { title = 'only', args = { 'je' } } .. "或" .. valueBE .. frame:expandTemplate { title = 'only', args = { 'be' } }
		end
	else
		result = value
	end
	result = result .. category
	return result
end

-- 去除参数字符串头尾的空格和换行符。
local function StripSpaceAndLineAtBothEnds(str)
	return string.gsub(str, '^[%s\n]*(.-)[%s\n]*$', '%1')
end

-- 将字符串转换为键值对表。
local function LoadKeyValuePairsFromString(str)
	local strTable = {}
	local resultTable = {}
	local lastPoint = 0
	while true do
		local point1,point2 = string.find(str, "[^;]+", lastPoint + 1)
		if point1 == nil then
			break
		end
		lastPoint = point2
		table.insert(strTable, string.sub(str, point1, point2))
	end
	for i,strInTable in ipairs(strTable) do
		local key, value
		local point = string.find(strInTable, ":", 1)
		if point ~= nil then
			key = StripSpaceAndLineAtBothEnds(string.sub(strInTable, 1, point - 1))
			value = StripSpaceAndLineAtBothEnds(string.sub(strInTable, point + 1, string.len(strInTable)))
		else
			key = StripSpaceAndLineAtBothEnds(strInTable)
		end
		table.insert(resultTable, {key = key, value = value})
	end
	return resultTable
end

-- 外部模块调用此函数。
function p.getRawValue(targetName, valueType, onlyBE)
	local values
	if hasBeData[valueType] and onlyBE then
		values = mw.loadData('Module:' .. valueType .. ' values BE')
	else
		values = mw.loadData('Module:' .. valueType .. ' values')
		onlyBE = false
	end
	local value = tryGetRawValue(values, valueType, targetName, onlyBE)
	if value == nil and onlyBE then
		return p.getValue(targetName, valueType, false)
	end
	return value
end

-- 外部模块调用此函数。
function p.getValue(argTargetNames, argType, argMode, argNocat, doNotMerge)
	local targetNames = LoadKeyValuePairsFromString(mw.text.trim(argTargetNames or ''):lower())
	local argOriginalMode = argMode
	
	if #targetNames < 1 then
		return GetValue('', argType, argMode, argNocat)
	end
	if #targetNames == 1 and targetNames.value == nil then
		return GetValue(targetNames[1].key, argType, argMode, argNocat)
	end

	if argMode == 'infobox' then
		argMode = 'content'
	end

	local resultEntries = {}

	for i,keyValuePair in ipairs(targetNames) do
		local entryName = keyValuePair.value or Autolink.invlink( keyValuePair.key, 'nolink' )
		local entryValue = GetValue(keyValuePair.key, argType, argMode, argNocat)
		
		local targetResultEntryFound = false
		if doNotMerge and doNotMerge ~= true then
			for i,resultEntry in ipairs(resultEntries) do
				if resultEntry.value == entryValue then
					targetResultEntryFound = true
					table.insert(resultEntry.names, entryName)
					break
				end
			end
		end
		if not targetResultEntryFound then
			table.insert(resultEntries, {
				names = { entryName },
				value = entryValue
			})
		end
	end

	local resultStringTable = {}
	for i,targetResultEntry in ipairs(resultEntries) do
		local rowNames = {}
		for i,entryName in ipairs(targetResultEntry.names) do
			table.insert(rowNames, "'''"..entryName.."'''")
		end
		local rowName = table.concat(rowNames, '、')
		local rowValue = targetResultEntry.value
		table.insert(resultStringTable, rowName..":"..rowValue)
	end

	if #resultStringTable == 1 then
		if argOriginalMode == 'infobox' and hasBeData[argType] then
			return GetValue(targetNames[1].key, argType, 'infobox', argNocat)
		else
			return resultEntries[1].value
		end
	else
		return table.concat(resultStringTable, "<br>")
	end
end

-- 模板调用此函数。
function p.value(f)
	local args = f
	local frame = mw.getCurrentFrame()
	if f == frame then
		args = require('Module:ProcessArgs').merge(true)
	end
	local argTargetNames = mw.text.trim(args[1] or ''):lower()
	local argType = args.type
	local argMode = args.mode or 'onlyJE'
	local argNocat = args.nocat
	local argNoMergeSameValues = args['autovalue-do-not-merge-rows']
	local doNotMerge = type(argNoMergeSameValues) == 'string' and #argNoMergeSameValues > 0

	return p.getValue(argTargetNames, argType, argMode, argNocat, doNotMerge )
end

return p