Cant find top and bottom blocks

Discussion in 'Plugin Development' started by CaveBoy36, Aug 26, 2015.

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

    CaveBoy36

    Hi! I am trying to make something where if you break the bottom of a tree it detects if its under a log and above dirt/grass, then places a sapling. It stops working when it gets to the part where it checks for the dirt/grass. Can anyone help?
    Code:
        @EventHandler
        public void onBlockBreak(BlockBreakEvent event) {
            Player player = (Player) event.getPlayer();
            Block block = (Block) event.getBlock();
            Location location = (Location) block.getLocation();
            Location dirt = (Location) location;
            dirt.setY(location.getY() -1);
            Location log = (Location) location;
            log.setY(location.getY() + 1);
            if (player instanceof Player && plugin.tree.get(player.getName()) != null) {
                if (block.getType().equals(Material.LOG)) {
                    if (dirt.getBlock().getType() == Material.DIRT || dirt.getBlock().getType() == Material.GRASS) {
                        if (log.getBlock().getType() == Material.LOG) {
                        player.sendMessage("Earth Killer!");   
                        location.getBlock().setType(Material.SAPLING);
                        }
                    }
                    }
            }
        }
    }
    
     
  2. Offline

    Zombie_Striker

    @CaveBoy36
    Did you debug? Are there any Errors?

    Please debug your dirt instance and post errors(if you have any) before you post.
     
  3. Offline

    CaveBoy36

    @Zombie_Striker There aren't any errors, when I break the log it just breaks nothing happens. And there is nothing in the console either
     
  4. Offline

    Zombie_Striker

     
  5. Offline

    ShadowRanger

    You've done a lot of unnecessary casting here. Nevertheless, try this:

    Code:
        @EventHandler
        public void onBlockBreak(BlockBreakEvent event) {
            Player player = event.getPlayer();
            Block block = event.getBlock();
    
            if (plugin.tree.get(player.getName()) != null) {
                if (block.getType() == Material.LOG) {
                    Block below = block.getRelative(BlockFace.DOWN);
    
                    if (below.getType() == Material.DIRT || below.getType() == Material.GRASS) {
                        Block above = block.getRelative(BlockFace.UP);
    
                        if (above.getType() == Material.LOG) {
                            player.sendMessage("Earth Killer!");
                            block.setType(Material.SAPLING);
                        }
                    }
                }
            }
        }
    
     
  6. Offline

    Zombie_Striker

    I don't think this is necessary

    Also you need to :
    1. Check if block is not equal to null
    2. check if below is not equal to null
    3. and check if above is not equal to null.
    Any of these are null, then your .getType will throw and exeption.

    PS, you might want to keep something to make sure that the player isn't breaking a log in a house. Also, if a player is mining the block, if they don't stop mining in time they will break the sapling.
     
  7. Offline

    CaveBoy36

    It's just my enabled checker, if they have /easycrops tree on.
     
  8. Offline

    The_BloodHound

    This should help:

    Code:
    @EventHandler
    
        public void onBlockBreak(BlockBreakEvent e) {
    
            Block b = e.getBlock();
    
            Player p = e.getPlayer();
    
            if (b.equals(Material.LOG) && p instanceof Player) {
    
                if (b.getLocation(
    
                        new Location(null, b.getX(), b.getY() - 1, b.getZ()))
    
                        .equals(Material.GRASS)
    
                        || b.getLocation(
    
                                new Location(null, b.getX(), b.getY() - 1, b.getZ()))
    
                                .equals(Material.DIRT)) {
    
                    b.setType(Material.SAPLING);
    
                    p.sendMessage(ChatColor.RED + "EARTH KILLER!");
    
                }
    
            }
    
        }
    
     
  9. 1. No, because it is spoonfeeding
    2. Again no, because it doesn't even work (for example you check if a block is equal to a material)
    3. .getPlayer() will always be a player. Why check if it is an instance of Player??
    4. new Location(null, x, y, z) will throw a NullPointerException. Must provide a world
    5. Again, a Location isn't equal to a Material either...

    That's how I'd do it:
    Code:
    Block b = e.getBlock(); //Get the block that was broken.
    
    if (b.getType() == Material.LOG &&  //Check if the block is a log
    b.getRelative(BlockFace.UP).getType() == Material.LOG && //Check if the block above it is a log
    (b.getRelative(BlockFace.DOWN).getType() == Material.DIRT || //Check if the block below it is either dirt
    b.getRelative(BlockFace.DOWN.getType() == Material.GRASS)) { //Or grass
    
    b.setType(Material.SAPLING); //Set the block (that was broken) to a sapling
    
    e.getPlayer().sendMessage("§7[§2Tree§7] §aYou killed me D: ...But now I will kill you >:D"); //Send message if you like
    e.getPlayer().setHealth(0.0); //Revenge from the poor tree :3
    }
     
  10. Offline

    ShadowRanger

    You do not need to check if the blocks are null in this situation. Checking if event.getBlock() is null is completely unnecessary. And so are the other null checks you suggested.

    The code I provided should work fine. OP have you tried using it?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 11, 2016
  11. Offline

    Zombie_Striker

    @ShadowRanger
    Actually no, If the block is air it will be null, and thus .getType would create a null pointer exception.
     
  12. Offline

    ShadowRanger

    Actually no, if the block is air it will return a block with it's Material as air. You do not need to check for null. If you don't believe me, then try it yourself.

    Just to verify @CaveBoy36, the following code below has been tested and works. In fact, yours would probably work too if you included an event.setCancelled(true). Basically the reason why your code doesn't work is because you don't cancel the event before you place the sapling, so the sapling doesn't get placed/gets destroyed. Simply cancel the event as well and it should work.

    Code:
        @EventHandler
        public void onBlockBreak(BlockBreakEvent event) {
            Player player = event.getPlayer();
            Block block = event.getBlock();
    
            if (plugin.tree.get(player.getName()) != null) {
                if (block.getType() == Material.LOG) {
                    Block below = block.getRelative(BlockFace.DOWN);
    
                    if (below.getType() == Material.DIRT || below.getType() == Material.GRASS) {
                        Block above = block.getRelative(BlockFace.UP);
    
                        if (above.getType() == Material.LOG) {
                            player.sendMessage("Earth Killer!");
                            event.setCancelled(true)
                            block.setType(Material.SAPLING);
                        }
                    }
                }
            }
        }
    
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 11, 2016
    au2001 likes this.
Thread Status:
Not open for further replies.

Share This Page