NPE TileEntity



  • Bonjour,
    Alors voilà : récemment, j'ai créé un bloc dont les boîte de collision doit changer en fonction des blocs adjacents (câbles).
    Sauf que, quand je pose ce bloc (ceux qui sont déjà posés ne posent pas ce problème), à l'appel de la fonction getCollisionBoundingBoxFromPool(World, int, int, int),
    je récupère le TileEntity du bloc (world.getTileEntity(x, y, z)) qui me retourne null. En résulte un NPE de la mort et paf le jeu crash.

    Pouvez-vous m'aider ?

    Code :

    
    public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z)
    {
            TileEntityCable te = (TileEntityCable)world.getTileEntity(x, y, z);
    
            float size = te.getModulo()/16/2;
            this.setBlockBounds(size - (te.connections[5] != null ? size : 0),
                                            size - (te.connections[1] != null ? size : 0),
                                            size - (te.connections[2] != null ? size : 0),
                                            1 - (size - (te.connections[3] != null ? size : 0)), 
                                            1 - (size - (te.connections[0] != null ? size : 0)), 
                                            1 - (size - (te.connections[4] != null ? size : 0)));
    
            return AxisAlignedBB.getBoundingBox((double)x + this.minX, (double)y + this.minY, (double)z + this.minZ, (double)x + this.maxX, (double)y + this.maxY, (double)z + this.maxZ);
    }
    
    


  • Tu ne peux pas directement cast ta TileEntity. Chaque chose en son temps 😃
    Il faut que tu apprennes à te servir du mot clé instanceof, car là il est necessaire dans ce cas là :

    
    TileEntity te = world.getTileEntity(x, y, z);
    if(te instanceof TileEntityCable)
    {
    float size = te.getModulo()/16/2;
    this.setBlockBounds(size - (te.connections[5] != null ? size : 0),
    size - (te.connections[1] != null ? size : 0),
    size - (te.connections[2] != null ? size : 0),
    1 - (size - (te.connections[3] != null ? size : 0)),
    1 - (size - (te.connections[0] != null ? size : 0)),
    1 - (size - (te.connections[4] != null ? size : 0)));
    
    return AxisAlignedBB.getBoundingBox((double)x + this.minX, (double)y + this.minY, (double)z + this.minZ, (double)x + this.maxX, (double)y + this.maxY, (double)z + this.maxZ);
    }
    }
    
    

  • Administrateurs

    Il suffit d'ajouter un null check.
    if(te != null)



  • Le null check et le instanceof j'y avais pensé, ça marche mais le problème c'est que du coup ça ne définit pas ma hitbox.
    Le problème est que le TileEntity récupéré est null alors que ça devrait être celui du bloc concerné.
    Dois-je en déduire que le TileEntity est créé après l'appel de cette méthode ?


  • Administrateurs

    getCollisionBoundingBoxFromPool est appelé dès que tu entre en collision avec le bloc.
    Il est possible que ton tile entity soit null à l'instant même où tu as posé le bloc.
    Par contre que ce soit encore le cas 1 secondes après ce n'est pas normal.
    Envoies tout le code de ton bloc.



  • BlockCable.java :

    
    package fr.mrblocktnt.newores.electricity.block;
    
    import java.util.List;
    
    import fr.mrblocktnt.newores.electricity.tileentity.TileEntityCable;
    import fr.mrblocktnt.newores.electricity.type.CableType;
    import net.minecraft.block.BlockContainer;
    import net.minecraft.block.material.Material;
    import net.minecraft.creativetab.CreativeTabs;
    import net.minecraft.item.Item;
    import net.minecraft.item.ItemStack;
    import net.minecraft.tileentity.TileEntity;
    import net.minecraft.util.AxisAlignedBB;
    import net.minecraft.world.World;
    
    public class BlockCable extends BlockContainer
    {
    public static String[] subBlock = new String[] { "copper", "copperx2", "gold", "goldx2", "glass_fibre", "platinum", "platinumx2" };
    
    public BlockCable()
    {
    super(Material.ground);
    float size = (11F / 16F) / 2;
    this.setBlockBounds(size, size, size, 1 - size, 1 - size, 1 - size);
    this.useNeighborBrightness = true;
    }
    
    public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z)
    {
    TileEntity tile = world.getTileEntity(x, y, z);
    
    if(tile instanceof TileEntityCable)
    {
    TileEntityCable te = (TileEntityCable)tile;
    float size = 11 / 16 / 2;
    this.setBlockBounds(size - (te.connections[5] != null ? size : 0), size - (te.connections[1] != null ? size : 0), size - (te.connections[2] != null ? size : 0), 1 - (size - (te.connections[3] != null ? size : 0)), 1 - (size - (te.connections[0] != null ? size : 0)), 1 - (size - (te.connections[4] != null ? size : 0)));
    }
    return AxisAlignedBB.getBoundingBox((double) x + this.minX, (double) y + this.minY, (double) z + this.minZ, (double) x + this.maxX, (double) y + this.maxY, (double) z + this.maxZ);
    }
    
    public void getSubBlocks(Item item, CreativeTabs tabs, List list)
    {
    for(int i = 0; i < subBlock.length; i++)
    {
    list.add(new ItemStack(item, 1, i));
    }
    }
    
    public int damageDropped(int metadata)
    {
    return metadata;
    }
    
    public boolean hasTileEntity(int metadata)
    {
    return true;
    }
    
    @Override
    public TileEntity createTileEntity(World world, int metadata)
    {
    switch(metadata)
    {
    case 0:
    return new TileEntityCable(CableType.COPPER);
    case 1:
    return new TileEntityCable(CableType.COPPERx2);
    case 2:
    return new TileEntityCable(CableType.GOLD);
    case 3:
    return new TileEntityCable(CableType.GOLDx2);
    case 4:
    return new TileEntityCable(CableType.GLASS_FIBRE);
    case 5:
    return new TileEntityCable(CableType.PLATINUM);
    case 6:
    return new TileEntityCable(CableType.PLATINUMx2);
    }
    return new TileEntityCable(CableType.COPPER);
    }
    
    @Override
    public TileEntity createNewTileEntity(World var1, int var2)
    {
    switch(var2)
    {
    case 0:
    return new TileEntityCable(CableType.COPPER);
    case 1:
    return new TileEntityCable(CableType.COPPERx2);
    case 2:
    return new TileEntityCable(CableType.GOLD);
    case 3:
    return new TileEntityCable(CableType.GOLDx2);
    case 4:
    return new TileEntityCable(CableType.GLASS_FIBRE);
    case 5:
    return new TileEntityCable(CableType.PLATINUM);
    case 6:
    return new TileEntityCable(CableType.PLATINUMx2);
    }
    return new TileEntityCable(CableType.COPPER);
    }
    
    public int getRenderType()
    {
    return -1;
    }
    
    public boolean isOpaqueCube()
    {
    return false;
    }
    
    public boolean renderAsNormalBlock()
    {
    return false;
    }
    }
    
    

  • Administrateurs

    Remplaces le extends BlockContainer par extends Block et vire la fonction qui était hérité de cette classe.



  • Ok cette fois le TileEntity n'est pas nul mais la boîte de collision change pas…
    ça vient cette fois du setBlockBounds, j'ai du faire une boulette parce qu'avec d'autres dimensions (fixes) ça marche...
    Je vais faire quelques tests et je verrais. Si ça ne marche pas ça doit venir du tableau connections[].

    À suivre donc...

    EDIT:
    Certains index du tableau connections sont vides mais aléatoirement et jamais les même deux fois de suite. Je regarderais ça plus en détail demain.



  • Rien à faire, ça ne fonctionne pas…


  • Administrateurs

    Envoies-moi un zip de ton dossier src je vais regarder de mon côté.