Jump to content

[FIXED]Weird NPE on opening a Tile Entity GUI


vroominator

Recommended Posts

Hi guys, I've been getting a strange problem recently. If you've ever made a block with a Gui/TileEntity/Container before, you're probably familiar with addCraftingToCrafters(), which keeps the Tile Entity and the Container in sync. I'm having problems there. Everything works fine right up until I open the Gui. Then I crash with this error.

 

java.lang.NullPointerException
at net.minecraft.src.Slot.getStack(Slot.java:82)
at net.minecraft.src.Container.getInventory(Container.java:63)
at net.minecraft.src.Container.addCraftingToCrafters(Container.java:47)
at vroominator.sorcery.common.ContainerRuneCrafting.addCraftingToCrafters(ContainerRuneCrafting.java:55)
at cpw.mods.fml.common.network.NetworkRegistry.openRemoteGui(NetworkRegistry.java:315)
at cpw.mods.fml.common.network.FMLNetworkHandler.openGui(FMLNetworkHandler.java:337)
at net.minecraft.src.EntityPlayer.openGui(EntityPlayer.java:2051)
at vroominator.sorcery.common.blocks.BlockRuneCraftingTable.onBlockActivated(BlockRuneCraftingTable.java:106)
at net.minecraft.src.ItemInWorldManager.activateBlockOrUseItem(ItemInWorldManager.java:390)
at net.minecraft.src.NetServerHandler.handlePlace(NetServerHandler.java:536)
at net.minecraft.src.Packet15Place.processPacket(Packet15Place.java:78)
at net.minecraft.src.MemoryConnection.processReadPackets(MemoryConnection.java:78)
at net.minecraft.src.NetServerHandler.networkTick(NetServerHandler.java:80)
at net.minecraft.src.NetworkListenThread.networkTick(NetworkListenThread.java:55)
at net.minecraft.src.IntegratedServerListenThread.networkTick(IntegratedServerListenThread.java:111)
at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:649)
at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:564)
at net.minecraft.src.IntegratedServer.tick(IntegratedServer.java:110)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:470)
at net.minecraft.src.ThreadServerApplication.run(ThreadServerApplication.java:18)

 

I realise it's traced back to getStack() on Line 82 of slot, but I just do not know why. I've made blocks like this before, and never run into this error. Any help would be greatly appreciated.

If you need to see code, just ask.

Link to comment
Share on other sites

  • 2 weeks later...

Sorry for the bump, but I just cannot figure out what's going on here.

I figure that when a thread just gets ignored like this, it's one of 2 things:

A: You're absolutely stumped

B: I'm missing something painfully obvious

 

I highly doubt it's A, so could someone please tell me what I've done wrong?

 

Link to comment
Share on other sites

Alrighty. Prepare for some messy code.

 

ContainerRuneCrafting

package sorcery.common;

import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import sorcery.common.core.Sorcery;

import net.minecraft.src.*;

public class ContainerRuneCrafting extends Container
{
    private TileEntityRuneCrafting tile;
    private World worldObj;
    private int posX;
    private int posY;
    private int posZ;
    private int lastCookTime;
    private int lastRuneCookTime;
    private int lastFuelCookTime;
    private int lastRune;

    public ContainerRuneCrafting(InventoryPlayer player, TileEntityRuneCrafting tile, World world, int i, int j, int k)
    {
        this.tile = tile;
        this.worldObj = world;
        this.posX = i;
        this.posY = j;
        this.posZ = k;
        this.addSlotToContainer(new Slot(tile, 0, 24, 35));
        this.addSlotToContainer(new Slot(tile, 1, 48, 35));
        this.addSlotToContainer(new SlotFurnace(player.player, tile, 2, 124, 35));
        int var3;

        for (var3 = 0; var3 < 3; ++var3)
        {
            for (int var4 = 0; var4 < 9; ++var4)
            {
                this.addSlotToContainer(new Slot(player, var4 + var3 * 9 + 9, 8 + var4 * 18, 84 + var3 * 18));
            }
        }

        for (var3 = 0; var3 < 9; ++var3)
        {
            this.addSlotToContainer(new Slot(player, var3, 8 + var3 * 18, 142));
        }
    }

    public void addCraftingToCrafters(ICrafting par1ICrafting)
    {
    	System.out.println(((EntityPlayer)par1ICrafting).getEntityName());
        super.addCraftingToCrafters(par1ICrafting); <<--This is where the problem starts
        par1ICrafting.updateCraftingInventoryInfo(this, 0, this.tile.currentCookTime);
        par1ICrafting.updateCraftingInventoryInfo(this, 1, this.tile.runeCookTime);
        par1ICrafting.updateCraftingInventoryInfo(this, 2, this.tile.fuelCookTime);
        par1ICrafting.updateCraftingInventoryInfo(this, 3, this.tile.currentRune);
    }

    /**
     * Updates crafting matrix; called from onCraftMatrixChanged. Args: none
     */
    public void updateCraftingResults()
    {
        super.updateCraftingResults();
        Iterator i = this.crafters.iterator();

        while (i.hasNext())
        {
            ICrafting crafter = (ICrafting)i.next();

            if (this.lastCookTime != this.tile.currentCookTime)
            {
                crafter.updateCraftingInventoryInfo(this, 0, this.tile.currentCookTime);
            }

            if (this.lastRuneCookTime != this.tile.runeCookTime)
            {
                crafter.updateCraftingInventoryInfo(this, 1, this.tile.runeCookTime);
            }
            
            if (this.lastFuelCookTime != this.tile.fuelCookTime)
            {
                crafter.updateCraftingInventoryInfo(this, 2, this.tile.fuelCookTime);
            }
            
            if (this.lastRune != this.tile.currentRune)
            {
                crafter.updateCraftingInventoryInfo(this, 3, this.tile.currentRune);
            }
        }

        this.lastCookTime = this.tile.currentCookTime;
        this.lastRuneCookTime = this.tile.runeCookTime;
        this.lastFuelCookTime = this.tile.fuelCookTime;
        this.lastRune = this.tile.currentRune;
    }

    @SideOnly(Side.CLIENT)
    public void updateProgressBar(int progress)
    {
            this.tile.currentCookTime = progress;
    }

    public boolean canInteractWith(EntityPlayer player)
    {
        return this.worldObj.getBlockId(this.posX, this.posY, this.posZ) != Sorcery.runeCraftingTable.blockID ? false : player.getDistanceSq((double)this.posX + 0.5D, (double)this.posY + 0.5D, (double)this.posZ + 0.5D) <= 64.0D;
    }
}

 

TileEntityRuneCrafting

package sorcery.common;

import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;

import sorcery.common.blocks.BlockHellFurnace;
import sorcery.common.core.Sorcery;
import sorcery.common.core.TileEntityBasic;
import sorcery.common.lib.ItemStackHelper;
import sorcery.common.lib.RuneCraftingHelper;
import sorcery.common.recipes.ForgeRecipes;
import net.minecraft.src.*;
import net.minecraftforge.common.ISidedInventory;
import net.minecraftforge.common.ForgeDirection;
import cpw.mods.fml.common.registry.GameRegistry;

import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;

public class TileEntityRuneCrafting extends TileEntityBasic implements IInventory, ISidedInventory
{
    public ItemStack[] inventory = new ItemStack[3];
    
    public int tier;
    
    public int currentCookTime = 0;

    public int runeCookTime = 0;
    
    public int fuelCookTime = 0;
    
    public int currentRune = 1;
    
    @Override
    public void handlePacket(NetworkManager network, Packet pack, String playerName) 
    {
    	ByteArrayDataInput data = ByteStreams.newDataInput(((Packet250CustomPayload)pack).data);
    	if(data.readInt() == 1)
    	{
    		++this.currentRune;
    	}
    	else if(data.readInt() == 2)
    	{
    		--this.currentRune;
    	}
    	
    }
    
    public TileEntityRuneCrafting(int tier)
    {
    	this.tier = tier;
    }

    public int getSizeInventory()
    {
        return this.inventory.length;
    }

    public ItemStack getStackInSlot(int slot)
    {
        return this.inventory[slot];
    }

    public ItemStack decrStackSize(int slot, int size)
    {
        if (this.inventory[slot] != null)
        {
            ItemStack var3;

            if (this.inventory[slot].stackSize <= size)
            {
                var3 = this.inventory[slot];
                this.inventory[slot] = null;
                return var3;
            }
            else
            {
                var3 = this.inventory[slot].splitStack(size);

                if (this.inventory[slot].stackSize == 0)
                {
                    this.inventory[slot] = null;
                }

                return var3;
            }
        }
        else
        {
            return null;
        }
    }

    public ItemStack getStackInSlotOnClosing(int slot)
    {
        if (this.inventory[slot] != null)
        {
            ItemStack var2 = this.inventory[slot];
            this.inventory[slot] = null;
            return var2;
        }
        else
        {
            return null;
        }
    }

    public void setInventorySlotContents(int slot, ItemStack item)
    {
        this.inventory[slot] = item;

        if (item != null && item.stackSize > this.getInventoryStackLimit())
        {
            item.stackSize = this.getInventoryStackLimit();
        }
    }

    public String getInvName()
    {
        return "container.runecrafting";
    }

    public void readFromNBT(NBTTagCompound tag)
    {
        super.readFromNBT(tag);
        NBTTagList var2 = tag.getTagList("Items");
        this.inventory = new ItemStack[this.getSizeInventory()];

        for (int var3 = 0; var3 < var2.tagCount(); ++var3)
        {
            NBTTagCompound var4 = (NBTTagCompound)var2.tagAt(var3);
            byte var5 = var4.getByte("Slot");

            if (var5 >= 0 && var5 < this.inventory.length)
            {
                this.inventory[var5] = ItemStack.loadItemStackFromNBT(var4);
            }
        }

        this.currentCookTime = tag.getShort("CookTime");
        this.runeCookTime = tag.getInteger("RuneCookTime");
        this.fuelCookTime = tag.getInteger("FuelCookTime");
        this.currentRune = tag.getInteger("CurrentRune");
    }

    public void writeToNBT(NBTTagCompound tag)
    {
        super.writeToNBT(tag);
        tag.setShort("CookTime", (short)this.currentCookTime);
        tag.setInteger("RuneCookTime", this.runeCookTime);
        tag.setInteger("FuelCookTime", this.fuelCookTime);
        tag.setInteger("CurrentRune", this.currentRune);
        NBTTagList var2 = new NBTTagList();

        for (int var3 = 0; var3 < this.inventory.length; ++var3)
        {
            if (this.inventory[var3] != null)
            {
                NBTTagCompound var4 = new NBTTagCompound();
                var4.setByte("Slot", (byte)var3);
                this.inventory[var3].writeToNBT(var4);
                var2.appendTag(var4);
            }
        }

        tag.setTag("Items", var2);
    }

    public int getInventoryStackLimit()
    {
        return 64;
    }
    
    public int getCurrentItemCookTime()
    {
    	if(this.inventory[1] != null && RuneCraftingHelper.getEnumFromMeta(this.inventory[1].getItemDamage()) != null)
    	{
    		System.out.println(((RuneCraftingHelper.EnumRuneTypes)RuneCraftingHelper.getEnumFromMeta(this.inventory[1].getItemDamage())).time);
    		return(((RuneCraftingHelper.EnumRuneTypes)RuneCraftingHelper.getEnumFromMeta(this.inventory[1].getItemDamage())).time);
    	}
    	return 0;
    }

    @SideOnly(Side.CLIENT)
    public int getCookProgressScaled(int scale)
    {
    	if(this.getCurrentItemCookTime() == 0)
    	{
    		return 0;
    	}
    	System.out.println(this.currentCookTime * scale / this.getCurrentItemCookTime());
        return this.currentCookTime * scale / this.getCurrentItemCookTime();
    }
    
    public boolean isCooking()
    {
    	return this.currentCookTime > 0;
    }
    
    public boolean hasFuel()
    {
    	return this.runeCookTime > 0;
    }
    
    @Override
    public void onInventoryChanged()
    {
    }

    public void updateEntity()
    {		
        if(this.fuelCookTime == 0 && this.isItemFuel(this.inventory[0]) > 0)
        {
        	this.fuelCookTime = this.isItemFuel(this.inventory[0]);
        	this.decrStackSize(0, 1);
        }
        
        if(this.canCook())
        {
        	++this.currentCookTime;
        	
        	if(this.currentCookTime == RuneCraftingHelper.getEnumFromMeta(this.currentRune).time)
        	{
        		this.smeltItem();
        		this.currentCookTime = 0;
        		this.runeCookTime -= RuneCraftingHelper.getEnumFromMeta(this.currentRune).fuelCost;
        		--this.inventory[1].stackSize; 
        	}
        }
    }

    private boolean canCook()
    {
        if(this.inventory[1] == null || this.fuelCookTime == 0 || this.inventory[2].stackSize == 64)
        {
            return false;
        }
        else if(ItemStackHelper.getInstance().areItemsEqual(this.inventory[1], new ItemStack(Sorcery.rune, 1, 0)))
        {
        	return true;
        }
        else if(ItemStackHelper.getInstance().areItemsEqual(this.inventory[2], new ItemStack(Sorcery.rune, 1, this.currentRune)) || this.inventory[2] == null)
        {
        	return true;
        }
        return false;
    }

    private int isItemFuel(ItemStack item)
    {
    	if(item == null)
    	{
    		return 0;
    	}
    	else
    	{
    		if(item.getItem() == Item.redstone)
    		{
    			return 10;
    		}
    		else if(item.getItem() == Item.lightStoneDust)
    		{
    			return 12;
    		}
    		else if(item.getItem() == Item.gunpowder)
    		{
    			return 14;
    		}
    		else if(item.getItem() == Sorcery.enderdust)
    		{
    			return 14;
    		}
    		else if(item.getItem() == Item.blazePowder)
    		{
    			return 18;
    		}
    		else if(item.getItem() == Sorcery.ectoplasm)
    		{
    			return 20;
    		}
    		else if(item.getItem() == Sorcery.magicDust)
    		{
    			return 30;
    		}
    	}
	return 0;
}

public void smeltItem()
    {
        if(this.canCook())
        {
        	ItemStack result = new ItemStack(Sorcery.rune, 1, this.currentRune);

        	if(this.inventory[2] == null)
        	{
        		this.inventory[2] = result;
        	}
        	else
        	{
        		++this.inventory[2].stackSize;
        	}
        }
    }

    public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer)
    {
        return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : par1EntityPlayer.getDistanceSq((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D;
    }

    public boolean canGoUpRune()
    {
    	if(this.currentRune == 4 && this.tier == 0)
    	{
    		return false;
    	}
    	else if(this.currentRune == 9 && this.tier == 1)
    	{
    		return false;
    	}
    	else if(this.currentRune == 13 && this.tier == 2)
    	{
    		return false;
    	}
    	else if(this.currentRune == 15)
    	{
    		return false;
    	}
    	return true;
    }
    
    public boolean canGoDownRune()
    {
    	if(this.currentRune == 1)
    	{
    		return false;
    	}
    	return true;
    }
    
    public void openChest()
    {
    }

    public void closeChest()
    {
    }

    @Override
    public int getStartInventorySide(ForgeDirection side)
    {
        if (side == ForgeDirection.DOWN) return 1;
        if (side == ForgeDirection.UP) return 0; 
        return 2;
    }

    @Override
    public int getSizeInventorySide(ForgeDirection side)
    {
        return 1;
    }

    public Packet getDescriptionPacket()
    {
        NBTTagCompound tag = new NBTTagCompound();
        this.writeToNBT(tag);
        return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 1, tag);
    }
    
    public void onDataPacket(NetworkManager manager, Packet132TileEntityData pack)
    {
    	this.readFromNBT(pack.customParam1);
    }
}

Link to comment
Share on other sites

First thing I would make sure is that the slotIndex is proper. It's not obvious how you have the slotIndex's right now and I can't guarantee they're returning the right number.Make sure you're getting the right slotIndex. If you're not, fix that. If it's not fixed after that, return here and read below.

 

I can't personally see exactly (possibly missing @Overrides?) what the issue is if not the above, but I would try the following:

 

You need to figure out what is null. The line in Slot.java:

 

this.inventory.getStackInSlot(this.slotIndex);

 

I would trace this and this.inventory. Figure out which of those is null.

 

If it is "this" that is null, one of your slots is returning true for hasNext() but is returning null for the actual slot.

If "inventory" is null (which I can't see why it would be) you need to properly set the Slots inventory to the TileEntityRuneCrafting.

If "inventory" and "this" aren't null then the TileEntityRunCrafting's inventory may be null. (judging from the constructor it's probably not this)

 

Once you know what is null just work backwards.

 

There's probably someone who can read this and tell you your issue, but this is all I can offer.

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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hello! My friends and I were attempting to add a few extra mods to the Create Chronicles modpack, and all was well until people started crashing when they opened their inventories. Any help finding the culprit would be MUCH appreciated, I've been scratching my head for the past few days on what went wrong. https://paste.ee/p/8pajP
    • >>>KLIK LOGIN DISINI SAYANG<<< >>>KLIK DAFTAR DISINI SAYANG<<< Pendahuluan Dalam dunia perjudian online, slot menjadi salah satu permainan yang paling diminati. Dengan munculnya berbagai platform, Togel2Win hadir sebagai salah satu pilihan menarik, terutama dengan fitur anti rungkad yang dijanjikan. Artikel ini akan membahas tentang Togel2Win, keunggulan slot terbaru, dan bagaimana server Thailand berperan dalam meningkatkan pengalaman bermain. Apa Itu Togel2Win? Togel2Win adalah platform permainan yang menawarkan berbagai jenis permainan, termasuk slot dan togel. Dengan antarmuka yang ramah pengguna dan beragam pilihan permainan, situs ini bertujuan untuk memberikan pengalaman bermain yang menyenangkan dan menguntungkan bagi para pemain. Keunggulan Slot Togel2Win Fitur Anti Rungkad: Salah satu keunggulan utama dari Togel2Win adalah fitur anti rungkad yang dirancang untuk mengurangi kemungkinan gangguan saat bermain. Ini memastikan bahwa pemain dapat menikmati permainan tanpa gangguan teknis, meningkatkan kenyamanan dan fokus. Beragam Pilihan Slot: Togel2Win menawarkan berbagai jenis slot, dari yang klasik hingga yang modern dengan grafis menawan dan tema yang menarik. Ini memberikan variasi yang cukup bagi pemain untuk menemukan permainan yang sesuai dengan preferensi mereka. Server Thailand yang Stabil: Server yang berlokasi di Thailand memberikan koneksi yang cepat dan stabil. Ini sangat penting untuk pengalaman bermain yang lancar, terutama saat bermain slot yang memerlukan respons cepat. Bonus dan Promosi Menarik: Togel2Win sering menawarkan bonus dan promosi yang menarik untuk menarik pemain baru dan mempertahankan loyalitas pemain yang sudah ada. Ini bisa berupa bonus deposit, putaran gratis, atau program loyalitas. Tips untuk Pemain Slot di Togel2Win Pilih Slot dengan RTP Tinggi: Sebelum memulai permainan, pastikan untuk memilih slot dengan tingkat pengembalian pemain (RTP) yang tinggi untuk meningkatkan peluang menang. Kelola Anggaran: Tentukan batasan anggaran sebelum bermain dan patuhi itu. Ini membantu mencegah kerugian besar dan menjaga pengalaman bermain tetap menyenangkan. Manfaatkan Bonus: Jangan ragu untuk memanfaatkan bonus dan promosi yang ditawarkan. Ini bisa memberikan tambahan modal untuk bermain lebih lama. Kesimpulan Togel2Win merupakan pilihan menarik bagi para penggemar slot, terutama dengan fitur anti rungkad dan server yang stabil. Dengan berbagai pilihan permainan dan bonus yang menggiurkan, Togel2Win siap memberikan pengalaman bermain yang tak terlupakan. Jika Anda mencari platform slot yang andal dan menyenangkan, Togel2Win bisa menjadi solusi yang tepat.
    • I'm trying to make my own modpack, but sometimes, in certain areas of the world, the game just says "server closed". Minecraft doesn't close, it just returns to the menu. When I tried to figure it out on my own and understand the logs, I didn't understand anything (English is not my native language, so it's difficult for me). I've been trying to solve the problem for the third month. So I ask if anyone is good at this and it's not difficult for you, to help me with this. If you need details, ask. I'll describe everything. What it looks like Logs
  • Topics

×
×
  • Create New...

Important Information

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