This is mostly for general information about NBT Tags. I really just want to know what all the compounds are that can be added to NBT Tags that actually do something. For instance I know the name of an Item is under a display compound then under Name and changing that would change the name of the item. But what about for things like enchantments and the skin that shows up on skulls or the information thing that shows up under a potion. Any explanation of these or others would be greatly appreciated.
O thanks, that helps a lot. I'm running into a problem whenever I try to set lore. It gives me this error then kicks me from an internal server error: Code: 23:28:27 [WARNING] Failed to handle packet: java.lang.IllegalArgumentException: Empty string not allowed java.lang.IllegalArgumentException: Empty string not allowed at net.minecraft.server.NBTTagString.<init>(SourceFile:15) at net.minecraft.server.NBTTagString.clone(SourceFile:39) at net.minecraft.server.NBTTagList.clone(SourceFile:87) at net.minecraft.server.NBTTagCompound.clone(NBTTagCompound.java:239) at net.minecraft.server.NBTTagCompound.clone(NBTTagCompound.java:239) at net.minecraft.server.ItemStack.cloneItemStack(ItemStack.java:232) at net.minecraft.server.Packet5EntityEquipment.<init>(SourceFile:20) at net.minecraft.server.EntityLiving.j_(EntityLiving.java:480) at net.minecraft.server.EntityHuman.j_(EntityHuman.java:154) at net.minecraft.server.EntityPlayer.g(EntityPlayer.java:188) at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:349) at net.minecraft.server.Packet10Flying.handle(SourceFile:136) at net.minecraft.server.NetworkManager.b(NetworkManager.java:282) at net.minecraft.server.NetServerHandler.d(NetServerHandler.java:111) at net.minecraft.server.ServerConnection.b(SourceFile:35) at net.minecraft.server.DedicatedServerConnection.b(SourceFile:30) at net.minecraft.server.MinecraftServer.r(MinecraftServer.java:569) at net.minecraft.server.DedicatedServer.r(DedicatedServer.java:215) at net.minecraft.server.MinecraftServer.q(MinecraftServer.java:486) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:419) at net.minecraft.server.ThreadServerApplication.run(SourceFile:818) My code for setting the Lore: Code: NBTTagCompound tag = getTag(p.getItemInHand()); if(tag.getCompound("display") != null) { tag.setCompound("display", new NBTTagCompound()); } // Gets the display tag. NBTTagCompound display = tag.getCompound("display"); //Removes the old name display.remove("Lore"); //sets the new name NBTTagList list = new NBTTagList(); list.add(new NBTTagString("TESTING")); display.set("Lore", list); The getTag method returns the tag of the itemstack. I know it works up until I create the NBTTagList object. I have tried it with replacing the name of the item and it works. EDIT by Moderator: merged posts, please use the edit button instead of double posting.
Huh. I wonder if you could, say set the "author" on a stone sword if you wanted to store information. If it works, that would be very interesting.
I wrote this off the top of my head, so it may need a few changes, but for the most part this is how you'd do that. Code: /*Get tag compound*/ NBTTagCompound c = item.getTag(); /*Create display tag if it does not already exist*/ if(!c.hasKey("display")) { c.set("display", new NBTTagCompound()); } /*Gets display compound*/ NBTTagCompound d = c.getCompound("display"); /*Create Lore tag if it does not already exist*/ if(!d.hasKey("Lore")) { d.set("Lore", new NBTTagList()); } /*Gets Lore list*/ NBTTagList l = d.getList("Lore"); /*Add a string to the list*/ l.add(new NBTTagString("", "String here1")); l.add(new NBTTagString("", "String here2")); /*Sets the list to the display compound*/ d.set("Lore", l); There may already be a method to set Lore data like there is to set the Name, but I didn't look.
Thank you that works. What's the "" for in the first argument of the NBTTagString though? Also I'm guessing I would do the same thing for enchantments but with NBTCompound objects holding NBTTagShort objects for the id and level.
The first parameter, the "", would be the name of the NBTTagString, but since that really isn't needed for a string it's normally left blank. The process should be the same for any NBT data. Of course with enchantments, you can always just use one of the addEnchantment methods which saves you the trouble of editing the NBT data yourself.
I wanted to use NBTTags for enchantments for items that aren't normally supposed to have enchantments like sticks. I've tried using the addUnsafeEnchantment() method but that only allows me to put on enchantments that have a higher level than they are supposed to and not actually put them on items that aren't supposed to have enchantments unless they changed it from 1.4. Anyways I think I've got the hang of NBT Tags, thanks for all of your help
Great, also I shouldn't say the first parameter in an NBTTagString is normally left blank, but in an NBTTagList, the name of a tag isn't saved, so there's not much of a point in putting something other than "".
Such as the title, author, Name, and SkullOwner tags. They're all NBTTagStrings and have a Name and data. But if the NBTTagString is in an NBTTagList like pages, or Lore, the string has only data, and no name. Edit - I take that and the last post back... it's 1 in the morning and I'm tired. I was mixing up two methods and a constructor - setString(String s, String s1), set(String s, NBTBase nbtbase), and new NBTTagString(String arg0, String arg1). But never mind I'm just confusing myself and you. 'night.
Hey. If you want to learn a little bit more about how NBT Tags work with names and such, check out DiabloDrops' source here: DiabloDrops It's a plugin entirely based around manipulating NBT Tags.
one4me I was trying to rename an item in a PrepareItemCraftEvent but when I tried to cast the ItemStack from that to a CraftItemStack to get the tag it threw a ClassCastException. What I do now is rename it in a CraftItemEvent and it works fine. Do those events use different ItemStack objects or something?
Use the constructor to make a new CraftItemStack? Code: @EventHandler public void onPrepareItemCraftEvent(PrepareItemCraftEvent event) { ItemStack bis = new ItemStack(1); CraftItemStack cis = new CraftItemStack(bis); net.minecraft.server.ItemStack mis = cis.getHandle(); mis.c("test"); event.getInventory().setResult(cis); } It was a little buggy when I shift clicked for the result, I'd recommend just adding a new recipe.[/CODE]
I could add the recipe, with enchantments, name, and lore easily enough, but the shift clicking issue remains. Code: public void test() { CraftItemStack cis = new CraftItemStack(1); net.minecraft.server.ItemStack mis = cis.getHandle(); mis.addEnchantment(net.minecraft.server.Enchantment.DAMAGE_ALL, 5); mis.addEnchantment(net.minecraft.server.Enchantment.SILK_TOUCH, 1); mis.c(ChatColor.RESET + "" + ChatColor.MAGIC + "Magic"); NBTTagList list = new NBTTagList(); list.add(new NBTTagString("", ChatColor.LIGHT_PURPLE + "Magic Stone")); mis.tag.getCompound("display").set("Lore", list); CraftingManager.getInstance().registerShapedRecipe(mis, new Object[] {"***", "*@*", "***", Character.valueOf('*'), Block.STONE, Character.valueOf('@'), Item.SUGAR}); }
Hmmm, whenever I tried adding a recipe only the enchantments would show up. I'll try it again. Thanks for the help
Mine wont work... This is what i tried. I have no idea how to use NBT so, can someone help? Code:java }else if(commandLabel.equalsIgnoreCase("TestCommand")) { NBTTagCompound c = getTag(player.getItemInHand()); if(!c.hasKey("display")) { c.set("display", new NBTTagCompound()); } NBTTagCompound d = c.getCompound("display"); if(!d.hasKey("Lore")) { d.set("Lore", new NBTTagList()); } NBTTagList l = d.getList("Lore"); l.add(new NBTTagString("", "String here1")); l.add(new NBTTagString("", "String here2")); d.set("Lore", l); } This is based off of what one4me said.
rmh4209 I looked at it but couldnt get it to work. I have a feeling im doing it wrong. Obviously i am because it wont work. here is my code: Code:java if(commandLabel.equalsIgnoreCase("TestCommand")) { ItemStack Sword = new ItemStack(Material.IRON_SWORD); player.setItemInHand(Sword); Namer.setName(Sword, "TestName"); Namer.addLore(Sword, "TestLore"); }
Can I see your getTag() method. I have a feeling you aren't casting to a CraftItemStack and instead you are using the CraftItemStack constructor. If you are you have to set the item with the CraftItemStack you get from your method
Well, let me take a stab at seeing if I can get this to work for you. Code:java /* Use command.getName() here instead of commandLabel *//* It's traditionally been more reliable than commandLabel in my experience */if(command.getName().equalsIgnoreCase("testcommand")){/* It's a good idea to make sure the amount in the ItemStack is 1 */ItemStack sword = new ItemStack(Material.IRON_SWORD, 1);/* This code should make sure that the ItemStack's name is "TestName" */sword = Namer.setName(sword, "TestName");/* This code should make sure that the ItemStack's lore contains "TestLore" */sword = Namer.addLore(sword, "TestLore");/* Make sure to only set the item in the players hand AFTER messing around with its values */player.setItemInHand(sword);} Hopefully that will fix your issue.
That might work.. i had been trying to set the item in hand first, then editing it. I'll test it when i get my computer on. Wont work.. Keep getting an error 012-11-22 11:49:07 [SEVERE] null org.bukkit.command.CommandException: Unhandled exception executing command 'testcommand' in plugin KhSkills v1.0.0 at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:186) at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:502) at net.minecraft.server.NetServerHandler.handleCommand(NetServerHandler.java:985) at net.minecraft.server.NetServerHandler.chat(NetServerHandler.java:903) at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:858) at net.minecraft.server.Packet3Chat.handle(Packet3Chat.java:44) at net.minecraft.server.NetworkManager.b(NetworkManager.java:290) at net.minecraft.server.NetServerHandler.d(NetServerHandler.java:113) at net.minecraft.server.ServerConnection.b(SourceFile:39) at net.minecraft.server.DedicatedServerConnection.b(SourceFile:30) at net.minecraft.server.MinecraftServer.r(MinecraftServer.java:595) at net.minecraft.server.DedicatedServer.r(DedicatedServer.java:222) at net.minecraft.server.MinecraftServer.q(MinecraftServer.java:493) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:426) at net.minecraft.server.ThreadServerApplication.run(SourceFile:856) Caused by: java.lang.NoClassDefFoundError: com/stirante/PrettyScaryLib/Namer at com.gmail.david.anekin.rosales.KhSkills.KhSkills.onCommand(KhSkills.java:1822) at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ... 15 more EDIT by Moderator: merged posts, please use the edit button instead of double posting.
Code:java public NBTTagList getLore(ItemStack i){ net.minecraft.server.ItemStack nms = ((CraftItemStack)i).getHandle(); NBTTagCompound tag = nms.getTag() if (!tag.hasKey("display")) { return new NBTTagList(); } NBTTagCompound display = (NBTTagCompound)tag.get("display"); NBTTagList lore = display.getList("Lore"); if (lore == null) { // returns empty list return new NBTTagList(); } return lore;} public void setLore(String lore, ItemStack i){ net.minecraft.server.ItemStack nms = ((CraftItemStack)i).getHandle(); NBTTagCompound tag = nms.getTag() if (!tag.hasKey("display")) { this.addDisplay(); } NBTTagCompound display = this.getDisplay(); NBTTagList l = new NBTTagList(); // Added multiline lore support // Splits the lines String[] loreLines = lore.split("\n"); // Add each line for(String line : loreLines) { l.add(new NBTTagString("", line)); } // Set the lore display.set("Lore", l);}
Jogy34 david_rosales was getting errors right? To make it easy for him I just posted 2 methods that take care of the lore without any other libraries or code using methods from other plugins david_rosales Name would kinda be the same, except for the fact that you set a NBTTagString instead of a NBTTagList