Solved Checking if there are blocks above the player (ignoring water)

Discussion in 'Spigot Plugin Development' started by BonesJones, Dec 4, 2019.

  1. Hello,

    I am trying to check if there are blocks above the player (does not matter how far they are, what matters is that they are above him, aka blocking the rain.)

    Code (Text):
    if (player.getLocation().getBlockY() + 1 >  player.getWorld().getHighestBlockYAt(player.getLocation())
    I succeeded in that part, but if the player is in water it does not fire. Water counts as a block above the player.
    And I don't want it to count water, so even if they were in water they would still get affected by the rain EXCEPT if there's a block above them INSIDE the water.

    this is where I got:
    Code (Text):
                    if ( player.getLocation().getBlockY() + 1 > player.getWorld().getHighestBlockYAt(player.getLocation()) ||
                                 player.getLocation().getBlock().getType() == Material.WATER
                            && player.getWorld().getHighestBlockAt(player.getLocation()).getType() == Material.CAVE_AIR
    This works, but the only problem is it fires even if there is a block above the player INSIDE the water. Any ideas?
  2. I think there was a method called #isSolid()
  3. That sounds cool but where do I even put that?
  4. Sorry it was #isLiquid()

    It could look something like this:
    Code (Java):
                        //get the block above the player
                        Block above = player.getWorld().getBlockAt(player.getLocation().getBlockX(), (int) (player.getEyeHeight() + 1), player.getLocation().getBlockZ());
                        //check if it isn't liquid
                        if(!above.isLiquid()) {
  5. You're gonna have to write a custom getHighestBlockAt method. It's not that hard, simply have a for loop running from the build limit to your player's eye location, and as soon as you encounter a block that is anything besides air and water, return it.
  6. That was a good idea.

    For people who need this in the future, this is what I used, If I find a bug with it later on i'll come back to this thread.
    Code (Text):
      private boolean getHighestBlockYAt(Location loc){

            for (int i = loc.getBlockY(); i < 256; i++){
                Block block = loc.getWorld().getBlockAt(loc.getBlockX(), i, loc.getBlockZ());

                if(block != null && !block.isLiquid()
                                 && block.getType() != Material.AIR
                                 && block.getType() != Material.CAVE_AIR) {
                    return true;

            return false;
  7. Note that this will NOT get the highest block, but the one closest to your location. If you want the highest one, you should invert the for loop!
  8. Yeah that's true, it's what I want though for now.