Question 1.19.4 Problem with ProtocolLib block break animations and Bukkit.getScheduler()

lollolcheese123

New member
May 27, 2023
12
0
1
This is basically two questions in one, so I'll split this post up into two parts.

I am trying to make a block breaking system that is almost identical to the one that Hypixel Skyblock uses, however with my current code I run into two problems.
Code: package lollolcheese123.zenofgens.blocks; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.wrappers.BlockPosition; import lollolcheese123.zenofgens.items.itemInit; import lollolcheese123.zenofgens.main; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockDamageAbortEvent; import org.bukkit.event.block.BlockDamageEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; import java.util.HashMap; import java.util.Random; public class blockBreakHandler implements Listener { private final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager(); public HashMap<Location, Integer> blockBreakIDs = new HashMap<>(); public HashMap<Location, Integer> blockBreakStage = new HashMap<>(); public HashMap<Location, Integer> taskIDs = new HashMap<>(); public HashMap<Location, Integer> currentHardness = new HashMap<>(); @EventHandler private void blockBreakStart(BlockDamageEvent event) { if (event.getPlayer().getGameMode().equals(GameMode.CREATIVE)) return; event.setCancelled(true); // Check if the block is a custom block if (!blockHandler.customBlockTypes.containsKey(event.getBlock().getLocation())) { return; } // Set useful values Location loc = event.getBlock().getLocation(); String blockType = blockHandler.customBlockTypes.get(loc); ItemStack item = event.getItemInHand(); // Check if you are breaking the block with the right tool if (!blockHandler.reqBreakingType.get(blockType).equalsIgnoreCase(itemInit.breakingType.get(item))) { if (!event.getPlayer().getGameMode().equals(GameMode.CREATIVE)) { event.setCancelled(true); event.getPlayer().sendMessage("§cThis isn't the right tool!"); } return; } // Check if the tool has enough breaking power if (!(blockHandler.reqMinePower.get(blockType) <= itemInit.breakingPower.get(item))) { if (!event.getPlayer().getGameMode().equals(GameMode.CREATIVE)) { event.setCancelled(true); event.getPlayer().sendMessage("§cThis tool isn't strong enough to break this block!"); event.getPlayer().sendMessage("§cYou need a breaking power of " + blockHandler.reqMinePower.get(blockType)); } return; } // Register the block to be in progress of being broken currentHardness.put(loc, blockHandler.blockHardness.get(blockType)); // Assign an EntityID for the block breaking animation int entityID = new Random().nextInt(blockBreakIDs.size() + 1); while (blockBreakIDs.containsValue(entityID)) entityID = new Random().nextInt(blockBreakIDs.size() + 1); blockBreakIDs.put(loc, entityID); // Start the breaking process blockBreakStage.put(loc, 0); taskIDs.put(loc, Bukkit.getScheduler().scheduleSyncRepeatingTask(main.getProvidingPlugin(main.class), () -> { // Decrease the hardness currentHardness.replace(loc, currentHardness.get(loc) - (itemInit.breakingSpeed.get(item) + itemInit.breakingSpeed.get(item) * (itemInit.breakingPower.get(item) - blockHandler.reqMinePower.get(blockType)) / 10)); // Update block break animation if (currentHardness.get(loc) % (blockHandler.blockHardness.get(blockType) / 9) == 0) { blockBreakStage.replace(loc, blockBreakStage.get(loc) + 1); // Create the packet PacketContainer minePacket = protocolManager.createPacket(PacketType.Play.Server.BLOCK_BREAK_ANIMATION); minePacket.getIntegers().write(0, blockBreakIDs.get(loc)); BlockPosition blockPosition = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); minePacket.getBlockPositionModifier().write(0, blockPosition); minePacket.getIntegers().write(1, event.getBlock().getType().getId()); minePacket.getIntegers().write(2, blockBreakStage.get(loc)); // Send the packet try { protocolManager.sendServerPacket(event.getPlayer(), minePacket); } catch (Exception e) { e.printStackTrace(); } } // When block broken if (currentHardness.get(loc) <= 0) { event.getPlayer().getInventory().addItem(itemInit.itemDrop.get(blockType)); event.getBlock().setType(Material.AIR); Bukkit.getScheduler().cancelTask(taskIDs.get(loc)); // Delete block breaking values taskIDs.remove(loc); currentHardness.remove(loc); blockBreakIDs.remove(loc); blockBreakStage.remove(loc); } }, 1, 1)); } @EventHandler private void blockBreakStop(BlockDamageAbortEvent event) { // Check if the block has an EntityID if (!blockBreakIDs.containsKey(event.getBlock().getLocation())) return; // Set useful values Block block = event.getBlock(); Location loc = block.getLocation(); int breakerID = blockBreakIDs.get(loc); BlockPosition blockPosition = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); // Create the packet PacketContainer minePacket = protocolManager.createPacket(PacketType.Play.Server.BLOCK_BREAK_ANIMATION); minePacket.getIntegers().write(0, breakerID); minePacket.getBlockPositionModifier().write(0, blockPosition); minePacket.getIntegers().write(1, block.getType().getId()); minePacket.getIntegers().write(2, 0); // Cancel the block breaking Bukkit.getScheduler().cancelTask(taskIDs.get(loc)); // Send the packet try { protocolManager.sendServerPacket(event.getPlayer(), minePacket); } catch (Exception e) { e.printStackTrace(); } // Delete block breaking values taskIDs.remove(loc); currentHardness.remove(loc); blockBreakIDs.remove(loc); blockBreakStage.remove(loc); } @EventHandler private void blockBroken(BlockBreakEvent event) { if (!event.getPlayer().getGameMode().equals(GameMode.CREATIVE)) event.setCancelled(true); } @EventHandler private void blockPlaced(BlockPlaceEvent event) { if (!event.getPlayer().getGameMode().equals(GameMode.CREATIVE)) event.setCancelled(true); } }

With this code, it's supposed to take the custom breaking power and speed of the tool that you are using, and then compare that with the required breaking power and the "hardness" of the block that you are mining, while also playing the breaking animation on the block, and then also stop the mining process when it's broken (this is in the BlockDamageEvent event).

Inside of the BlockDamageAbort event it should cancel the mining process on that block if the process had existed.

However, (as I stated before) two things go wrong.
1. For the block breaking animation, I need the blockId. However, block.getType().getId() doesn't work on modern materials, and I'll get an error message telling me so.
2. The Bukkit.getScheduler().cancelTask(taskIDs.get(loc)); code never actually cancels the scheduledSyncRepeatingTask that I created.

How can I fix these bugs?

Edit: Yes, I referenced this class in my main class with this code: Bukkit.getServer().getPluginManager().registerEvents(new blockBreakHandler(), this);