Adding NBTTagCompound (or other things for saving data..) to an Item?

Discussion in 'Plugin Development' started by Uniclaw, Nov 10, 2012.

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

    Uniclaw

    Hi!

    how i can add own NBTTagCompounds to an existing Item? I need it to save a specific property to an Item, wich can be given to another Player without losing the Property, and so on.

    Greet
     
  2. Offline

    Hoolean Retired Staff

    Last edited by a moderator: May 29, 2016
    Uniclaw likes this.
  3. Offline

    Uniclaw

    No, because that's for own items / changed items ^^
     
  4. Offline

    Hoolean Retired Staff

    :(
    That's a shame...
     
    Uniclaw likes this.
  5. Offline

    Njol

    CraftBukkit doesn't keep custom NBT data on items if they are dropped or copied. So you might not be able to achieve what you want with NBTTags, but you could try to use unsafe enchantments.
     
  6. Offline

    Uniclaw

    Thanks! But if the item is droppen, i can re-assign the nbt with droppeditem = itemwithdata
    The Problem is, i don't know how to add nbtdata...

    And what are unsafeenchantments :eek:?
     
  7. Offline

    Hoolean Retired Staff

    UnsafeEnchantments are enchantments that either:
    1. Have higher levels than possible normally
    2. Are applied to objects that don't usually have enchantments and/or that enchantment
     
  8. Offline

    Njol

    To modify NBT data i suggest to use CraftItemStack and it's NMS code ;)

    You will find some example code when searching for heads or books as modifying those has to be done this way.
     
  9. Offline

    Uniclaw

    Yes, i know, but how iadd NBT Data D: ?
     
  10. Offline

    Njol

    Simply create a new NBTTagCompound or whatever it's called and use some unique string as it's key, e.g. "your_plugin's_name" (I suggest to save that String in some public final static String in yout plugin's main class so that you can easily use it wherever you need it). Just take a look at other NBT code and replace the string that's used with yours.
    You can then use this compound to save any kind of data you want as long as it's serializable I guess (but maybe it's limited to Strings & numbers)
     
  11. Offline

    Uniclaw

    Thanks :D ! i will try it ;)
     
  12. Offline

    stirante

    Example:
    Code:java
    1. public static ItemStack setData(ItemStack item, String data) {
    2. CraftItemStack craftStack = null;
    3. net.minecraft.server.ItemStack itemStack = null;
    4. if (item instanceof CraftItemStack) {
    5. craftStack = (CraftItemStack) item;
    6. itemStack = craftStack.getHandle();
    7. }
    8. else if (item instanceof ItemStack) {
    9. craftStack = new CraftItemStack(item);
    10. itemStack = craftStack.getHandle();
    11. }
    12. NBTTagCompound tag = itemStack.tag;
    13. if (tag == null) {
    14. tag = new NBTTagCompound();
    15. itemStack.tag = tag;
    16. }
    17.  
    18. tag.setString("data", data);
    19. return craftStack;
    20. }
     
  13. Offline

    thebiologist13

    I have just started working with NBT for my plugin, but I think I understand it alright by looking at the NMS source and this: http://www.minecraftwiki.net/wiki/Player.dat_Format#Item_Structure.

    I made a class for NBT management in my plugin and this is how I set NBTTagCompounds to a Bukkit ItemStack:
    Code:
    /**
    * Sets the NBT of a item to what you specify.
    *
    * @param i The item to set the NBT to.
    * @param n The NBTTagCompound containing the information to be set.
    */
    public void setItemNBT(ItemStack i, NBTTagCompound n) {
        ((CraftItemStack) i).getHandle().c(n);
    }
    What this should do is take a Bukkit item stack (i) and cast it to a CraftItemStack. Then, it will get the handle to the NMS instance. Finally, it calls ItemStack.c(NBTTagCompound nbttagcompound). I found this to set the data to the item like so (copied from the class):
    Code:
    public void c(NBTTagCompound nbttagcompound) {
        this.id = nbttagcompound.getShort("id");
        this.count = nbttagcompound.getByte("Count");
        this.damage = nbttagcompound.getShort("Damage");
        if (nbttagcompound.hasKey("tag"))
            this.tag = nbttagcompound.getCompound("tag");
        }
    }
    So data in the compound you pass in for "n" in the setItemNBT method should carry through to the actual item stack for Minecraft (in theory, I haven't tested this yet).

    I'd love to know if this actually isn't what you are supposed to do though, that would save a lot of time debugging ;).

    Hope this helps!
    ~thebiologist13
     
Thread Status:
Not open for further replies.

Share This Page