Jump to content

Recommended Posts

Posted

Hi. I posted a couple of days ago about delaying the deletion of a block and its tile entity until after the drops were picked up by the player. Diesieben pointed me in the right direction (thanks).

 

The solution has created a small problem for me: I am getting two drops when I break the block. When I comment out removedByPlayer, I get only one. Printlns indicate removedByPlayer is being called once on the server side with willHarvest = true, and once on the client side with willHarvest = false.

 

Here is my getDrops, removedByPlayer, and harvestBlock:

 

 

 

@Override
public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune) {
	List<ItemStack> itemStacks = super.getDrops(world, pos, state, fortune);
	TileEntity te = world.getTileEntity(pos);
	if (te == null) {
		System.out.println("Could not write path to tag. te=" + te);
		return itemStacks;
	}
	if (!(te instanceof BlockSavedTileEntity)) {
		System.out.println("Could not write path to tag. TileEntity not a BlockSavedTileEntity. te=" + te);
		return itemStacks;
	}

	String path = ((BlockSavedTileEntity) te).getPath();
	ItemStack stack = new ItemStack(this);
	NBTTagCompound tag = new NBTTagCompound();
	stack.setTagCompound(tag);
	((BlockSavedTileEntity) te).writeToNBT(tag);
	itemStacks.add(stack);
	return itemStacks;
}

// FIXME creates two drops
@Override
public boolean removedByPlayer(World world, BlockPos pos, EntityPlayer player, boolean willHarvest) {
	System.out.println("world=" + world);
	System.out.println("willHarvest=" + willHarvest);
	if (willHarvest) {
		// Delay deletion of the block until after getDrops
		return true;
	}
	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);
}

 

 

 

Here is my console:

 

[10:30:53] [Client thread/INFO] [sTDOUT]: [org.snowyegret.mojo.block.BlockSaved:removedByPlayer:132]: world=net.minecraft.client.multiplayer.WorldClient@77e55368
[10:30:53] [Client thread/INFO] [sTDOUT]: [org.snowyegret.mojo.block.BlockSaved:removedByPlayer:133]: willHarvest=false
[10:30:53] [server thread/INFO] [sTDOUT]: [org.snowyegret.mojo.block.BlockSaved:removedByPlayer:132]: world=net.minecraft.world.WorldServer@6caed19b
[10:30:53] [server thread/INFO] [sTDOUT]: [org.snowyegret.mojo.block.BlockSaved:removedByPlayer:133]: willHarvest=true

 

For reference, here are BlockFlowerPot's overrides of the three methods:

 

 

    /*============================FORGE START=====================================*/
    @Override
    public java.util.List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
    {
        java.util.List<ItemStack> ret = super.getDrops(world, pos, state, fortune);
        TileEntityFlowerPot te = world.getTileEntity(pos) instanceof TileEntityFlowerPot ? (TileEntityFlowerPot)world.getTileEntity(pos) : null;
        if (te != null && te.getFlowerPotItem() != null)
            ret.add(new ItemStack(te.getFlowerPotItem(), 1, te.getFlowerPotData()));
        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);
    }
    /*===========================FORGE END==========================================*/

 

 

Posted

you should only create the drops on the serverside.

 

Just do a check to see if !world.isRemote() and only run if that is the case.

Long time Bukkit & Forge Programmer

Happy to try and help

Posted

Block#getDrops

adds the return of

getItemDropped

(which is the

Item

form of the

Block

by default) to the drops list, so you're adding the same drop again with the NBT.

 

Override

getItemDropped

to return

null

and prevent the drop without the NBT from being added.

 

 

Side note: if you create a compound tag with the key

"BlockEntityTag"

in an

ItemStack

's compound tag and your

Block

has a

TileEntity

,

ItemBlock

will call

TileEntity#readFromNBT

with it after placing the

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.

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.