Posted May 22, 20169 yr Hello everyone. So I've been experimenting with the idea of creating a crate block, which would store a unlimited amount of just one item. To do this, I would need a tile entity, since I need to store extra variables in the block. However, when I run Minecraft, it gives me a null pointer exception. Here's the code for the tile entity class: public class CrateTileEntity extends TileEntity { private ItemStack item; private int amount; /** * This method will return the item variable. */ public ItemStack getItemStack() { return item; } /** * This method will return the count variable. */ public int getAmount() { return amount; } /** * This method will be called whenever an item is added to the Crate. Items will only be added to this block through * a player's inventory (ItemStack is therefore used). * * Will return true only if a transaction takes place. */ public boolean addItem(ItemStack stack) { //If no item is selected if (stack.getItem() == null) { return false; } //If item of stack is not the correct type... if (stack.getItem() != item.getItem()) { //If item for Crate is not determined if (item == null) { //Set item and amount equal to that of ItemStack item.setItem(stack.getItem()); amount = stack.stackSize; return true; } //Else, return.false else { return false; } } //if item is selected and item is of correct type, then add to Crate else { //Adds the size of stack amount += stack.stackSize; return true; } } // Loading and saving the data to NBT, so the info is not lost when the world is reloaded. /** * This method will read the information from the NBT regarding the item and amount for the Crate. * */ @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); //ItemStack: this.item = ItemStack.loadItemStackFromNBT(compound.getCompoundTag("item")); this.amount = compound.getInteger("amount"); } /** * This method will write the information from the NBT regarding the item and amount for the Crate. * */ @Override public void writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); compound.setInteger("amount", amount); //Item Stack: NBTTagCompound stack = new NBTTagCompound(); this.item.writeToNBT(stack); compound.setTag("item", stack); } } and the code for the block class: package crate; import net.minecraft.block.Block; import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraftforge.fml.common.registry.GameRegistry; /** * This class will create a Crate block, which will be able to store an infinite amount of a selected type of item. * However, it can only store one item at a time. * * Created by Haaris Tahir-Kheli on 5/21/2016. */ public class CrateBlock extends Block implements ITileEntityProvider { //Constructor protected CrateBlock() { //Set material for block (through superclass constructor) super(Material.wood); //Set unlocalized name this.setUnlocalizedName("crateBlock"); //Set registry name and register this.setRegistryName("crateblock"); //Set up which creative tab it can be found in this.setCreativeTab(CreativeTabs.tabBlock); //Set hardness this.setHardness(8.0F); //Set blast resistance this.setResistance(5.0F); //Set brightness this.setLightLevel(0.2F); //Set harvest level this.setHarvestLevel("axe", 1); //Set block container to true this.isBlockContainer = true; } /** * This method will establish a new tile entity that will be created and associated with this block */ @Override public TileEntity createNewTileEntity(World worldIn, int meta) { return new CrateTileEntity(); } /** * This method will return the tile entity of the block that was clicked */ private CrateTileEntity getTileEntity(World world, BlockPos pos) { return (CrateTileEntity) world.getTileEntity(pos); } /** * Thie method will trigger as a clean-up for when the block is destroyed. */ @Override public void breakBlock(World world, BlockPos pos, IBlockState state) { super.breakBlock(world, pos, state); world.removeTileEntity(pos); } /** * This method will handle the passing of block events, which are useful for synchronizing data. */ @Override public boolean onBlockEventReceived(World worldIn, BlockPos pos, IBlockState state, int eventID, int eventParam) { super.onBlockEventReceived(worldIn, pos, state, eventID, eventParam); TileEntity tileentity = worldIn.getTileEntity(pos); return (tileentity == null) ? false : tileentity.receiveClientEvent(eventID, eventParam); } /** * This method will trigger whenever the block is right-clicked. */ @Override public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) { super.onBlockActivated(world, pos, state, player, hand, heldItem, side, hitX, hitY, hitZ); //Make sure event only takes place on client side if (world.isRemote) { return false; } //Check if player is holding an item if (player.getHeldItemMainhand() == null) { //Print message assessing crate player.addChatComponentMessage(new TextComponentString(TextFormatting.RED + "As you are not holding an item," + " no item will be added to the crate.")); return false; } //Create CrateTileEntity CrateTileEntity tileEntity = getTileEntity(world, pos); //Add item based on Crate tile entity if (tileEntity.addItem(heldItem)) { //Print messages assessing crate player.addChatComponentMessage(new TextComponentString(TextFormatting.AQUA + "The crate holds " + tileEntity.getItemStack().getItem().getUnlocalizedName() + ".")); player.addChatComponentMessage(new TextComponentString(TextFormatting.AQUA + "It holds " + tileEntity.getAmount() + ".")); return true; } //Else will trigger only if item is not the correct one for the crate. else { //Print message assessing crate player.addChatComponentMessage(new TextComponentString(TextFormatting.RED + "This is not a " + heldItem.getUnlocalizedName() + " crate. It is a " + tileEntity.getItemStack().getItem().getUnlocalizedName() + " crate.")); return false; } } } And finally, the main class: @Mod(modid = Main.MODID, version = Main.VERSION) public class Main { public static final String MODID = "CrateMod"; public static final String VERSION = "1.0"; public static void init() { GameRegistry.registerTileEntity(CrateTileEntity.class, "Crate tile entity"); } @EventHandler public static void init(FMLInitializationEvent event) { CrateBlock block = new CrateBlock(); } }
May 22, 20169 yr Author Whoops, sorry, the previous post was incomplete. Here's the crash report I keep getting: ---- Minecraft Crash Report ---- // Surprise! Haha. Well, this is awkward. Time: 5/22/16 12:21 PM Description: Ticking player java.lang.NullPointerException: Ticking player at net.minecraft.world.World.getBlockState(World.java:906) at net.minecraft.world.World.isMaterialInBB(World.java:2383) at net.minecraft.entity.Entity.isInLava(Entity.java:1306) at net.minecraft.entity.Entity.onEntityUpdate(Entity.java:536) at net.minecraft.entity.EntityLivingBase.onEntityUpdate(EntityLivingBase.java:252) at net.minecraft.entity.Entity.onUpdate(Entity.java:427) at net.minecraft.entity.EntityLivingBase.onUpdate(EntityLivingBase.java:2078) at net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:252) at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:339) at net.minecraft.network.NetHandlerPlayServer.update(NetHandlerPlayServer.java:174) at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.update(NetworkDispatcher.java:196) at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:307) at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:195) at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:802) at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:683) at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:155) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:532) at java.lang.Thread.run(Thread.java:745) A detailed walkthrough of the error, its code path and all known details is as follows: --------------------------------------------------------------------------------------- -- Head -- Stacktrace: at net.minecraft.world.World.getBlockState(World.java:906) at net.minecraft.world.World.isMaterialInBB(World.java:2383) at net.minecraft.entity.Entity.isInLava(Entity.java:1306) at net.minecraft.entity.Entity.onEntityUpdate(Entity.java:536) at net.minecraft.entity.EntityLivingBase.onEntityUpdate(EntityLivingBase.java:252) at net.minecraft.entity.Entity.onUpdate(Entity.java:427) at net.minecraft.entity.EntityLivingBase.onUpdate(EntityLivingBase.java:2078) at net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:252) -- Player being ticked -- Details: Entity Type: null (net.minecraft.entity.player.EntityPlayerMP) Entity ID: 110 Entity Name: Player464 Entity's Exact location: 142.12, 80.00, 415.89 Entity's Block location: World: (142,80,415), Chunk: (at 14,5,15 in 8,25; contains blocks 128,0,400 to 143,255,415), Region: (0,0; contains chunks 0,0 to 31,31, blocks 0,0,0 to 511,255,511) Entity's Momentum: 0.00, -0.08, 0.00 Entity's Passengers: [] Entity's Vehicle: ~~ERROR~~ NullPointerException: null Stacktrace: at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:339) at net.minecraft.network.NetHandlerPlayServer.update(NetHandlerPlayServer.java:174) at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.update(NetworkDispatcher.java:196) at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:307) -- Ticking connection -- Details: Connection: net.minecraft.network.NetworkManager@2dbcb696 Stacktrace: at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:195) at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:802) at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:683) at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:155) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:532) at java.lang.Thread.run(Thread.java:745) -- System Details -- Details: Minecraft Version: 1.9 Operating System: Windows 10 (amd64) version 10.0 Java Version: 1.8.0_91, Oracle Corporation Java VM Version: Java HotSpot 64-Bit Server VM (mixed mode), Oracle Corporation Memory: 411156400 bytes (392 MB) / 983564288 bytes (938 MB) up to 1888485376 bytes (1801 MB) JVM Flags: 0 total; IntCache: cache: 0, tcache: 0, allocated: 12, tallocated: 94 FML: MCP 9.23 Powered by Forge 12.16.1.1892 8 mods loaded, 8 mods active States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored UCHIJAAAA mcp{9.19} [Minecraft Coder Pack] (minecraft.jar) UCHIJAAAA FML{8.0.99.99} [Forge Mod Loader] (forgeSrc-1.9-12.16.1.1892.jar) UCHIJAAAA Forge{12.16.1.1892} [Minecraft Forge] (forgeSrc-1.9-12.16.1.1892.jar) UCHIJAAAA BlocksMods{1.0} [blocksMods] (modid-1.0.jar) UCHIJAAAA examplemod{1.0} [Example Mod] (modid-1.0.jar) UCHIJAAAA CommandMods{1.0} [CommandMods] (modid-1.0.jar) UCHIJAAAA CrateMod{1.0} [CrateMod] (modid-1.0.jar) UCHIJAAAA myMods{1.0} [myMods] (modid-1.0.jar) Loaded coremods (and transformers): GL info: ~~ERROR~~ RuntimeException: No OpenGL context found in the current thread. Profiler Position: N/A (disabled) Player Count: 1 / 8; [EntityPlayerMP['Player464'/110, l='Copy of New World', x=142.12, y=80.00, z=415.89]] Type: Integrated Server (map_client.txt) Is Modded: Definitely; Client brand changed to 'fml,forge' I thought about using getDescriptionPacket or onDataPacket, but I tried learning them on my own, and tutorials I've been looking at are pretty out-of-date. If anyone could help me out with understanding these methods, or point me to a good tutorial on them, I would be grateful.
May 22, 20169 yr Your crash report shows you are on 1.9, but this does not match up with your block class. onBlockActivated does not return a boolean in 1.9. Uhmm, for me it does... maybe not in 1.9.4, but 1.9 it does. Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support. 1.12 -> 1.13 primer by williewillus. 1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support. http://www.howoldisminecraft1710.today/
May 23, 20169 yr Author So I got rid of the implementation, removed the isBlockContainer, removed the removeTileEntity, registered the tile entity in the main (and set the registration name to the MODID). When the program runs, it now crashes with a null pointer exception when the Crate block is right-clicked. Here's the updated code for the CrateBlock class: http://pastebin.com/tWkDJ7yg Here's the update code for the CrateTileEntity class: http://pastebin.com/t8ie1G67 And here's the crash report: ---- Minecraft Crash Report ---- // I bet Cylons wouldn't have this problem. Time: 5/22/16 7:05 PM Description: Unexpected error java.lang.NullPointerException: Unexpected error at crate.CrateBlock.onBlockActivated(CrateBlock.java:128) at net.minecraft.client.multiplayer.PlayerControllerMP.processRightClickBlock(PlayerControllerMP.java:439) at net.minecraft.client.Minecraft.rightClickMouse(Minecraft.java:1597) at net.minecraft.client.Minecraft.processKeyBinds(Minecraft.java:2268) at net.minecraft.client.Minecraft.runTickKeyboard(Minecraft.java:2052) at net.minecraft.client.Minecraft.runTick(Minecraft.java:1840) at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1114) at net.minecraft.client.Minecraft.run(Minecraft.java:401) at net.minecraft.client.main.Main.main(Main.java:118) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) at net.minecraft.launchwrapper.Launch.main(Launch.java:28) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) at GradleStart.main(GradleStart.java:26) Based on the report, the error must occur because the getTileEntity(world, pos) in the CrateBlock class is returning a null. However, I am unclear as to how to improve the code.
May 23, 20169 yr Override Block#hasTileEntity(IBlockState) , not the deprecated Block#hasTileEntity() . Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
May 23, 20169 yr Author That makes sense, but I'm still lost at what I should replace the method body with, since I'm not sure how to check whether or not the block does indeed contain a tile entity...
May 23, 20169 yr If your block always has a TileEntity , simply return true . If it depends on the state, use the IBlockState argument to determine the return value. Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
May 23, 20169 yr Author It does not crash now, but the data members of the crates are not saved when the game is exited. Any ideas on how to proceed? I thought writing and reading from the NBT would solve the problem, but I guess not... Here's the code for the CrateTileEntity: http://pastebin.com/t8ie1G67 By the way, thank you to everyone for your help so far!
May 23, 20169 yr Don't save the item using its unlocalised name, use its registry name ( IForgeRegistryEntry#getRegistryName , inherited by Item ). This is the name used by Item.getByNameOrId . Why not store the item as an ItemStack or a 1-slot IItemHandler ? Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
May 24, 20169 yr Author The block works great now. Thank you for your time. P.S. I don't know. I just never considered using an ItemStack for the variable, since I thought I wouldn't need it.
May 24, 20169 yr Author The block works great now. Thank you for your time. P.S. I don't know. I just never considered using an ItemStack for the variable, since I thought I wouldn't need it.
May 24, 20169 yr So I ...set the registration name to the MODID I think you should include the MODID in the reg name, but you probably shouldn't use that as your whole name. The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.
May 24, 20169 yr So I ...set the registration name to the MODID I think you should include the MODID in the reg name, but you probably shouldn't use that as your whole name. The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.
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.