Inventory setItem problems

Discussion in 'Plugin Development' started by adreide, May 16, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    adreide

    Hi there, I've got some problems with the setItem method in the Inventory.java. I'm making a mini-api for inventories and other things. And one thing I'm not able tu debug is how to put an item into an inventory.

    Yeah, sounds easy, but there is my problem:

    I have an array of an Object wich contains the typeId and damageId of the Material. I do not wich to put an ItemStack in that object, so I'm handling myself the typeId and damageId.

    Then, with that array, I'm looping on it to add all the items specified into the player inventory. I'm stacking the quantity to add to existing items and adding to empty slots if no existing. Also if the player has a full inventory I'm popping the Material just in front of the player.

    Here is my method and it works quite well:
    Code:
    public static void putRessourceAtAllCost(Player player, Inventory inv, int ressourceId, short damageId, int quantity) {
            int toAdd = isStackable(ressourceId) ? 64 : 1;
            int stackSize;
    
            ItemStack[] iss = inv.getContents();
            int imax = iss.length;
            for (int i = 0; i < imax && quantity > 0; i++) {
                ItemStack is = iss[i];
    
                if (is == null) {
                    if (quantity > toAdd) {
                        stackSize = toAdd;
                    } else {
                        stackSize = quantity;
                    }
                    quantity -= stackSize;
    
                    inv.setItem(i, new ItemStack(ressourceId, stackSize, damageId));
    
                } else if (is.getTypeId() == ressourceId && is.getDurability() == damageId && is.getAmount() < toAdd) {
                    if (is.getAmount() + quantity > toAdd) {
                        stackSize = toAdd - is.getAmount();
                        if (stackSize > quantity) {
                            stackSize = quantity;
                        }
                    } else {
                        stackSize = is.getAmount() + quantity;
                    }
                    quantity -= stackSize;
    
                    is.setAmount(stackSize);
                }
            }
    
            if (quantity > 0) {
                player.getWorld().dropItem(player.getLocation(), new ItemStack(ressourceId, quantity, damageId));
            }
        }
    Everything work fine except that inGame, when adding something with this method, the Material is then stored in the player's Inventory BUT it doesn't appear. The player must play with the empty slots to find the Material I've just inserted in.
     
  2. Offline

    Ne0nx3r0

    I think there's a workaround Player.updateInventory().

    I have to say it seems like it would be simpler and less buggy to convert your stuff into an ItemStack[] before putting it into their inventory. Then you can just use addItem and handle the leftovers.
     
  3. Offline

    lycano

    @ne0nx3r0: never use this method intentional .. if something is not updated it is mostly because something is messed up in the code. In this case he uses getContents() instead of player.getInventory() and simply has forgotten to call setContents() after modifing the inventory with getContents() ;)

    @adreide: Well, here is my approach. Written down with Notepad++ so i hope this will not throw out any errors in eclipse or netbeans ;) Im not at home currently so i couldn't check if everything works fine but it should work.

    You can extend those methods to sendMessage() with item.name. I was to lazy to add this too as im currently quite busy ^^

    Put this into a class InventoryManager or something =)

    Let me know if it works for you ^^

    I used Bukkit.getServer() cause i dunno if you have YourPlugin plugin available.
    You can replace "Bukkit." with "plugin." if you have it =)

    Regards, Lycano

    EDIT: if you have dificulties to use giveInventoryItemQuantToPlayers() properly e.g. players must be an ArrayString just use "String[] playerArgString = inputString.split(\\,");"

    Code:
    public boolean giveInventoryItem(CommandSender sender, String playerName, Material item) {
        if ((playerName == null) || (playerName.isEmpty())) {
            sender.sendMessage(ChatColor.RED + "PlayerName is empty or null. Check input.");
            return false;
        }
    
        // check if player exists and is online
        Player targetPlayer = Bukkit.getServer().getPlayer(playerName);
        if (targetPlayer == null) {
            sender.sendMessage(ChatColor.RED + "Player with name: '" + playerName + "' not found. Is the player offline?");
            return false;
        }
    
        // get targetPlayer's inventory
        Inventory inv = targetPlayer.getInventory();
    
        // send message to sender if there is no space left in targetPlayer's inventory
        if(inv.firstEmpty() == -1) {
            sender.sendMessage(ChatColor.RED + "No space left in '" + targetPlayer.getName() + "' inventory");
            return false;
        }
    
        // if inventory contains item add it to stack if maxStackSize is not reached
        if (inv.contains(item)) {
            int slotId = inv.first(item);
            ItemStack stack = inv.getItem(slotId);
            int stackAmount = stack.getAmount();
            int maxStackSize = stack.getMaxStackSize();
    
            // can we add it to stack?
            if (( maxStackSize != -1) && ((stackAmount + 1) <= maxStackSize)) {
                stack.setAmount( stackAmount + 1 );
                return true;
            }
        } else {
            // no match found add new Item to Inventory
            inv.setItem(inv.firstEmpty(), new ItemStack(item));
            return true;
        }
    }
    
    public boolean giveInventoryItemQuantity(CommandSender sender, String playerName, Material item, int maxQuantity) {
        boolean requestItemInsert;
    
        // call giveInventoryItem unless maxQuantity is reached or an error occured e.g. inventory full or maxStackSize reached
        for (int i = 0; i < maxQuantity; i++) {
            requestItemInsert = this.giveInventoryItem(sender, playerName, item);
            if (!requestItemInsert) {
                return requestItemInsert;
            }
        }
    
        sender.sendMessage(ChatColor.DARK_GREEN + "Successfully added item to '" + targetPlayer.getName() + "' inventory");
        return true;
    }
    
    public boolean giveInventoryItemQuantToPlayers(CommandSender sender, String[] playerNames, Material item, int maxQuantity) {
        boolean requestItemInsert;
    
        if (players.size() > 0) {
            Player player;
            for (String playerName: playerNames) {
                requestItemInsert = this.giveInventoryItemQuantity(sender, player, item, maxQuantity);
                if (requestetItemInsert) {
                    sender.sendMessage(ChatColor.DARK_GREEN + "Added item to '" + player.getName + "' inventory");
                }
            }
    
            return true;
        } else {
            sender.sendMessage(ChatColor.RED + "Empty playerlist. Check your syntax");
            return false;
        }
    }
    
     
  4. Offline

    adreide

    thanks a lot for your answers ! It helped me a lot

    @lycano, I got stuck for 5 minutes on your code. Thanks, it's a lot simplier your way. I'm going to steel your structure for sure.

    @ne0nx3r0, thanks for that workaround, but i'm going the "lycano" way.
     
Thread Status:
Not open for further replies.

Share This Page