Hey what’s going on guys titus here and welcome back to another minecraft morning show for version 1.15. in this tutorial i’m going to be covering how we can go ahead and create our custom furnace now this has been uh might i say a long awaited tutorial And i do apologize for the delay i’ve just been trying to make it as efficient and best code as i can it’s probably still going to be perfect of course um but yeah so obviously for the first thing you need to go ahead and do is create our block Class now obviously this needs to extend block and just have the default constructor and then we need to go ahead and create two properties for this this will be the facing property and the lit property so for the facing property that will be a public static final direction Property i’m just going to call that facing and that can just be equal to block state properties dot horizontal facing and then we can create a public static final boolean property and we’ll call that lit and that’ll be equal to boolean property dot create just taking the name which i’m just Going to put lit then we actually need to set the default state in the constructor and we can just do that by calling this dot set default state that takes in this dot state container dot get base state and then after that we can do dot with It first takes in the property so the first one will be facing and then the value we want the default to be direction.north sure you import the direction from net.minecraft.util.direction not from the chunk palette thing and then we need another dot with this takes in lit and for the value it Will just be false then we obviously need to override the has tile entity method make sure it is the one with the block state and in here we can just return true we obviously need the create tylency method in which we will return mod tile entity types Dot example furnace dot get dot create then we need to make sure we override the method field state container so that we can actually add these properties to the block and in here we first need to call the super and then we need to add the other ones to the builder then We just need to override the mirror method in which we will call state dot rotate and that’ll take in mirror.2 rotation and that takes in the facing then we need the rotate method for that we can just go ahead and copy this mirror method rename it to rotate and change Mirror out to rotation and we can change state dot rotate to state dot with and then put in the facing and then instead of mirror index to rotate we just want to put rot dot rotate then since it is a furnace and the lit state we obviously want to emit a light We can override the get light value method in here we want to return uh whether the state is lit and if it is we just want to call the super and else we just want to put zero and if you want you can just suppress this for deprecation Then we obviously need to override the get state for placement method in here we can just return this dot get default state dot with now taken facing and context dot get placement horizontal facing dot get opposite and this just make sure it places it in the opposite direction to the way you Are facing next we want to override the method on block placed by in which we will first call the super then we will check if the stack has a display name if it does have a display name we want to get the thailand’s t from the pos and then we need to check If this tile is instance of our tile entity class which i’m going to call example furnace tile entity now if it is then we want to call tile dot set custom name and that will take in stack dot get display name and obviously we need to go ahead and cast tile To our tile entity class now obviously we are doing this because we want it so if they rename the item in an anvil it will change the name in the inventory since that is what vanilla does if you don’t want to do that you can just completely remove this method And ignore its existence next we want to override the method has comparator input override in which we will just return true because we want to be able to handle the comparator input ourselves and then we obviously want to override a git comparator input override and here we will return container.calc Redstone and that will take in the tire lens t from the pos finally we need the animate tick method which will do all of the particles and stuff um i’m not going to go ahead and code that all out because that will take a while um the link for this little block of Code will be in the description and it’s just for playing the sounds and spawning the particles uh obviously if you don’t want that or you want different sounds or something you can go ahead and change this how you want this just the vanilla furnace stuff next we need the on block activated method First we will check if the world is not null and the the world is not remote the reason we are doing this is because of course we don’t want the world to be null and we don’t want it to be client-side so obviously checking that it’s not remote will mean that it is Server-side if that is true uh we can get the tile entity from the pos and then we can check if that is an instance of our tile entity class if it is an instance we want to call networkhooks.opengui this will take in the player and then our tile and you need to Make sure you put the pause at the end of ours you’ll get some strange errors later on now obviously this gives us an error because we need to cast the player to serve a player entity and we need to cast the tile to i named container provider Now that we have done that we can just return actionresulttype.success and we also want to return actionresult type.success at the end now one last method we need is the unreplaced method here we first need to check if the state has a tile entity we also need to check if the state dot Get block is not equal to the new state dot get block if both of those are true we want to call world in dot remove tire lens t then we want to get the thailand seat at the pause then we actually need to check if that is an instance of Our tile entity if it is we can just create a field for that tile and then we can create a field for an item entity and then after that we can call furnace dot get inventory got two non-null list dot four each and here we can just do uh item And let’s just rename this up here to item entity and then we can set item entity to a new item entity and then we can add that item entity to the world now we actually do need to go ahead and move this if statement below this code right here otherwise detail Entity won’t actually be there when we attempt to do that now we can go ahead and close this class and we need to go ahead and initialize the block and the tile length t and obviously we can just do the normal stuff for that i’m not going to go over that too much And then we can just do the tile entity which will be the same as all our other tile entities now obviously we’re going to have some errors here because we haven’t created our tile entity class so let’s go ahead and do that now obviously this class will just Extend thailand’s t but it needs to go ahead and implement two things it needs to implement i typical tile entity and also i named container provider okay now the first thing we want in here is obviously the constructor and then we want the second constructor this one will just be a blank Constructor where we call this and that takes in our module entity types to example furnace then we need to go ahead and add the unimplemented methods now for the create menu let’s just go ahead and rename some of these so let’s make these all final and then Let’s rename them so this one is the window id this one can just be the player in and the last one can just be the player in in here we obviously need to return our container class and that takes in the window id the player inventory And this now we need to create a bunch of name methods to handle the name handling now if obviously if you don’t want it to change the name of the inventory based on the name of the item stack you can leave all the methods i am about to create And just use this get display name method as the name first method we need to create is a setter for the custom name so that’ll be a public void set custom name now we’re taking an itext component which will be the name and in here we can just do this.custom name is Equal name now obviously we need to go ahead and create a field for this custom name so that will just be a private i text components then we can create a method to get the name so that would just be a public i text component get name in here we will return This.custom name is not equal to null now if it’s not we can return this.custom name else we can return this.getdefaultname then we need to create this getdefaultname method and that will just be a private itexcomponent name and in here we can just return a normal text component so that can be a string Or a translation or any of the other millions that there are now in the get display name method we can just return this dot get name finally we can create a getter for the custom name and we can annotate this with nullable now let’s just go ahead and override the Read and write methods in the right method we just want to return compound but before that we need to call super.right now let’s first deal with the custom name so we can check if the compound contains so if compound dot contains in here we’ll take Custom name and this will just take in a value of constant dot mbt dot tag string then if it is we will set this dot custom name to itexcomponent.serializer dot from json and that will take in compound.getstring and that will take in custom name in the right method we first want to Check if this dot custom name is not equal to null if it’s not we can do compound.put string and in custom name we will put itex component.serializer.2.json now let’s go into the tick method and handle what we want to do every tick so the first thing we’re going to do Every tick is create a boolean called dirty now the reason we are creating this boolean is because we don’t want it to mark dirty every tick we only want it to mark dirty when it needs to mark dirty and what do i mean by mark dirty i i’m Always some of you may not know so mark dirty basically tells it to write and read from disk so it doesn’t actually do it it just tells the game to do it however it is quite an expensive uh operation in actually calling it so cooling does some expensive stuff afterwards Obviously reading and writing is quite expensive and you only want to do that when you need to so after that we need to go ahead and check that the world is not null and that it is not remote and the reason we need to go ahead and do that Is because obviously we want it to only happen on the server side we only want server side logic and then obviously since we are marking dirty that will go ahead rewrite it to disk and then it will read it and then the client will also get the info In here we first are going to check if the block is powered now the reason i’m doing this is because eventually i’m going to be changing this furnace so it uses energy but currently i just want to check if it is powered by redstone so this furnace is not going to have Fuel obviously if you want it to have fuel instead of checking it’s powered you check if it is a fuel item uh in that slot and you can just look at the normal furnace code for that if you wish so to check if it’s powered i’m just going to check if This dot world dot is block powered and that takes in this dot pause if that’s true then we will do all the logic here so we’ll first check if the recipe is not null and we’re going to do that by creating a method called get recipe so this will be a Private method and it will return our recipe class which we created in the previous video on recipes so it’ll be a private example recipe and we’ll call that method get recipe and that takes in an item stack stack so this will just be the input that we are checking if it is A valid input so we first obviously need to check if it’s null if it is now we just want to return no in which case we just want to go ahead and annotate this with at nullible if it’s not null we want to create a set of eye recipe and i’m Just going to call this recipes and that is going to be equal to a method called find recipes by type now this will take in our recipe serializer init dot example type and then it will take in this dot world now if we needed this recipe On the client side we would just get rid of this.world but since we are doing all the logic on the server side we just need to put in the world so that it has the world and then we’re going to loop through all the eye recipes In the recipes and then we are going to cast that to our recipe and then we are going to check if recipe dot matches and we are going to check if that matches a new recipe wrapper that takes in this top inventory which we obviously haven’t created yet And it will take in this stock world if it does match we just want to return the recipe and if it doesn’t match so if it comes out of this for loop and it hasn’t returned the recipe we just want to return no now obviously we need to create this Find recipes by type method now we just need to make sure this is static and that it is public in here we want to check that the world is not equal to null now if it’s not we want to do world.getrecipemanager.getrecipes.stream.filter dot and in the predicate we want to check if The recipe type is equal to the inputted recipe type and then dot collect and that will take in the collectors dot to set now if that world does happen to be null we just want to return collections dot empty set now we just want to duplicate this method This will be the client one so we can just add the at only in desktop client annotation and we can get rid of the world here and we can create a client’s world using minecraft.getinstance.world now obviously if you wish you can just go ahead and suppress that Which i am going to do now we are going to create a public static set of item stack and this is going to be called get all recipe inputs and this will take in an eye recipe type and the world and here we will first create a set of Items stacked and we’ll call that the inputs and that’s going to be equal to a new hash set then we’ll create a set of eye recipe and we’ll call that the recipes and that will be equal to find recipes by type that takes in the type and the world Then we’re going to loop through all the recipes in the recipes and in here we’re going to create a non-null list of ingredient and we’ll just call that ingredients and that is going to be equal to recipe dot get ingredients and then we’ll loop through all the ingredients And in here we’ll loop through all the stacks in ingredient dot get matching stacks and then we can call inputs.add stack finally we can just return inputs now let’s go back to our tick method and in here we can do if this dot get recipe and that’ll Take in this dots inventory dot get stacking slot zero the reason we are checking the zero slot is because that is the input slot and we just need to check if that’s not equal to null if it’s not we want to check that the current smell time is not Equal to the max smelt time if it’s not e if it’s not equal we want to increment this current smelt time and then we can set dirty to true because we have changed a value now let’s just go ahead and create this current smelt time and this max Smelt time and i’m just going to set that to 100 ticks but you can set that to however long you want the smelting to take obviously you don’t have to set it to a constant you can make it based on your different items uh however you want to do that but uh I’m just going to do it like that now if it is not equal to the max smelt time then that means it has finished and then we can set the current amount time to zero we can get the output from this dot get recipe and that will take in this Dot get stacking slot obviously that will take in zero because we want to get it from the input slot and then we will call dot get recipe output then we can call this.inventory.insert item this will take in the count which is just one then it will take in the output so we Can call output.copy and then whether we want to actually simulate it which we don’t want to simulate it we want it to actually happen then we can decrease the stack size in the input slot and then we can set dirty to true at the end of the tick method we Can check if dirty if it is we can just call this stock mark dirty now i would guess that you have all noticed by now this inventory variable does not exist um and i’m not crazy we are going to create it now now we are going to be using item Handlers for this inventory since that is the way you are meant to do inventories but in the past i’ve been using i inventory which let’s just say is not the best uh choice of things to do so i’m going to create a private example item handler now in the constructor we want to Set that and we’re going to set that to a new example item handler and that’ll take in the size of the handler which will be two now let’s just go into the read and write methods and let’s go and read and write some stuff so first we need to read my inventory And we can do that by creating a non-null list of item stack and that will be the inventory and that will be equal to non-list dot with size that takes in this dot inventory dot get slots and then item stack dot empty then we want to call item stack helper dot load all Items that takes in compound and inventory then we want to do this.inventory.set non-null list and that takes in the inventory finally we can set the smelt time to compound.getint and that takes in the name of the compound which will just be current smelt time now in the right method we can just call Item stack helper dot save all items this takes in the compound and this.inventory.2 non-null list and then we can do compound.putin this takes in the name which is just the current smell time and the value will be this.currentsmailtime next we can create a method to get the inventory And that will return an i item handler modifiable then we need the synchronization methods which i’m just going to copy in um you can find these in the description or from my github whichever one you find easiest and then we need to override the get capability method In here we can just return capability item handler dot item handler capability dot or empty now take in cap and lazy optional dot off and that takes in a supplier of this.inventory now obviously we have a load of errors because it doesn’t know what the example item handler is so let’s go into Our util package and let’s go ahead and create this class this is going to extend item stack handler in here we first want the constructor and this takes in an int size and an itemstack.stacks and then we can just call super of size and then we want to loop through the Stacks dot length and we want to do this dot stacks dot set now taking the index and then stacks of index this way we are setting the stacks to an actual uh stacks that we put in then we want a clear method so that would be a public Void clear in here we once again want the same for loop however instead of it being stacks dot length it will be desktop get slots and instead of stacks of index it will be item stack dot empty and then we want to call this dot on contents changed Now for time’s sake i am once again going to ask you to copy these in from the description obviously you can type them out as you want but i’m going to copy in the rest of the methods as that will save us a lot of time they’re pretty self-explanatory what they do So i’ll just quickly go through them this one checks if the handler is empty this one just decreases the stack slice stack size in the given slot by the given count this one removes a stack from the given slot this one converts all these slots to a non-null list And this one sets it to a non-null list and this one converts it to a string so now if we go ahead and import that in here we should see all those errors should clear up and we should be left with the container error now in the block class uh you do Actually need to go ahead and cast furnace dot get inventory to the item stack handler and i also realized i made a stupid mistake of creating the item entity field before and which obviously you can’t lose it’s the wrong scope so you just need to go ahead and Actually create that field in here which isn’t too much of an issue i’ve just gone and imported it and fixed all the errors here i forgot to put a dot build taken in null which gave me a stupid little error and all those little things so this is actually going to be the End of episode one of the furnace tutorial and in the next one i’ll do both the container and the guide class hopefully in the same tutorial so yeah if you guys did enjoy this tutorial please do smash your face into that like button and subscribe if you really enjoyed please do be sure To share it and uh yeah i will see you guys in the next video good bye well they said everybody not to panic remain calm well i don’t know there’s two rats fighting over food you tell me how the world’s looking right now they were told to wait in line At the grocery store and go two at a time and they said it let’s throw down right here right now big right jab there from the little rat on the left the big round on the right has the advantage right now you can see him using his hands he’s Trying to grapple him as he hops on top of the counter he’s got an angle now children watching at home turn your heads this is not ratatouille this is ratatouille on crack the x-rated version both trying to just get a piece of cheese at the market and now it’s turned into An all-out warfare the little rat is on top and it looks like he slams him down on the ground and he repeatedly slams him down Video Information
This video, titled ‘Minecraft Modding Tutorial 1.15 | Custom Furnace(Part 1/2) – Episode 46’, was uploaded by TurtyWurty on 2020-08-22 15:30:23. It has garnered 4549 views and 91 likes. The duration of the video is 00:26:41 or 1601 seconds.
Hey guys, I’m back with another video. In this video, I am going to be covering how we can add a custom furnace.
My Discord Server: https://discord.gg/d5cGhKQ Episode 45: https://youtu.be/Ri0Mqv_FXA4 My GitHub: https://github.com/DaRealTurtyWurty/1.15-Tut-Mod Tutorials I will be doing: https://trello.com/b/LNQlC0l1 A Free Java Course that I would really recommend: https://www.udemy.com/course/java-tutorial/
animateTick method: https://pastebin.com/AZcNcib7 TileEntity Synchronization methods: https://pastebin.com/hamu66ja ExampleItemHandler class: https://pastebin.com/egYyc6tQ
Minecraft Forge 1.15.2: https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_1.15.2.html