Solved Player "spazzes out" on BlockBreakEvent

Discussion in 'Plugin Development' started by plisov, Aug 28, 2019.

Thread Status:
Not open for further replies.
  1. Offline

    plisov

    Hi all,

    I'm currently working on a custom enchantment plugin and have come across an unusual bug I have no clue on how to fix. It just started happening recently and I'm not too sure what I changed for it to act the way it is. I have a simple class shown below
    Code:
    package me.plisov.customenchantments.enchantments.rare;
    
    import java.util.Random;
    
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.Sound;
    import org.bukkit.block.Block;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    
    public class Treasure implements Listener {
        @EventHandler
        public void onBlockBreak(BlockBreakEvent event) {
            Player player = event.getPlayer();
            Block minedBlock = event.getBlock();
            ItemStack item = player.getInventory().getItemInMainHand();
            ItemMeta meta = item.getItemMeta();
    
            Random random = new Random();
            int chance = random.nextInt(100) + 1;
            if ((meta.getLore().contains(ChatColor.GOLD + "Treasure 1") && chance >= 98)
                    || (meta.getLore().contains(ChatColor.GOLD + "Treasure 2") && chance >= 96)
                    || (meta.getLore().contains(ChatColor.GOLD + "Treasure 3") && chance >= 94)
                    || (meta.getLore().contains(ChatColor.GOLD + "Treasure 4") && chance >= 0)) {
                event.setCancelled(true);
                event.getBlock().setType(Material.GOLD_BLOCK);
                player.playSound(minedBlock.getLocation(), Sound.BLOCK_ANVIL_LAND, 10, 0);
            }
        }
    }
    
    which, in theory, should cancel the breaking of a block, play a sound and set the block to a golden block. It does all of that perfectly well except every time the block breaks, it causes the player's view to jump back to the block that was just broken. So in other words it sets the player's cursor to be looking at the block that was just broken. I have done some testing and even removed all other classes except this one from my project and still, it seems that it's only on the BlockBreakEvent. There is one thing that I found that fixes the problem, though it's not the most optimal way of fixing it. If I remove
    Code:
    event.getBlock().setType(Material.GOLD_BLOCK);
    the bug goes away, though it breaks the block and drops the golden block without first setting the broken block to the golden block.

    Any help is much appreciated!
     
  2. Offline

    CraftCreeper6

    @plisov
    I imagine it has something to do with cancelling the event. Remove that and see what happens.
     
  3. Offline

    plisov

    Hey @CraftCreeper6
    I have also tried removing the setCancelled and that does fix the problem however it breaks the block and drops the gold block instead of setting the block to the gold block for it to be broken again.
     
  4. Offline

    CraftCreeper6

    @plisov
    Try moving the set cancelled to after you play the sound.
     
  5. Offline

    plisov

    @CraftCreeper6
    Same thing happens where it moves the player's cursor to the block.
     
  6. Offline

    Strahan

    Odd, it seems to work fine for me. Hard to see if it snaps my view back because I have to be looking at the block to break it anyway, unless I'm misunderstanding what the problem is.

    That aside, you should be verifying the item in hand actually has lore before checking it else you'll throw NPE. Also there is no need to do the check for T4.. >= 0 just means always do it as the random won't be negative.

    PS also I'd try to avoid hardcoding values that you may want to change later, like the percentage thresholds. I'd switch to using config, like:

    Code:
    @EventHandler
    public void onBlockBreak(BlockBreakEvent event) {
      int treasurePct = getTreasurePct(event.getPlayer());
      if (treasurePct == -1) return;
    
      if ((new Random().nextInt(100) + 1) < (100 - treasurePct)) return;
    
      event.setCancelled(true);
      event.getBlock().setType(Material.GOLD_BLOCK);
      event.getPlayer().playSound(event.getBlock().getLocation(), Sound.BLOCK_ANVIL_LAND, 10, 0);
    }
    
    int getTreasurePct(Player p) {
      ItemStack item = p.getInventory().getItemInMainHand();
      if (!item.hasItemMeta()) return -1;
    
      ItemMeta meta = item.getItemMeta();
      if (!meta.hasLore()) return -1;
    
      for (String lore : meta.getLore()) {
          if (!lore.contains(ChatColor.GOLD + "Treasure ")) continue;
          return getConfig().getInt("config.treasurelevels." + ChatColor.stripColor(lore).replaceAll("[^0-9]",""), -1);
      }
    
      return -1;
    }
    
    ...with a config like:
    
    config:
      treasurelevels:
        '1': 2
        '2': 4
        '3': 6
        '4': 100
     
    Last edited: Aug 28, 2019
  7. Offline

    CraftCreeper6

    @plisov
    This could potentially have something to do with client side lag. Do you notice any drop in frame rate when mining a block?
     
  8. Offline

    plisov

    @Strahan
    That's very odd that you're not getting the same bug as me. The snapping wasn't too hard to spot so I assume it's just my project? The T4 >= 0 was for testing purposes only. I'll try to make a completely new project and see if I get the same bug there. I'll also look into adding a config, thanks!

    @CraftCreeper6
    I don't think it's client side lag because I tried mining with a regular pickaxe and everything was working great. It only happened with pickaxes which had a custom enchantment on them.
     
  9. Offline

    CraftCreeper6

    @plisov
    The pickaxes with custom enchantments could be causing the lag.
     
  10. Offline

    plisov

    @Strahan
    After doing a bit more testing I've noticed that for this specific enchantment, the player isn't snapped back to the block but is rather lagged back. I'm curious if you could recreate this bug. Try going into creative mode and break blocks with the pickaxe while also moving around or alternatively enchant the pickaxe with efficiency 5.

    @CraftCreeper6
    I'm almost certain it's not lag because once the block is broken, it does drop but the player is lagged back or snapped to the broken block.
     
  11. Offline

    CraftCreeper6

    @plisov
    Could be client side, have you had anyone else test this?
     
  12. Offline

    Strahan

    What MC version are you targeting with this plugin?
     
  13. Offline

    DerDonut

    So I remember seeing this bug a few days ago, version 1.14.4. Anyways I'm pretty sure is client-side but I am still working on recreating it
     
  14. Offline

    plisov

    @CraftCreeper6
    I haven't had anyone else test it yet.

    @Strahan
    Version 1.14.4 currently.

    UPDATE
    After more testing I've come to the conclusion that it is a 1.14.4 bug just how @DerDonut predicted. I've changed over to 1.14 and the bug seems to have stopped.
    Thanks for the help guys, much appreciated!
     
    Last edited: Sep 1, 2019
Thread Status:
Not open for further replies.

Share This Page