Destroy blocks after placing them with an Animation

Discussion in 'Spigot Plugin Development' started by Flortex, Dec 6, 2018 at 8:54 PM.

  1. I have a problem with a BuildFFA plugin. When a player sets a block, a dismantling animation should start and dismantling the block afterwards. The animation works for one block, but not for multiple blocks (it jumps from one block to another).

    Here is my code:

    Code (Text):
    public class BreakBlockListener implements Listener {

        @EventHandler
        public void onBlockPlace(BlockPlaceEvent e) {

            if (!(Build_CMD.build.contains(e.getPlayer()))) {
                if (e.getBlock().getType().equals(Material.SANDSTONE)) {

                    Block b = e.getBlock();

                    new BukkitRunnable() {
                        int i = 0;

                        @Override
                        public void run() {

                            if (i == 0 || i == 1 || i == 2 || i == 3 || i == 4 || i == 5 || i == 6 || i == 7) {

                                PacketPlayOutBlockBreakAnimation packet = new PacketPlayOutBlockBreakAnimation(0, new BlockPosition(b.getX(), b.getY(), b.getZ()), i);
                                ((CraftPlayer) e.getPlayer()).getHandle().playerConnection.sendPacket(packet);

                            }

                            if(i== 8) {
                                PacketPlayOutBlockBreakAnimation packet = new PacketPlayOutBlockBreakAnimation(0, new BlockPosition(b.getX(), b.getY(), b.getZ()), i);
                                ((CraftPlayer) e.getPlayer()).getHandle().playerConnection.sendPacket(packet);
                                b.breakNaturally();
                                e.getPlayer().getWorld().playEffect(b.getLocation().subtract(0.5, 0, 0.5), Effect.LARGE_SMOKE, 20);
                            }

                            i++;
                        }

                    }.runTaskTimer(Main.getPlugin(Main.class), 60, 5);
                }
            }
        }
    }
    How can I fix this?
     
  2. It doesn't work because the task is sync. (so only one task can run at time)
    You could use BukkitSchedular#runTaskTimerAsynchronously but async tasks can't access any bukkit api which is a problem.

    EDIT: I'm an idiot... @Parozzz of course you're right, sorry.
     
    #2 Boy132, Dec 6, 2018 at 9:35 PM
    Last edited: Dec 6, 2018 at 10:03 PM
  3. What the heck are you saying? Async task doesn't do anything better here ...

    Is because, when sending the break animation packet, it also need an entity id to associate with the damage. In your code, you are always setting it to 0, and since there cannot be more than one block damaged by the same entity, it removes the old one.

    Code (Java):

    //                                                                   This zero VV here is your problem.
    PacketPlayOutBlockBreakAnimation packet = new PacketPlayOutBlockBreakAnimation(0, new BlockPosition(b.getX(), b.getY(), b.getZ()), i);
    What I suggest you is to create a counter, that reset when reaches max, but start at a big number, like 10000. It might create some interference with actual mobs, but chances are so slim I would not care.

    EDIT: I just read proof what @Boy123 said, and is not the truth. Running a task sync means that the code is scheduled in the main thread tick (After everything is done running), so multiple tasks can run, just not at the same time but one after another.
     
    • Agree Agree x 1
  4. 2008Choco

    Junior Mod

    >.> There are better ways to do this
    Code (Java):
    if (i >= 0 && i <= 7) {
        // Do your thing
    } else {
        // Do your other thing
    }
    i++;
     
    • Agree Agree x 3

  5. I donĀ“t know exactly what you mean. Can you explain it a bit more detailed? :confused:
     

Share This Page