Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

shapeless recipe with leaves block as ingredient: only works if it's oak leaves.


kauan99
 Share

Recommended Posts

Hello, I'm new to mod coding and Java programing (have only a little bit of experience in C#), so I'm sorry if this is a dumb question. Also, my English is far from perfect, so pardon me for that too.

 

I searched the forums for some thread about this matter but I couldn't find one (I forgot to mention that I suck at searching forums too).

 

My problem is: I want to add a shapeless recipe which outputs a mossy cobblestone block and uses one leaves block and one cobblestone block as ingredients. My code is:

 

ItemStack leavesBlock = new ItemStack(Block.leaves);
ItemStack cobbleStoneBlock = new ItemStack(Block.cobblestone);

GameRegistry.addShapelessRecipe(new ItemStack(Block.cobblestoneMossy), //output
			leavesBlock, cobbleStoneBlock); //ingredients

 

I get no errors when recompiling, reobfuscating and running. But the recipe only works with oak leaves. If I use spruce leaves, birch leaves or jungle leaves nothing gets formed in the output box of the crafting table.

 

I think that's very strange and I imagined a solution: to instantiate one ItemStack for each type of leaf and to add 4 recipes. I don't think this is how I should solve this, and also, I don't even know how to instantiate a block of a certain type of leaf (so if anyone know how to instantiate an ItemStack of a certain type of leaf that info would be much welcome and apretiated too).

 

What am I doing wrong?

 

Thanks in advance.

WIP mods: easyautomation, easyenergy, easyelectronics, easymoney, easytrasportation, easysecurity, easymultiverse, easyfactions, easymagick, easyalchemy, easyseasons

Link to comment
Share on other sites

I cannot assist too much but had found this code on Tutorials/Metadata Based Subblocks where it dealt with metadata shapeless recipes. It appears you will need to do it for each sub-type according to that page and the example presented.

 

Here's what the page showed for a multi-block (block with metadata)

 

GameRegistry.registerBlock(multiBlock, MultiItemBlock.class);

for (int ix = 0; ix < 16; ix++) {
ItemStack cloth = new ItemStack(Block.cloth, 1, ix);
ItemStack multiBlockStack = new ItemStack(multiBlock, 1, ix);

GameRegistry.addShapelessRecipe(multiBlockStack, cloth, cloth);
LanguageRegistry.addName(multiBlockStack, multiBlockNames[multiBlockStack.getItemDamage()]);
}

Link to comment
Share on other sites

Thanks a lot! I didn't quite understand the tutorial, that's really complicated stuff! But it put me in the right way to find the solution (I think there should be an easier way to do this. This for statement adding the exact same recipe for every subblock is just dreadful. Either minecraft or forge should implement this thing better).

 

Anyway, through this tutorial I found out about the constructor I needed: ItemStack(int blockID, int stackSize, int metadata). So my final code is:

 

ItemStack cobbleStoneBlock = new ItemStack(Block.cobblestone);
ItemStack mossyCobblestoneOutput = new ItemStack(Block.cobblestoneMossy);
for(int i = 0; i <= 3; ++i)
{
     ItemStack leaves = new ItemStack(Block.leaves.blockID, 1, i);
     GameRegistry.addShapelessRecipe(mossyCobblestoneOutput,
          leaves, cobbleStoneBlock);
}

 

Thank you!!

WIP mods: easyautomation, easyenergy, easyelectronics, easymoney, easytrasportation, easysecurity, easymultiverse, easyfactions, easymagick, easyalchemy, easyseasons

Link to comment
Share on other sites

Thanks! According to the tutorial I was following, the Object parameters should be of type ItemStack, but as you showed me, they can be of type Block too (or mixing ItemStack and Block). I don't know why the tutorial does that. It's a lot of wasted code.

 

Well, when the last argument of a Java method is of type Object[], you can either call it by explicitly passing an Object[] like you did (array of elements of type Object, that is) or do it implicitly, by passing any number of arguments each of them of any type, in a comma separated list, just like a regular method call. Object[] is a way for the method to say "I accept a varying number of arguments of any type".

 

The arguments can be of any type, because the type Object (more specifically java.lang.Object) is like "the mother of all classes", the topmost class of the inheritance hierarchy. If a class doesn't extend any other class, then by default it extends Object. And if it happens to extend some other class, that other class it extends also can extend another class or not. You can keep going up that tree hierarchy until a point where you will find a class that won't extend any other class explicity. It still implicitly extends java.lang.Object. In short, everything is an Object.

 

Of course, inside the method implementation, some types will make sense while others will not. You won't know it until the method gets called and causes an error and probably a crash (For example, even though a cow is an Object, remember everything is an object, the method GameRegistry.addShapelessRecipe(ItemStack output, Object[] ingredients) will probably cause a crash if one of your ingredients is a cow).

 

Anyway, you helped me save a lot of useless ItemStack instantiations (damn you tutorial! Kidding, I love you, tutorial. Now kiss). But the code you suggested doesn't take into account the very problem my post was about, that is, I need one recipe for every type of leaf, or it will only work on the type of leaves that has 0 as metadata (oak leaves, that is).

 

So thanks to you my code is now as follows:

 

ItemStack mossyCobblestoneOutput = new ItemStack(Block.cobblestoneMossy);
for(int i = 0; i <= 3; ++i)
{
ItemStack leaves = new ItemStack(Block.leaves.blockID, 1, i);
GameRegistry.addShapelessRecipe(mossyCobblestoneOutput,
	leaves, Block.cobblestone);
}

 

I still need the mossyCobblestoneOutput to be an ItemStack, because the signature of GameRegistry.addShapelessRecipe requires the first argument to be of type ItemStack, but I no longer need all my ingredients arguments to be of type ItemStack! (Although in the case of leaves I still have that extra step, because I need the metadata, which tells what kind of leaf I'm talking about, and I don't think theres a constructor of the type Block that accepts metadata, which is pretty strange...)

 

That will save me A LOT of coding throughout my project, thanks again!

WIP mods: easyautomation, easyenergy, easyelectronics, easymoney, easytrasportation, easysecurity, easymultiverse, easyfactions, easymagick, easyalchemy, easyseasons

Link to comment
Share on other sites

It doesn't work for me. That's pretty much my original problem. When I register a recipe for Block.leaves (the argument being either new ItemStack(Block.leaves) or just Block.leaves, as you just taught me) I only get the recipe registered for the oak leaf (which has the metadata of 0). I just tested it just now. Unless there's something wrong with my forge release or theres a neater way of doing this, I'm stuck with that awful for loop.

 

Back to the subject of not needing to create instances of ItemStack to use them as the ingredients part of a call to GameRegistry.addShapelessRecipe(ItemStack output, Object[] ingredients). Just now reading some stuff on Java performance, I learned the Java JIT compiler is not as smart as I expected and every single time you reference a class field (be it static or not) a thing called "field lookup" occurs, which is similar to a method call, and that gets the field value for you (unless it's a value field, like int, float, etc, and it's marked as final).

 

So, my guess is that the final version of the code should be:

 

temStack mossyCobblestoneOutput = new ItemStack(Block.cobblestoneMossy);
Block cobblestoneBlock = Block.cobblestone; //this line is new
for(int i = 0; i <= 3; ++i)
{
ItemStack leaves = new ItemStack(Block.leaves.blockID, 1, i);
GameRegistry.addShapelessRecipe(mossyCobblestoneOutput,
	leaves, cobblestoneBlock); //this line changed
}

 

That will avoid 4 field lookups and perform just 1 instead. Even better if you use cobblestoneBlock other times throughout your code, avoiding more field lookups and improving performance.

WIP mods: easyautomation, easyenergy, easyelectronics, easymoney, easytrasportation, easysecurity, easymultiverse, easyfactions, easymagick, easyalchemy, easyseasons

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.