Posted July 29, 201510 yr 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==========================================*/
July 29, 201510 yr 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
July 29, 201510 yr Author I have tried returning true, false, and super.removedByPlayer when world.isRemote, all with no effect (still two drops).
July 29, 201510 yr 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.