Jump to content

Recommended Posts

Posted

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();

    }
}

Posted

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.

Posted

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/

Posted

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.

Posted

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.

Posted

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.

Posted

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!

Posted

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.

Posted

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.

Posted

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.

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



×
×
  • Create New...

Important Information

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