Posted October 13, 201410 yr I made a tile entity that works ok, but whenever I try to add an item into it with a hopper (or take one out) it crashes with: ---- Minecraft Crash Report ---- // I feel sad now Time: 13/10/14 19:23 Description: Ticking block entity java.lang.NullPointerException: Ticking block entity at net.minecraft.item.ItemStack.getMaxStackSize(ItemStack.java:214) at net.minecraft.tileentity.TileEntityHopper.func_145899_c(TileEntityHopper.java:558) at net.minecraft.tileentity.TileEntityHopper.func_145889_a(TileEntityHopper.java:525) at net.minecraft.tileentity.TileEntityHopper.func_145892_a(TileEntityHopper.java:466) at net.minecraft.tileentity.TileEntityHopper.func_145891_a(TileEntityHopper.java:439) at net.minecraft.tileentity.TileEntityHopper.func_145887_i(TileEntityHopper.java:246) at net.minecraft.tileentity.TileEntityHopper.updateEntity(TileEntityHopper.java:226) at net.minecraft.world.World.updateEntities(World.java:2158) at net.minecraft.world.WorldServer.updateEntities(WorldServer.java:515) at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:703) at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:614) at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:485) at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:752) A detailed walkthrough of the error, its code path and all known details is as follows: --------------------------------------------------------------------------------------- -- Head -- Stacktrace: at net.minecraft.item.ItemStack.getMaxStackSize(ItemStack.java:214) at net.minecraft.tileentity.TileEntityHopper.func_145899_c(TileEntityHopper.java:558) at net.minecraft.tileentity.TileEntityHopper.func_145889_a(TileEntityHopper.java:525) at net.minecraft.tileentity.TileEntityHopper.func_145892_a(TileEntityHopper.java:466) at net.minecraft.tileentity.TileEntityHopper.func_145891_a(TileEntityHopper.java:439) at net.minecraft.tileentity.TileEntityHopper.func_145887_i(TileEntityHopper.java:246) at net.minecraft.tileentity.TileEntityHopper.updateEntity(TileEntityHopper.java:226) -- Block entity being ticked -- Details: Name: Hopper // net.minecraft.tileentity.TileEntityHopper Block type: ID #154 (tile.hopper // net.minecraft.block.BlockHopper) Block data value: 0 / 0x0 / 0b0000 Block location: World: (411,3,260), Chunk: (at 11,0,4 in 25,16; contains blocks 400,0,256 to 415,255,271), Region: (0,0; contains chunks 0,0 to 31,31, blocks 0,0,0 to 511,255,511) Actual block type: ID #154 (tile.hopper // net.minecraft.block.BlockHopper) Actual block data value: 0 / 0x0 / 0b0000 Stacktrace: at net.minecraft.world.World.updateEntities(World.java:2158) at net.minecraft.world.WorldServer.updateEntities(WorldServer.java:515) -- Affected level -- Details: Level name: New World All players: 1 total; [EntityPlayerMP['Player346'/200, l='New World', x=412.73, y=4.00, z=258.61]] Chunk stats: ServerChunkCache: 625 Drop: 0 Level seed: -6805577707855591753 Level generator: ID 01 - flat, ver 0. Features enabled: true Level generator options: Level spawn location: World: (409,4,260), Chunk: (at 9,0,4 in 25,16; contains blocks 400,0,256 to 415,255,271), Region: (0,0; contains chunks 0,0 to 31,31, blocks 0,0,0 to 511,255,511) Level time: 13686 game time, 13686 day time Level dimension: 0 Level storage version: 0x04ABD - Anvil Level weather: Rain time: 56061 (now: false), thunder time: 72177 (now: false) Level game mode: Game mode: creative (ID 1). Hardcore: false. Cheats: true Stacktrace: at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:703) at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:614) at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:485) at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:752) -- System Details -- Details: Minecraft Version: 1.7.10 Operating System: Windows 8 (amd64) version 6.2 Java Version: 1.7.0_51, Oracle Corporation Java VM Version: Java HotSpot 64-Bit Server VM (mixed mode), Oracle Corporation Memory: 869727800 bytes (829 MB) / 1056309248 bytes (1007 MB) up to 1056309248 bytes (1007 MB) JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M AABB Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0 FML: MCP v9.05 FML v7.10.85.1225 Minecraft Forge 10.13.1.1225 4 mods loaded, 4 mods active mcp{9.05} [Minecraft Coder Pack] (minecraft.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available FML{7.10.85.1225} [Forge Mod Loader] (forgeSrc-1.7.10-10.13.1.1225.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available Forge{10.13.1.1225} [Minecraft Forge] (forgeSrc-1.7.10-10.13.1.1225.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available soulWizardry{0.0.1} [soul Wizardry] (bin) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available Profiler Position: N/A (disabled) Vec3 Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used Player Count: 1 / 8; [EntityPlayerMP['Player346'/200, l='New World', x=412.73, y=4.00, z=258.61]] Type: Integrated Server (map_client.txt) Is Modded: Definitely; Client brand changed to 'fml,forge' I checked and ItemStack.getMaxStackSize() is at ItemStack.java:214 which is what the report blames and it calls ItemStack.getItem() which uses an uninitialised delegate. The report doesn't reference any of my code whatsoever. After the crash the item's in the tile entity and everything, just doesn't like it when it goes in/out.
October 14, 201410 yr Author public class TileEntityResearchDesk extends TileEntity implements IInventory { private ItemStack[] contents = new ItemStack[2]; public TileEntityResearchDesk() { contents[0] = new ItemStack((Item)null); } @Override public int getSizeInventory() { return 2; } @Override public ItemStack getStackInSlot(int p_70301_1_) { return contents[p_70301_1_]; } @Override public ItemStack decrStackSize(int p_70298_1_, int p_70298_2_) { if (this.contents[p_70298_1_] != null) { ItemStack itemstack; if (this.contents[p_70298_1_].stackSize <= p_70298_2_) { itemstack = this.contents[p_70298_1_]; this.contents[p_70298_1_] = null; this.markDirty(); return itemstack; } else { itemstack = this.contents[p_70298_1_].splitStack(p_70298_2_); if (this.contents[p_70298_1_].stackSize == 0) { this.contents[p_70298_1_] = null; } this.markDirty(); return itemstack; } } else { return null; } } @Override public ItemStack getStackInSlotOnClosing(int p_70304_1_) { if (this.contents[p_70304_1_] != null) { ItemStack itemstack = this.contents[p_70304_1_]; this.contents[p_70304_1_] = null; return itemstack; } else return null; } @Override public void setInventorySlotContents(int p_70299_1_, ItemStack p_70299_2_) { contents[p_70299_1_] = p_70299_2_; contents[p_70299_1_].func_150996_a(contents[p_70299_1_].getItem()); } @Override public String getInventoryName() { return "Research Desk"; } @Override public boolean hasCustomInventoryName() { return false; } @Override public int getInventoryStackLimit() { return 64; } @Override public boolean isUseableByPlayer(EntityPlayer p_70300_1_) { return true; } @Override public void openInventory() {} @Override public void closeInventory() {} @Override public boolean isItemValidForSlot(int p_94041_1_, ItemStack p_94041_2_) { if (p_94041_2_.getItem() == Item.itemRegistry.getObject("paper")) { return true; } else return false; } @Override public void readFromNBT(NBTTagCompound nbtTag) { super.readFromNBT(nbtTag); contents[0] = ItemStack.loadItemStackFromNBT(nbtTag.getCompoundTag("Item")); } @Override public void writeToNBT(NBTTagCompound nbtTag) { super.writeToNBT(nbtTag); NBTTagCompound item = new NBTTagCompound(); if (contents[0] != null) contents[0].writeToNBT(item); nbtTag.setTag("Item", item); } public ResourceLocation getBlockTexture() { if (contents[0] == null) return new ResourceLocation("soulwizardry:textures/blocks/ModelResearchDesk.png"); else return new ResourceLocation("soulwizardry:textures/blocks/ModelResearchDeskPaper.png"); } @Override public Packet getDescriptionPacket() { NBTTagCompound tag = new NBTTagCompound(); writeToNBT(tag); return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 3, tag); } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { readFromNBT(pkt.func_148857_g()); } public ItemStack tryAddItemToSlot(int slot, ItemStack item) { // TODO: Cut down on the 'if's if (isItemValidForSlot(slot, item)) { if (contents[slot] != null) { if (contents[slot].getItem() == item.getItem()) { contents[slot].stackSize += item.stackSize; item.stackSize = 0; if (contents[slot].stackSize > contents[slot].getMaxStackSize()) { item.stackSize = contents[slot].stackSize - contents[slot].getMaxStackSize(); contents[slot].stackSize = contents[slot].getMaxStackSize(); } } else return null; } else { contents[slot] = item; return null; } } return item; } } I'm using 1 piece of paper.
October 15, 201410 yr Author It seems to be the only way to be able to call loadItemStackFromNBT() with nothing in the slot. I fixed the crash by calling func_150996_a() every time the item gets changed but now the changing texture doesn't work again. The S35PacketUpdateTileEntity only gets sent on world load, so I tried using markDirty() but that makes no difference.
October 15, 201410 yr quick tip, if you want to have an ItemStack that isn't null but doesn't contain anything, use "new ItemStack(Item.getItemByID(0),0)". All this does is create an itemstack with the id of 0 and quantity of 0. I use this instead of null but I couldn't tell you if it works properly with GUIs. The proud(ish) developer of Ancients
October 15, 201410 yr @memcallen very bad idea. Null ItemStacks are OK. You just need a ways to handle it.
October 16, 201410 yr Author Remove second line of your setInventorySlotContents. That's what stopped the crash. It actually sets the delegate so there isn't an NPE when you use getItem().
October 18, 201410 yr Author Remove the line from your constructor. You should not make an ItemStack that has a null as the Item. I can't do that because if I do it crashes with an NPE because contents[0] is null when I try to call loadItemStackFromNBT(). I ran func_150996_a() to set the null delegate every time setInventorySlotContents() gets called and that fixed the bug. Now S35PacketUpdateTileEntity only gets sent on world load for some reason, but I'm not sure if it did that anyway. Also markDirty() doesn't do anything.
October 19, 201410 yr Author I can't do that because if I do it crashes with an NPE because contents[0] is null when I try to call loadItemStackFromNBT().That statement makes no sense. You are assigning something to contents[0] in readFromNBT, so the value of contents[0] does not matter, whether it's null or not. Sorry, I got confused between the staticness of readFromNBT() (non-static) and loadItemStackFromNBT() (static). That isn't the problem though. I fixed the crash with func_150996_a() but now the S35PacketUpdateTileEntity only gets sent once when you load the world.
October 19, 201410 yr Author You can re-sent the description packet with markBlockForUpdate. Do that when the data changes on the server. You should be using this sparingly though. I found that on another post as well, still didn't do anything.
October 21, 201410 yr Author Define "didn't do anything". Show your updated code. Didn't do anything=no difference between before using markBlockForUpdate() and after. @Override public void setInventorySlotContents(int p_70299_1_, ItemStack p_70299_2_) { contents[p_70299_1_] = p_70299_2_; contents[p_70299_1_].func_150996_a(contents[p_70299_1_].getItem()); markDirty(); worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); } @Override public String getInventoryName() { return "Research Desk"; } @Override public boolean hasCustomInventoryName() { return false; } @Override public int getInventoryStackLimit() { return 64; } @Override public boolean isUseableByPlayer(EntityPlayer p_70300_1_) { return true; } @Override public void openInventory() {} @Override public void closeInventory() {} @Override public boolean isItemValidForSlot(int p_94041_1_, ItemStack p_94041_2_) { if (p_94041_2_ != null && p_94041_2_.getItem() == Item.itemRegistry.getObject("paper")) { return true; } else return false; } @Override public void readFromNBT(NBTTagCompound nbtTag) { super.readFromNBT(nbtTag); contents[0] = ItemStack.loadItemStackFromNBT(nbtTag.getCompoundTag("Item")); } @Override public void writeToNBT(NBTTagCompound nbtTag) { super.writeToNBT(nbtTag); NBTTagCompound item = new NBTTagCompound(); if (contents[0] != null) contents[0].writeToNBT(item); nbtTag.setTag("Item", item); } public ResourceLocation getBlockTexture() { if (contents[0] == null && contents[0] != new ItemStack((Item)null)) { return new ResourceLocation("soulwizardry:textures/blocks/ModelResearchDesk.png"); } else { return new ResourceLocation("soulwizardry:textures/blocks/ModelResearchDeskPaper.png"); } } @Override public Packet getDescriptionPacket() { NBTTagCompound tag = new NBTTagCompound(); writeToNBT(tag); return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 0, tag); } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { System.out.println("Packet!"); readFromNBT(pkt.func_148857_g()); } public ItemStack tryAddItemToSlot(int slot, ItemStack item) { // TODO: Cut down on the 'if's if (isItemValidForSlot(slot, item)) { if (contents[slot] != null) { if (contents[slot].getItem() == item.getItem() && contents[slot].getTagCompound() == item.getTagCompound()) { contents[slot].stackSize += item.stackSize; item.stackSize = 0; if (contents[slot].stackSize > contents[slot].getMaxStackSize()) { item.stackSize = contents[slot].stackSize - contents[slot].getMaxStackSize(); contents[slot].stackSize = contents[slot].getMaxStackSize(); } this.worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); } else return null; } else { contents[slot] = item; return null; } } return item; } }
October 22, 201410 yr Author What's up with the 2nd line in setInventorySlotContents ? Why do you re-send the packet whenever the inventory changes? That's kinda a bad idea. That's not sending the packet, it's setting the null delegate that caused the first crash.
October 23, 201410 yr Author func_150996_a is setItem . So you are saying: stack.setItem(stack.getItem()); - Makes no sense and will crash when a slot in your Inventory is set to empty (stack == null). And yes, markBlockForUpate IS resending the packet. Line 2 removed, for some reason original "vanilla" crash doesn't come back. And no, markBlockForUpdate ISN'T resending the packet.
October 24, 201410 yr Author I repeat my question: why do you need the inventory permanently synced? The block renders differently dependant on whether there's something in the slot or not.
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.