1.14.4 Setting blocks instantly without sinking into them?

Discussion in 'Spigot Plugin Development' started by Sean0402, Jan 28, 2020.

  1. Hey all, I was wondering, how do you set blocks instantly without a delay like this;

    https://imgur.com/MNQ6QZt

    CosmicPrisons example:
    https://imgur.com/VVXf3sm


    See how I sink a little in the first one compared to the second one? How do you get such a smooth block break event? (If it is that)
     
  2. You just set the block type to a new one, cancel the break event and drop an item. As simple as that.
     
  3. That makes it as smooth as they done it?
     
  4. I can't think of a smoother way, will test it and tell you!
     
  5. Just tested myself. It isn't as smooth with the basic code of;
    Code (Java):
    @EventHandler
        public void onBreak(BlockBreakEvent e) {
            if (e.getBlock().getType() == Material.DIAMOND_ORE) {
                e.setCancelled(true);
                e.getBlock().setType(Material.STONE);
            }
        }
     
  6. Code (Java):

    @EventHandler
    public void onBlockPlace(BlockBreakEvent event) {
        final Block block = event.getBlock();
        final Location location = block.getLocation();
        location.getBlock().getDrops().forEach(itemStack ->
                location.getWorld().dropItemNaturally(location, itemStack));

        if (block.getType().equals(Material.STONE)) {
            block.setType(Material.DIRT);
        } else if (block.getType().equals(Material.DIRT){
            block.setType(Material.STONE);
        }

        event.setCancelled(true);
    }
     
    This seems to work fine and smooth for me
     
  7. Whatsover I don't see better way except playing with packets and etc..
     
  8. Strahan

    Benefactor

    Works fine for me, like in the video. Granted, I'm not dropping anything but that's not relevant to the break/replace.
    Code (Text):
    @EventHandler
    public void obb(BlockBreakEvent e) {
      if (e.getBlock().getType() != Material.IRON_ORE) return;
       
      e.setCancelled(true);
      e.getBlock().setType(Material.STONE);
    }
     
  9. I can see the delay in it, the split like, half a second before it turns to stone.Do you know of any packets or any other ways?
    EDIT: Look at the Gifs carefully. You can see the difference clear. One has a drop in my player, the other on doesn't
     
  10. I think you can do it with BlockDamageEvent. When it's close to breaking, you just replace the block and cancel the event and drop.
     
  11. Not a bad idea. I may look around at that
     
  12. Strahan

    Benefactor

    Yea, once I played the video and went frame by frame I see what you mean. Half a second is a bit much, it's really around three hundredths of a second, but definitely not the same as the original example you posted.

    How does one determine when it's close to breaking? I don't see a damage count in there.
     
  13. https://wiki.vg/Protocol#Player_Digging
     
    • Like Like x 1
    • Useful Useful x 1
  14. The problem that you're facing, is that Bukkit tells the player that the block has been destoryed, even if the BlockBreakEvent has been cancelled, it sends the packet setting it to air, before BBE is called.

    Only way I can think to get around this is either use something like ProtocolLib to catch and cancel/change it, or you modify the server (probably out of scope) to add another event. Obviously you could also catch it before it breaks and send the break animation yourself, as suggested above.
     
    • Agree Agree x 1