Solved BlockBreakEvent going on endlessly

Discussion in 'Plugin Development' started by DeathWizsh, Apr 10, 2015.

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

    DeathWizsh

    In order to allow my plugin to co-operate with protection plugins I changed the way my 3x3 mining breaks the blocks. Underneath is my current code. I'm still testing with one extra block wich is relative to the north of the block broken

    Code:
        
    @EventHandler
        public void heavyPickAxeEffect(BlockBreakEvent event) {
            Player player        = event.getPlayer();
            ItemStack itemInHand = player.getItemInHand();
            if(itemInHand.hasItemMeta() && itemInHand.getItemMeta().getLore() != null && itemInHand.getItemMeta().getLore().equals(DelzTools.loreHM)) {
                if(player.hasPermission("dt.*") || player.hasPermission("dt.pickaxe")) {
                    if(toolModeHM.containsKey(player.getName())) {
                        if(toolModeHM.get(player.getName()) == 0) {
                            Block mainBlock       = event.getBlock();
                            Material mainMaterial = mainBlock.getType();
                            boolean inList        = false;
                            for(Material materialList : DelzTools.listHM) {
                                if(materialList == mainMaterial) {
                                    inList = true;
                                    break;
                                }
                            }
                            if(inList = true) {
                                Block extraBlock = mainBlock.getRelative(BlockFace.NORTH);
                                BlockBreakEvent b1 = new BlockBreakEvent(extraBlock, player);
                                Bukkit.getServer().getPluginManager().callEvent(b1);
                                if(!b1.isCancelled()) {
                                    player.sendMessage("Block broken");
                                    b1.getBlock().breakNaturally();
                                    b1.setCancelled(true);
                                }
                            }
                        }
                    }
                }
            }
        }
    I call a new BlockBreakEvent called b1 and check if it is not cancelled, if not I break the block and try to cancel the event but it goes on breaking blocks endlessly. How can I make it stop?
     
  2. Offline

    WinX64

    If you meant to call the event manually if inList is true, then there's the problem.
    Code:
    if (inList = true) {
    You're assigning a new value for your inList variable instead of checking its value. That expression will always be evaluated as true, and the stop condition will never be met.
     
  3. Offline

    mine-care

    @DeathWizsh you are doing an endless recursion, umm i dont really understand what you try to do, are you trying to check if it is canceled by anthtign else? then play with the EventHandler anotation properties (priority, ignorecanceled) and/or with event#isCanceled();
    also
    ?????
    if(assigning boolean to value) ?? this is not a valid if condition, does this compile?
     
  4. Offline

    DeathWizsh

    I want to check some conditions.

    1: Item in hand is my custom tool.
    2: Player has permission for it.
    3: Check the toolmode the player is currently using for my custom tool. if == 0 its 3x3 mining, if == 1 its normal pickaxe behaviour.
    4: Check if the block broken has the same material as one in my list.

    if these conditions are met I want to break the block relative to North aswell.
    However to make it co-operate with protections plugins I need to call a new BlockBreakEvent.
    Its my first plugin and I've yet to learn how everything exactly works.

    How should I check my materials list instead of using this boolean?

    My new code, removed the boolean and for loop but still the same issue.
    Is it because I call the event b1 that it also recalls heavyPickAxeEffect?
    If so, how do I prevent this?

    Code:
        
    @EventHandler
        public void heavyPickAxeEffect(BlockBreakEvent event) {
            Player player        = event.getPlayer();
            ItemStack itemInHand = player.getItemInHand();
            if(itemInHand.hasItemMeta() && itemInHand.getItemMeta().getLore() != null && itemInHand.getItemMeta().getLore().equals(DelzTools.loreHM)) {
                if(player.hasPermission("dt.*") || player.hasPermission("dt.pickaxe")) {
                    if(toolModeHM.containsKey(player.getName())) {
                        if(toolModeHM.get(player.getName()) == 0) {
                            Block mainBlock       = event.getBlock();
                            Material mainMaterial = mainBlock.getType();
                            if(DelzTools.listHM.contains(mainMaterial)) {
                                Block extraBlock = mainBlock.getRelative(BlockFace.NORTH);
                                BlockBreakEvent b1 = new BlockBreakEvent(extraBlock, player);
                                Bukkit.getServer().getPluginManager().callEvent(b1);
                                if(!b1.isCancelled()) {
                                    player.sendMessage("Block broken");
                                    b1.getBlock().breakNaturally();
                                    b1.setCancelled(true);
                                }
                            }
                        }
                    }
                }
            }
        }
    Changed it to a PlayerInteractEvent, basicly same code as above and now it works properly.
    Seems indeed that the main event heavyPickAxeEffect is being recalled constantly
    However I want the other blocks to break after the one I clicked broke not on interact.
     
    Last edited by a moderator: Apr 10, 2015
  5. Offline

    Zombie_Striker

    did you Debug? Which line does not get read?
     
  6. Offline

    DeathWizsh

    All lines are read.

    It looks like the main Event is recalled, does this mean I cannot call another BlockBreakEvent inside a BlockBreakEvent?

    [​IMG]

    EDIT: When I use PlayerInteractEvent it works correcly, does everything once.

    I need to do some more testing, but atm it looks like the following code achieves what I want.
    It calls the BlockBreakEvent "heavyPickAxeEffect" when the player breaks a block with my pickaxe.
    Then when all conditions are met it calls BlockBreakEvent "b1".
    I figured that b1 recalls all the BlockBreakEvents and because I'm carrying my pickaxe it recalls my main event "heavyPickAxeEvent" aswell, and that triggers "b1" again, endlessly.
    With the boolean Stop at the start of the main Event and changed it to 1 right before it calls "b1" I end this loop.
    When b1 isen't cancelled by another plugin it reset stop to 0, and the same when it is cancelled by another plugin to insure the next BlockBreakEvent started by my pickaxe is new working cycle.

    Code:
     
    @EventHandler
        public void heavyPickAxeEffect(BlockBreakEvent event) {
            if(stop == 0) {
                Player player        = event.getPlayer();
                ItemStack itemInHand = player.getItemInHand();
                if(itemInHand.hasItemMeta() && itemInHand.getItemMeta().getLore() != null && itemInHand.getItemMeta().getLore().equals(DelzTools.loreHM)) {
                    if(player.hasPermission("dt.*") || player.hasPermission("dt.pickaxe")) {
                        if(toolModeHM.containsKey(player.getName())) {
                            if(toolModeHM.get(player.getName()) == 0) {
                                Block mainBlock       = event.getBlock();
                                Material mainMaterial = mainBlock.getType();
                                if(DelzTools.listHM.contains(mainMaterial)) {
                                    Block e1           = mainBlock.getRelative(BlockFace.NORTH);
                                    BlockBreakEvent b1 = new BlockBreakEvent(e1, player);
                                    stop = 1;
                                    Bukkit.getServer().getPluginManager().callEvent(b1);
                                    if(!b1.isCancelled()) {
                                        b1.getBlock().breakNaturally();
                                        stop = 0;
                                    }
                                    if(b1.isCancelled()) {
                                        stop = 0;
                                    }
                                }
                            }
                        } else { player.sendMessage(DelzTools.DT + ChatColor.RED + "Error: Tool mode settings could not be found, please rejoin the server!"); }
                    }
                }
            } else { event.getPlayer().sendMessage("stop is 1"); }
        }
    If any have suggestions on how to improve this code I'm all ears
    I would like to thank those who responded, much appreciated!

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 12, 2016
Thread Status:
Not open for further replies.

Share This Page