Code (Java): [outerLoop: for (int i = 0; i < CollectionChests.getInstance().collectionChest.getChestIds().get(event.getEntity().getLocation().getChunk()) + 1; i++) { for (CollectionChestData collectionChestData : CollectionChests.getInstance().collectionChest.getChestData().get(event.getEntity().getLocation().getChunk())) { if (collectionChestData.getId() != i) continue; Chest chest = (Chest) collectionChestData.getLocation().getBlock().getState(); for (int j = 0; j < event.getDrops().size(); j++) { if (!hasItemSpace(chest.getBlockInventory(), event.getDrops().get(j))) continue; if (!CollectionChests.getInstance().getFilterItems().contains(event.getDrops().get(j).getType())) continue; chest.getBlockInventory().addItem(event.getDrops().get(j)); event.getDrops().remove(j); } if (event.getDrops().isEmpty()) return; continue outerLoop; } } } Code (Java): public boolean hasItemSpace(Inventory inventory, ItemStack itemStack) { AtomicInteger freeSpace = new AtomicInteger(0); for (ItemStack item : inventory.getContents()) { if (item == null || item.getType().equals(Material.AIR)) freeSpace.getAndAdd(itemStack.getType().getMaxStackSize()); else if (item.getType().equals(itemStack.getType())) freeSpace.getAndAdd(item.getType().getMaxStackSize() - item.getAmount()); } return itemStack.getAmount() <= freeSpace.get(); } This is in EntityDeathEvent. Not all the drops get put into an empty chest, any idea why that is? A skeleton drops 2 bones and only 1 bone gets added to the chest, why is that?
This is kind of unnecessary complicated... Inventory has a method called addItem() that takes an array, tries to put all of the contents into the chest and returns what didn‘t fit. Just use that
As said before, Inventory::addItem returns a map of items it wasn’t able to put into the inventory. Use that instead of making a mess and trying to calculate it yourself.
Code (Java): outerLoop: for (CollectionChestData collectionChestData : CollectionChests.getInstance().collectionChest.getChestData().get(event.getEntity().getLocation().getChunk())) { for (int i = 0; i < CollectionChests.getInstance().collectionChest.getChestIds().get(event.getEntity().getLocation().getChunk()) + 1; i++) { if (collectionChestData.getId() != i) continue; HashMap<Integer, ItemStack> leftOver = null; Chest chest = (Chest) collectionChestData.getLocation().getBlock().getState(); for (int j = 0; j < event.getDrops().size(); j++) { if (!CollectionChests.getInstance().getFilterItems().contains(event.getDrops().get(j).getType())) continue; leftOver = chest.getBlockInventory().addItem(event.getDrops().get(j)); event.getDrops().remove(j); } if (leftOver != null && !leftOver.isEmpty()) continue outerLoop; } } How would I go about implementing that? Tried this and it didn't work. Also, there's enough space in the inventory/chest, it's completely empty. Only 1 bone gets added and one stays as a drop.
Whatabout this? Code (Java): @EventHandler public void onEntityDeath(@NotNull EntityDeathEvent event) { final List<ItemStack> drops = event.getDrops(); // or do some fancy stream-collector stuff here HashMap<Integer,ItemStack> leftover = new HashMap<>(); for (int i = 0; i < drops.size(); i++) { leftover.put(i, drops.get(i)); } for (Chest chest: chests) { leftover = chest.getBlockInventory().addItem(leftover.values().toArray(new ItemStack[0])); if (leftover.isEmpty()) return; } }
Code (Java): @EventHandler public void onDeath(@NotNull EntityDeathEvent event) { if (event.getEntity() instanceof Player) return; if (event.getEntity().getKiller() != null) return; if (CollectionChests.getInstance().collectionChest.getChestData().get(event.getEntity().getLocation().getChunk()) == null) return; final List<ItemStack> drops = event.getDrops(); for (CollectionChestData collectionChestData : CollectionChests.getInstance().collectionChest.getChestData().get(event.getEntity().getLocation().getChunk())) { for (int i = 0; i < CollectionChests.getInstance().collectionChest.getChestIds().get(event.getEntity().getLocation().getChunk()) + 1; i++) { if (collectionChestData.getId() != i) continue; Chest chest = (Chest) collectionChestData.getLocation().getBlock().getState(); HashMap<Integer, ItemStack> leftover = Maps.newHashMap(); for (int j = 0; j < drops.size(); j++) { leftover.put(j, drops.get(j)); } leftover = chest.getBlockInventory().addItem(leftover.values().toArray(new ItemStack[0])); if (leftover.isEmpty()) return; } } } Same thing happens - not all of the drops get added
hmm, where's the error happening? Is the drops-list already containing the wrong drops or does is the conversion from drops to chest not working?
The latter. If a skeleton dies and it drops 5 bones, for example, 3 of the bones will get removed from the drops and added to the chest, and 2 will remain as drops and not get added to the chest.
Well, for me, your problem is not reproducible, unfortunately. You are considering that, if the stack does not fit into one chest, the remainders will be transferred to another chest?
Wait I just realised I'm not removing the drops anymore, that's why there was still stuff dropping lol. How would I remove the drops that have been added?
Code (Java): for (int j = 0; j < drops.size(); j++) { if (leftOver.containsValue(drops.get(j))) continue; drops.remove(j); } Tried this but it only removes one of the item. If I have 2 bones it will only remove one.
nvm, you only get the ItemStack. In that case, clear the list or set every element's amount to zero or something
Code (Java): @EventHandler public void onDeath(@NotNull EntityDeathEvent event) { if (event.getEntity() instanceof Player) return; if (event.getEntity().getKiller() != null) return; if (CollectionChests.getInstance().collectionChest.getChestData().get(event.getEntity().getLocation().getChunk()) == null) return; List<ItemStack> drops = event.getDrops(); for (CollectionChestData collectionChestData : CollectionChests.getInstance().collectionChest.getChestData().get(event.getEntity().getLocation().getChunk())) { for (int i = 0; i < CollectionChests.getInstance().collectionChest.getChestIds().get(event.getEntity().getLocation().getChunk()) + 1; i++) { if (collectionChestData.getId() != i) continue; Chest chest = (Chest) collectionChestData.getLocation().getBlock().getState(); HashMap<Integer, ItemStack> leftOver = Maps.newHashMap(); for (int j = 0; j < drops.size(); j++) leftOver.put(j, drops.get(j)); leftOver = chest.getBlockInventory().addItem(leftOver.values().toArray(new ItemStack[0])); for (int j = 0; j < drops.size(); j++) if (!leftOver.containsValue(drops.get(j))) event.getDrops().remove(j); if (leftOver.isEmpty()) break; } } } } So this doesn't drop anything, but it doesn't fill the first chest up before filling the second one, any idea why that is?
I have 6 arrows in the first chest, and 2 arrows in the second. It should fill the first chest with 64 arrows, and only then should it move to the second and start filling it up.
Code (Java): for (int i = 0; i < CollectionChests.getInstance().collectionChest.getChestIds().get(event.getEntity().getLocation().getChunk()); i++) { for (CollectionChestData collectionChestData : CollectionChests.getInstance().collectionChest.getChestData().get(event.getEntity().getLocation().getChunk())) { if (collectionChestData.getId() != i) continue; Chest chest = (Chest) collectionChestData.getLocation().getBlock().getState(); HashMap<Integer, ItemStack> leftOver = Maps.newHashMap(); for (int j = 0; j < event.getDrops().size(); j++) { if (!CollectionChests.getInstance().getFilterItems().contains(event.getDrops().get(j).getType())) continue; leftOver.put(j, event.getDrops().get(j)); } leftOver = chest.getBlockInventory().addItem(leftOver.values().toArray(new ItemStack[0])); for (int j = 0; j < event.getDrops().size(); j++) { if (!CollectionChests.getInstance().getFilterItems().contains(event.getDrops().get(j).getType())) continue; if (!leftOver.containsValue(event.getDrops().get(j))) event.getDrops().remove(j); } } } Updated code.