Posted March 31, 20187 yr Hey everyone. So I have this block that takes enchants from items and turns it into "enchant essence", this part of the block works great, however I also want the block to "learn" the enchants given, so it can be applied to a different item using said essence. I have most of that system figured out; the only part I don't is: Saving all given enchants to a hashset, then storing it to NBT Have a list of buttons (with a scroll menu) for the user to select their enchant, and have another set of buttons to display what level of enchant (have this figured out other than the scroll menu ) So my question is: How can I save the array list to NBT & create a list of buttons (via scroll menu) to display all enchants? Edited April 1, 20187 yr by Lambda dog jumped on keyboard and did a lot of shit LOL Relatively new to modding. Currently developing: https://github.com/LambdaXV/DynamicGenerators
March 31, 20187 yr Author Edit: I ended up using a hashset for this as because I do not want duplicate enchantments. So how to save to NBT with a hashset? Relatively new to modding. Currently developing: https://github.com/LambdaXV/DynamicGenerators
March 31, 20187 yr A HashSet is just a collection of values, so you can save it to an NBTTagList. If all you're storing in the HashSet is the enchantment types (i.e. Enchantment instances), you can save the registry names to the NBTTagList. 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.
March 31, 20187 yr I quite literally just did this the othe day. Feel free to take a look at the code. What it does is generate two numbers and stores them. It coverts one of the number to the string value which acts as the key (since that works for my uses) and then it simply stores the whole set in a tag list. https://hastebin.com/netoleheya.cpp You can ignore the commented HashMap as I used that originally to make sure that no values were getting lost and calculated incorrectly. I commented it out but just forgot to remove it from the code base. Feel free to take an edit as you need for your uses. Edited March 31, 20187 yr by HalestormXV
April 1, 20187 yr Author Okay, so I got completely rid of the hashmap and I'm now using: public NBTTagList enchantNBT = new NBTTagList(); and every time an Item is used by the machine -- this line runs: this.enchantNBT.appendTag(itemInput.getEnchantmentTagList()); However, I'm having issues with finding how to save this NBTListTag to the TE's NBT. thanks for the help! Relatively new to modding. Currently developing: https://github.com/LambdaXV/DynamicGenerators
April 1, 20187 yr You should not be using NBT for runtime data. Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
April 1, 20187 yr Author Oh yeah, for some reason that totally slipped my mind. So still have the hashmap, still save to it every time it needs to. However, how do I write to it then? Do I iterate through the hashmap and append it to the TagList within the write NBT method? Then how would I read it and assign it back to the map? Thanks Relatively new to modding. Currently developing: https://github.com/LambdaXV/DynamicGenerators
April 1, 20187 yr When writing to NBT, iterate through the HashSet and add a tag for each entry to the NBTTagList. When reading from NBT, iterate through the NBTTagList and add an entry for each tag to the HashSet. Note that you don't need to store the NBTTagList in a field or use it at runtime in any way, just read it from/write it to the NBTTagCompound argument of the TileEntity#readFromNBT/writeToNBT methods. Forge patches NBTTagList to implement Iterable<NBTTagBase>, but you can't really do much with an NBTTagBase without casting it to the appropriate subtype so it's not all that useful. Instead, you'll probably want to use a numeric for loop with NBTTagList#tagCount and NBTTagList#getStringTagAt. 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.
April 1, 20187 yr Author ok, so I think I have it mostly right, however I'm getting a crash: Spoiler [11:36:36] [Server thread/ERROR]: Encountered an unexpected exception net.minecraft.util.ReportedException: Exception ticking world at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:835) ~[MinecraftServer.class:?] at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:741) ~[MinecraftServer.class:?] at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192) ~[IntegratedServer.class:?] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:590) [MinecraftServer.class:?] at java.lang.Thread.run(Unknown Source) [?:1.8.0_111] Caused by: java.lang.NullPointerException at com.unassigned.customenchants.blocks.tile.TileEntityEnchantmentFab.writeSyncableNBT(TileEntityEnchantmentFab.java:71) ~[TileEntityEnchantmentFab.class:?] at com.unassigned.customenchants.blocks.tile.base.TileEntityBase.getUpdateTag(TileEntityBase.java:111) ~[TileEntityBase.class:?] at net.minecraft.network.play.server.SPacketChunkData.<init>(SPacketChunkData.java:51) ~[SPacketChunkData.class:?] at net.minecraft.server.management.PlayerChunkMapEntry.sendToPlayers(PlayerChunkMapEntry.java:161) ~[PlayerChunkMapEntry.class:?] at net.minecraft.server.management.PlayerChunkMap.tick(PlayerChunkMap.java:212) ~[PlayerChunkMap.class:?] at net.minecraft.world.WorldServer.tick(WorldServer.java:236) ~[WorldServer.class:?] at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:829) ~[MinecraftServer.class:?] ... 4 more Which points to this line: enRegStorage.setString(e.getRegistryName().toString(), e.getRegistryName().toString()); within this block of code in the writeNBT: NBTTagList enchantList = new NBTTagList(); NBTTagCompound enRegStorage = new NBTTagCompound(); for(Enchantment e : knownEnchants) { enRegStorage.setString(e.getRegistryName().toString(), e.getRegistryName().toString()); } enchantList.appendTag(enRegStorage); compound.setTag("enchantList", enchantList); Now I know the line I wrote is wrong, because visually it doesn't look right, however thinking about it, it makes since. and for reading I'm doing this: NBTTagList list = compound.getTagList("enchantList", 10); if(list != null) { for(int i = 0; i < list.tagCount(); i++) { Enchantment theEnch = Enchantment.getEnchantmentByLocation(list.getStringTagAt(i)); knownEnchants.add(theEnch); } } thanks. Relatively new to modding. Currently developing: https://github.com/LambdaXV/DynamicGenerators
April 1, 20187 yr Author Yeah, and I thought this when coding it, but I'm so inexperienced within NBT that I can't figure out whats wrong. So instead of creating a new NBTTagCompound, I'm going to use the one within the method itself. How would my write method be written as then? I find all enchants within the hashmap, get their registry name then how would I write it to an NBTTagList then store it to the compound? Thanks. Relatively new to modding. Currently developing: https://github.com/LambdaXV/DynamicGenerators
April 1, 20187 yr Author so append to the list every time it iterates a new NBTTagString? If thats the case, how can you set a NBTTagString, as there isnt a method for one? thanks Relatively new to modding. Currently developing: https://github.com/LambdaXV/DynamicGenerators
April 1, 20187 yr Author For some reason, I thought setting it would be like "NBTTagString.setString()", however I did realize it is set in the contructor So something like this? NBTTagList enchantList = new NBTTagList(); for(Enchantment e : knownEnchants) { NBTTagString eString = new NBTTagString(e.getRegistryName().toString()); enchantList.appendTag(eString); } compound.setTag("enchantList", enchantList); Edited April 1, 20187 yr by Lambda Relatively new to modding. Currently developing: https://github.com/LambdaXV/DynamicGenerators
April 1, 20187 yr Tip: I highly recommend that when implementing tag functionality, especially if you're not highly familiar with it, that you print out the compounds to the console/logger throughout your code that reads and writes it. It can much more quickly get you a sense of what is going on. NBT is technically very simple, but I think it can be confusing (for beginners) because you can "nest" them in different ways. You can have compounds of mixed types, lists of compounds, compounds of lists, and so forth. Furthermore, the reading and writing need to be perfectly "reciprocal" which a lot of people mess up. So seeing the compounds in print statements I find is extremely helpful to track what is going on. Check out my tutorials here: http://jabelarminecraft.blogspot.com/
April 1, 20187 yr Author Yeah, I understand the basic concept of NBT, however when it comes down to other types of things (like creating NBTLists or strings) it just gets confusing, I only know writing to a compound values of my TE and having them saved and loaded back in. Thanks for the tip. Also, I test my code above and still got the same crash, on this line however: NBTTagString eString = new NBTTagString(e.getRegistryName().toString()); and I still cant see what I'm doing wrong Relatively new to modding. Currently developing: https://github.com/LambdaXV/DynamicGenerators
April 1, 20187 yr Author Okay now I check if e!=null and it doesn't crash anymore, however the list still resets when I leave and join the game: [13:40:56] [Server thread/INFO] [STDOUT]: [com.unassigned.customenchants.blocks.tile.TileEntityEnchantmentFab:update:111]: [net.minecraft.enchantment.EnchantmentLootBonus@5d98364c, net.minecraft.enchantment.EnchantmentDurability@cea67b1] rejoins: [13:41:04] [Server thread/INFO] [STDOUT]: [com.unassigned.customenchants.blocks.tile.TileEntityEnchantmentFab:update:111]: [] here is updated code: write: NBTTagList enchantList = new NBTTagList(); for(Enchantment e : knownEnchants) { if(e != null) { NBTTagString eString = new NBTTagString(e.getRegistryName().toString()); enchantList.appendTag(eString); } } compound.setTag("enchantList", enchantList); read: NBTTagList list = compound.getTagList("enchantList", 10); if(list != null) { for(int i = 0; i < list.tagCount(); i++) { Enchantment theEnch = Enchantment.getEnchantmentByLocation(list.getStringTagAt(i)); knownEnchants.add(theEnch); } } thanks for your help! Relatively new to modding. Currently developing: https://github.com/LambdaXV/DynamicGenerators
April 1, 20187 yr Author I'm still confused: NBTTagList list = compound.getTagList("enchantList", Constants.NBT.TAG_COMPOUND); So is the issue, correct? And what I'm trying to see is that the main reason why this isn't working is because i'm asking for a TAG_COMPOUND when I really want a Tag List? As you mentioned, minecraft ignores the different type, so how would I end up doing this then? Relatively new to modding. Currently developing: https://github.com/LambdaXV/DynamicGenerators
April 1, 20187 yr Author So NBTTagCompound.getTagList() returns a list of NBTTagCompounds , correct? So How would I make it return NBTTagString? There doesn't seem to be another method. Sorry for my little knowledge on this, probably getting quite annoying. Relatively new to modding. Currently developing: https://github.com/LambdaXV/DynamicGenerators
April 1, 20187 yr Author Oh! So I needed the TAG_STRING type to return the list of strings I set! That makes complete sense and I should of looked more into the system. Thanks you all for the help, it works perfectly now! Relatively new to modding. Currently developing: https://github.com/LambdaXV/DynamicGenerators
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.