1.16.x How to detect torch break by breaking holding block etc.

Discussion in 'Spigot Plugin Development' started by Hanssc, Jul 23, 2020.

  1. Hi!
    Is there any way to detect torch or saplings break by breaking holding block or flowing water?
    I tried BlockBreakEvent to check if there is a torch attached to this block and BlockPhysicsEvent.
    Both of them works incorrectly.
    Thx
     
  2. Sorry i may have mis understood, but you want to detect water breaking a torch? Use on block change event, if you mean breaking a block and see if there is a torch nearby, get all sides and loop them and check if the block is a torch. Source code could be really helpful
     
  3. You should use BlockFromToEvent.

    If this does not work, off the top of my head you use BlockBreakEvent and scan all blocks (left, right, up) to see if there is water, probably not the most efficient way and it might be finicky.

    See this thread from Bukkit: https://bukkit.org/threads/water-and-torches.93049/
     
  4. Yeah, I want to detect both of them. Flowing water and breaking holding block.
    But checking if the nearby block is a torch is not a good way. Players can use piston to move the block.
    If check all the blocks moved by piston, it may cause a huge performance loss.
     
  5. Thx, I solved it in some cases.
    But about the piston, is there any efficient way to detect ?

    Test Code
    Code (Java):
    @EventHandler
        public void onBlockFromTo(BlockFromToEvent e) {
            if (e.getToBlock().getType() == Material.TORCH || e.getToBlock().getType() == Material.WALL_TORCH) {
                e.setCancelled(true);
            }
        }

        @EventHandler
        public void onBlockFromTo(BlockBreakEvent e) {
            BlockFace[] blockFaces = new BlockFace[]{BlockFace.UP, BlockFace.WEST, BlockFace.EAST, BlockFace.SOUTH, BlockFace.NORTH};
            boolean flag = Arrays.stream(blockFaces)
                    .anyMatch((f) -> e.getBlock().getRelative(f).getType() == Material.TORCH || e.getBlock().getRelative(f).getType() == Material.WALL_TORCH);
            if (flag) {
                e.setCancelled(true);
            }
        }

        @EventHandler
        public void onBlockPiston(BlockPistonExtendEvent e) {
            BlockFace[] blockFaces = new BlockFace[]{BlockFace.UP, BlockFace.WEST, BlockFace.EAST, BlockFace.SOUTH, BlockFace.NORTH};
            boolean flag = e.getBlocks().stream()
                    .anyMatch((b) -> Arrays.stream(blockFaces).anyMatch((f) -> e.getBlock().getRelative(f).getType() == Material.TORCH || e.getBlock().getRelative(f).getType() == Material.WALL_TORCH));
            if (flag) {
                e.setCancelled(true);
            }
        }
     
  6. No I don't think so.
     
  7. Code (Java):
       
    @EventHandler
    public void onBlockFromTo(BlockFromToEvent e) {
        if (e.getToBlock().getType() == Material.TORCH || e.getToBlock().getType() == Material.WALL_TORCH) {
            e.setCancelled(true);
        }
    }

    @EventHandler
    public void onBlockBreak(BlockBreakEvent e) {
        if (e.getBlock().getType() == Material.TORCH || e.getBlock().getType() == Material.WALL_TORCH) {
            return;
        }
        if (e.getBlock().getRelative(BlockFace.UP).getType() == Material.TORCH) {
            e.setCancelled(true);
            return;
        }
        BlockFace[] blockFaces = new BlockFace[]{BlockFace.WEST, BlockFace.EAST, BlockFace.SOUTH, BlockFace.NORTH};
        boolean flag = Arrays.stream(blockFaces)
                .anyMatch((f) -> e.getBlock().getRelative(f).getType() == Material.WALL_TORCH);
        if (flag) {
            e.setCancelled(true);
        }
    }

    @EventHandler
    public void onBlockPistonExtend(BlockPistonExtendEvent e) {
        BlockFace[] blockFaces = new BlockFace[]{BlockFace.WEST, BlockFace.EAST, BlockFace.SOUTH, BlockFace.NORTH};
        boolean flag = e.getBlocks().stream()
                .anyMatch((b) -> {
                    if (b.getRelative(BlockFace.UP).getType() == Material.TORCH) {
                        return true;
                    }
                    return Arrays.stream(blockFaces).anyMatch((f) -> b.getRelative(f).getType() == Material.WALL_TORCH);
                });
        if (flag) {
            e.setCancelled(true);
        }
    }

    @EventHandler
    public void onBlockPistonRetract(BlockPistonRetractEvent e) {
        BlockFace[] blockFaces = new BlockFace[]{BlockFace.WEST, BlockFace.EAST, BlockFace.SOUTH, BlockFace.NORTH};
        boolean flag = e.getBlocks().stream()
                .anyMatch((b) -> {
                    if (b.getRelative(BlockFace.UP).getType() == Material.TORCH) {
                        return true;
                    }
                    return Arrays.stream(blockFaces).anyMatch((f) -> b.getRelative(f).getType() == Material.WALL_TORCH);
                });
        if (flag) {
            e.setCancelled(true);
        }
    }
     
    I made some changes.
    Now, it works well. The only problem is performance I think.
     
    #7 Hanssc, Jul 23, 2020
    Last edited: Jul 23, 2020
  8. Maybe detect block break by piston ? If thats a thing
     
  9. I tried it, it not works. I think I should stick to this way until it suffers a considerable lag.
     
  10. As nobody has suggested it: BlockPhysicsEvent. The torch is broken by physic updates triggered by the blocks around it. Using #getChangedType() you can see if a torch was broken due to updated physics. I am not fully sure if this event is also called when you break a torch manually. If so, you can exclude those by looking at #getSourceBlock() (make sure it is not a torch).