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:LootChest/config' not found.

item

Lua error in package.lua at line 80: module 'Module:LootChest/config' 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: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
    if cov['structure']['text'][name]
        then
        text = cov['structure']['text'][name]
    else
        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
            if not(config['customize']['noUseAutoLink'])
                then
                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
            end
            if func['function'] == 'set_data'
                then
                dataNum = func['value']
            end
        end
    end
    if not(config['customize']['noUseAutoLink'])
        then
        if Er then text = config['mark']['enchanted'] .. text end
        if Sd then text = config['mark']['set_damage'] .. text end
    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'] and 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