Hey what’s going on guys it’s dirty worthy here and welcome back to another minecraft running tutorial for version 1.18 in this tutorial we’re going to be covering item capabilities so this is a way of saving items inside of our block entity this is actually fairly simple to do And so let’s just go ahead and let’s get started with it so for this tutorial i’m going to be creating a new class which will be sort of a um an abstract layer between your block entity and the actual block entity class so it’s essentially a utility class if You think of it like that so what i’m going to be creating in this drawer is i’m going to creating a draw and it will simply hold one um one type of item and it will hold up to um well a large number i forgot what number specifically thirty two thousand Seven hundred and something um and it will hold that number of that singular stack of items and it’s actually very simple to do this way um in the next tutorial i will be covering containers and then i’ll be covering screens or i might do those both in the same tutorial actually because They’re kind of attached to each other so let’s get started let’s come into our block nt package and let’s create a new class now i’m going to call this class inventory block and see and you’re going to want to make sure this extends block entity okay and let’s finish now well obviously Going to want to change these to be what they actually are so type pause and state if you’re wondering what key i did in order to change both of these at once in eclipse that is alt shift r and then you should start hoping and it will change all of them And enter will actually refactor it let’s get rid of this white space up there actually let’s add that white space back because we’re going to need some fields so first we’re going to need a integer which is the size of our inventory so how many slots it can hold So we’ll have a protected final int size it’s final because we only want it to be able to be set once and we’re going to now want to take that size in our constructor and do this.size is equal size now we could even add some validation Here so we could say if size is less than not equal to zero then size is equal one okay you could do something like that and then say this dot size is equal size in fact i’m going to do that because just to make sure you actually put in a correct value We don’t want to accidentally create something with um an undefined size that wouldn’t be very good then we’re going to want an integer which is for a timer now we’ll just use this for ticking stuff so protected int timer and then we’ll have another field which is a protected Boolean and we will use this for determining whether our block nst needs updating since basically we’re going to be messing around with capabilities and we need to make sure it’s updated when things are changed so i’m going to have a boolean here called requires update and when this is ever true we’re just Going to update the tile entity or block entity i mean and um there are two more fields that we’re going to want so let’s actually create the inventory itself so to do that we’re first going to want a protected final item stack handler and we’ll call this the inventory Then we’re going to want a protected lazy optional of item stack handler and we’ll just call this the handler just import lazy optional and i’ll explain what these are in a second it’s right now that would probably be a bit confusing to explain however we do need to go ahead and set These in the constructor so this dot inventory is equal to and this is going to be a method which we’ll create in a second called create inventory that’ll just create it for us and then we’ll do the same with the handler so the start handler But this time it’s going to be equal to lazy optional dot of and then we just want a simple supplier of desktop inventory like that okay now let’s create this uh create inventory method so we can make this private and it’ll be an item stack handler create inventory Now in here we’re just going to want to return a new item stack handler and that’s going to be the one that takes in an integer which will be this dot size now we’re going to want to make this an inner class just like that and we’re going to want to override two Methods so we’re going to want to override extract item and also insert item okay and just before actually we’ll leave that for a second yeah we’ll leave that so let’s now create our capability stuff so we’re going to want to override git capability the one that takes in the side is preferable And in here we’re just going to return cap which is the capability that’s being passed in is equal to and since our capability is an item we need to use capability item handler dot item handler capability if it is then we’ll use this.handler and we need to cast that so that gives Us the lazy optional that it wants it’s simply just casting uh this item stack handler to whatever this is looking for as you can see here it just returns it like that and if not we’ll just say super get capability now if you have multiple capabilities you’re probably just going to want to Change this to a if statement uh instead of uh inline if statement after we’ve done that let’s create two getters in this class let’s create a get handler and let’s create a get inventory there we go let’s also create a getter for the size it’s like in fact um It’s final isn’t it so we can just make this public and in fact we can also make this public because that’s also final so we don’t need that there we go cleaning it up a little bit as we go now we’re going to want these same methods that we used in the last Block entity tutorial so if we come into here you can see we made our handle update tag get update tag get update packet etc etc so we’re going to want those first let’s do get update packet and as in the last tutorial we just returned client uh client bound update No client client pound block entity data packet dot create this then we’re going to want get update tag now here’s where i want to mention something i did differently in the last tutorial so in the last tutorial when we come down to somewhere here we go get update tag now i previously Had something along the lines of save a new compound tag right so if you could if you check the last tutorial you’ll see that i had it like this however as of recent forged versions and as of my recently gained knowledge this save method is basically broken at the moment um so we Need to actually use save additional now you’ll see i’ve already changed it in here um because it was causing some issues so all you need to do is change every save method to save additional and inside of get update tag we need to change save to serialize nbt So that is just one la one difference from the last tutorial let’s just plug that in here as well serialize mbt then let’s do a handle update tag so we’ll call the super and then we’ll just load tag simple and what’s the other one the other one is on data packet Okay we will call the super and then we’ll just handle update tag and that is packet dot get tag there we go now we’re going to want to override the to saving so the saving and the loading so we’ll override save additional and this is the tag oh what the hell okay eclipse Sure so we’ll just call the super in there as we always do and simply to save our capability we can do compound dots put oh it’s tag okay i always name it different things i don’t know why so let’s put tag.puts and then let’s go inventory and For the actual inventory we’re going to want this dot inventory dot serialize nvt fantastic so that’s our save method and then we’re going to want load as well so we’ll call the super.load once again and this time we’ll just use this.inventory dot d serialize mbt tag dot get compound inventory This way is basically all being done for us now we need to go back to our capability stuff and we need to make sure our capabilities are invalidated so you can override the invalidate caps method now essentially what this what’s it got what this method does Is it is just called when the block entity is removed it makes sure the cats are invalidated so they don’t sort of um persist when they shouldn’t be so we just need to make sure every capability we have gets invalidated so our only capability is this.inventory So you may think we would just do invalidate but that’s not correct because we actually need to invalidate the lazy optional so it’s this.handler.invalidate there we go make sure you keep the super here as well in fact uh some of this might be done in the super anyways just in case it’s not And is there anything else yes there is there’s a few things else that we’re going to need so the first thing that we’re probably going to want is hm okay let’s create our update method first so that we can go through this right here so let’s create a public void And we’ll call this update now this is the method you’re going to want to call anytime that you need to update your block end state in here there’s a few things you need to do so first we’re going to request model data update let’s just make sure Make sure our model is correctly updated then we want to set changed that will make sure it’s marked as dirty and so it can be saved and load and then we can just do if this level is not equal to null which should always be true but just in case We want to do this.level set block updated and we’ll say world position get block state now i should mention just before people go ham using this method you need to be careful when you use it don’t use it too often because a lot of stuff is happening here request model update for example It does quite a lot of sort of caching and um it’s quite expensive and like this for example it sets changed and then it updates all the neighbors and all that different stuff and this this sets the block with the specific flag and etc etc you just need to make sure You don’t do this any more often than you need to use it i will show you an example of where we do need to use it since we do need to use it let’s go into our little inner class here our item stack handler and let’s call um inventory block entertain dot this Dot update so any time that we extract an item or insert an item from our inventory we’re going to want to update our block entity that just makes sure everything happens correctly and everything saves now additionally we’re going to need another method so we’re going to want a public void tick And in here we can use disk.timer plus so that’ll just increment our timer then we can say if this dot level is not equal to null which as i said earlier it shouldn’t be but just in case and this still requires update in fact probably better if we use this dot Requires update first there we go then we can just say update and this dot requires update is equal false otherwise it would be an endless loop if we didn’t do that other than that there are two more methods that we are actually okay three more methods that we’re gonna Want so we’re gonna want a method to easily extract an item from our item stack handler so to do this we’re going to want a public item stack extract item and we’re going to want to use the slot as the integer in here and for this we can just go uh Final int count is equal get item in slot we haven’t created that yet we can do that in a second get item in slot don’t get count that way we can get the current count of what is in the slot then we can just say this dot requires update Is equal to because it does indeed now require an update or at least it’s about to require an update then we can do return this.handler dot map inventory so we’re going to map the inventory to extract an item at the slot of the count and this is a boolean for whether this Is a simulation or whether it’s real now since we actually want to extract it we want to just put false in here if we are going to fake that it’s been extracted we can put true and then we can say or else item stack dot empty so basically if this part fails right Here we’re just going to give it item stack dot empty uh let’s create this get item in slot method so public item stack get item in slot once again this is going to take an int slot now this one is extremely simple too we can use disk.handler dot map this is the inventory Inventory don’t get stacking slot and slot once again we just want to put all else and item stack dot empty and we need to return that of course fantastic now we’re going to want the opposite of extract item and that is obviously in the cert item so public And i guess this would be well yeah it needs to return an item stack just in case the whole thing doesn’t manage to insert so we might be left over with some because the slot gets full for example so that’ll be insert item now this will once again need the slot And then it will need an item stack stack so that’s the stack that we want to insert from there we’re going to want to make a copy of the stack so let’s go item item stack copy is equal stack dot copy thankfully that is already a method Then we can go stack dot shrink and we’re going to go copy it’s count then we’re going to save this dot requires update since it obviously requires an update and then finally we can just return this.handler dot map inventory inventory dot insert item at the slot the copy false because we want to We don’t want to simulate it or else once again item stack dot empty fantastic so that should be everything unless i’m forgetting something of course so now we need to come and actually create our block entity so all you need to do is just create a normal block Entity i’ve already created the block as you can see here and i’ve created the block entity i have initialized them both in blocking it and inside of block entity in it so as you can see there and there and obviously i’ve created the block item as we do Now from there you can see i’ve already got some stuff in here since there’s no point me doing this logic specifically in this video that doesn’t make any sense because this is not really related logic but i will quickly just run through everything that’s happening here please Do note this code is not great um i have sort of been rushing this code through just trying to get it to work it has caused me a lot of issues already so i’ll quickly run through we’re first specifying a limit right here so this is Just the max amount of items we want to hold in our drawer you might not want this to be hard coded if you were to actually create a door drawer because you might want like limit upgrades and whatever and then we just have the normal constructor and as you can see we’re Passing in one since that is the amount of slots i want to have say you wanted the chest obviously you would put 27 in here or if you wanted a hopper you would put five hops have five slots don’t they yeah i think so uh if you had a furnace You would put three etcetera etcetera then i have uh two methods now i have three methods so i have append item as you can see here i have prepend item and prepend stack now what i’m doing in here is i’m simply just appending whatever item there is there’s some honestly Quite janky logic in here i’m sure it’s not great so there’s that and then we have a load method now this might be a little bit confusing so we have our original load method that we just created in here right so where’s that it is here and this usually serializes the Inventory now that’s fine for most cases however it will not work for this case because the thing is minecraft saves an item sax count as a byte so that obviously means the count cannot go beyond 127 otherwise it just overflows and goes back to negative 127. so that was causing the issues because Obviously our limit here is 2 to the power of 15 which is 32 700 something i don’t remember specifically so i had to sort of write my own load method where it would save a real count as you can see here and i have also done the same thing with the save method Um it’s basically the exact same as this method right here this d serialize and serialize methods except i’m adding um an extra integer in here that’s basically all it is it’s nothing too complicated and but it did cause me a little bit of grief Um and yeah as i was saying then i just have the prepend and pre-pen stack in fact i don’t think these work because i think i broke them and yeah i’m pretty sure i broke them if we just come into the block our block class you can see that if i’m not crouching And i right click it then i just call the append and if i’m crouching and i right click it then we just print how much is in there and for the pre-fending i just do that inside the attack method and i do the same thing but i don’t Think this one will work because i think i need to rewrite this logic in order for that to work i haven’t adjusted this one so yeah but let’s let’s give this a go yeah okay here we are we’re back or we are now in the game So i placed down our block here i haven’t made a texture for it or anything that’s way too much effort um and if i shift right click it so let’s do that we can see the current count is zero now if we put some leaves in We can see it’s now 64. put some more in 128 etc etc just go all the way to 512. there we go now if we leave the game and Come on if we load back in we should be able to see that it is still 512. yep it is still 512 and obviously if i go into game mode survival the theory would be that when i attack it it’s going to give me one probably won’t oh it did I’m actually quite impressed that works because i didn’t think it would work is that actually yeah that is working wow um i don’t suppose that works does it oh it does not quite but um unless i put in a really weird number but yeah that is that is it basically obviously You would fix that jankiness if you do this for real but uh yeah um that is it so i hope you guys did enjoy this tutorial and i hope you found it useful if you did please do be sure to let your parrot scream at that like button and subscribe If you really enjoyed or found it useful please share it around and uh yeah i’ll see you guys in the next tutorial good bye now this might be look just like rubber glove on a plastic bottle but i show you is much more because when you give squeeze you get middle Finger that say you Video Information
This video, titled ‘1.18 Minecraft Forge Modding Tutorial – Block Entity Inventories’, was uploaded by TurtyWurty on 2022-01-20 19:30:10. It has garnered 3399 views and 72 likes. The duration of the video is 00:28:46 or 1726 seconds.
In this video, I cover how to make a block entity that holds an inventory.
In the next video, I will be covering containers and screens, in order to get a visible GUI which can display our inventory slots.
Join my Discord Server, to receive support with your modding related questions: https://discord.gg/jCTnnhxc7J My CurseForge where you can find my released mods: https://www.curseforge.com/members/realturtywurty Github Repository: https://github.com/DaRealTurtyWurty/1.18-Tutorial-Mod Check out the trello: https://trello.com/b/6lLTY9js/118-modding-tutorials