Custom ItemMeta Metadata

Discussion in 'Plugin Development' started by Dragonphase, Feb 26, 2013.

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

    Dragonphase

    Greetings.

    I am attempting to add custom metadata values to itemMeta, but it just isn't working as expected. Here is what I have so far, and it works to some extent:

    Code:java
    1. public static ItemStack getItem(int ID){
    2. ItemStack item = new ItemStack(getID(ID));
    3. ItemMeta itemMeta = item.getItemMeta();
    4. itemMeta.setDisplayName(ChatColor.RESET + ChatColor.translateAlternateColorCodes('&', getLadderColor(ID)) + ChatColor.translateAlternateColorCodes('&', getName(ID)));
    5. itemMeta.setLore(getLore(ID));
    6. item.setAmount(getAmount(ID));
    7. Map<String, Object> sMeta = new HashMap<String, Object>();
    8. sMeta.put("==", "ItemMeta");
    9. sMeta.putAll(itemMeta.serialize());
    10. sMeta.put("ID", ID);
    11. itemMeta = (ItemMeta)ConfigurationSerialization.deserializeObject(sMeta);
    12. item.setItemMeta(itemMeta);
    13. FileManager.set("test1", item.getItemMeta(), "config.yml");
    14. return item;
    15. }


    In my code, I have set it so that the plugin will drop said item when a block is broken - this all works. The item does drop and no errors occur beforehand.

    However, I cannot pick these items up (I previously was able to), and in config.yml file, the "ID" key is not set.

    Edit:

    This now works, items are being dropped and can be picked up correctly, however, the ID meta value is not being set to the itemMeta. Here's an updated version of the code i'm using now - the problem was an error in my configuration which i have fixed:

    Code:java
    1. public static ItemStack getItem(int ID){
    2. ItemStack item = new ItemStack(getID(ID));
    3. ItemMeta itemMeta = item.getItemMeta();
    4. itemMeta.setDisplayName(ChatColor.RESET + ChatColor.translateAlternateColorCodes('&', getLadderColor(ID)) + ChatColor.translateAlternateColorCodes('&', getName(ID)));
    5. itemMeta.setLore(getLore(ID));
    6. item.setAmount(getAmount(ID));
    7. Map<String, Object> sMeta = new HashMap<String, Object>();
    8. sMeta.put("==", "ItemMeta");
    9. sMeta.putAll(itemMeta.serialize());
    10. sMeta.put("ID", ID);
    11. item.setItemMeta((ItemMeta)ConfigurationSerialization.deserializeObject(sMeta));
    12. System.out.println("" + item.getItemMeta());
    13. return item;
    14. }


    It just won't add the ID section I created. Any help appreciated.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 31, 2016
  2. Offline

    Technius

  3. Offline

    Dragonphase

    I see, that's a shame. Lets hope this is added in the near future, then! I really need it for a plugin i'm developing at the moment.
     
  4. Offline

    Technius

    As do I. You can still manage this, but you'll have to touch NMS which is not preferable.
     
  5. I belive there would be a problem with custom NBT where stacking is involved... and maybe other stuff as well.

    You could use a lore line, it will prevent that kind of item to stack with any other normal items as well, so meta won't be lost... and you can even hide it by using black or magic font.
     
  6. Offline

    Technius

    That's not pretty or elegant though...

    Best "nice" solution is NBT. With 1.5 coming soon, I don't suggest investing any time into it right now though. I'd wait until 1.5 CB is out and then dig through NMS code.
     
  7. Offline

    Dragonphase

    I've used this method before and agree with how Technius says it's not elegant. I want to be able to set damage variables on my items so that I can retrieve them when and were.

    What I have done for now however is similar to what you mentioned - i'm checking the item name against ones in the config to identify them, which works:

    Code:java
    1.  
    2.  
    3.  
    4. public static int getID(ItemStack itemStack){
    5. if (itemStack.getType() == Material.AIR) return 0;
    6. for (String key : FileManager.getKeys(true, "config.yml")){
    7. if (StringUtils.countMatches(key, ".") == 1 && key.startsWith("items.")){
    8. String itemName = FileManager.getString(key + ".name");
    9. if (ChatColor.stripColor(itemStack.getItemMeta().getDisplayName().toLowerCase()).contains(ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', itemName.toLowerCase())))){
    10. return Integer.parseInt(key.replace("items.", ""));
    11. }
    12. }
    13. }
    14. return 0;
    15. }


    this is applied where:

    Code:
    items:
      '1':
        name: 'Example''s Sword'
        ladder: common
        lore:
        - 'This is an example of a custom sword'
        - 'It is dropped by zombies and creepers'
        - 'It is also dropped by mining coal'
        - 'It belongs in the common ladder'
        - 'With a 100 in 300 chance of dropping'
        chance: 0
        id: 272
        stats:
          damage: '25-30'
        mobs:
        - zombie
        - creeper
        blocks:
        - 16
     
  8. Offline

    Technius

    Although that serializes properly, I don't think it'll be applied to items correctly. CraftBukkit uses hardcoded ItemMetaKeys to apply NBT data. You'll have to tamper directly with NMS ItemStack.
     
  9. Offline

    Dragonphase

    I don't understand what you mean - the purpose of what I and you want is to apply custom metadata to items, correct? The reason I want to do this is to set an "ID" metadata value to easily identify which item is which from the config, but since this isn't directly possible, the current method in my snip above would suffice. And it works.

    I don't think I'll be applying NBT data directly by tampering with NMS ItemStacks, more-so because I have never really used NMS ItemStacks before.

    Edit: One main problem I still see with this is different items with duplicate names. I guess it's a bridge I'll have to cross when I come to it.
     
  10. Offline

    Technius

    One problem with that is that people can use anvils to rename their items.

    Applying custom metadata is quite easy. It's something like this:
    Code:
    ItemStack i; //Your item stack
    //Apply ItemMeta before doing this
    net.minecraft.server.1_4_R1.ItemStack nms = CraftItemStack.asNMSCopy(i);
    NBTTagCompound tag;
    if(nms.tag != null)tag = nms.tag;
    else
    {
        nms.tag = new NBTTagCompound();
        nms.tag = tag;
    }
    tag.setInt("Your Key", yourint);
    ItemStack n = CraftItemStack.asCraftMirror(nms); //New/resulting item stack
    
     
    Windy Day likes this.
  11. Offline

    Dragonphase


    You sir, are a legend. Thankyou!
     
  12. Offline

    Technius

    No problem and good luck!
     
Thread Status:
Not open for further replies.

Share This Page