Vswe's Summer Courses | You're not logged in. Sign up or log in | Server time: | Donate
One can now see other persons' badge hunts. Simply head over to their profiles to access them.

Go back to course page

Forging a Minecraft mod

Basic Minecraft modding with Minecraft Forge

where should i check for recipes for my block?

  • 2013-08-14 13:27:41
    My block has his own inventory and i wanna make him able to check if the items it have match with certain recipes...the question is....Where should i check if it have a matching recipe? my first guess is on the tile entity... but...there is a method that is called every time the inventory is updated? because i could override it so every time the inventory is updated it will search for recipes....

  • 2013-08-14 22:23:30
    This depends a bit on what you want to achieve. If you want a block that works like a crafting table(the items are not visible to others and are dropped on the ground when you close the interface) or if you want them to stay, more like the vanilla furnace or many mod crafting tables.

    Take a look on the crafting table code or the furnace code depending on which approach you want to take.
  • 2013-08-14 23:44:21
    well im trying to get something like a furnace....

    i checked the BlockFurnace code and the TileEntityFurnace

    I couldn't find a method that is called when the inventory is updated... in BlockFurnace and TileEntityFurnace is just a bunch of methods that i can use but they are no called when the Inventory updates...
  • 2013-08-15 09:16:50
    you could use onInventoryChanged(in your tileentity class) and check all the slots in your inventory and see if that pattern matches any of your recipe.

    when that happens,you then give the output in the output slot.
  • 2013-08-16 15:10:53
    yeah..that kinda works thanks a lot for your help... =) I have another problem...

    the GUI of my block is simple....in the Block's Container i have one array of slots for the input and one slot for the output

    something like this

    for(int x =0;x < 5; x++){
        addSlotToContainer(new Slot(table, x, 8 + 18 * x, 26)); //input
    }
    addSlotToContainer(new Slot(table, 5, 8 + 134 * 1 , 25)); //output


    so i have 6 slots that's why in my tile etitty i have this

    items = new ItemStack[6];

    so 0-4 are the input slots and the 5º is the output....

    i can check and do whatever i want with all the slots but the last one (the output) when i try to set any item in that slot with     

    setInventorySlotContents(5,randomItemStack); the game crash...but when i do this

    setInventorySlotContents(4,randomItemStack);    it works fine....(but not in the slot i want)

    i made the first array (the input) following the tutorial, for the silly machine the aditional slot i made it myself....but i dont know what could i done wrong......
  • 2013-08-16 15:47:54
    Without the error or the code no body will know what you could've done wrong either.
  • 2013-08-16 17:19:46
    oh my bad.... here it is...

    http://pastebin.com/UMSkNxzZ
  • 2013-08-17 01:30:27
    error code didnt really help. you might want to give us the tile entity code too.
  • 2013-08-17 10:28:07
    no problemo

    i tried to comment as much as possible to help you guys to understand my code (because im doing some weird stuff XD)

    http://pastebin.com/6a23fkAf
  • 2013-08-17 11:28:16
    The error code means you have an infinite loop, the reason why is because setInventorySlotContents is called by onInventoryChanged and onInventoryChanged is called by setInventorySlotContents.

    You have two solutions.

    1. Make sure that the onInventoryChanged doesn't do anything if the slot is already occupied. That makes sure that when you set the flour it won't try to do it again.

    2. Use inventory[5] = CheckRecipesMortar(items2); to bypass the infinite loop. This is a approach which is totally fine to use.
  • 2013-08-17 12:09:44
    Master Vswe doesnt need source XD
  • 2013-08-17 12:50:07
    thanx again for your help... i will get better on seeing this kind of errors in the future i promise!

  • 2013-08-17 13:00:45
    mielleman: after a while you know what most errors are caused by. It also says that every second method call is the onInventoryChanged and every second is setInventorySlotContents, which means they are calling each other all the time. However, I did check the code as well, otherwise I wouldn't be able to write the code for solution 2 (I wouldn't know all the names).


    Kionashi: Finding errors is all about practice, it's tricky in the beginning but after a bunch of errors it becomes easier. Then you can use your experience from previous solutions for the new errors since there are plenty of times where errors are caused by similar things. Like I said, it's all about practicing.
  • 2013-08-18 09:37:14
    Well i got another crash...this time seems like a null pointer exception...

    here is the crash code
    http://pastebin.com/v8zAyX8d

    and here is the updated tile entity
    http://pastebin.com/L2RtRF0v

    now my block can check recipes with no problems... so my next step was decreasing the items in the input slots and increasing the items in the output slots

    by example... if i place a stack of 64 wheats in any input slot it should consume the whole stack and place 64 flour in the output slot.

    so i created a new method called clearItems() that decrease the stacksize of every itemstack in the input slots

    i checked the clearItems() and seems to work just fine...the problems seems to be when i try to increase the stacksize of the output slot...

    as far a i can tell the problem should be in onInventoryChanged() because is there where i try to increase the stacksize of the output slot
  • 2013-08-18 10:12:10
    Line 220:if(items[5] == CheckRecipesMortar(items2))
    Shouldnt it be items[2]?
  • 2013-08-18 10:13:19
    No my bad
  • 2013-08-18 10:19:59
    This error occures when youve the rightitem in the input slot or the wrong item (or any)?
  • 2013-08-18 10:23:11
    You are making it yourself a little harder then it is i think...i made a craftingtable myself, i just made a recipes class and a check method, you give it a input itemstack array and a blueprint intem array and it just loops trought them and stops if 1 is not the same
  • 2013-08-18 11:10:26
    You should make sure that the output slot is not null, also if you want to check if to ItemStacks have the same item you should use itemstack1.isItemEqual(itemstack2).

    But as mielleman says, you're making it hard for yourself. It will be lots of work to keep adding more recipes. Set up a class to help you with the recipes.
  • 2013-08-18 20:49:53
    i tried to make

    but there are all shapeless recipes with 5 slots... i cant make a blueprint for it because i would need to implement too many times the same recipe.... by example...if the recipe is coal + water i would have to make...

    coal,water,0,0,0
    water,coal,0,0,0
    0,coal,water,0,0
    0,water,coal,0,0
    0,coal,0,0,water

    etc.....but im pretty sure there is a way to make it easier, i was planning to try making a "recipe" class when i manage to make the system works with one or two recipes...

    my tile entity should extend the recipe class right?

    the error happen when i place any matching recipe....

    i already change it to itemstack1.isItemEqual(itemstack2) but the error is the same... and with the "if(items[5].isItemEqual(CheckRecipesMortar(items2)) )" im already checking if is not null

    TileEntity
    http://pastebin.com/2L7NsyRj

    Crash log
    http://pastebin.com/NHKBRa8J
  • 2013-08-18 21:18:10
    Your tileentity should not extendthe recipe class at all
  • 2013-08-18 21:26:47
    You're not checking if the ItemStack is not null.

    If you make a recipe class that would have nothing to do with the vanilla recipe. It would simply be your own code. If you don't want it to bother about its position in the slots then simply don't do so in the code. Just give each recipe up to 5 items as input and 1 as the output.
  • 2013-08-18 21:28:48
    First, you are using 1 itemstack for 5 slots, isnt that a problem?
    And you are never check if items[5] == null, because its probably null because i cant see where you set it? Am i right?
  • 2013-08-18 21:29:56
    Oh i didnt see your reply vswe, didnt reload while reading his code xD
  • 2013-08-18 21:42:29
    mielleman: he isn't using 1 ItemStack for 5 slots he is using an array and items[5] is set if items[5] isn't the result so it can be an old result or null.

    And I have noticed something with the setting of the output, if something is crafted and the user is crafting something else before emptying the output the output will be removed. There should be a check that the output is empty before setting the new item to not remove it.
  • 2013-08-18 21:49:57
    I ment array not itemstack xD
  • 2013-08-18 21:50:49
    Wait what, he is using 1 itemstack 5 times, for bed
  • 2013-08-18 21:54:01
    lol :P

    And no it's not a problem to use 1 array for 5 slots, a Chest for example have 1 array for all slots, and Vswe example in Climbing the Interface ladder he is using 1 array for the slots in the block.
  • 2013-08-18 22:03:43
    For the thing with the beds, the easiest way to see how many empty spaces an array has is to count how many null you get.
    Example:

    int count = 0;
    for (int i = 0; i < inventory.length - 1; i++){
        if(inventory[i] == null){
            count++;
        }
    }
  • 2013-08-18 22:45:20
    well well well... i think i finally got it.....

    @Override
    public void onInventoryChanged(){
        
        ItemStack[] items2 = GetItems();
        

        
        if (worldObj.getBlockMetadata(xCoord, yCoord, zCoord)== 6){
            if(CheckRecipesMortar(items2) != null){
                if(items[5] == null){
                    ItemStack stack = CheckRecipesMortar(items2);
                    clearItems();
                    items[5] = stack;
                }else if(items[5].isItemEqual(CheckRecipesMortar(items2)) ){ // here im checking if the item in the output slot is the same of the current recipe
                        items[5].stackSize++;
                        clearItems();
                    }else{


        
                }
            }    
        }        
            
    }

    now it works almost perfectly.... one recipe is simple if you place wheat it returns flour....i place one wheat and it returns one flour...i place another wheat and it will increase the stacksize of the flour in the output....

    now there is just one thing....when i place a stack of wheat in the input slot it will consume the whole stack but only placing one flour in the output slot...BUT if i place another stack (when the output slot has only one flour) it will add the right amount of flour to the stack...

    example...i place one stack of 3 wheat....it will consume the stack and return just one flour...but then i place another stack of 3 wheat...and in the output slot will be 4 flour

    so the logic thinking suggest something should be wrong with clearitems() but i dont see the problem

        public void clearItems(){//this method should decrease the stacksize of every itemstack in the input slots
            
            for (int i = 0; i < 5; i++){
                if(items[i] != null){
                    decrStackSize(i,1);
                }
            }

        }

    seems pretty straightforward....
  • Log in or sign up to reply to this thread