HalestormXV
Forge Modder-
Posts
328 -
Joined
-
Last visited
Everything posted by HalestormXV
-
Okay, thank you for the example. So in reading it over I see that in your handler, you don't even have a write or a read, you kept those within the storage? So now in my case I should for sure have some functions that would return that particular instance's list this way it can be called from the storage. So ideally in my functions I should have something simply like: @Override public NBTTagCompound serializeNBT() { NBTTagCompound nbt = new NBTTagCompound(); int[] convertedList = Ints.toArray(knownSpells); nbt.setIntArray("LearnedSpells", convertedList); return nbt; } @Override public void deserializeNBT(NBTTagCompound nbt) { int[] convertedList = Ints.toArray(knownSpells); convertedList = nbt.getIntArray("LearnedSpells"); } And in my storage i should have something along the lines of public NBTBase writeNBT(Capability<ILearnedSpells> capability, ILearnedSpells instance, EnumFacing side) { NBTTagCompound nbt = new NBTTagCompound(); nbt.setIntArray("LearnedSpells", instance.getSpellList); return nbbt; } @Override public void readNBT(Capability<ILearnedSpells> capability, ILearnedSpells instance, EnumFacing side, NBTBase base) { NBTTagCompound nbt = (NBTTagCompound) base; instance.setSpellList(nbt.getIntArray("LearnedSpells")); } I'm guessing?
-
I didn't relaize a guava version existed. Thank you, it is far more conveneient. And draco I thought you were talking about something else. My mistake. int[] convertedList = Ints.toArray(knownSpells); nbt.setIntArray("LearnedSpells", convertedList); Much better and cleaner. So what i crossed out is a simple fix for me, no problem. But if the capability should not extend anything then are you saying that the storage class should be the one doing everything that is within the functions when it comes to the read and write of the NBT. So should i scrap what is in the LearnedSpellsFunctions (writeNBT, serializeNBT, and deserializeNBT) and move it into the storage or something else entirely. Sure this may seem like relatively simply stuff but unfortunatly documentation on the capabilities is not as abundant as some of the other things. And most of the research I did find and examples I did follow did so this way (with much simpler capabilities). Now be that the wrong way is clearly not for me to decide but I am just working off what I have found and read. The ProjectE Primer on Capabilities is probably the only one that has advanced Capability manipulation in it but even that doesn't fit what I am trying to do. So once again, yes this all may seem simple and chalk full of stupid errors lol but that is how I am learning this. And generally when posting on these forums in particula me personally follow through with all the suggestions and learn from it as you may or may not already know. So unfortuantly that is happening with this. I even tried doing a (literally just to try an alternative) return new NBTTagIntArray(getListFunction); } and having the getListFunction do basically everything that was being done before and got stopped by the fact that NBTTagIntArray is private.
-
I seemed to have fixed it with this updated code: https://hastebin.com/hufinerope.java I tried testing, but becasue every re-run of the environment generates a new UUID i can't tell if it is actually saving the old values or not or just replacing whats there with new values.
-
Becasue I thought that over-riding in the functions part of the code would resolve it since in this particular capability i used public static class LearnedSpellsProvider implements ICapabilitySerializable<NBTTagCompound> instead of public static class LearnedSpellsProvider implements ICapabilitySerializable<NBTBase>
-
Maybe in the povider? Since that is the only place i see returning a null? Although having it in the override in the functions class should stop that right? https://hastebin.com/ututihoyeq.java or line 96 of the whole class pasted on this page https://hastebin.com/olohifagap.java
-
Because even with the entire capability: https://hastebin.com/olohifagap.java Having zero errors in the compiler at least. This is still occuring when the game attemptes to save the data (pause menu or whatever) https://hastebin.com/etikawuqad.css So something is casuing null somwhere. Also, this entire capability class was recycled from another one of my capabilities that simply stores a single integer under a single key that changes throughout the game. Having a Capability that stores an array of integers under one key must require some additional modifications somewhere else within the capability I would think?
-
Well there has to be more to it then this: https://hastebin.com/livubofure.java Surely there needs to be more work done on the writeNBT right. I am guessing I can't jump right to the deserializeNBT just yet. I mean private NBTTagCompound writeNBT(List<Integer> knownSpells ) { NBTTagCompound nbt = new NBTTagCompound(); nbt.setIntArray("LearnedSpells", convert2Primative(knownSpells)); return nbt; } cant be correct
-
It wasn't a crash. It was just what spit out when it attempted to save the player. No crash. Alright so the setIntArray also sets up the tag if it doesn't exist yet. I knew the setTag did that, I didn't realize the setIntArray did that also. I am guessing all the setters in the NBT do the same? Secondly, you have to first create the tagCompound before you can manipulate it, just like an item right? Or do i have to do something like get the storage of this capability?
-
Okay so now that, that is all set up here is what happens in game: https://hastebin.com/pinajapohi.css I know that is happening because it is attempting to save the data likely to a tag that is non-existant? Correct? Which I expect with the way the code is now. So now the next step is to properly write the array to a tagCompound utilizing the writeNBT correctly? Is leaving serilizeNBT the way it is fine? @Override public NBTTagCompound serializeNBT() { return writeNBT(this.knownSpells); } Because from what I am gathering this writeNBT private NBTTagCompound writeNBT(List<Integer> knownSpells ) { NBTTagCompound nbt = new NBTTagCompound(); nbt.setIntArray("LearnedSpells", convert2Primative(knownSpells)); return nbt; } currently is just taking a non-existant tagCompound and trying to set an intArray (which is the coverted knownSpells) to a tag that does not yet exist correct?
-
Alright so in other words you dont need to ever call that, becasue it does it on its own correct? If you call it, then it will over-write the one that has already been setup within the capability right?
-
I didn't realize there was a method to do it for you already so I just made one, but I'd be happy to sub it out. But this is what I have done so far. Like I said, I am doing this as I go and read these responses and do some searching. And I do appreciate the responses. I am getting an understanding so far. https://pastebin.com/3FGJuz6X (since the code is getting larger now)
-
Right I know that, like I said I am writing it as I respond and read this thread, writing in the checks thats fine. if (nbt.hasKey("LearnedSpells")) //ENTER CODE HERE }else{ nbt.setIntArray("LearnedSpells", knownSpells);} create the tag and set it. That part I know. I've worked with the NBT before, but what I am struggling with is how to actually take that list created above in the learnSpell and store it into the NBTTagIntArray. trying to setIntArray like that throws and error.
-
I know I'm not writing anything at all. I am actually doing this at the same time as I am posting and just posting the bits as I go. I didn't get down to that segment yet. This is literally the skeleton of the code. I am filling it in as I watch for the responses.
-
Yeah that is what I meant sorry. So it would look something like this? public class LearnedSpellsFunctions implements ILearnedSpells { private int SPELL_ID = 0; private List<Integer> knownSpells = new ArrayList<>(); public void learnedSpell(int spellLearned) { this.SPELL_ID = spellLearned; this.knownSpells.add(SPELL_ID); writeNBT(); } private NBTTagCompound writeNBT(NBTTagIntArray listSpells) { NBTTagCompound nbt = new NBTTagCompound(); return null; } Since an Interger list is primative you need to ArrayList it right? But would the writeNBT be a NBTTagCompoud that writes the NBTTagIntArray? or do you need some type of getter to get the list and pass it in? That is where I am getting hung up I think, becasue I can't figure how to pass the list that is created and added to, into the writeNBT
-
And then the writeNBT would write an NBTTagArray rather than an NBTCompound?
-
Sorry. Here is how I did this capability in particular. My other ones are slightly different, but I decided to try this one with a different approach. So here is the class: https://pastebin.com/PNXtRZX7 All I need to do is essentially have: public void learnedSpell(int spellLearned) { this.SPELL_ID = spellLearned; //writeNBT(this.SPELL_ID); } place the spellID in. All the spells are integers so they would all go into a key "SpellsLearned" and then the values would be [1, 3, 4, 5, etc. etc. etc.]. I just made the capability a little while ago so as it stands this is simply just the skeleton.
-
So I am guessing it would work something like this? (Never used the NBTTagIntArray before) I need a function in my capability functions that takes the int and passes it to a writeNBT and in that writeNBT it adds it to an NBTTagIntArray? And then the serilize returns the writeNBT(spellID)? If you have or anyone has or knows of any examples showing how the NBTTagIntArray works I'd appreciate it. This is something totally new to me. I mean the concept is so simple. Pass an int into a function. Call a method that uses that int to write data into the writeNBT. Check if the key exists, if not create it, otherwise find the key that has the NBTTagIntArray and add the id to that array. I just think since I havent worked with this before it is giving me a block.
-
Quick question and it is simply just because I can't find it. I am fairly certain it exists becasue I thought I saw a thread about it on here, or at least saw it being discussed. I have a few Constants that I utilize to identify some ints. I want to store them in a player's capability under one tag, namely IntList. So the key "intList" will contain, 1, 2, 3, 4, etc. etc. etc. So essentially it is a NBTKey that contains a list of ints. And if memory serves I thought it was called NBTList or TagList or something like that. I am fairliy certain it is within the NBT methods (the writing and reading of the list) but I can't seem to find it or how to properly execute it and am not in front of my code atm to search. Any help? Also, secondary question. Does this really need a Capability? All I am essentially doing is storing a list under one key on the player. Or is there an alternative way to do it? Perhaps simply just writing NBT data onto the player?
-
[1.12.2] Checking a Specific Container for Items
HalestormXV replied to HalestormXV's topic in Modder Support
I like that universal method as there are quite a few abilities and creating a List for each ability seems like the best way especially if I store it in its own class (all the lists with the requirements). Then I am guessing I can do a call to initialize the list before the check runs, and then as the check runs remove the items from the list as you said when it finds the item and check if the list is empty and return true or not then it will just rinse and repeats itself when the item is used. Could that cause any problems though? Re-initializing the list over and over or is that probably the best way to do it. EDIT: I managed to get the universal method working. I'm open to criticism as I don't know quite how effective this is or how "hacky/sloppy" it is on efficency but I'm open to suggestions. But as it stands this piece of code looks into the ItemStack list that was passed to it and then calculates if the player has the items in the list and how many of those items should be removed. I also have a backpack in my mod so it also will check the inventory of the player's backpack and compare. From testing it seems to respect the slots that the player has in inventory and if it can find an item in the inventory but is looking for another item as well and can't find it and the player has a backpack it will check that inventory as well. Overall I am pretty happy with it but I am open to comments or suggestions as well. Here is the link to the code segment: https://pastebin.com/Jrs7XD9Q -
[1.12.2] Checking a Specific Container for Items
HalestormXV replied to HalestormXV's topic in Modder Support
To be quite honest @diesieben07 I was hoping for either you or @Draco18s to reply and say exactly what you said which was somewhat like. "hey dope, why are you creating a new ItemStackHandler - stop being a dingus and remember the getCapability function to get the correct IItemHandler. Which is pretty much exactly what you said, in a more poignant way as I am the said dingus who forgot about the the IItemHandler capability entirely (even though it is in the actual bag but I was too focused on this single piece of code). I knew that creating the new IItemHandler was going to cause me issues because my debug messages kept saying that "air" was present in the slots. That being said your four sentences managed to let me combine both my checks into one check that will first look at the inventory and if nothing is there, check if there is a bag in the inventory, and if yes then check that inventory and if nothing is in the bag then return a 0 lol. So I have to thank you as per usual lol. I am going to post the code once I finish fixing it up as I do have one other question relating to having different items as requirements as for example you require both 3 Redstone AND 4 Glowstone to successfully use this. I am not sure of the best way to do this. EDIT: Here is the new code: https://pastebin.com/X22LRFaP Still need the best method to take care of different item requirements though. -
[1.12.2] Checking a Specific Container for Items
HalestormXV replied to HalestormXV's topic in Modder Support
What am I mucking up over here. I can't figure it out. public static int checkForReagentQuantityRuneBag(ItemStack itemStack, EntityPlayer thePlayer) { System.out.println("Good news is I am getting called at least."); Item reagentItem; IItemHandler itemHandler = new ItemStackHandler(thePlayer.inventory.getSizeInventory()); for (int slot = 0; slot < thePlayer.inventory.getSizeInventory(); slot++) { ItemStack stack = itemHandler.getStackInSlot(slot); //if (stack.getItem() == ItemInit.ITEM_RUNE_BAG) if (stack.getItem() instanceof RuneBag) { System.out.println("I found the rune bag while going through all the slots!"); IRuneBagProvider theRuneBag = thePlayer.getCapability(RuneBagProvider.RUNEBAG_CAP, null); theRuneBag.getBag(EnumDyeColor.RED); reagentItem = itemStack.getItem(); IItemHandler bagHandler = new ItemStackHandler(theRuneBag.getBag(null).getSlots()); for (int bagSlots = 0; bagSlots < bagHandler.getSlots(); bagSlots++) { ItemStack stackInBagSlot = bagHandler.getStackInSlot(bagSlots); if (!stackInBagSlot.isEmpty() && stackInBagSlot.getItem().equals(reagentItem)) { int total = stackInBagSlot.getCount(); System.out.println("Player has: " + total + stackInBagSlot.getDisplayName() + " in the Rune Bag."); return total; } } } else { Logging.getLogger().debug("Sorry Kappa, you almost got it."); //return 0; } } Logging.getLogger().debug("Sorry Kappa, no Rune Bag here."); return 0; } System.out.println("Good news is I am getting called at least."); - The is where my code makes it and then stops. I am likely doing the whole checking the inventory of the RuneBag thing wrong, but I would at least want to try and get into that step before I start worrying about it. Thoughts on what I am doing wrong that I am getting stopped before even reaching any other of my debug messages? As you can see from the commented line I have tried both if (stack.getItem() == ItemInit.ITEM_RUNE_BAG) if (stack.getItem() instanceof RuneBag) -
[1.12.2] Checking a Specific Container for Items
HalestormXV replied to HalestormXV's topic in Modder Support
Okay, I missed that myself. Let me try and explain better. You need particular items to cast something. Example, in order to apply a resistance you need both 4 Redstone Dust and 3 Glowstone Dust. This dust can be in the player inventory. But if not and the player has the BackPack item in their inventory we want to check that also. So I am thinking a check of the inventory first. --> Okay we have nothing in the players inventory but we see that the player has a backpack, --> lets check that also. I am going to have to use the Backpacks itemHandler to look inside it right? So I would have to first get the Capability of that Backpack? Then after returning it, call the ItemHandler functions and check through that backpack to see if we have both of the items and their quantities required. So I am also guessing, that these Items that are required will have to be stored in an Array, correct? Since I can't pass multiple items through? Instead, I'd have to pass the array through and iterate through the array right? That is why this is tripping me up I think, because I am just trying to get the steps right and ordered correctly. The code above once fixed will work right? But won't work if there are multiple items required correct? -
[1.12.2] Checking a Specific Container for Items
HalestormXV replied to HalestormXV's topic in Modder Support
So something like this? public static int checkForReagentQuantityRuneBag(ItemStack itemStack, IItemHandler itemHandler) { int count = 0; Item reagentItem = itemStack.getItem(); for (int index = 0; index < itemHandler.getSlots(); index++) { ItemStack stack = itemHandler.getStackInSlot(index); if (!stack.isEmpty() && stack.getItem().equals(reagentItem)) { int total = count += stack.getCount(); System.out.println("There are "+total+" "+stack.getDisplayName()+" in the inventory."); return total; } else { return 0; } } return 0; } I am going to take a wild guess and say you can't actually pass the itemHandler in because you need to get the actual IItemHandler for your Backpack right? So do I have to call/check the capability somewhere? Perhaps I am totally wrong which is certainly probable since I am so used to the IInventory that this is like throwing me off. -
[1.12.2] Checking a Specific Container for Items
HalestormXV replied to HalestormXV's topic in Modder Support
I've been using that code since forever, so I can imagine that it has been replaced. Do you have an example or pseudo code using IItemHandler for that above? I'm trying to migrate everything I can over to the better implementations. For starters like how I made the backpack with Capabilities. I'm imagining you are referring to the @Nonnull ItemStack getStackInSlot(int slot); /** * Returns the number of slots available * * @return The number of slots available **/ int getSlots(); in the IItemHandler and simply just replicating the above with those calls instead and obviously adjusting accordingly? -
So I made a custom backpack and it works nicely. No issues. What I am trying to do next is check a players inventory for items. However now that I have added my backpack I want to also check the backpack's inventory. Not sure how I would go reaching into the container to look for items though. Here is my simple function that checks for quantity in the player's inventory which I have been using for some time with no problems. How could I make this work on my backpack's inventory also? public static int checkForReagentQuantity(ItemStack itemStack, EntityPlayer player) { int count = 0; Item reagentItem = itemStack.getItem(); boolean hasReagent = player.inventory.hasItemStack(itemStack); if (hasReagent) { for (int slot = 0; slot < player.inventory.getSizeInventory(); slot++) { ItemStack stack = player.inventory.getStackInSlot(slot); if (stack != null && stack.getItem().equals(reagentItem)) { int total = count += stack.getCount(); //System.out.println("Player has: " + total); return total; } } } else { return 0; } return 0; } Ideally, I want to try and run that on my Backpack's as well. It sounds quite simple, but my gut is telling me it isn't that easy.