-
Bug
-
Resolution: Fixed
-
Minecraft 15w44b, Minecraft 15w45a, Minecraft 15w46a, Minecraft 15w47c, Minecraft 15w50a, Minecraft 16w02a, Minecraft 16w04a, Minecraft 16w05a, Minecraft 16w06a, Minecraft 1.9 Pre-Release 1, Minecraft 1.9 Pre-Release 2, Minecraft 1.9 Pre-Release 3, Minecraft 1.9, Minecraft 1.9.1 Pre-Release 1, Minecraft 1.9.1 Pre-Release 2, Minecraft 1.9.1 Pre-Release 3, Minecraft 1.10.2, Minecraft 1.11.2, Minecraft 17w06a, Minecraft 1.12.2, Minecraft 18w03b, Minecraft 1.13-pre5
-
Confirmed
The bug
Item stacks with a count > 1 generated by loot tables are spread into multiple smaller item stacks even if there is not enough place in the container resulting in a loss of items and the following warning message:
[Server thread/WARN]: Tried to over-fill a container
How to reproduce
- Create a loot table which generates 27 item stacks, with some of them having a count > 1
{ "pools": [ { "rolls": 24, "entries": [ { "type": "item", "name": "minecraft:iron_sword", "weight": 1 } ] }, { "rolls": 3, "entries": [ { "type": "item", "name": "minecraft:torch", "functions": [ { "function": "set_count", "count": 16 } ], "weight": 1 } ] } ] }
- Save it for example in a data pack under \data\loot_tables\custom\test_loot_table.json
- Load the world and place a chest with the loot table
/setblock ~ ~ ~ chest{LootTable:"custom:test_loot_table"}
- Open the chest
→ You will notice that it contains less than 24 swords, but the torch item stacks are split into more than 3. Additionally a warning should appear in the log: "[Server thread/WARN]: Tried to over-fill a container"
Code analysis and suggested fix
Based on 1.11.2 decompiled using MCP 9.35 rc1
The problem is that the method net.minecraft.world.storage.loot.LootTable.shuffleItems(List<ItemStack>, int, Random) only calculates the amount of free slots once and not in every iteration and additionally the amount of stacks which should be split is not subtracted.
Suggested fix
/** * shuffles items by changing their order and splitting stacks * * @param p_186463_2_ Free slots in container */ private void shuffleItems(List<ItemStack> stacks, int p_186463_2_, Random rand) { // Comment: "list" contains the item stacks to split List<ItemStack> list = Lists.<ItemStack>newArrayList(); Iterator<ItemStack> iterator = stacks.iterator(); while (iterator.hasNext()) { ItemStack itemstack = (ItemStack)iterator.next(); if (itemstack.isEmpty()) { iterator.remove(); } else if (itemstack.getCount() > 1) { list.add(itemstack); iterator.remove(); } } // Comment: Removed this and moved it in the loop condition // p_186463_2_ = p_186463_2_ - stacks.size(); // while (p_186463_2_ > 0 && ((List)list).size() > 0) while ((p_186463_2_ - stacks.size() - list.size()) > 0 && ((List)list).size() > 0) { ItemStack itemstack2 = (ItemStack)list.remove(MathHelper.getInt(rand, 0, list.size() - 1)); int i = MathHelper.getInt(rand, 1, itemstack2.getCount() / 2); ItemStack itemstack1 = itemstack2.splitStack(i); if (itemstack2.getCount() > 1 && rand.nextBoolean()) { list.add(itemstack2); } else { stacks.add(itemstack2); } if (itemstack1.getCount() > 1 && rand.nextBoolean()) { list.add(itemstack1); } else { stacks.add(itemstack1); } } stacks.addAll(list); Collections.shuffle(stacks, rand); }