Jump to content

[SOLVED] [1.8] Container that keeps inventory when broken


Recommended Posts

Posted

I am trying to create a container that keeps its inventory when broken. I have the tile entity and container block created. I can place and break the container as expected. I just want it to maintain its inventory when broken, so its contents aren't spilled out and when I re-place the container, its inventory is the same as when it was broken. I've done some searching and haven't really found anything.

 

Any ideas how to do this? What methods do I need to be looking at? I know the breakBlock method is what causes the container's contents to spill out when the container is broken. Do I override it?

Posted

You need to keep the tile alive and not destroy it when you destroy the block then store the tile somewhere and replace it on the map when you place the block.

 

Generally tile is placed in the same location as the parent block.

 

I have to do this for a Locked Chest mechanic so I gotta figure this out as well.

Disclaimer:  I been told to keep my opinions to myself, to shut up and that I am spreading lies and misinformation or even that my methods are unorthodox and or too irregular. Here are my suggestions take it or leave it.

Posted

No no no, don't do that at all!

 

When the block is broken save the TE's data to the dropped item!  Then when the block is placed again, do the reverse.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

First you need to delay the removal of the

TileEntity

by overriding

Block#removedByPlayer

and

Block#harvestBlock

like

BlockFlowerPot

does in Forge's patch.

 

Then you need to override

Block#getDrops

to create an

ItemStack

of the

Item

to drop and write the

TileEntity

's NBT to the

"BlockEntityTag"

sub-compound of the

ItemStack

's compound tag.

 

Minecraft will automatically read your

TileEntity

from the

"BlockEntityTag"

sub-compound of the

ItemStack

used to place your block.

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

I will have to do this so if this post is still unsolved I will report here my findings. I will HAVE to do it. So I will do it (eventually)

Disclaimer:  I been told to keep my opinions to myself, to shut up and that I am spreading lies and misinformation or even that my methods are unorthodox and or too irregular. Here are my suggestions take it or leave it.

Posted

Thank you, Choonster, that worked! It took me a while to figure out how to use the "BlockEntityTag" sub-compound. Google ended up taking me to a couple other posts you made to help out other folks. :) I ended up having to also override getItemDropped to prevent two copies of the container from dropping when broken.

 

Finished code, for the record:

// Keep inventory when block is broken
    @Override
    public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
    {
    	List<ItemStack> ret = super.getDrops(world, pos, state, fortune);
        PrimalTileEntity te = world.getTileEntity(pos) instanceof PrimalTileEntity ? (PrimalTileEntity)world.getTileEntity(pos) : null;
        if (te != null && Item.getItemFromBlock(state.getBlock()) != null) {
        	ItemStack stack = new ItemStack(this);
        	NBTTagCompound tag = new NBTTagCompound();
        	NBTTagCompound tagCompound = new NBTTagCompound();
        	te.writeToNBT(tag);
        	tagCompound.setTag("BlockEntityTag", tag);
        	stack.setTagCompound(tagCompound);
        	ret.add(stack);
        }
        return ret;
    }
    @Override
    public boolean removedByPlayer(World world, BlockPos pos, EntityPlayer player, boolean willHarvest)
    {
        if (willHarvest) return true; //If it will harvest, delay deletion of the block until after getDrops
        return super.removedByPlayer(world, pos, player, willHarvest);
    }
    @Override
    public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, TileEntity te)
    {
        super.harvestBlock(world, player, pos, state, te);
        world.setBlockToAir(pos);
    }
    @Override
    public Item getItemDropped(IBlockState state, Random rand, int fortune) {
        return null;
}

Posted

Instead of overriding

Block#getItemDropped

and calling

super.getDrops

, just create the

List

to return from

getDrops

yourself.

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.

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.