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'][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