本站文本内容除另有声明外,转载时均必须注明出处,并遵守CC BY-NC-SA 3.0协议。(转载须知)
本站是中文Minecraft Wiki的镜像站,与Mojang Studios、Weird Gloop没有从属关系。(免责声明)
模块:Autovalue
本模块用于实现值提供器模板。
用法
此模块对外公开了以下方法:
p.value(f)
:模板使用的方法,会解析模板被传入的参数。p.getValue(argTargetNames, argType, argMode, argNocat, argLastNamedOthers)
:其他模块可以使用的易于调用的方法。p.getRawValue(targetName, valueType, onlyBE)
:直接返回原始数据类型、不进行转换为字符串的方法。每次调用只能处理单个目标名称。
名称 | p.value | p.getValue |
---|---|---|
目标名称 | 1 | argTargetNames |
目标类型 | type | argType |
数据模式 | mode | argMode |
停用分类 | nocat | argNocat |
最后值为其他 | autovalue-last-named-others | argLastNamedOthers |
目标名称
需要解析的一系列目标名称。
每一个目标名称应当是一个中文名称,之间使用;
作为分割,分隔符之间可以插入空格、制表符和换行符。显示名称可以通过目标名称:显示名称
来覆盖。
{{Hardness values| 结构空位; 工作台; 蜂巢; 蜂箱; 箱子:大箱子; }}
结构空位:0
工作台、大箱子:2.5
蜂巢:0.3
蜂箱:0.6
目标类型
目标值的类型。
* 合适挖掘工具:{{#invoke: Autovalue | value | 工作台 | type = breaking tool }} * 硬度:{{#invoke: Autovalue | value | 工作台 | type = hardness }} * 爆炸抗性:{{#invoke: Autovalue | value |工作台 | type = blast resistance }}
数据模式
影响模块在数据于JE和BE有不同值时的输出方式。若没有JE和BE使用不同值的情况,模式对输出没有影响。
模式 | 输出 | 说明 |
---|---|---|
onlyJE | 0 | 只输出JE值。 |
content | 0 |
适用于文内插入的使用{{only}} 的叙述。
|
infobox | Java版:0 基岩版:-1 |
适用于插入信息框的纵列叙述。 |
onlyBE | -1 | 只输出BE值。 |
停用分类
指定后不再添加缺失值的维护分类。
最后值为其他
指定后,最后一个组的名称会设置为其他。
依赖项
另见
- 实现
- 主要用途
- Module:Autovalue builders
- Module:Autovalue infobox
- Module:Breaking table
{{Hardness values}}
{{Blast resistance values}}
- 分类
- 数据
local p = {}
local valueTypes = mw.loadData('Module:Autovalue/types')
local groups = mw.loadData('Module:Autovalue/groups')
local function tableHasValue (targetTable, targetValue)
for index, value in ipairs(targetTable) do
if index ~= 'metatable' and value == targetValue then
return true
end
end
return false
end
local function IsSameArray(arr1, arr2)
for i,entry in ipairs(arr1) do
if not tableHasValue (arr2, entry) then
return false
end
end
for i,entry in ipairs(arr2) do
if not tableHasValue (arr1, entry) then
return false
end
end
return true
end
local function ValueTypeExist(valueType)
return not not valueTypes[valueType]
end
local function MappingKey(key, mappingName, onlyBE)
return p.getRawValue(key, mappingName, onlyBE) or key
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
-- 键映射方法。
local keyMappingMethod = {
}
-- 值获取方法,不设置则直接使用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 function FormatRomanNumber(value)
if value == 1 then return 'I' end
if value == 2 then return 'II' end
if value == 3 then return 'III' end
if value == 4 then return 'IV' end
if value == 5 then return 'V' end
if value == 6 then return 'VI' end
return FormatNumber (value)
end
-- 值映射方法,不设置则输出原值。
local valueMappingMethod = {
['blast resistance'] = FormatNumber,
['hardness'] = FormatNumber,
['maxstack'] = FormatNumber,
['flame odds'] = FormatNumber,
['burn odds'] = FormatNumber,
['friction'] = FormatNumber,
['speed factor'] = FormatNumber,
['suffocating'] = TrueFalueMapping,
['redstone conductor'] = TrueFalueMapping,
['lava flammable'] = TrueFalueMapping,
['replaceable'] = TrueFalueMapping,
['solid'] = TrueFalueMapping,
['rarity'] = (function (value)
return MappingValue('rarity', 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),
['instrument'] = (function (value)
return MappingValue('instrument', value)
end),
['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),
['map color'] = (function (value)
if value == 'NONE' or value == '#0' then
return '透明'
else
if type(value) == 'string' then
local colorString
if string.sub(value, 1, 1) == '#' then
colorString = value
else
local colorTable = MappingValue('map color', value)
if type(colorTable) == 'table' then
colorString = '#'
..string.format('%02X',colorTable[1])
..string.format('%02X',colorTable[2])
..string.format('%02X',colorTable[3])
end
end
if colorString then
return mw.getCurrentFrame():expandTemplate { title = 'color', args = {string.upper(colorString)} }
else
return value
end
else
return value
end
end
end),
['durability'] = (function (value)
if type(value) == 'number' then
if value == 0 then
return '\'\'无\'\''
else
return FormatNumber(value)
end
else
return value
end
end),
['burn duration'] = (function (value)
if type(value) == 'number' then
if value == 0 then
return '\'\'无\'\''
else
if value % 2 ~= 0 then
return FormatNumber(value)..'游戏刻('..FormatNumber(value / 20.0)..'秒,<span class="explain" title="在高炉或烟熏炉中为'..FormatNumber(math.floor(value * 0.5) / 100.0)..'个物品" >'..FormatNumber(value / 200.0)..'个物品</span>)'
else
return FormatNumber(value)..'游戏刻('..FormatNumber(value / 20.0)..'秒,'..FormatNumber(value / 200.0)..'个物品)'
end
end
else
return value
end
end),
['food properties'] = (function (value)
if type(value) == 'table' then
if (not value[1]) or (not value[2]) then
return '\'\'无\'\''
else
return mw.getCurrentFrame():expandTemplate { title = 'Hunger', args = {value[1]} }..'+'..FormatNumber(2 * value[1] * value[2])..'饱和度'
end
else
return value
end
end),
['enchantment max level'] = FormatRomanNumber,
['enchantment category'] = (function (value)
return MappingValue('enchantment category', value)
end),
['enchantment flag'] = (function (value)
return MappingValue('enchantment flag', value)
end),
['enchantment rarity'] = (function (value)
return MappingValue('enchantment rarity', value)
end),
['enchantment incompatible'] = (function (value)
if type(value) == 'table' then
local valueTable = {}
for k, v in pairs( value ) do
table.insert(valueTable, '[['..MappingValue('enchantment incompatible', v)..']]')
end
if #valueTable <= 0 then
return "''无''"
end
return table.concat(valueTable, ",")
end
return value
end),
['enchantment cost'] = (function (value)
if type(value) == 'table' then
local valueTable = {}
for i, v in ipairs( value ) do
table.insert(valueTable, ''..FormatRomanNumber(i)..'级:'..v[1]..' – '..v[2])
end
if #valueTable <= 0 then
return nil
end
return table.concat(valueTable, "<br>")
end
return value
end),
}
local function ExpandGroups(targetNames)
local names = {}
for i,v in ipairs(targetNames) do names[i] = v end
local excludesFromExpand = {}
local anyExpanded = true
while anyExpanded do
anyExpanded = false
local newNames = {}
for i,nameInNames in ipairs(names) do
local name = nameInNames
local titleOverwrite
local isTable = false
if type(nameInNames) == 'table' then
isTable = true
name = nameInNames.key
titleOverwrite = nameInNames.value
end
local group = groups[name]
if group and not excludesFromExpand[name] then
anyExpanded = true
excludesFromExpand[name] = true
for i,value in ipairs(group) do
if isTable then
table.insert(newNames, {key = value, value = titleOverwrite})
else
table.insert(newNames, value)
end
end
else
table.insert(newNames, nameInNames)
end
end
names = newNames
end
return names
end
local function MergeGroups(targetNames)
for groupName, group in pairs(groups) do
if IsSameArray(targetNames, ExpandGroups(group)) then
return {groupName}
end
end
return targetNames
end
-- 提供值列表、类型名称、键值名称来获取值。返回原始数据类型。
local function tryGetRawValue(values, valueType, targetName, onlyBE)
if type(keyMappingMethod[valueType]) == 'function' then
targetName = keyMappingMethod[valueType](targetName, onlyBE)
elseif type(valueTypes[valueType].keyMap) == 'string' then
targetName = MappingKey(targetName, valueTypes[valueType].keyMap, onlyBE or valueType == 'creative category')
end
if type(valueGettingMethod[valueType]) == 'function' then
return valueGettingMethod[valueType](values, targetName, onlyBE)
else
return ValueFromValuesByKey(values, targetName)
end
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 valueTypes[argType].beTable 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
end
if valuesBE then
valueBE = tryGetValue(valuesBE, argType, targetName, true)
end
if value == nil and valueBE ~= nil then
value = valueBE
valueBE = nil
end
if value == nil then
if valueTypes[argType].noNullError then
value = '\'\'无\'\''
else
--value = '[[Template:' .. argType .. ' values#缺失值|?]]'
value = '?'
local title = mw.title.getCurrentTitle()
if not nocat and title.namespace == 0 and not title.isSubpage then
category = '[[Category:缺失' .. (valueTypes[argType].name) .. ']]'
end
end
end
if valueBE and value ~= valueBE then
local linebreak = ''
if valueTypes[argType].multiline then
linebreak = '<br>'
end
if argMode == 'infobox' then
local Editions = require( [[Module:Editions]] )
result = "'''" .. Editions.editions{ 'je', nocat = true } .. "''':" .. linebreak .. value .. "<br>'''" .. Editions.editions{ 'be', nocat = true } .. "''':" .. linebreak .. valueBE
else
result = value .. frame:expandTemplate { title = 'only', args = { 'je' } } .. linebreak .. "或" .. linebreak .. 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 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
-- 将字符串转换为键值对表。
local function LoadKeyValuePairsFromString(str, keyValueSplitter, keyValuePairsSplitter, nokvsplitterAsValue)
local resultTable = {}
local strTable = StringToArray(str, keyValuePairsSplitter)
for i,strInTable in ipairs(strTable) do
local key, value
local point = string.find(strInTable, keyValueSplitter, 1)
if point ~= nil then
key = StripSpaceAndLineAtBothEnds(string.sub(strInTable, 1, point - 1))
value = StripSpaceAndLineAtBothEnds(string.sub(strInTable, point + 1, string.len(strInTable)))
else
if nokvsplitterAsValue then
value = StripSpaceAndLineAtBothEnds(strInTable)
else
key = StripSpaceAndLineAtBothEnds(strInTable)
end
end
table.insert(resultTable, {key = key, value = value})
end
return resultTable
end
-- 外部模块调用此函数。
function p.getRawValue(targetName, valueType, onlyBE)
if not ValueTypeExist(valueType) then
return
end
local values
if valueTypes[valueType].beTable 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.getRawValue(targetName, valueType, false)
end
return value
end
-- 外部模块调用此函数。
function p.getValue(argTargetNames, argType, argMode, argNocat, doNotMerge, lastNamedOthers)
local targetNames = LoadKeyValuePairsFromString(mw.text.trim(argTargetNames or ''), ':', ';')
local argOriginalMode = argMode
targetNames = ExpandGroups(targetNames)
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 keyValuePair.key
local entryValue = GetValue(keyValuePair.key, argType, argMode, argNocat)
local targetResultEntryFound = false
--if 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
if lastNamedOthers and #resultEntries > 0 and string.sub(resultEntries[#resultEntries].value,1,1) ~= '?' then
resultEntries[#resultEntries].names = {'其他'}
end
for i,targetResultEntry in ipairs(resultEntries) do
targetResultEntry.names = MergeGroups(targetResultEntry.names)
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
local resultString
if #resultStringTable == 1 then
if argOriginalMode == 'infobox' and valueTypes[argType].beTable then
resultString = GetValue(targetNames[1].key, argType, 'infobox', argNocat)
else
resultString = resultEntries[1].value
end
else
resultString = table.concat(resultStringTable, "<br>")
end
return resultString
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 '')
local argType = args.type
local argMode = args.mode or 'onlyJE'
local argNocat = args.nocat
local argLastNamedOthers = args['autovalue-last-named-others']
local argNoMergeSameValues = args['autovalue-do-not-merge-rows']
local doNotMerge = type(argNoMergeSameValues) == 'string' and #argNoMergeSameValues > 0
return p.getValue(argTargetNames, argType, argMode, argNocat, doNotMerge, argLastNamedOthers )
end
-- 外部模块调用此函数。
function p.expandGroups(targetNames)
return ExpandGroups(targetNames)
end
function p.mergeGroups(targetNames)
return MergeGroups(targetNames)
end
-- 模板调用此函数。
function p.expandGroupsTemplate(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 '')
local targetNames = StringToArray(mw.text.trim(argTargetNames or ''), ',')
return ExpandGroups(targetNames)
end
return p