Solved Loop Help

Discussion in 'Spigot Plugin Development' started by DarkKnights22, Jan 26, 2020.

  1. 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?
     
  2. 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
     
  3. FrostedSnowman

    Resource Staff

    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.
     
  4. 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.
     
  5. 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;
        }
    }
     
  6. 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
     
  7. 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?
     
  8. 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.
     
  9. 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?
     
  10. Yes
     
  11. 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?
     
  12. you should have a handle to the item. You could just remove that item, right? (Entity#remove())
     
  13. Wdym?
     
  14. 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.
     
  15. nvm, you only get the ItemStack. In that case, clear the list or set every element's amount to zero or something
     
  16. 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?
     
    #16 DarkKnights22, Jan 26, 2020
    Last edited: Jan 26, 2020
  17. 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.
     
  18. 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.