ItemStack.Clone() doesn't work?

Discussion in 'Plugin Development' started by BlueSin, Jun 16, 2012.

  1. Offline

    BlueSin

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Hello all, I am new to developing Bukkit plugins. I have been developing in C# for years but am picking up Java to do these plugins. With that having been said I am trying to just take baby steps here and have started a sample project that saves your inventory/exp when you die so that when you respawn you don't lose anything. I know these already exist, but like I said...baby steps lol.

    Anyways, my issue is when I run my onPlayerDeath event handler, I do this:

    Code:
    inventory = event.getEntity().getInventory();
    // Get a clone of the player's armor contents
    armorContents = inventory.getArmorContents().clone();


    Then in my onPlayerRespawn event handler I am just printing to log to check that armorContents is what I expected it to be:
    Code:
    for(int i = 0; i < armorContents.length; i++) {
        plugin.log.info(armorContents[i].toString());
    }
    The result is what was once my equipment is now Air. I don't understand why my instance variable (armorContents) was not cloned, and rather appears to be referencing the player's inventory? Technically armorContents should now be a local copy rather than a reference right?

    EDIT: Okay, so I moved the loop to the PlayerDeathEvent event handler and noticed it appears this event is running several times, but even still this makes things easier. Now I can just check if the list is already initialized and if so, not update it again, since it grabs the items properly the first time.

    This post has been edited 3 times. It was last edited by BlueSin Jun 17, 2012.
  2. Offline

    chenr1

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    I dont know the answer but from experience I would find a source for a similar plugin. Thats what I do when I cant figure something out. Sorr I couldnt be more help.
  3. Offline

    Technius

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    If you're copying items, here's one way to do it:
    NOTE: Untested
    Code:
    ItemStack orginal = inventory.getArmorContents();
    ItemStack copy = new ItemStack(original.getType(), original.getAmount(), original.getDurability(), original.getData());
    //not sure if the getData method will work
    HashMap<Enchantment, Integer> ench = new HashMap<Enchantment, Integer>();
    for(Map.Entry<Enchantment, Integer> e: original.getEnchantments())ench.put(e.getKey(), e.getValue());
    copy.addUnsafeEnchantments(ench);//unsafe in case of stuff like TimTheEnchanter
    
  4. Offline

    r3Fuze

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    getArmorContents() returns an Array of ItemStack. You'll have to loop through the array or do something like: ItemStack[] itemArray = inventory.getArmorContents();

    (I could be wrong)
  5. Offline

    BlueSin

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    I actually figured it out and got the mod all up and running now. I switched to a hash map being that it is a server plugin, and just checked if the armorContents and inventoryItems hash maps already contained that player. For some reason, the PlayerDeathEvent runs twice, not as a part of my plugin but just the way the server works, perhaps some kind of redundancy. But by checking if the hash maps already contain that player then I don't create two inventory item sets and two armor sets for each player death.

    Tested it out and works perfectly, no exp drops on the floor or items when I die. When I respawn, I still have all my inventory items and experience. Groovy =)
  6. Offline

    ferrybig

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    PlayerDeathEvent is called just 1 time on my server...
  7. Offline

    BlueSin

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    I was actually able to track down that for some reason Essentials was the culprit to calling multiple PlayerDeathEvents. When I removed Essentials, it was only being called once at that point.

Share This Page