Posted September 4, 20169 yr I may have finally run aground with the way my pre-written books are added. The loot table entry below only produces an item for the bookScale class (also below). the itemstacks have no unlocalised name so I cant reference them directly as a string. elsewhere in the code, I can reference the subitems, via "bookScale.eastScale" or "bookScale.eastScale.getMetadata()" which is how I was doing it when loot tables were handled directly in code. is there a way to add items to loot tables in the code still? The book in the loot table: { "type": "item", "name": "thejungle:bookScale", "weight": 10, "functions": [ { "function": "set_data", "data": 367 } ] }, The book class (chopped down to remove all page data): public class bookScale extends ItemWrittenBook { public static ItemStack eastScale; public static ItemStack westScale; public static ItemStack northScale; public static ItemStack southScale; public bookScale() { super(); this.setUnlocalizedName("bookScale"); //Omnibusaurus Codex this.setContainerItem(this); this.setCreativeTab(w2theJungle.JungleModTab); this.setHasSubtypes(true); } { { eastScale = new ItemStack(Items.WRITTEN_BOOK); eastScale.setItemDamage(367); NBTTagCompound tag = new NBTTagCompound(); eastScale.setTagCompound(tag); } } @SuppressWarnings({"rawtypes", "unchecked"}) @Override @SideOnly(Side.CLIENT) public void getSubItems(Item i, CreativeTabs c, List list) { list.add(bookScale.eastScale); list.add(bookScale.westScale); list.add(bookScale.northScale); list.add(bookScale.southScale); } }
September 4, 20169 yr Either use the set_nbt function in the loot table file to set the NBT or create your own LootFunction that sets the appropriate NBT. You're setting the bookScale.eastScale field to an ItemStack of Items.WRITTEN_BOOK instead of the bookScale instance, are you sure this is what you want? I recommend following Java and MCP naming conventions: PascalCase for class names, prefixed with the base type that they extend (i.e. ItemBookScale instead of bookScale ). Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
September 4, 20169 yr Author I've had the field for the subitems set every which way over the course of the orginial mods development. i dont recall if using the bookscale instance actually works. ill try it. in the mean time, regarding the nbt function for loot tables, are you talking about creating a custom loot tag?
September 4, 20169 yr Author changing the field to bookScale throws up a null pointer at the setItemDamage line.
September 5, 20169 yr I've had the field for the subitems set every which way over the course of the orginial mods development. i dont recall if using the bookscale instance actually works. ill try it. Do you ever create an register an instance of bookScale ? If so, why use the vanilla book for its sub-items? If not, why does it extend Item at all? changing the field to bookScale throws up a null pointer at the setItemDamage line. A NullPointerException is thrown when you attempt access a method or field of a null value. You'll have to figure out what's null and why it's null . in the mean time, regarding the nbt function for loot tables, are you talking about creating a custom loot tag? I mean you should use a loot function (either set_nbt or your own custom function) in the loot table file to fill out the page data for the book. Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
September 6, 20169 yr can i create a custom function that accepts an itemstack? Your LootFunction will receive the ItemStack it's supposed to modify as an argument in the LootFunction#apply . There's not much point in specifying a whole ItemStack as an argument in the loot table itself, you may as well just use set_nbt . Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
September 6, 20169 yr Author sorry, what i meant was a custom type. the issue lies in the type being an item. calling getItem on bookScale will not return any of the actual books. adding the nbt directly in the loot table seems overboard as a solution, is all. its about 30+ pages across 4 books and multiple loot tables. if i need to change anything in any book, all those files need to be altered. i know loot tables can be nested, but that doesn't replicate simply adding an item to an existing loot table - if the nested table has multiple rolls it will do all those rolls, each time it gets selected. hmm. as i type, i think i know a way around that. so anyway, yeah. custom type? also, if i set the nbt in the loot table, id still need the nbt in the bookScale.class for the creative tab.
September 6, 20169 yr Create a LootFunction that takes some sort of book ID (probably a ResourceLocation ) as an argument in the loot table and fills the ItemStack with the NBT for that book. Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
September 6, 20169 yr Author ok, let me see if ive got the logic clear here. i create a custom lootfunction. the function needs to be able to distinguish which book is being specified. then, in the lootFunction#apply i can call the nbt for that book and apply it to the passed in stack before returning it. the nbt will still actually be set in the bookScale.class? i wonder. what if i set the method apply to create a new itemstack right there depending on the getMetadata of the passed in stack and return that? eg. if(stack.getMetadata() = 367) return new bookScale.eastScale;??
September 6, 20169 yr i create a custom lootfunction. the function needs to be able to distinguish which book is being specified. then, in the lootFunction#apply i can call the nbt for that book and apply it to the passed in stack before returning it. the nbt will still actually be set in the bookScale.class? Yes, I'd recommend creating a method in bookScale to apply the NBT for the specified book to a provided ItemStack and then using this in both bookScale#getSubItems and the LootFunction . Now that I think about it more, you shouldn't be storing pre-written text directly in NBT anyway. Any text you display to the user should be translated to the client's locale, which won't work if you store the English text in the NBT. The best way to do this is the following: Store the number of pages in each book somewhere Store the book ID in the ItemStack using metadata or NBT Don't extend ItemWrittenBook Create a client-only (@SideOnly(Side.CLIENT) ) method (we'll call it getBookStack , but the name doesn't really matter) that takes the book ID or ItemStack and returns an ItemStack of Items.WRITTEN_BOOK with the translated text for that book in the NBT. To gather the translated text for a book, iterate from 0 (inclusive) to numPages (exclusive) and call I18n.format with a translation key containing the book name and the page number (e.g. book.<yourmod>:bookScale.east.page.0 , book.<yourmod>:bookScale.west.page.5 , etc.). Provide translations for these keys in your mod's lang files. [*]Use the IGuiHandler system to open the vanilla book GUI when the item is right clicked (only on the client): Pass the book's ID as the x argument of EntityPlayer#openGUI (since you don't need actual coordinates for item-based GUIs) Return null from IGuiHandler#getServerGuiElement (since your GUI doesn't have a server component) Return an instance of GuiScreenBook from IGuiHandler#getClientGuiElement . Pass it an ItemStack of Items.WRITTEN_BOOK returned from getBookStack . Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
September 6, 20169 yr Author thanks for the help thus far. your above post is taking me into pretty deep waters from my point of view, though. although it would be really great to allow the books to be translated into different languages, i'm trying to stay focused on getting my mod updated to 1.9.4+. i'm going to give the custom lootfunction a shot first. With this in mind, how do i get the game to use my custom function class? i found these in forgehooks: public static LootEntry deserializeJsonLootEntry(String type, JsonObject json, int weight, int quality, LootCondition[] conditions){ return null; } public static String getLootEntryType(LootEntry entry){ return null; } //Companion to above function the former is called in LootEntry#deserialise, the latter in lootEntry#serialise
September 7, 20169 yr Register your LootFunction 's Serializer with LootFunctionManager.registerFunction . Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.