Minecraft Wiki
Advertisement
[view | edit | history | purge]DocumentationJump to code ↴

Usage

all

{{#invoke:Sandbox/LootChest|all|structure ID|structure ID}}
{{#invoke:Sandbox/LootChest|all|bastion_bridge|bastion_other|bastion_hoglin_stable|<!-- Java -->bastion_treasure|<!-- Bedrock -->buriedtreasure}}

item

{{#invoke:Sandbox/LootChest|item|Namespace ID|Namespace ID}}
{{#invoke:Sandbox/LootChest|item|dye|only=bedrock}}
{{#invoke:Sandbox/LootChest|item|dye|1function=set_data|1value=0}}
{{#invoke:Sandbox/LootChest|itemall}} or {{#invoke:Sandbox/LootChest|item|type=all}}

display

all

Lua error in package.lua at line 80: module 'Module:Autolink' not found.

item

Lua error in package.lua at line 80: module 'Module:Autolink' not found.

[view | edit | history | purge]The above documentation is transcluded from Module:Sandbox/LootChest/doc.
local getArgs = require('Module:Arguments').getArgs
local config = require('Module:Sandbox/LootChest/config')
local sprite, alink
if not(config['customize']['itemLink'] and config['customize']['struLink'])
    then
    sprite = require('Module:Sprite').link
    alink = require('Module:Autolink').invlink
end
local cov = mw.text.jsonDecode(mw.getCurrentFrame():expandTemplate{title = 'User:Star00/cov.json'})

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
    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

    if config['debug']['showId']
        then
        return (sprite({['data'] = dataType, ['id'] = id, ['link'] = link, ['text'] = text})..'('..name..')')
    else
        return sprite({['data'] = dataType, ['id'] = id, ['link'] = link, ['text'] = text})
    end
end

function ref(NsId, enName, functions)
    -- 输入物品的命名空间ID和itemLink最后的显示结果,对齐检索cov.json并添加注释。

    local ref = ""
    local getRef = function(text, name)
        return mw.getCurrentFrame():callParserFunction('#tag:ref', {text, ['name'] = name})
    end

    if cov['note']['assign'][NsId]
        then
        ref = ref..getRef(cov['note']['assign'][NsId], NsId)
    end

    local funcRefList = cov['note']['functions']

    if functions and funcRefList
        then
        for _, func in ipairs(functions)
            do
                if funcRefList[func['function']]
                    then
                    if funcRefList[func['function']][tonumber(func['value']) or func['value']]
                        then
                        ref = ref..getRef(funcRefList[func['function']][tonumber(func['value']) or func['value']],
                        func['function'] .. ':'..funcRefList[func['function']][tonumber(func['value']) or func['value']])
                    end
                end
            end
        end

        if ref == ""
            then
            return enName
        else
            return enName..ref
        end
    end

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

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

        --- 如果在cov.json中存在转换规则,则进行转换,否则直接将命名空间ID作为英文名输入sprite
        local itemCov
        if cov['item']['cov'][NsId]
            then
            itemCov = cov['item']['cov'][NsId]
            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
        if functions
            then
            for _, func in ipairs(functions) do
                if cov['item']['cov'][NsId]
                    and itemCov['functions']
                    and itemCov['functions'][func['function']]
                    and itemCov['functions'][func['function']][tonumber(func['value']) or func['value']]
                    then
                    funcCov = itemCov['functions'][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
                text = text or alink(enName):gsub('.*%|', '')
                if func['function'] == 'enchant_randomly' or func['function'] == 'enchant_with_levels'
                    then
                    Er = true
                end
                if func['function'] == 'set_damage'
                    then
                    Sd = true
                end
                if func['function'] == 'set_data'
                    then
                    dataNum = func['value']
                end
            end
        end
        if Er then text = config['mark']['enchanted'] .. text end
        if Sd then text = config['mark']['set_damage'] .. text end
        Er, Sd = nil, nil

        if cov['item']['sprite-data-type'][NsId]
            then
            dataType = cov['item']['sprite-data-type'][NsId]
        else
            dataType = cov['item']['sprite-data-type']['default']
        end

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

        if config['debug']['showId']
            then
            if dataNum
                then
                return ref(NsId, enName..'<span class="lootchest-id" style="display:none;">('..NsId..':'..dataNum..')</span>', functions)
            else
                return ref(NsId, enName..'<span class="lootchest-id" style="display:none;">('..NsId..')</span>', functions)
            end
        else
            return ref(NsId, enName, functions)
        end

    end

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

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

    function judge(condition, a, b)
        if condition then return a else return b end
    end

    function getData(lootTable)
        -- 从JSON中获取数据,返回一个查询的函数。

        --通过函数闭包使JSON文件不被刷新。
        return function(name, stru, poolNum, itemNum)
            --利用表结构和匿名函数实现switch。
            local switch = {
                ["value"] = function()
                    if not(lootTable[stru]['pools'][poolNum]['entries'][itemNum]['type'] == "minecraft:item"
                    or lootTable[stru]['pools'][poolNum]['entries'][itemNum]['type'] == "item")
                    or not(lootTable[stru]['pools'][poolNum]['entries'][itemNum]['functions'])
                    or not(lootTable[stru]['pools'][poolNum]['entries'][itemNum]['functions'][1]['count'])
                    then
                    return 1
                end

                if type(lootTable[stru]['pools'][poolNum]['entries'][itemNum]['functions'][1]['count']) == 'table'
                    then
                    return tostring(lootTable[stru]['pools'][poolNum]['entries'][itemNum]['functions'][1]['count']['min']) ..
                    '-'..tostring(lootTable[stru]['pools'][poolNum]['entries'][itemNum]['functions'][1]['count']['max'])
                else
                    return lootTable[stru]['pools'][poolNum]['entries'][itemNum]['functions'][1]['count']
                end

            end,
            ["averageValue"] = function()
                if not(lootTable[stru]['pools'][poolNum]['entries'][itemNum]['type'] == "minecraft:item"
                or lootTable[stru]['pools'][poolNum]['entries'][itemNum]['type'] == "item")
                or not(lootTable[stru]['pools'][poolNum]['entries'][itemNum]['functions'])
                or not(lootTable[stru]['pools'][poolNum]['entries'][itemNum]['functions'][1]['count'])
                then
                return 1
            end

            if type(lootTable[stru]['pools'][poolNum]['entries'][itemNum]['functions'][1]['count']) == 'table'
                then
                return (lootTable[stru]['pools'][poolNum]['entries'][itemNum]['functions'][1]['count']['min'] + lootTable[stru]['pools'][poolNum]['entries'][itemNum]['functions'][1]['count']['max']) / 2
            else
                return lootTable[stru]['pools'][poolNum]['entries'][itemNum]['functions'][1]['count']
            end
        end,
        ["weight"] = function()
            return lootTable[stru]['pools'][poolNum]['entries'][itemNum]['weight']
        end,
        ["name"] = function()
            if not(lootTable[stru]['pools'][poolNum]['entries'][itemNum]['type'] == "minecraft:item" or lootTable[stru]['pools'][poolNum]['entries'][itemNum]['type'] == "item")
                then
                return "nothing"
            end

            return (lootTable[stru]['pools'][poolNum]['entries'][itemNum]['name']:gsub('minecraft:', ''))
        end,
        --计算用的堆叠数
        ["rolls"] = function()
            if type(lootTable[stru]['pools'][poolNum]['rolls']) == "table" then
                return {
                    lootTable[stru]['pools'][poolNum]['rolls']['min'],
                lootTable[stru]['pools'][poolNum]['rolls']['max']}
            else
                return lootTable[stru]['pools'][poolNum]['rolls']
            end
        end,
        --显示用的堆叠数
        ["rollsOut"] = function()
            if type(lootTable[stru]['pools'][poolNum]['rolls']) == "table" then
                return (lootTable[stru]['pools'][poolNum]['rolls']['min'] .. '-'..lootTable[stru]['pools'][poolNum]['rolls']['max']) .. 'x'
            else
                return lootTable[stru]['pools'][poolNum]['rolls']
            end
        end,
        ['functions'] = function()
            local functions = lootTable[stru]['pools'][poolNum]['entries'][itemNum]['functions']
            local result = {}
            local covSingle
            if functions == nil then return nil end
            for _, func in ipairs(functions) do
                func['function'] = func['function']:gsub('minecraft:', '')
                covSingle = config['function'][func['function']]
                if covSingle
                    then
                    if covSingle[2] and type(func[covSingle[1]]) == 'table'
                        then
                        if covSingle[3]
                            then
                            table.insert(
                                result,
                                {['function'] = func['function'],
                                ['value'] = tostring(func[covSingle[1]][covSingle[2]]) .. '-'..tostring(func[covSingle[1]][covSingle[3]])})
                            else
                                table.insert(
                                    result,
                                    {['function'] = func['function'],
                                    ['value'] = tostring(func[covSingle[1]][covSingle[2]])})
                                end
                            else
                                table.insert(
                                    result,
                                    {['function'] = func['function'],
                                    ['value'] = tostring(func[covSingle[1]])})
                                end
                            end
                        end

                        return result
                    end,
                    ["entries"] = function()
                        return lootTable[stru]['pools'][poolNum]['entries']
                    end,
                    ["pools"] = function()
                        return lootTable[stru]['pools']
                    end,
                    ["table"] = function()
                        return lootTable
                    end

                }

                return switch[name](stru, poolNum, itemNum)
            end
        end

        function dataParsing(args, edition, genre)
            -- 获取数据table,同时用于all模式和item模式。

            local data = getData(config['json'][edition])
            --此处data被赋予一个函数,作为数据查找函数。

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

            if genre == "all" then loopPrimer = data('table') else loopPrimer = args end

            local stru
            for q, w in pairs(loopPrimer) do
                --结构循环
                itemNum, fakeItemNum = 1, 1
                --伪物品序号,服务于第二个物品循环,用于重新遍历第一个循环的物品,计算其概率等信息。
                poolsList, poorsValue = {}, {}

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

                if data('table')[stru] ~= nil
                    then

                    for o in ipairs(data('pools', stru)) do
                        --奖池循环

                        poorsWeight = 0
                        rolls = data('rolls', stru, o)

                        if type(rolls) == 'table'
                            then
                            poorsValue[o] = rolls[1] .. '-'..rolls[2]
                        else
                            poorsValue[o] = rolls
                        end

                        for n in ipairs(data('entries', stru, o)) do
                            --物品循环
                            poolsList[itemNum] = {}
                            poolsList[itemNum]['name'] = data('name', stru, o, n)
                            poolsList[itemNum]['functions'] = data('functions', stru, o, n)
                            poolsList[itemNum]['value'] = data('value', stru, o, n)
                            poolsList[itemNum]['pools'] = o

                            if data('weight', stru, o, n) then
                                poolsList[itemNum]['weight'] = data('weight', stru, o, n)
                            else
                                poolsList[itemNum]['weight'] = 1
                            end

                            poolsList[itemNum]['averageValue'] = data('averageValue', stru, o, n)
                            poorsWeight = poorsWeight + poolsList[itemNum]['weight']
                            itemNum = itemNum + 1
                        end
                        --到这里为止,poolsList包含了一个奖池的全部信息,然后在下一个循环进行几率等内容的计算,之后在最外层进行排序。

                        for n in ipairs(data('entries', stru, o)) do
                            --物品循环
                            poolsList[fakeItemNum]['weightProportion'] = tonumber(poolsList[fakeItemNum]['weight']) / poorsWeight
                            poolsList[fakeItemNum]['weightProportionOut'] = '<sup>'..tostring(poolsList[fakeItemNum]['weight']) .. '</sup>/<sub>'..tostring(poorsWeight) .. '</sub>'
                            poolsList[fakeItemNum]['chance'] = chanceCount(poolsList[fakeItemNum]['weightProportion'], rolls)
                            poolsList[fakeItemNum]['chanceOut'] = tonumber(poolsList[fakeItemNum]['chance'] * 100) .. '%'
                            poolsList[fakeItemNum]['itemNum'] = string.format("%.2f", poolsList[fakeItemNum]['averageValue'] * poolsList[fakeItemNum]['chance'])
                            poolsList[fakeItemNum]['boxNum'] = string.format("%.1f", 1 / poolsList[fakeItemNum]['chance'])
                            fakeItemNum = fakeItemNum + 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'] = #data('pools', stru)
                    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 = '', '', {}
    local box = mw.html.create("div"):cssText('display:flex;flex-wrap:wrap;overflow:auto')
    local modifyTag = false

    for i, k in ipairs(data) do
        if k['poolNum'] ~= 0
            then
            poolNum = k['poolNum']
            --表头部分
            wikiTable = '{| 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['name'], p['functions'], config)
                else
                    wikiTablePart[o] = '|'..itemLink(p['name'], p['functions'])
                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..'|}'
            box:wikitext('<div>\n'..wikiTable..'\n</div>')
            if not(modifyTag)
                then
                modifyTag = true
            end
        end
    end
    if not(modifyTag)
        then
        return ''
    else
        return tostring(box)
    end
    
end

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

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

            if itemList[itemInf['name']] == nil
                then
                itemList[itemInf['name']] = {  ['list']={}, ['name']=itemInf['name'] }
            end

            itemInf['stru'] = struInf['name']

            table.insert(itemList[itemInf['name']]['list'], itemInf)

        end

    end

    for _,Inf in pairs(itemList) do
        Inf['long'] = #Inf['list']
        table.insert( resultList, Inf )
    end

    return resultList
end

function getDataItem(args, edition, genre)
    if genre == 'all' then return getDataItemAll(edition) end
    local itemList = {}
    local boxNum
    local data = dataParsing({}, edition, 'all')
    for argNum, name in ipairs(args) do
        boxNum = 1
        itemList[argNum] = {}
        itemList[argNum]['list'] = {}
        itemList[argNum]['name'] = name
        for struNum, struInf in pairs(data) do

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

                if itemInf['name'] == name
                    then

                    if not(args[argNum..'function'])
                        then
                        itemList[argNum]['list'][boxNum] = itemInf
                        itemList[argNum]['list'][boxNum]['stru'] = struInf['name']
                        boxNum = boxNum + 1
                    else
                        for _,func in ipairs(itemInf['functions'])
                        do
                            if func['function'] == args[argNum..'function'] and func['value'] == args[argNum..'value']
                                then
                                itemList[argNum]['list'][boxNum] = itemInf
                                itemList[argNum]['list'][boxNum]['stru'] = struInf['name']
                                boxNum = boxNum + 1
                            end
                        end

                    end

                end

            end
            table.sort(itemList[argNum]['list'], function(a, b) return struLink(a['stru']) > struLink(b['stru']) end)

        end
        itemList[argNum]['long'] = #itemList[argNum]['list']

    end

    return itemList

end

function getTableItem(data)
    local box = mw.html.create("div"):cssText('display:flex;flex-wrap:wrap;overflow:auto')

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

    for itemNum, itemInf in ipairs(data) do
        if itemInf['long'] > 0 
            then
            wikiTable = wikiTable..'| rowspan='..itemInf['long'] .. '|'..itemLink(itemInf['name']) .. '\n'

            for boxNum, boxInf in ipairs(itemInf['list']) do
                wikiTable = wikiTable
                .. '|' ..struLink(boxInf['stru']) .. '\n'
                .. '|' ..boxInf['value'] .. '\n'
                .. '|' ..boxInf['chanceOut'] .. '\n'
                .. '|' ..boxInf['boxNum'] .. '\n'
                .. '|' ..judge(boxInf['functions'][1],
                            itemLink(boxInf['name'], boxInf['functions']), config['header']['noForm']) .. '\n'
                .. '|-\n'
            end
            if not(modifyTag)
                then
                modifyTag = true
            end
        end
    end

    wikiTable = wikiTable..'|}'

    box:wikitext('\n'..wikiTable..'\n')

    if not(modifyTag)
        then
        return ''
    else
        return tostring(box)
    end
end

function getDataAll(args, edition, genre)
    return dataParsing(args, edition, genre)
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
    local dataJavaTable, dataBedrockTable, dataJavaDevTable, dataBedrockBetaTable
    dataJava = getData(args, 'java', genre)
    dataBedrock = getData(args, 'bedrock', genre)
    dataJavaTable = tostring(getTable(dataJava))
    dataBedrockTable = tostring(getTable(dataBedrock))

    if dataJavaTable == dataBedrockTable
        then
        cout = cout .. config['label']['javaAndBedrock'] .. '\n'..dataJavaTable
    else
        cout = cout .. 
        config['label']['java'] .. '\n'..dataJavaTable .. '\n' .. 
        config['label']['bedrock'] .. '\n'..dataBedrockTable
    end

    if config['debug']['onlyJava'] 
        or args['only'] == 'java'
        or dataBedrockTable == '' 
        then 
        cout = config['label']['java'] .. '\n'.. dataJavaTable
    end
    if config['debug']['onlyBedrock'] 
        or args['only'] == 'bedrock' 
        or dataJavaTable == '' 
        then 
        cout = config['label']['bedrock'] .. '\n'.. dataBedrockTable
    end

    
    if config['json']['javaDev'] 
        and args['only'] ~= 'bedrock'
        and config['switch']['javaDev']
        then
        dataJavaDev = getData(args, 'javaDev', genre)
        dataJavaTable = tostring(getTable(dataJavaDev))
        if dataJavaTable ~= dataJavaDevTable
            and dataJavaTable ~= '' 
            then
            cout = cout .. config['label']['javaDev'] .. '\n'..dataJavaTable
        end
    end
    if config['json']['bedrockBeta'] 
        and args['only'] ~= 'java'
        and config['switch']['bedrockBeta']
        then
        dataBedrockBeta = getData(args, 'bedrockBeta', genre)
        dataBedrockBetaTable = tostring(getTable(dataBedrockBeta))
        if dataBedrockTable ~= dataBedrockBetaTable
            and dataBedrockBetaTable ~= ''
            then
            cout = cout .. config['label']['bedrockBeta'] .. '\n'..dataBedrockBetaTable
        end
    end

    return cout
end

p.all = makeInvokeFunc('_all')

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

p.item = makeInvokeFunc('_item')

function p._item(args)
    return result(args, getDataItem, getTableItem)
end

return p
Advertisement