Solved [1.12.2]dropItem multiplying item

Discussion in 'Spigot Plugin Development' started by Waysho, Jun 24, 2018.

  1. I have a command that's supposed to drop/spawn an item at a location, and it works fine, no crashes or anything related, the only problem is that it's apparently using the number of items I have on the hand and multiplying it, not just dropping x quantity of the item.

    Code (Text):

    @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {if (label.equalsIgnoreCase("itemspawn")) {

                if (!(sender instanceof Player)) {sender.sendMessage(ChatColor.RED + "Only players.");return true;}
               
                Player p = (Player) sender;

                if (!p.hasPermission("is.use")) {p.sendMessage(ChatColor.RED + "Not permitted.");return true;}


                double x = 0;
                double y = 0;
                double z = 0;
                int amount = 0;

                if (args.length == 4) {
                   
                    try {
                        x = Double.parseDouble(args[0]);
                        y = Double.parseDouble(args[1]);
                        z = Double.parseDouble(args[2]);

                        amount = Integer.parseInt(args[3]);
                    } catch (NumberFormatException e) {p.sendMessage(ChatColor.RED + "Invalid input, please try again.");return false;}
                   
                } else if (args.length == 2) {
                   
                    Player t = Bukkit.getServer().getPlayer(args[0]);
                    if (t == null) {p.sendMessage(ChatColor.RED + "Please input a valid player and try again.");return false;}

                    x = t.getLocation().getX();
                    y = t.getLocation().getY() + 0.1;
                    z = t.getLocation().getZ();
                   
                    try {
                    amount = Integer.parseInt(args[1]);
                    }catch (NumberFormatException e) {p.sendMessage(ChatColor.RED + "Invalid input, please try again.");return false;}

                }else {
                    return false;
                }

                ItemStack item = p.getInventory().getItemInMainHand();
               

                if (item.getType() == Material.AIR) {p.sendMessage(ChatColor.RED + "Cannot drop Air.");return true;}
               

                World world = p.getWorld();

                Location location = new Location(world, x, y, z);
               

                for (int i = 0; i < amount; i++) {
                    world.dropItem(location, new ItemStack(item));
                }
               
                x = (int)x;
                y = (int)y;
                z = (int)z;

                p.sendMessage(ChatColor.GREEN + "[ItemSpawner] Droped " + item.getType().name() + " at (" + x + ", " + y + ", " + z + ") " + amount + " times.");
            }
            return true;
        }
     

    I'm pretty sure the problem it's on the for loop
    Code (Text):

    for (int i = 0; i < amount; i++) {
                    world.dropItem(location, new ItemStack(item));
                }
     
    but i can't seem to solve it. Please send help.
     
  2. yeah, dont loop it. just drop 1 item with the correct amount set.

    Code (Java):
    world.dropItem(location, new ItemStack(item, amount));
     
    • Like Like x 1
  3. FrostedSnowman

    Resource Staff

    if the amount is less than 65 that is^^
     
    • Like Like x 2
  4. Thanks, I'll try this.
    Edit:
    Here is how I fixed it(with a for loop :\):
    Code (Text):


                int loops = 1;
                int na = amount;//Only to send to the player, makes no difference.
                for(int i = 0; i < loops; i++) {
                    if(amount > 64) {
                        item.setAmount(64);
                        world.dropItem(location, new ItemStack(item).clone());
                        amount -= 64;
                        loops++;
                        continue;
                    }
                    item.setAmount(amount);
                    world.dropItem(location, new ItemStack(item).clone());
                   
                }
     
    I don't have a clue whether the .clone() makes a difference or not, but it works.
     
    #4 Waysho, Jun 24, 2018
    Last edited: Jun 24, 2018
  5. You don't need the .clone() (as if you look at the method, all it does is return new ItemStack(item), so it's redundant), also your continue is unnecessary as once a for loop reaches the end of its loop it continues unless given a break;
    Also, you need an else statement for if it is less than 64, in which case have the amount set to that variable and break; from the loop.
    also, I wouldn't recommend increasing your "loops" function by 1 every time... that'll be an infinite loop... simply have it as i < na / 64 or something of the sort.
     
  6. I did it increase the "loops" so it continues until the "amount" is dropped since it can't drop more than 64 at a time and if I wanted to only drop a max of 64 I could just
    Code (Text):
    world.dropItem(location, new ItemStack(item);
    . I would like to see how would you handle this loop in a more efficient way, would help me a lot.
    This is my current code:
    Code (Text):

        public static void Drop(World world, Location location, ItemStack item, int amount) {
            int loops = 1;
            for (int i = 0; i < loops; i++) {
                if (amount > 64) {
                    item.setAmount(64);
                    world.dropItem(location, new ItemStack(item));
                    amount -= 64;
                    loops++;
                    continue;
                }
                item.setAmount(amount);
                world.dropItem(location, new ItemStack(item));

            }
        }
     
     
    #6 Waysho, Jun 25, 2018
    Last edited: Jun 25, 2018
  7. Code (Java):
    public static void drop(Location location, ItemStack item, int amount) {
        int max = item.getMaxStackSize();
        while (amount > 0) {
            ItemStack droppedItem = item.clone();
            droppedItem.setAmount(amount > max ? max : amount);
            amount -= droppedItem.getAmount();
            location.getWorld().dropItem(location, droppedItem);
        }
    }
     
    #7 BillyGalbreath, Jun 25, 2018
    Last edited: Jun 25, 2018
    • Like Like x 1
    • Winner Winner x 1
  8. Thanks! A much cleaner and beautiful code :)