Get Block from 1.115 #349 api Crash

  • Hey guys!
    I tried to code a little mod generating additional ores (Vanilla + IC2 + Appeng).
    After reading me into the api stuff again, I fetched the Itemstack of the ore with

    Code
    ItemStack copperstack = Items.getItem("copperOre");


    Next I used the way described in the api to create a Block from an ItemStack

    Code
    Block c_Ore = Block.blocksList[copperstack.itemID]


    eclipse and mcp don't give me any errors, I can recompile and reobfuscate.
    But when I start up my mc, It crashes, giving me an error in this line:

    Code
    Block c_Ore = Block.blocksList[copperstack.itemID]
    //(here I also tried other names instead of c_Ore like copperore and copperoreblock)


    The error is:



    can anyone tell me what I'm doing wrong?


    It is sufficient to only have the Id in my code, so I also tried

    Code
    int copperid = copperstack.itemID;


    which gives me the samme error on game startup.


    Thanks for helping me, If you need more of my code, tell me.
    - Shad0w

    Iff yu find misstaks, you may keep them! (Or tell me if neccessary...)

  • Code
    int copperid = copperstack.itemID;


    If that gives a NullPointerException then it can only be because copperstack is null. Copperstack can only be null if Items.getItem("copperOre"); return null, which only happens if the IC2 config enableWorldGen is on false or the api doesn't support that call anymore. Try getting copper ore using the OreDictionary.


    Code
    ItemStack copperstack = OreDictionary.getOres("oreCopper").get(0).copy();


    What does this do? OreDictionary.getOres("oreCopper") returns a list of the ItemStacks that are registered as "oreCopper". get(0) returns the element at the index 0 of that list, so the first one that was registered. This means if other mods than ic2 have copper ore in the OreDict, you might spawn a different copper ore, but that shouldn't be a problem. copy() is a "security" measure you should get used to use. Many people just get an ItemStack from the OreDictionary and modify its StackSize, ItemDamage or other things and thus break the OreDict Entry since ItemStacks follow the call-by-reference principle. copy() ensures you are not messing anything up.

  • Ok, thanks for that. And, I have used copy later too (still with my old method so it didn'T work either) buth thanks anyways.
    What is weird for me is, that I've already coded a recipe with an uranium drop in another little mod, and there everything works fine (using #341 i think).
    I probably have a sort of solution by entering the Block ID in a config and then just calling the number from a method, I suppose that should work too.
    Gonna try yours anyway as it is much cleaner.


    €dit: also this direct approach gave me the crash:

    Code
    Block c_Ore = Block.blocksList[Items.getItem("copperOre").itemID]

    Iff yu find misstaks, you may keep them! (Or tell me if neccessary...)

  • Put a null check before you do anything with the ItemStack from my way of doing it and it should be failsafe.


    And of course your Edit will also crash since it is exactly the same code just in one line. You'll always get a NullPointerException when you try to access the itemID of a null Object.

  • Umm, ok, but how do I do a null check?


    I suppose I'm going to play around with it some more, because I'd really prefer to have IC2 copper generated.
    I have IC2 in my dependencies, so my mod should be loaded after ic2, right?
    But As far as I've seen, the error in the forge log is before IC2 items are initialized. thats sorta weird.


    €dit: so I tried this now in my main mod class and call the variable from the gen class:


    So the itemstack can not be null (I think). Still, minecraft crashes on me with


    Line 28 in IC2Ore is

    Code
    Block copperOre = getBlock(AdditionalOres.copperstack.copy().itemID);


    calling this method

    Code
    public Block getBlock(int bid)
        {
            return Block.blocksList[bid];
        }


    Line 42 in AdditionalOres is

    Code
    IC2Ore ic2gen = new IC2Ore();


    it is in the @Instance section.
    I'm going to put this somewhere later now.
    Any other ideas?

    Iff yu find misstaks, you may keep them! (Or tell me if neccessary...)

    Edited once, last by Shadowlife ().

  • I can't really see the mistake right now, try doing this in other phases (like do it all in load instead of preInit) or try the OreDict-way. You could also look at how other mods have done it.

    • Official Post

    Here is the Mistake


    ItemStack ccheck = Items.getItem("copperOre").copy();
    ItemStack tcheck = Items.getItem("tinOre").copy();
    ItemStack ucheck = Items.getItem("uraniumOre").copy();


    That "copy" without a != null Check results in Nullpointers


    In addition if that check failed you do


    Block copperOre = getBlock(AdditionalOres.copperstack.copy().itemID);


    Without any != null Check either, resulting into another Nullpointer Exception.

  • Ah, ok. Thanks.
    Anyway, I already managed to fix it by putting this line

    Code
    IC2Ore ic2gen = new IC2Ore();


    after this stuff


    that worked for me. If it's unsafe, I might have anohter look at it again later, but now I still need to fix the applied energistics part. :D

    Iff yu find misstaks, you may keep them! (Or tell me if neccessary...)