Check if a player is in an area?

Discussion in 'Plugin Development' started by MrSoLegitimate, Aug 24, 2012.

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

    MrSoLegitimate

    Like a rectangle area using 2 Locations?
     
  2. Offline

    skore87

    I thought about looping through all chunks within the selection, but they would overlap (often) and extend outside your selection. The only way I can come up with right now is to loop through the online players.

    Code:
        public boolean playerInArea(Location loc1, Location loc2){
            int x1,x2,y1,y2,z1,z2;
            x1 = loc1.getX() > loc2.getX() ? (int) loc2.getX() : (int) loc1.getX();
            y1 = loc1.getY() > loc2.getY() ? (int) loc2.getY() : (int) loc1.getY();
            z1 = loc1.getZ() > loc2.getZ() ? (int) loc2.getZ() : (int) loc1.getZ();
           
            x2 = ((int) loc1.getX()) == x1 ? (int) loc2.getX() : (int) loc1.getX();
            y2 = ((int) loc1.getY()) == y1 ? (int) loc2.getY() : (int) loc1.getY();
            z2 = ((int) loc1.getZ()) == z1 ? (int) loc2.getZ() : (int) loc1.getZ();
                   
            for (int x = x1; x <= x2; x++){
                for (int y = y1; y <= y2; y++){
                    for (int z = z1; z <= z2; z++){
                        for (Player p : Bukkit.getOnlinePlayers()){
                            // I don't like this bit, but it is the simplest way without annoying to write code.
                            if (p.getLocation().getBlock().getLocation() == new Location(loc1.getWorld(),x,y,z)) return true;
                        }
                    }
                }
            }
           
            return false;
        }
     
  3. Offline

    Courier

    No. That code does not work. For one thing, p.getLocation().getBlock().getLocation() == new Location(loc1.getWorld(), x, y, z)) will never return true, because you are comparing an object reference to a newly created object. You mean to use .equals().

    For another thing, that is terrible style, what you posted in an older thread was much closer.
    MrSoLegitimate If you are talking about checking for a specific player (which is what your title implies), just compare the player's location to loc1 and loc2.
    Code:java
    1. public boolean isInRect(Player player, Location loc1, Location loc2)
    2. {
    3. double[] dim = new double[2];
    4.  
    5. dim[0] = loc1.getX();
    6. dim[1] = loc2.getX();
    7. Arrays.sort(dim);
    8. if(player.getLocation().getX() > dim[1] || player.getLocation().getX() < dim[0])
    9. return false;
    10.  
    11. dim[0] = loc1.getZ();
    12. dim[1] = loc2.getZ();
    13. Arrays.sort(dim);
    14. if(player.getLocation().getZ() > dim[1] || player.getLocation().getZ() < dim[0])
    15. return false;
    16.  
    17. /*TODO same thing with y*/
    18.  
    19. return true;
    20. }
     
  4. Offline

    skore87

    Yeah I messed up.

    Code:
        public boolean playerInArea(Location loc1, Location loc2){
            int x1,x2,y1,y2,z1,z2;
            x1 = loc1.getX() > loc2.getX() ? (int) loc2.getX() : (int) loc1.getX();
            y1 = loc1.getY() > loc2.getY() ? (int) loc2.getY() : (int) loc1.getY();
            z1 = loc1.getZ() > loc2.getZ() ? (int) loc2.getZ() : (int) loc1.getZ();
         
            x2 = ((int) loc1.getX()) == x1 ? (int) loc2.getX() : (int) loc1.getX();
            y2 = ((int) loc1.getY()) == y1 ? (int) loc2.getY() : (int) loc1.getY();
            z2 = ((int) loc1.getZ()) == z1 ? (int) loc2.getZ() : (int) loc1.getZ();
                 
            for (int x = x1; x <= x2; x++){
                for (int y = y1; y <= y2; y++){
                    for (int z = z1; z <= z2; z++){
                        for (Player p : Bukkit.getOnlinePlayers()){
                            if (p.getWorld().getBlockAt(p.getLocation()).equals(loc1.getWorld().getBlockAt(new Location(loc1.getWorld(),x,y,z)))) return true;
                        }
                    }
                }
            }
         
            return false;
        }
    And I'm almost certain he means a selection of blocks using two points like a cuboid selection in WorldGuard for example.
     
  5. Offline

    Courier

    skore87If he does mean to check all players, instead of just one, it would still be greatly sped up by comparing the x, y, and z, of each player, instead of looping through each block and each player.
    Code:java
    1. double[] x = {loc1.getX(), loc2.getX()};
    2. Arrays.sort(x);
    3. /*etc for y and z*/
    4. for(Player k : Bukkit.getOnlinePlayers())
    5. {
    6. if(k.getLocaton().getX() >= x[0] &&
    7. k.getLocation().getX() <= x[1] &&
    8. /*etc for z and y*/)
    9. {
    10. return true;
    11. }
    12. }
    13. return false;
    It seems strange that you were not using that method, since you used it earlier today, here.
     
  6. Offline

    skore87

    I frequently go through different ideas to get a result I want so I can learn more than just one methodology. And of course other times I just don't care to put a lot of effort into it lol.
     
  7. Offline

    MrSoLegitimate

    This works perfectly. Thanks!
     
Thread Status:
Not open for further replies.

Share This Page