Minecraft Wiki

由于与微软方面的协商问题,本站应要求修改了Logo等图像。详情见此

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

了解更多

Minecraft Wiki
Advertisement

本模块生成一个带有战利品信息的表格。

用法[]

以下具体信息请查看对应模板的文档。

all函数[]

嵌套模板:Template:LootChest

隐式参数输入若干结构ID值,生成这些结构箱子中的战利品信息。战利品ID值取决于JSON文件中的值。

若Java和基岩版的结构ID值不同的,需要同时输入参数。

{{LootChest|bastion_bridge|bastion_other|bastion_hoglin_stable|<!-- Java -->bastion_treasure|<!-- Bedrock -->buriedtreasure}}

item函数[]

嵌套模板:Template:LootChestItem

隐式参数输入若干物品的命名空间ID,生成这些物品可被获取的结构名信息。

{{LootChestItem|emerald|apple}}

维护[]

模块使用JSON文件生成信息表。

版本 JSON版本号 最后更新日期
Java版 1.17.1 2021年9月12日 (日) 05:31 (UTC)(更新
Java开发版 当前继承于Java正式版 2021年9月12日 (日) 05:31 (UTC)(更新
基岩版 1.17.11 2021年9月12日 (日) 05:31 (UTC)(更新
基岩Beta版 1.17.30.25 2021年9月12日 (日) 05:31 (UTC)(更新

Json的数据结构是:

{
    "structure ID": {

    },
    "structure ID": {

    }
}

您可以使用此脚本生成JSON,只需放置在游戏内的\chests文件夹中运行即可。

配置[]

模块使用配置页面进行控制。

页面:模块:LootChest/config

  • switch (对开发/Beta版进行开关)
  • header (表格开头的文本,用于不同语言本地化)
  • report (报错信息)
  • mark (物品前后缀的标注信息)
  • debug
    • onlyJava (只显示Java版的内容)
    • onlyBedrock (只显示bedrock的内容)
  • style (两个生成表的自定义样式)
  • json (生成表的JSON文件页面名)
  • functions (指定读取哪些function至下一级转换)
    • functionsName (对应的function名,其中包含了一个表。表的第一个值是函数的数值对应,会读取为函数的value值。如果指定二三值且存在这两个值,自动使用a-b式链接)
  • customize (定制物品名/结构名的转换方案,如果启用则使用config末尾的函数替代代码中的对应的函数。
  • itemLink (输入物品命名空间ID和配置,返回显示内容的函数,如果customize中启用本函数。)
  • struLink (同上)

转换[]

模块使用转换JSON表进行物品名,结构名等的转换。
页面:模块:LootChest/cov.json

  • structure
    • text (结构的显示文本,输入到Sprite的text参数,结构ID→显示文本)
    • sprite-data-type (结构Sprite的数据类型,默认为EnvSprite)
    • sprite-id (用于生成图的结构ID,输入到Sprite的id参数,结构ID→Sprite ID)
  • item
    • sprite-data-type (设置物品Sprite的数据类型,默认为ItemSprite)
    •  cov (item的结构转换表)
      • id/name/text/link (默认将item的命名空间ID输入到Sprite的1参数,可用这些键值替代模板的参数)
      • function (如果存在某个函数指定,那使用function内的表重新覆盖Sprite参数)
        • id/name/text/link
      • aux (如果存在物品附加值,那使用aux内的表重新覆盖Sprite参数)
        • id/name/text/link (默认将item的命名空间ID输入到Sprite的1参数,可用这些键值替代模板的参数)
        • function (如果存在某个函数指定,那使用function内的表重新覆盖Sprite参数)
          • id/name/text/link
  • note (注释信息)
    • functions (函数指定的注释,具有某个函数定义则添加对应注释)
      • functionName (对应的function名)
        • valueName (对应function的值内容)
    • assign (自定义的注释,格式为命名空间ID:注释内容)

本地化[]

请将本段文本翻译至其他语言。

结构名和物品名使用模块:Sprite生成一个带图标的链接,这意味着如果本地没有此模块,将无法使用内置转换函数。不过可以在配置中启用独立转换函数(参见配置页文档)。

对于物品名,默认会将命名空间ID作为模块:Sprite的一参数传入,可以通过转换表来补充或改变参数内容(参见转换表文档)。如果一参数没有被转换,那么会进行简单处理(下划线替换,后缀删除等)。另外,如果一个物品属于方块的数据组,那么需要在转换组中为物品特殊声明(type=block),才可以正常生成Sprite图标。

对于结构名,没有一个标准的命名格式,因此必须同时传入本地化翻译和模块:Sprite要求的参数值。同样,如果数据组特殊,也需要特殊声明(data-type=BlockSprite)。

对于注释,转换表使用了两种方案。一,对于损坏或魔咒,有模板注释自动添加。二,可以通过制定命名空间ID给其添加注释。

对于以上三者,如果有特殊的使用需求,则可以在配置中启用独立转换函数。

此模块目前处于Beta版,有问题或需求建议优先在相关讨论话题中进行通知,以进行代码统一修改。

local getArgs = require('Module:Arguments').getArgs
local config = require('Module:LootChest/config')
local cov = config['json']['cov']
local sprite, alink
if not(config['customize']['itemLink'] and config['customize']['struLink'])
    then
    sprite = require('Module:Sprite').link
end
if config['customize']['noUseAutoLink'] == true
    then
    alink = function(a) return a end
else
    alink = require('Module:Autolink').invlink
end

local p = {}

local function makeInvokeFunc(funcName)
    return function (frame)
        local args = getArgs(frame)
        return p[funcName](args)
    end
end

function struLink(name)
    -- 输入结构的ID,返回最后结果。

    local text = name
    if cov['structure']['text'][name]
        then
        text = cov['structure']['text'][name]
    end

    local id = ''
    if cov['structure']['sprite-id'][name]
        then
        id = cov['structure']['sprite-id'][name]
    end

    local dataType
    if cov['structure']['sprite-data-type'][name]
        then
        dataType = cov['structure']['sprite-data-type'][name]
    else
        dataType = cov['structure']['sprite-data-type']['default']
    end

    local link = 'none'
    if text:find('%|')
        then
        link = text:match('%[%[(.*)%|')
        text = text:match('%|(.*)%]%]')
    end

    return sprite({['data'] = dataType, ['id'] = id, ['link'] = link, ['text'] = text})

end

function ref(list)
    -- 输入物品的命名空间ID和itemLink最后的显示结果,对齐检索cov.json并添加注释。
    local ref = ""
    local generator = function(text, name)
        return mw.getCurrentFrame():callParserFunction('#tag:ref', {text, ['name'] = name})
    end

    for _, entry in ipairs(list)
        do
        ref = ref..generator(entry[1], entry[2])
    end

    return ref
end


function itemLink(NsId, aux, functions, ref)
        -- 输入物品的命名空间ID,返回最终的显示结果。

    local enName, id, link, text, dataType
    local refText = {}
    enName = NsId:gsub('_', ' ')

        --- 如果在cov.json中存在转换规则,则进行转换,否则直接将命名空间ID作为英文名输入sprite
    local itemCov = {}
    if cov['item']['cov'][NsId]
        then
        itemCov = cov['item']['cov'][NsId]
        if aux and itemCov['aux']
            then
            itemCov = itemCov['aux'][tonumber(aux)] or itemCov
        end
        if itemCov['name'] then enName = itemCov['name'] end
        if itemCov['id'] then id = itemCov['id'] end
        if itemCov['link'] then link = itemCov['link'] end
        if itemCov['text'] then text = itemCov['text'] end
    end

    local Er, Sd, dataNum
    local funcCov
    for _, func in ipairs(functions) do
        funcCov = itemCov['functions']
        if funcCov and funcCov[func['function']] and funcCov[func['function']][tonumber(func['value']) or func['value']]
            then
            funcCov = funcCov[func['function']][tonumber(func['value']) or func['value']]
            if funcCov['name'] then enName = funcCov['name'] end
            if funcCov['id'] then id = funcCov['id'] end
            if funcCov['link'] then link = funcCov['link'] end
            if funcCov['text'] then text = funcCov['text'] end
        end
        Er = Er or func['function'] == 'enchant_randomly' or func['function'] == 'enchant_with_levels' or func['function'] == 'specific_enchants'
        Sd = Sd or func['function'] == 'set_damage'
    end
    text = text or alink(enName):gsub('.*%|', '')
    if Er and Sd and config['mark']['damaged enchanted']
        then
        text = config['mark']['damaged enchanted']:gsub('$s',text)
        else
        if Er then text = config['mark']['enchanted']:gsub('$s',text) end
        if Sd then text = config['mark']['damaged']:gsub('$s',text) end
    end
    dataType = cov['item']['sprite-data-type'][NsId] or cov['item']['sprite-data-type']['default']

    enName = sprite({['data'] = dataType, [1] = enName, ['id'] = id, ['link'] = link, ['text'] = text})

    for _, entry in ipairs(ref)
        do
        table.insert(refText, entry[2])
    end
    table.sort(refText)

    return enName..'<!--ref:'..table.concat(refText, ', ')..'-->'

end

function chanceCount(weightProportion, rolls)
        -- 概率计算函数

    if type(rolls) == "table"
        then
        local fp = 1 - weightProportion--failureProbability
        local sum = 0
        for i = rolls['min'], rolls['max'] do
            sum = sum + math.pow(fp, i)
        end
        return string.format("%.4f", 1 - (sum / (rolls['max'] - rolls['min'] + 1)))
        else
        return string.format("%.4f", 1 - math.pow((1 - weightProportion), rolls))
    end
end

function getItemStack(item, poolFuncs, edition)

        local functions = item['functions'] or {}
        for _,v in ipairs(poolFuncs) do table.insert(functions,v) end
        local covSingle, funcName, funcValue
        local id = (item['name'] or 'nothing'):gsub('minecraft:', '')
        local aux = 0
        local funcList = {}
        local count, averageCount = 1, 1
        local ref = {}

        ---遍历所有函数
        for _, func in pairs(functions) do
            funcName = func['function']:gsub('minecraft:','')
            funcValue = funcName
            if funcName == 'set_count'
                then
                count = func['count']
            elseif funcName =='set_data'
                then
                aux = func['data']
            elseif funcName =='exploration_map' and id == 'map'
                then
                id = 'buried_treasure_map'--此处使用英文名而非nsid以作区分
            else

                covSingle = config['function'][funcName]
                if covSingle
                    then

                    ---处理函数值
                    if covSingle[1]
                        then
                        if type(func[covSingle[1]]) == 'table' and func[covSingle[1]]['min']
                            then funcValue = tostring(func[covSingle[1]]['min']) .. '-'..tostring(func[covSingle[1]]['max'])
                        else
                            funcValue = tostring(func[covSingle[1]]):gsub('minecraft:','')
                        end
                    end
                    ---储存各个函数
                    table.insert(
                                    funcList,
                                    {['function'] = funcName,
                                     ['value'] = funcValue})

                    --处理注释
                    local funcRefList = cov['note']['functions']
                    if funcRefList[funcName] and funcRefList[funcName][tonumber(funcValue) or funcValue]
                    then
                        table.insert(ref, {funcRefList[funcName][tonumber(funcValue) or funcValue],
                        covSingle['name'] or funcName .. ':'..((config['function'][funcValue] or {})['name'] or funcValue)})
                    end
                end
            end
        end

        ---处理物品数量
        if type(count) == 'table'
            then
            if count['max'] ~= count['min']
                then
                averageCount = (count['min'] + count['max']) /2
                count = tostring(count['min']) ..
           '-'..tostring(count['max'])
                else
                averageCount = count['min']
                count = tostring(count['min'])
            end
            else
            averageCount = count
            count = tostring(count)
        end

        --此处使用硬编码以区分游戏中做特殊处理的物品
        if id == 'book' and funcList[1] and funcList[1]['function']:match('enchant')
            then id = 'enchanted_book'
        elseif id == 'map' and edition:find('java')
            then id = 'empty_map'--此处使用英文名而非nsid以作区分
        end

        --处理注释
        if cov['note']['assign'][id]
            then
            table.insert(ref, {cov['note']['assign'][id], id})
        end

        return {
            ['id'] = id,
            ["value"] = count,
            ["averageValue"] = averageCount,
            ["weight"] = item['weight'] or 1,
            ['functions'] = funcList,
            ["aux"] = tostring(aux),
            ['ref'] = ref
            }
end

function dataParsing(args, edition, genre)
    -- 获取数据table,同时用于all模式和item模式。
    local loot = config['json'][edition]

    local struList, listNum = {}, 1
    local poorsValue, stru, itemNum, rItemNum, poolsList
    local poorsWeight, rolls
    -- 预定义循环内变量,分别为函数体内使用,第一层for使用,第二层for使用

    if genre == "all" then loopPrimer = loot else loopPrimer = args end

    for q, w in pairs(loopPrimer) do
        --结构循环
        itemNum, rItemNum = 1, 1

        poolsList, poorsValue = {}, {}

        if genre == "all" then stru = q else stru = w end

        if loot[stru] ~= nil
            then

            for o, pool in ipairs(loot[stru]['pools']) do
                --奖池循环

                poorsWeight = 0
                
                
                rolls = pool['rolls']


                if type(rolls) == 'table'
                    then
                    poorsValue[o] = rolls['min'] .. '-'..rolls['max']
                else
                    poorsValue[o] = tostring(rolls)
                end

                for _, itemStack in ipairs(pool['entries']) do
                    --物品循环
                    poolsList[itemNum] = getItemStack(itemStack, pool['functions'] or {}, edition)
                    poolsList[itemNum]['pools'] = o
                    poorsWeight = poorsWeight + poolsList[itemNum]['weight']
                    itemNum = itemNum + 1
                end
                --到这里为止,poolsList包含了一个奖池的全部信息,然后在下一个循环进行几率等内容的计算,之后在最外层进行排序。

                for n in ipairs(pool['entries']) do
                    --物品循环
                    poolsList[rItemNum]['weightProportion'] = tonumber(poolsList[rItemNum]['weight']) / poorsWeight
                    poolsList[rItemNum]['weightProportionOut'] = '<sup>'..tostring(poolsList[rItemNum]['weight']) .. '</sup>/<sub>'..tostring(poorsWeight) .. '</sub>'
                    poolsList[rItemNum]['chance'] = chanceCount(poolsList[rItemNum]['weightProportion'], rolls)
                    poolsList[rItemNum]['chanceOut'] = tonumber(poolsList[rItemNum]['chance'] * 100) .. '%'
                    poolsList[rItemNum]['itemNum'] = string.format("%.2f", poolsList[rItemNum]['averageValue'] * poolsList[rItemNum]['chance'])
                    poolsList[rItemNum]['boxNum'] = string.format("%.1f", 1 / poolsList[rItemNum]['chance'])
                    rItemNum = rItemNum + 1
                end

                table.sort(poolsList, function(a, b) return a['chance'] > b['chance'] end)

            end
            struList[listNum] = {}
            struList[listNum]['name'] = stru
            struList[listNum]['value'] = poolsList
            struList[listNum]['poolsValue'] = poorsValue
            struList[listNum]['poolNum'] = #loot[stru]['pools']
            struList[listNum]['itemNum'] = itemNum - 1
            listNum = listNum + 1
        else
            struList[listNum] = {}
            struList[listNum]['poolNum'] = 0
            struList[listNum]['itemNum'] = 0
            listNum = listNum + 1
        end

    end

    table.sort(struList, function(a, b) return a['itemNum'] > b['itemNum'] end)

    return struList
end

function getTableAll(data)
    --获取all函数的结果文本。
    local wikiTable, poolNum, wikiTablePart = '', '', {}

    for i, k in ipairs(data) do
        if k['poolNum'] ~= 0
            then
            poolNum = k['poolNum']
            --表头部分
            wikiTable = wikiTable..'<div>\n{| class="wikitable sortable jquery-tablesorter" style="'..config['style']['allTableStyle'] .. '"\n!colspan="' .. (poolNum * 2 + 4)

            if config['customize']['struLink'] then
                wikiTable = wikiTable..'"|'..config['struLink'](k['name']) .. '\n|-\n'
            else
                wikiTable = wikiTable..'"|'..struLink(k['name']) .. '\n|-\n'
            end
            --此处

            wikiTable = wikiTable..
            '! rowspan=2 | ' .. config['header']['item'] .. '\n' ..
            '! colspan='..poolNum..' | ' .. config['header']['stack'] .. '\n' ..
            '! colspan='..poolNum..' | ' .. config['header']['weight'] .. '\n' ..
            '! rowspan=2 | ' .. config['header']['probability'] .. '\n' ..
            '! rowspan=2 | ' .. config['header']['itemNumber'] .. '\n' ..
            '! rowspan=2 | ' .. config['header']['boxNumber'] .. '\n |- \n'

            --表中部分
            for h = 1, 2 do
                for y = 1, poolNum do
                    wikiTable = wikiTable..'! '..config['header']['weightNoteH']..k['poolsValue'][y]..config['header']['weightNoteF']..k['poolsValue'][y] .. '×</abbr> \n'
                end
            end

            wikiTable = wikiTable..'|- \n'

            for o, p in ipairs(data[i]['value']) do
                --值循环
                if config['customize']['itemLink'] then
                    wikiTablePart[o] = '|'..config['itemLink'](p['id'], p['aux'], p['functions'], config)..ref(p["ref"])
                else
                    wikiTablePart[o] = '|'..itemLink(p['id'], p['aux'], p['functions'], p['ref'])..ref(p["ref"])
                end

                for m = 1, poolNum do
                    if p['pools'] == m
                        then
                        wikiTablePart[o] = wikiTablePart[o] .. '||'..p['value']
                    else
                        wikiTablePart[o] = wikiTablePart[o] .. '||' .. ' '
                    end
                end

                for m = 1, poolNum do
                    if p['pools'] == m
                        then
                        wikiTablePart[o] = wikiTablePart[o] .. '||'..p['weightProportionOut']
                    else
                        wikiTablePart[o] = wikiTablePart[o] .. '||' .. ' '
                    end
                end

                wikiTablePart[o] = wikiTablePart[o] .. '||'..p['chanceOut'] .. '||'..p['itemNum'] .. '||'..p['boxNum'] .. '\n|-\n'
                wikiTable = wikiTable..wikiTablePart[o]
            end
            wikiTable = wikiTable..'|}\n</div>'
        end
    end
    return wikiTable
end

function itemDataCov(args, edition)
    local itemList = {}
    local link,aux,name
    local data = dataParsing({}, edition, 'all')
 
    for _, arg in ipairs(args) do
        name = arg:gsub('minecraft:', ''):gsub(':.*','')
        aux = arg:gsub('minecraft:', ''):match(':(.*)')
        for _, struInf in ipairs(data) do

            for _, itemInf in ipairs(struInf['value']) do

                if itemInf['id'] == name and (aux==nil or itemInf['aux'] == aux)
                    then
                    link = itemLink(itemInf['id'], itemInf['aux'], itemInf['functions'], itemInf['ref'])
                    itemList[link] = itemList[link] or {}                   
                    itemList[link]['ref'] = itemList[link]['ref'] or ref(itemInf["ref"])
                    itemList[link]['list'] = itemList[link]['list'] or {}
                    itemInf['stru'] = struInf['name']
                    table.insert(itemList[link]['list'], itemInf) 
                end

            end

        end

    end
    return itemList
end

function getTableItem(data)
    local wikiTable = ''
    if next(data) ~= nil then

    wikiTable = '\n{| class="wikitable sortable jquery-tablesorter" style="'..config['style']['itemTableStyle'] .. '\n' ..
            '! ' .. config['header']['item'] .. '\n' ..
            '! ' .. config['header']['source'] .. '\n' ..
            '! ' .. config['header']['itemNumber'] .. '\n' ..
            '! ' .. config['header']['quantity'] .. '\n' ..
            '! ' .. config['header']['probability'] .. '\n' ..
            '! ' .. config['header']['boxNumber'] .. '\n' ..
            '|-\n'

    for itemLink, itemInf in pairs(data) do
        if #itemInf['list'] > 0
            then
            wikiTable = wikiTable..'| rowspan='.. #itemInf['list'] .. '|'.. itemLink .. itemInf['ref'] .. '\n'

            for _, lineInf in pairs(itemInf['list']) do
                wikiTable = wikiTable
                .. '|' ..struLink(lineInf['stru']) .. '\n'
                .. '|' ..lineInf['itemNum'] .. '\n'
                .. '|' ..lineInf['value'] .. '\n'
                .. '|' ..lineInf['chanceOut'] .. '\n'
                .. '|' ..lineInf['boxNum'] .. '\n'
                .. '|-\n'
            end
        end
    end

    wikiTable = wikiTable..'|}\n'

    end
    return wikiTable
end

function getTableItemAll(edition)
    local data = dataParsing({}, edition, 'all')
    local itemList, resultList = {}, {}
    for struNum, struInf in pairs(data) do

        for itemNum, itemInf in ipairs(struInf['value']) do
            itemList[itemInf['id']] = true 
        end

    end

    for id in pairs(itemList) do
        table.insert(resultList, id)
    end
    resultList['only'] = edition
    return p._item(resultList)
end


function result(args, getData, getTable)
    local genre
    if args['type'] == 'all' or args[1] == 'all'
        then
        genre = 'all'
    else
        genre = 'arg'
    end
    local cout = ''
    local dataJava, dataBedrock, dataJavaDev, dataBedrockBeta
    dataJava = getTable(getData(args, 'java', genre))
    dataBedrock = getTable(getData(args, 'bedrock', genre))

    if config['debug']['onlyJava'] or args['only'] == 'java'
        then 
        cout = tostring(mw.html.create("div"):cssText('display:flex;flex-wrap:wrap;overflow:auto'):wikitext(dataJava))
    elseif config['debug']['onlyBedrock'] or args['only'] == 'bedrock'
        then 
        cout = tostring(mw.html.create("div"):cssText('display:flex;flex-wrap:wrap;overflow:auto'):wikitext(dataBedrock))
    elseif dataJava:gsub('`UNIQ.-QINU`','') == dataBedrock:gsub('`UNIQ.-QINU`','')
        then
        cout = config['label']['javaAndBedrock'] .. '\n'..tostring(mw.html.create("div"):cssText('display:flex;flex-wrap:wrap;overflow:auto'):wikitext(dataJava))
    else
        if dataJava ~= ''
            then
            cout = config['label']['java'] .. '\n'..tostring(mw.html.create("div"):cssText('display:flex;flex-wrap:wrap;overflow:auto'):wikitext(dataJava))
        end
        if dataBedrock ~= ''
            then
            cout = cout .. config['label']['bedrock'] .. '\n'..tostring(mw.html.create("div"):cssText('display:flex;flex-wrap:wrap;overflow:auto'):wikitext(dataBedrock))
        end
    end
    
    if config['switch']['javaDev'] and args['only'] ~= 'bedrock'
        then
        dataJavaDev = getTable(getData(args, 'javaDev', genre))
        if dataJava:gsub('`UNIQ.-QINU`','') ~= dataJavaDev:gsub('`UNIQ.-QINU`','') and dataJavaDev ~= ''
            then
            cout = cout .. config['label']['javaDev'] .. '\n'..tostring(mw.html.create("div"):cssText('display:flex;flex-wrap:wrap;overflow:auto'):wikitext(dataJavaDev))
        end
    end
    if config['switch']['bedrockBeta'] and args['only'] ~= 'java'
        then
        dataBedrockBeta = getTable(getData(args, 'bedrockBeta', genre))
        if dataBedrock:gsub('`UNIQ.-QINU`','') ~= dataBedrockBeta:gsub('`UNIQ.-QINU`','') and dataBedrockBeta ~= ''
            then
            cout = cout .. config['label']['bedrockBeta'] .. '\n'..tostring(mw.html.create("div"):cssText('display:flex;flex-wrap:wrap;overflow:auto'):wikitext(dataBedrockBeta))
        end
    end

    return cout
end

p.all = makeInvokeFunc('_all')

function p._all(args)
    return result(args, dataParsing, getTableAll)
end

p.item = makeInvokeFunc('_item')

function p._item(args)
    if args['type'] == 'all' or args[1] == 'all'
        then
        return result(args, function(a,b) return b end, getTableItemAll)
        else
        return result(args, itemDataCov, getTableItem)
    end
end

return p
Advertisement