Module:Sandbox/LootTable
Jump to navigation
Jump to search
Trying to make a Loot Table parser that can be used instead of the current LootChest module, but with support for other loot types and the ease of use of just needing to paste the JSON loot tables when new versions comes out (very early version, pretty much nothing is working).
Usage[edit source]
[view] [edit] [history] [refresh]The above documentation is transcluded from Module:Sandbox/LootTable/doc.
local java_data = mw.text.jsonDecode(require('Module:Sandbox/LootTable/Java.json'))
local p = {
calc_average_amount_this_item_per_pool = function(
min_stacksize, max_stacksize,
min_pool_rolls, max_pool_rolls,
item_weight, pool_total_item_weight )
local avg_stacksize = ( min_stacksize + max_stacksize ) / 2
local avg_rolls = ( min_pool_rolls + max_pool_rolls ) / 2
return avg_stacksize * avg_rolls * item_weight / pool_total_item_weight
end,
calc_chance_any_of_this_item_per_pool = function(
min_pool_rolls, max_pool_rolls,
item_weight, pool_total_item_weight )
local inverse_result = 0 -- 1 - inverse_result = return value
local inverse_item_weight = pool_total_item_weight - item_weight
-- will be used for the division in the for loop to avoid the slightly
-- less performant math.pow(). The divisor already includes the probability
-- of picking any specific number of rolls.
local cur_dividend = pool_total_item_weight
local cur_divisor = pool_total_item_weight * (max_pool_rolls - min_pool_rolls + 1)
for i = 0, max_pool_rolls do
if i >= min_pool_rolls then
inverse_result = inverse_result + cur_dividend / cur_divisor
end
cur_dividend = cur_dividend * inverse_item_weight -- simulate pow
cur_divisor = cur_divisor * pool_total_item_weight -- simulate pow
end
return 1 - inverse_result
end,
get_tables_and_items = function(data)
local items = {}
local loottables = {}
for table_id, details in pairs(java_data) do
loottables[table_id] = {
category = details.category,
sub_category = details.sub_category,
type = details.type,
pools = {},
}
for pool_i, pool in ipairs(details["loot_table"]["pools"]) do
loottables[table_id].pools[pool_i] = {
min_rolls = 1,
max_rolls = 1,
total_weight = 0
}
if type(pool.rolls) == "number" then
loottables[table_id].pools[pool_i].min_rolls = pool.rolls
loottables[table_id].pools[pool_i].max_rolls = pool.rolls
else
loottables[table_id].pools[pool_i].min_rolls = pool.rolls.min
loottables[table_id].pools[pool_i].max_rolls = pool.rolls.max
end
-- TODO parse conditions
for i, entry in ipairs(pool["entries"]) do
if entry["type"] == "minecraft:item" then
local item = {
id = entry["name"],
min_stacksize = 1,
max_stacksize = 1,
item_weight = entry["weight"] or 1,
pool = pool_i,
loot_table = table_id,
}
if entry["functions"] then
for i, func in ipairs(entry["functions"]) do
if func["function"] == "minecraft:set_count" then
item.min_stacksize = func["count"]["min"] or 1
item.max_stacksize = func["count"]["max"] or 1
-- TODO parse other functions
end
end
end
loottables[table_id].pools[pool_i].total_weight = loottables[table_id].pools[pool_i].total_weight + item.item_weight
if items[item.id] then
table.insert(items[item.id], item)
else
items[item.id] = {item}
end
end
end
end
end
return items, loottables
end,
current_frame = nil
}
p.loot_tables = function( ... )
local items, loottables = p.get_tables_and_items(java_data)
local output = '{| class="wikitable sortable"\n|-\n! Item !! Pool !! Chance per pool !! Average amount per pool'
for item_id, item_data in pairs(items) do
for _, item in ipairs(item_data) do
local chance = p.calc_chance_any_of_this_item_per_pool(
loottables[item.loot_table].pools[item.pool].min_rolls,
loottables[item.loot_table].pools[item.pool].max_rolls,
item.item_weight,
loottables[item.loot_table].pools[item.pool].total_weight
)
local avg_amount = p.calc_average_amount_this_item_per_pool(
item.min_stacksize,
item.max_stacksize,
loottables[item.loot_table].pools[item.pool].min_rolls,
loottables[item.loot_table].pools[item.pool].max_rolls,
item.item_weight,
loottables[item.loot_table].pools[item.pool].total_weight
)
output = output .. string.format('\n|-\n| %s || %d || %f || %f', item_id, item.pool, chance, avg_amount)
end
end
output = output .. '\n|}'
return output
end
return p