Problems with ItemStack References

Discussion in 'Plugin Development' started by ndvenckus1, Nov 11, 2014.

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

    ndvenckus1

    For my plugin, I need to schedule a task to check if an item is still in a player's inventory after several ticks, and I'm running into more trouble than expected.

    Here's the method I created to check if the specified inventory contains the specified ItemStack:
    Code:java
    1. public static boolean itemInInventory(ItemStack item, Inventory inv) {
    2. for(int i = 0; i < inv.getSize(); i++) {
    3. if(inv.getItem(i) == item) //If ItemStack in inventory references the same object as item...
    4. return true;
    5. }
    6.  
    7. return false;
    8. }

    And here's where I use it:
    Code:java
    1. @EventHandler(priority=EventPriority.HIGHEST, ignoreCancelled=true)
    2. public void onPlayerInteract(PlayerInteractEvent e) {
    3. final Player player = e.getPlayer();
    4. final ItemStack item = player.getItemInHand();
    5.  
    6. Bukkit.getScheduler().runTaskLater(plugin, new Runnable() {
    7. @Override
    8. public void run() {
    9. if(!Util.itemInInventory(item, player.getInventory())) { //If item is no longer in player's inventory...
    10. player.sendMessage("Item is no longer in your inventory!");
    11. }
    12. }
    13. }, 5L);
    14. }

    The player right clicks, a reference to getItemInHand() is stored, and 5 ticks later, the itemInInventory method loops the player's inventory to see if it still contains a reference to the object specified. The problem is, itemInInventory always seems to return false, even when the player doesn't switch items. In testing, I also found that this code:
    Code:java
    1. player.getItemInHand() == player.getItemInHand();

    returns false. Yet I can operate directly on the ItemStack returned by the method, like so:
    Code:java
    1. player.getItemInHand().setType(Material.IRON_INGOT);

    and the code works... Could anyone explain this strange behavior to me?
     
  2. Offline

    DJSkepter

  3. Offline

    ndvenckus1

    I'm not trying to figure out if the ItemStacks have the same data attached to them; I'm trying to figure out if their variables reference the same object, which is precisely what the == operator is for.

    Can anyone explain this behavior?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 13, 2016
  4. Offline

    SuperOriginal

    Have you tried using DJSkepter 's method? That could at least isolate the problem
     
  5. Offline

    mythbusterma

    ndvenckus1

    That the ItemStack is created when you request it from the player, and a reference to it is not maintained between calls to retrieve it from the inventory.
     
    tangster132 likes this.
  6. Offline

    ndvenckus1

    Ah, that makes sense. Thanks! I was under the impression that all ItemStacks on the server already existed in memory, and that when you made calls to retrieve them a reference was returned rather than a new object. With this being the case, I guess there's no way to get the inventory an ItemStack is located in, which is unfortunate.
     
  7. Offline

    mythbusterma

    ndvenckus1

    I could certainly see where that idea comes from, and that's likely the way we'll do it in Trident. You could attach unique metadata to the item I believe, that would allow you to keep track of it.
     
Thread Status:
Not open for further replies.

Share This Page