Module:LootChest2

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 = inverse_item_weight local cur_divisor = pool_total_item_weight * (max_pool_rolls - min_pool_rolls + 1) for i = 1, 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, ['java'] = 'In Java Edition, ', ['java-upcoming'] = 'In, ', ['bedrock'] = 'In Bedrock Edition, ', ['bedrock-upcoming'] = 'In ', ['java-upcoming-version'] = '', ['bedrock-upcoming-version'] = '', -- These 'items' define which sprite, label and link to use in the table. -- Order within this 'items' list doesn't matter. items = { ["acacia-log"]         = { "block", link="Log" }, ["acacia-sapling"]     = { "block", link="Sapling" }, ["activator-rail"]     = { "block" }, ["apple"]              = { "item" }, ["arrow"]              = { "item" }, ["bamboo"]             = { "item" }, ["barrel"]             = { "block" }, ["beetroot"]           = { "item" }, ["beetroot-seeds"]     = { "item" }, ["beetroot-soup"]		= { "item" }, ["birch-log"]          = { "block", link="Log" }, ["birch-sapling"]      = { "block", link="Sapling" }, ["black-wool"]         = { "block", link="Wool" }, ["blue-ice"]			= { "block" }, ["bone"]               = { "item" }, ["book"]               = { "item" }, ["book-and-quill"]     = { "item", title="Book and Quill" }, ["bottle-o'-enchanting"] = { "item", title="Bottle o' Enchanting" }, ["bread"]              = { "item" }, ["brown-mushroom"]     = { "block", link="Mushroom" }, ["brown-wool"]         = { "block", link="Wool" }, ["bucket"]             = { "item" }, ["buried-treasure-map"] = { "item", link="Explorer Map" }, ["cactus"]             = { "block" }, ["cake"]               = { "block" }, ["carrot"]             = { "item" }, ["chainmail-boots"]    = { "item", link="Armor" }, ["chainmail-chestplate"] = { "item", link="Armor" }, ["chainmail-helmet"]   = { "item", link="Armor" }, ["chainmail-leggings"] = { "item", link="Armor" }, ["clay"]				= { "item" }, ["clock"]				= { "item" }, ["coal"]               = { "item" }, ["cocoa-beans"]        = { "item" }, ["cooked-cod"]         = { "item", link="Cooked Cod" }, ["cooked-salmon"]      = { "item", link="Cooked Salmon" }, ["compass"]            = { "item" }, ["crossbow"]           = { "item" }, ["dandelion"]			= { "block", link="Flower" }, ["dark-oak-log"]       = { "block", link="Log" }, ["dark-oak-sapling"]   = { "block", link="Sapling" }, ["dead-bush"]			= { "block", link="Dead Bush" }, ["detector-rail"]      = { "block" }, ["diamond"]            = { "item" }, ["diamond-chestplate"] = { "item", link="Armor" }, ["diamond-hoe"]        = { "item", link="Hoe" }, ["diamond-horse-armor"] = { "item", link="Horse Armor" }, ["disc-13"]            = { "item", id='music-disc-13', title="Music Disc (13)", link="Music Disc" }, ["disc-cat"]           = { "item", id='music-disc-cat',title="Music Disc (Cat)", link="Music Disc" }, ["disc-mellohi"]       = { "item", id='music-disc-mellohi',title="Music Disc (Mellohi)", link="Music Disc" }, ["disc-wait"]          = { "item", id='music-disc-wait',title="Music Disc (Wait)", link="Music Disc" }, ["egg"]                = { "item" }, ["emerald"]            = { "item" }, ["empty-map"]          = { "item", link="Map", title="Empty Map" }, ["enchanted-book"]     = { "item", id='enchanted-book', title="Enchanted Book", link="Enchanted Book", note="enchant-with-levels-30" }, ["enchanted-book-rnd"] = { "item", id='enchanted-book', title="Enchanted Book", link="Enchanted Book", note="enchant-randomly" }, ["enchanted-book-rnd-treasure"] = { "item", id='enchanted-book', title="Enchanted Book", link="Enchanted Book", note="enchant-randomly-treasure" }, ["enchanted-fishing-rod"] = { "item", id="fishing-rod", link="Fishing Rod", note="enchant-randomly" }, ["enchanted-golden-apple"] = { "item", id='golden-apple', link="Golden Apple" }, ["ender-pearl"]        = { "item" }, ["feather"]            = { "item" }, ["fern"]				= { "block", link="Grass" }, ["flint"]              = { "item" }, ["flint-and-steel"]    = { "item" }, ["flower-pot"]			= { "item" }, ["furnace"]            = { "block" }, ["golden-apple"]       = { "item" }, ["golden-chestplate"]  = { "item", link="Armor" }, ["golden-helmet"]      = { "item", link="Armor" }, ["golden-horse-armor"] = { "item", link="Horse Armor" }, ["golden-sword"]       = { "item", link="Sword" }, ["gold-ingot"]         = { "item" }, ["gold-nugget"]        = { "item" }, ["grass"]				= { "block", link="Grass" }, ["gray-wool"]          = { "block", link="Wool" }, ["green-dye"]			= { "item", link="Dye" }, ["gunpowder"]          = { "item" }, ["heart-of-the-sea"]   = { "item", link="Heart of the Sea" }, ["ink-sac"]            = { "item" }, ["iron-boots"]         = { "item", link="Armor" }, ["iron-chestplate"]    = { "item", link="Armor" }, ["iron-helmet"]        = { "item", link="Armor" }, ["iron-horse-armor"]   = { "item", link="Horse Armor" }, ["iron-ingot"]         = { "item" }, ["iron-leggings"]      = { "item", link="Armor" }, ["iron-nugget"]        = { "item" }, ["iron-pickaxe"]       = { "item", link="Pickaxe" }, ["iron-shovel"]        = { "item", link="Shovel" }, ["iron-sword"]         = { "item", link="Sword" }, ["jungle-log"]         = { "block", link="Log" }, ["jungle-sapling"]     = { "block", link="Sapling" }, ["lapis-lazuli"]       = { "item" }, ["large-fern"]			= { "block", link="Grass" }, ["lead"]               = { "item" }, ["leather"]     		= { "item" }, ["leather-boots"]      = { "item", link="Armor" }, ["leather-cap"]        = { "item", link="Armor" }, ["leather-pants"]      = { "item", link="Armor" }, ["leather-tunic"]      = { "item", link="Armor" }, ["light-gray-wool"]    = { "block", link="Wool" }, ["map"]                = { "item", link="Map", note="map" }, ["melon-seeds"]        = { "item" }, ["name-tag"]           = { "item" }, ["nether-wart"]        = { "item" }, ["oak-log"]            = { "block", link="Log" }, ["oak-planks"]         = { "block", link="Planks", id="oak-wood-planks" }, ["oak-sapling"]        = { "block", link="Sapling" }, ["oak-sign"]           = { "item", link="Sign" }, ["obsidian"]           = { "block" }, ["paper"]              = { "item" }, ["poisonous-potato"]   = { "item" }, ["poppy"]				= { "block", link="Flower" }, ["potato"]             = { "item" }, ["potion-of-regeneration"] = { "item", link="Potion", title="Potion of Regeneration" }, ["potion-of-water-breathing"] = { "item", link="Potion", title="Potion of Water Breathing" }, ["powered-rail"]       = { "block", title="Powered Rails" }, ["prismarine-crystals"] = { "item" }, ["pumpkin"]            = { "block" }, ["pumpkin-pie"]        = { "item" }, ["pumpkin-seeds"]      = { "item" }, ["rail"]               = { "block", title="Rails" }, ["raw-beef"]		   = { "item", link="Raw Beef" }, ["raw-cod"]            = { "item", link="Raw Cod" }, ["raw-mutton"]			= { "item", link="Raw Mutton" }, ["raw-porkchop"]		= { "item", link="Raw Porkchop" }, ["raw-salmon"]         = { "item", link="Raw Salmon" }, ["redstone"]           = { "item", id="redstone-dust", title="Redstone Dust" }, ["rotten-flesh"]       = { "item" }, ["saddle"]             = { "item" }, ["sand"]               = { "block" }, ["shears"]             = { "item" }, ["smooth-stone"]		= { "block" }, ["snowball"]			= { "item", link="Snowball" }, ["snow-block"]			= { "block", link="Snow Block" }, ["spider-eye"]         = { "item" }, ["spruce-log"]         = { "block", link="Log" }, ["spruce-sapling"]     = { "block", link="Sapling" }, ["spruce-sign"]    	= { "item", link="Sign" }, ["stick"]              = { "item" }, ["stone"]              = { "block" }, ["stone-axe"]          = { "item", link="Axe" }, ["stone-bricks"]       = { "block" }, ["stone-pickaxe"]      = { "item", link="Pickaxe" }, ["string"]             = { "item" }, ["suspicious-stew"]    = { "item", note="suspicious-stew" }, ["sweet-berries"]      = { "item" }, ["tall-grass"]			= { "block", link="Grass" }, ["tnt"]                = { "block", title="TNT" }, ["torch"]              = { "block" }, ["tripwire-hook"]      = { "block" }, ["water-bucket"]       = { "item" }, ["wheat"]              = { "item" }, ["wheat-seeds"]        = { "item" }, ["white-wool"]         = { "block", link="Wool" }, ["wooden-axe"]         = { "item", link="Axe" }, ["wooden-hoe"]         = { "item", link="Hoe" }, ["wooden-pickaxe"]     = { "item", link="Pickaxe" }, ["yellow-dye"]			= { "item", link="Dye" },

["enchanted-diamond-boots"]     = { "item", id="diamond-boots", link="Armor", note="enchant-with-levels-20-39" }, ["enchanted-diamond-chestplate"] = { "item", id="diamond-chestplate", link="Armor", note="enchant-with-levels-20-39" }, ["enchanted-diamond-helmet"]    = { "item", id="diamond-helmet", link="Armor", note="enchant-with-levels-20-39" }, ["enchanted-diamond-leggings"]  = { "item", id="diamond-leggings", link="Armor", note="enchant-with-levels-20-39" }, ["enchanted-diamond-pickaxe"]   = { "item", id="diamond-pickaxe", link="Pickaxe", note="enchant-with-levels-20-39" }, ["enchanted-diamond-shovel"]    = { "item", id="diamond-shovel", link="Shovel", note="enchant-with-levels-20-39" }, ["enchanted-diamond-sword"]     = { "item", id="diamond-sword", link="Sword", note="enchant-with-levels-20-39" }, ["enchanted-iron-boots"]        = { "item", id="iron-boots", link="Armor", note="enchant-with-levels-20-39" }, ["enchanted-iron-chestplate"]   = { "item", id="iron-chestplate", link="Armor", note="enchant-with-levels-20-39" }, ["enchanted-iron-helmet"]       = { "item", id="iron-helmet", link="Armor", note="enchant-with-levels-20-39" }, ["enchanted-iron-leggings"]     = { "item", id="iron-leggings", link="Armor", note="enchant-with-levels-20-39" }, ["enchanted-iron-pickaxe"]      = { "item", id="iron-pickaxe", link="Pickaxe", note="enchant-with-levels-20-39" }, ["enchanted-iron-shovel"]       = { "item", id="iron-shovel", link="Shovel", note="enchant-with-levels-20-39" }, ["enchanted-iron-sword"]        = { "item", id="iron-sword", link="Sword", note="enchant-with-levels-20-39" }, ["enchanted-leather-boots"]     = { "item", id="leather-boots", link="Armor", note="enchant-randomly" }, ["enchanted-leather-cap"]       = { "item", id="leather-cap", link="Armor", note="enchant-randomly" }, ["enchanted-leather-pants"]     = { "item", id="leather-pants", link="Armor", note="enchant-randomly" }, ["enchanted-leather-tunic"]     = { "item", id="leather-tunic", link="Armor", note="enchant-randomly" },

["empty"]                       = { "block", id="air", link='', title='Nothing', note="nothing" }, },

notes = { ["enchant-randomly"] = "All enchantments are equally probable, except treasure enchantments, and any level of the enchantment is equally probable.", ["enchant-randomly-treasure"] = "All enchantments are equally probable, including treasure enchantments, and any level of the enchantment is equally probable.", ["enchant-with-levels-20-39"] = "Enchantment probabilities are the same as a level-20 to level-39 enchantment would be on an enchantment table that had no cap at level 30, and that was able to apply treasure enchantments, and where the chance of multiple enchantments is not reduced.", ["enchant-with-levels-30"] = "Enchantment probabilities are the same as a level-30 enchantment on an enchantment table that was able to apply treasure enchantments, and where the chance of multiple enchantments is not reduced.", ["map"] = "Named unknown map, but changed to map 0, the scale level is 1:4, Maps from the same stack are stackable, but maps which are not stacked are unstackable despite looking identical.", ["nothing"] = "'Nothing' does not refer to the chance of an empty chest. Instead, it refers to the chance that the random loot generator will not add any loot on a single roll.", ["suspicious-stew"] = "The stew will grant one of the following effects: 5–7 seconds of Blindness, 7–10 seconds of Jump Boost, 10–20 seconds of Poison, 7–10 seconds of Saturation, 7–10 seconds of Speed, or 6–8 seconds of Weakness.", },

--  -- NOTE: order here doesn't matter. --		 * in the table, chests will sort in alphabetical order --      * in the table, items will sort by chance, then by avg#, then alphabetically. --      * If poolsJavaUpcoming is omitted, poolsJava will be used. To omit a pool entirely, set it to {}. --      * If poolsBedrock is omitted, it implies that Bedrock has the same pools as Java. This is a shortcoming; it ought to be made explicit somehow. chests = { ["shipwreck-map"] = { -- shipwreck_map.json header = "Map", superheader = "Shipwreck", link  = "shipwreck map", structure = "Shipwreck", container = "Map chest", structID = "shipwreck", pools = { {					{"java"}, {						rolls = {1,1}, items = { ["buried-treasure-map"] = {1,1,1}, }					},					{						rolls = {3,3}, items = { ["compass"]            = {1,1,1}, ["empty-map"]          = {1,1,1}, ["clock"]              = {1,1,1}, ["paper"]              = {1,10,20}, ["feather"]            = {1,5,10}, ["book"]               = {1,5,5}, }					},				},				{					{"bedrock"}, {						rolls = {1,1}, items = { ["buried-treasure-map"] = {1,1,1}, }					},					{						rolls = {3,3}, items = { ["compass"]            = {1,1,1}, ["map"]                = {1,1,1}, ["clock"]              = {1,1,1}, ["paper"]              = {1,10,20}, ["feather"]            = {1,5,10}, ["book"]               = {1,5,5}, }					},				},			}		},		["shipwreck-supply"] = { -- shipwreck_supply.json header = "Supply", superheader = "Shipwreck", link  = "shipwreck supply", structure = "Shipwreck", container = "Supply chest", structID = "shipwreck", pools = { {					{"java"}, {						rolls = {3,10}, items = { ["paper"]              = {1,12,8}, ["potato"]             = {2,6,7}, ["poisonous-potato"]   = {2,6,7}, ["carrot"]             = {4,8,7}, ["wheat"]              = {8,21,7}, ["coal"]               = {2,8,6}, ["rotten-flesh"]       = {5,24,5}, ["bamboo"]             = {1,3,2}, ["suspicious-stew"]    = {1,1,10}, ["pumpkin"]            = {1,3,2}, ["gunpowder"]          = {1,5,3}, ["tnt"]                = {1,2,1}, ["enchanted-leather-cap"]        = {1,1,3}, ["enchanted-leather-tunic"]      = {1,1,3}, ["enchanted-leather-pants"]      = {1,1,3}, ["enchanted-leather-boots"]      = {1,1,3}, }					},				},				{					{"bedrock"}, {						rolls = {3,10}, items = { ["paper"]              = {1,12,8}, ["potato"]             = {2,6,7}, ["poisonous-potato"]   = {2,6,7}, ["carrot"]             = {4,8,7}, ["wheat"]              = {8,21,7}, ["coal"]               = {2,8,6}, ["rotten-flesh"]       = {5,24,5}, ["bamboo"]             = {1,3,2}, ["pumpkin"]            = {1,3,2}, ["gunpowder"]          = {1,5,3}, ["tnt"]                = {1,2,1}, ["enchanted-leather-cap"]        = {1,1,3}, ["enchanted-leather-tunic"]      = {1,1,3}, ["enchanted-leather-pants"]      = {1,1,3}, ["enchanted-leather-boots"]      = {1,1,3}, }					},				},			}		},		["shipwreck-treasure"] = { -- shipwreck_treasure.json header = "Treasure", superheader = "Shipwreck", link  = "shipwreck treasure", structure = "Shipwreck", container = "Treasure chest", structID = "shipwreck", pools = { {					{"java","bedrock"}, {						rolls = {3,6}, items = { ["iron-ingot"]         = {1,5,90}, ["gold-ingot"]         = {1,5,10}, ["emerald"]            = {1,5,40}, ["diamond"]            = {1,1,5}, ["bottle-o'-enchanting"] = {1,1,5}, }					},					{						rolls = {2,5}, items = { ["iron-nugget"]        = {1,10,50}, ["gold-nugget"]        = {1,10,10}, ["lapis-lazuli"]       = {1,10,20}, }					},				},			}		},		["buried-treasure"] = { -- buried_treasure.json header = "Buried treasure", link  = "buried treasure", structure = "Buried treasure", container = "", structID = "buried-treasure", pools = { {					{"java"}, {						rolls = {1,1}, items = { ["heart-of-the-sea"]   = {1,1,1}, }					},					{						rolls = {5,8}, items = { ["iron-ingot"]         = {1,4,20}, ["gold-ingot"]         = {1,4,10}, ["tnt"]                = {1,2,5}, }					},					{						rolls = {1,3}, items = { ["emerald"]            = {4,8,5}, ["diamond"]            = {1,2,5}, ["prismarine-crystals"] = {1,5,5}, }					},					{						rolls = {0,1}, items = { ["leather-tunic"]      = {1,1,1}, ["iron-sword"]         = {1,1,1}, }					},					{						rolls = {2,2}, items = { ["cooked-cod"]         = {2,4,1}, ["cooked-salmon"]      = {2,4,1}, }					},				},				{					{"bedrock"}, {						rolls = {1,1}, items = { ["heart-of-the-sea"]   = {1,1,1}, }					},					{						rolls = {5,12}, items = { ["prismarine-crystals"] = {1,5,5}, ["iron-ingot"]         = {3,5,20}, ["gold-ingot"]         = {1,5,10}, ["tnt"]                = {1,2,10}, ["diamond"]            = {1,1,15}, ["disc-wait"]          = {1,1,5}, ["disc-mellohi"]       = {1,1,5}, ["name-tag"]           = {1,1,10}, ["chainmail-chestplate"] = {1,1,20}, ["chainmail-helmet"]   = {1,1,20}, ["chainmail-leggings"] = {1,1,20}, ["chainmail-boots"]    = {1,1,20}, ["book-and-quill"]     = {1,2,5}, ["lead"]               = {1,3,10}, ["bottle-o'-enchanting"] = {1,1,3}, ["potion-of-water-breathing"] = {1,1,15}, ["potion-of-regeneration"] = {1,1,10}, ["cake"]               = {1,1,1}, }					},				},			}		},		["underwater-ruin-big"] = { -- underwater_ruin_big.json header = "Big", superheader = "Underwater ruins", link  = "big underwater ruins", structure = "Underwater ruins", container = "Big chest", structID = "underwater-ruins", pools = { {					{"java","bedrock"}, {						rolls = {2,8}, items = { ["coal"]               = {1,4,10}, ["gold-nugget"]        = {1,3,10}, ["emerald"]            = {1,1,1}, ["wheat"]              = {2,3,10}, }					},					{						rolls = {1,1}, items = { ["golden-apple"]       = {1,1,1}, ["enchanted-book-rnd"] = {1,1,5}, ["leather-tunic"]      = {1,1,1}, ["golden-helmet"]      = {1,1,1}, ["enchanted-fishing-rod"] = {1,1,5}, ["buried-treasure-map"] = {1,1,10}, }					},				},			}		},		["underwater-ruin-small"] = { -- underwater_ruin_small.json header = "Small", superheader = "Underwater ruins", link  = "small underwater ruins", structure = "Underwater ruins", container = "Small chest", structID = "underwater-ruins", pools = { {					{"java","bedrock"}, {						rolls = {2,8}, items = { ["coal"]               = {1,4,10}, ["stone-axe"]          = {1,1,2}, ["rotten-flesh"]       = {1,1,5}, ["emerald"]            = {1,1,1}, ["wheat"]              = {2,3,10}, }					},					{						rolls = {1,1}, items = { ["leather-tunic"]      = {1,1,1}, ["golden-helmet"]      = {1,1,1}, ["enchanted-fishing-rod"] = {1,1,5}, ["buried-treasure-map"] = {1,1,5}, }					},				},			}		},	},

-- these descriptions are the column text. columns = { ["stacksize"] = 'The size of stacks (or for unstackable items, number) of this item on any given roll.', ["weight"] = 'The weight of this item relative to other items in the pool.', ["items"] = 'The number of items expected per chest, averaged over a large number of chests.', ["chance"] = 'The odds of finding any of this item in a single chest.', ["chests"] = 'The number of chests the player should expect to search, to find any of this item.' }, }

p.itemtable = function( ... )

p.current_frame = mw.getCurrentFrame

local args = { ... }	if args[1] == p.current_frame then args = require( 'Module:ProcessArgs' ).merge( true ) else args = args[1] end local error_msg = "" local item_names = {} if args[1] == "!!!ALL!!!" then for item_name, v in pairs( p.items ) do			table.insert( item_names, item_name ) end else item_names = mw.text.split( args[1], ',' ) end local single_item = q.has_one_entry( item_names ) -- error message for unknown items for x, item_name in pairs( item_names ) do		if p.items[item_name] == nil then error_msg = error_msg .. " Unknown item '" .. item_name .. "'. \n" end end -- calculate the chances, change from an associative array to an array, and sort local chances_hash = p.find_chances_for_items( item_names ) local chances_list = {} for key, editions in pairs( chances_hash ) do		table.insert( chances_list, { key, editions } ) end table.sort( chances_list, function(a,b) return a[1] < b[1] end ) -- build the html local html = {} local item_expanded = {} local chest_expanded = {} local chances, key, editions local key_split, item_display_name, item_key, chest_key, chance, stacksize

table.insert( html, error_msg ) if q.has_entries( chances_list ) then table.insert( html, '{| class="wikitable sortable" \n' ) if not single_item then table.insert( html, '! Item \n' ) end table.insert( html, '! Container \n' ) table.insert( html, '! # Stacks \n' ) table.insert( html, '!  Stack Size \n' ) table.insert( html, '!  Weight \n' ) table.insert( html, '!  # Items \n' ) table.insert( html, '!  Chance \n' ) table.insert( html, '!  # Chests \n' ) table.insert( html, '! Java \n! Bedrock \n! Console \n' ) end for _, chances in pairs( chances_list ) do		key = chances[1] editions = chances[2] key_split = q.split( key, '/' ) item_key = key_split[1] chest_key = key_split[2] chance = key_split[3] stacksize = key_split[4] if p.items[item_key].title ~= nil then item_display_name = p.items[item_key].title else item_display_name = q.titlecase( string.gsub( item_key, '-', ' ' ) ) end local java_cell, bedrock_cell, console_cell if editions['java'] ~= nil and editions['java-upcoming'] == nil then java_cell = q.planned_cell .. ' ' .. q.java_until_cell elseif editions['java'] == nil and editions['java-upcoming'] ~= nil then java_cell = q.planned_cell .. ' ' .. q.java_upcoming_cell elseif editions['java'] ~= nil and editions['java-upcoming'] ~= nil then java_cell = q.yes_cell else java_cell = q.no_cell end if editions['bedrock'] ~= nil and editions['bedrock-upcoming'] == nil then bedrock_cell = q.planned_cell .. ' ' .. q.bedrock_until_cell elseif editions['bedrock'] == nil and editions['bedrock-upcoming'] ~= nil then bedrock_cell = q.planned_cell .. ' ' .. q.bedrock_upcoming_cell elseif editions['bedrock'] ~= nil and editions['bedrock-upcoming'] ~= nil then bedrock_cell = q.yes_cell else bedrock_cell = q.no_cell end if editions['console'] ~= nil then console_cell = q.yes_cell elseif editions['console-unknown'] ~= nil then console_cell = q.unknown_cell else console_cell = q.no_cell end if not single_item and item_expanded[item_key] == nil then item_expanded[item_key] = p.get_item( item_key, item_display_name ) end if chest_expanded[chest_key] == nil then chest_expanded[chest_key] = p.current_frame:expandTemplate{ title = 'EnvLink', args = { p.chests[chest_key].structure, id = p.chests[chest_key].structID } } end table.insert( html, '|-\n' ) if not single_item then table.insert( html, "|" .. item_expanded[item_key] .. "\n" ) end table.insert( html, "|" .. chest_expanded[chest_key] .. " " ) table.insert( html, string.gsub( p.chests[chest_key].container, ' ', ' ' ) .. '\n' ) table.insert( html, "|style='text-align:center;'|" .. 0 .. '\n' ) table.insert( html, "|style='text-align:center;'|" .. stacksize .. '\n' ) table.insert( html, "|style='text-align:center;'|" .. 0 .. '\n' ) table.insert( html, "|style='text-align:center;'|" .. 0 .. '\n' ) table.insert( html, "|style='text-align:center;'|" .. chance .. '%\n' ) table.insert( html, "|style='text-align:center;'|" .. 0 .. '\n' ) table.insert( html, '|' .. java_cell .. '\n' ) table.insert( html, '|' .. bedrock_cell .. '\n' ) table.insert( html, '|' .. console_cell .. '\n' ) end if q.has_entries( chances_list ) then table.insert( html, '|}\n' ) table.insert( html, p.current_frame:extensionTag( 'references', "", { group="note" } ) ) end return table.concat( html ) end

p.get_item = function( item_key, item_display_name ) local html = {} local item_title = item_display_name local item_link = item_display_name local item_id = item_key local sprite_type = p.items[item_key][1] local note_key = p.items[item_key].note if p.items[item_key].title ~= nil then item_title = p.items[item_key].title end if p.items[item_key].link ~= nil then item_link = p.items[item_key].link end if p.items[item_key].id ~= nil then item_id = p.items[item_key].id	end if sprite_type == "item" or sprite_type == "block" then table.insert( html, p.current_frame:expandTemplate{ title = q.titlecase(sprite_type) .. 'Link', args = { item_link, item_title , id = item_id } } ) end if note_key ~= nil and note_key ~= "" then table.insert( html, p.current_frame:extensionTag( 'ref', p.notes[note_key], { group='note', name=note_key } ) ) end return table.concat( html ) end

p.find_chances_for_items = function( item_names ) local chances = {} local lang = mw.getContentLanguage for chest_name, chest in pairs(p.chests) do		for _, poolset in pairs(chest.pools or {}) do			local chest_has_java = false local chest_has_java_upcoming = false local chest_has_bedrock = false local chest_has_bedrock_upcoming = false local chest_has_console = false for _, edition in pairs(poolset[1]) do				chest_has_java = chest_has_java or edition == 'java' chest_has_java_upcoming = chest_has_java_upcoming or edition == 'java-upcoming' chest_has_bedrock = chest_has_bedrock or edition == 'bedrock' chest_has_bedrock_upcoming = chest_has_bedrock_upcoming or edition == 'bedrock-upcoming' chest_has_console = chest_has_console or edition == 'console' end if chest_has_java and not chest_has_java_upcoming then table.insert( poolset[1], 'java-upcoming' ) end if chest_has_bedrock and not chest_has_bedrock_upcoming then table.insert( poolset[1], 'bedrock-upcoming' ) end if not chest_has_console then table.insert( poolset[1], 'console-unknown' ) end for _, item_name in pairs(item_names) do				local poolset_chances_per_stacksize = {} for pool_idx, pool in pairs(poolset) do					if pool_idx > 1 then local poolitem = pool.items[item_name] if poolitem ~= nil then local stacksize = poolitem[1] if poolitem[1] ~= poolitem[2] then stacksize = stacksize .. "–" .. poolitem[2] end local itemweight = poolitem[3] local pool_total_item_weight = 0 for item_name, item in pairs(pool.items) do								pool_total_item_weight = pool_total_item_weight + item[3] end local chance = q.round( p.calc_chance_any_of_this_item_per_pool( pool.rolls[1], pool.rolls[2], itemweight, pool_total_item_weight ), 3 ) if poolset_chances_per_stacksize[stacksize] == nil then poolset_chances_per_stacksize[stacksize] = chance else poolset_chances_per_stacksize[stacksize] = poolset_chances_per_stacksize[stacksize] + (1 - poolset_chances_per_stacksize[stacksize]) * chance end end end end for stacksize, chance in pairs( poolset_chances_per_stacksize ) do local key = item_name .. '/' .. chest_name .. '/' .. lang:formatNum( chance * 100 ) .. '/' .. stacksize if chances[key] == nil then chances[key] = {} end for _, edition in pairs(poolset[1]) do						chances[key][edition] = true end end end end end return chances end

q = {

-- these templates should only get expanded once. java_upcoming_expanded = nil, java_until_expanded = nil, bedrock_upcoming_expanded = nil, bedrock_until_expanded = nil, yes_expanded = nil, no_expanded = nil, planned_expanded = nil, unknown_expanded = nil, java_upcoming_cell = function if q.java_upcoming_expanded == nil then q.java_upcoming_expanded = p.current_frame:expandTemplate{ title = 'Upcoming', args = { 'JE ' .. p['java-upcoming-version'] } } end return q.java_upcoming_expanded end, java_until_cell = function if q.java_until_expanded == nil then q.java_until_expanded = p.current_frame:expandTemplate{ title = 'Until', args = { 'JE ' .. p['java-upcoming-version'] } } end return q.java_until_expanded end, bedrock_upcoming_cell = function if q.bedrock_upcoming_expanded == nil then q.bedrock_upcoming_expanded = p.current_frame:expandTemplate{ title = 'Upcoming', args = { 'BE ' .. p['bedrock-upcoming-version'] } } end return q.bedrock_upcoming_expanded end, bedrock_until_cell = function if q.bedrock_until_expanded == nil then q.bedrock_until_expanded = p.current_frame:expandTemplate{ title = 'Until', args = { 'BE ' .. p['bedrock-upcoming-version'] } } end return q.bedrock_until_expanded end, yes_cell = function if q.yes_expanded == nil then q.yes_expanded = p.current_frame:expandTemplate{ title = 'Table Choice', args = { 'Yes' } } end return q.yes_expanded end, no_cell = function if q.no_expanded == nil then q.no_expanded = p.current_frame:expandTemplate{ title = 'Table Choice', args = { 'No' } } end return q.no_expanded end, planned_cell = function if q.planned_expanded == nil then q.planned_expanded = p.current_frame:expandTemplate{ title = 'Table Choice', args = { 'Planned', 'Yes' } } end return q.planned_expanded end, unknown_cell = function if q.unknown_expanded == nil then q.unknown_expanded = p.current_frame:expandTemplate{ title = 'Table Choice', args = { 'Unknown' } } .. ' ' .. p.current_frame:expandTemplate{ title = 'needs testing', args = { 'This loot information has not been tested, in this edition.' } } end return q.unknown_expanded end,

has_entries = function(_table) for _ in pairs(_table) do return true end return false end,

has_one_entry = function(_table) local first = false local second = false for _ in pairs(_table) do			if first then second = true end first = true if first and second then return false end end return first and not second end,

round = function(num, numDecimalPlaces) local mult = 10^(numDecimalPlaces or 0) return math.floor(num * mult + 0.5) / mult end, split = function (s, delimiter) result = {}; for match in (s..delimiter):gmatch("(.-)"..delimiter) do	       table.insert(result, match); end return result; end, titlecase = function( str ) local buf = {} for word in string.gfind(str, "%S+") do			if word == "and" then table.insert( buf, word ) else local first, rest = string.sub( word, 1, 1 ), string.sub( word, 2 ) table.insert( buf, string.upper(first) .. string.lower(rest) ) end end return table.concat( buf, " " ) end, }

return p