How can I get all players nearby a specific Player?

Discussion in 'Plugin Development' started by Eistee², Jul 22, 2012.

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

    Eistee²

    Hello , I never worked much with locations so I dosent know how this works.

    I want to find all players nearby a specific Player to send them a message
    My plugin (MineBuilder) gives money or exp and i had a request if i can add a messanger for money where all players nearby the player which earned money by breaking a block or something else gets a message but how can i make this possible? :/
    Would be nice if some one can help me :)

    Sorry for my bad english
    Mfg Eistee²
     
  2. Offline

    Njol

    Loop through all online players and make use of Location's distance() method:
    Code:
    Player p = ...; // your player
    double maxDist = getConfig().getDouble("money-message.max-distance");// whatever
    for (Player other : Bukkit.getOnlinePlayers()) {
      if (other.getLocation().distance(player.getLocation()) <= maxDist) {
        other.sendMessage("your message here");
      }
    }
     
    Ganga likes this.
  3. Offline

    Eistee²

    Thank you :)
     
  4. Offline

    LexLaiden

    Use
    Code:
    List<Entity> entitylist = player.getNearbyEntities(radiusX, radiusY, radiusZ);
    for(int t=0;t<entitylist.size();t++){
        if(entitylist.get(t).getType()==EntityType.PLAYER){
     
            //its a player in the radius so do whatever
            // you need to with each
     
        }       
    }    
     
  5. LexLaiden
    getNearbyEntities() loops through all entities in that world... which are *alot* more than the online players.

    Njol
    From what I've seen in the Location source code, calling .distance() on locations that have diferent worlds would throw an exception.
     
  6. Offline

    LexLaiden

    getNearbyEntities() is not as intence as you may think and it does all the work for you without worring about worlds.
     
  7. Offline

    Eistee²

    Njol
    From what I've seen in the Location source code, calling .distance() on locations that have diferent worlds would throw an exception.[/quote]

    Hm can i fix the problem when i write it like this?

    Code:
         
        for (Player other : Bukkit.getOnlinePlayers()) {
                    if(!(other == Specificplayer)){
                   
                         if(other.getWorld() == Specificplayer.getWorld()){
             
                              if (other.getLocation().distance(Specificplayer.getLocation()) <= maxDist) {
           
                                    other.sendMessage("your message here");
               
                                 }
                              }
                           }
                 }
     
    Ganga likes this.
  8. Offline

    Lolmewn

    @Eistee2 Yea, I guess it would.
     
  9. Offline

    desht

    For performance reasons, you should use .distance() inside a loop like that (it does an expensive Math.sqrt() call).

    Use .distanceSquared() and compare it against the square of the desired threshold, which you can calculate once outside the loop.

    Right, it would be better to use player.getWorld().getPlayers(), which will only get the players in the subject player's current world.

    Also, I haven't looked too deeply into the CraftBukkit/NMS code, but I suspect LexLaiden is correct on that particular point, since the Bukkit world.getPlayers() and server.getOnlinePlayers() methods need to iterate through all entities anyway to extract those that are players. There is, however, a very important distinction:
    • The distance() (or preferably distanceSquared()) approach gets all the players within a spherical radius of the subject
    • The getNearest() approach gets all the players within a cuboid of the given size around the subject
    So you will get different results depending on just where nearby players are. How important that distinction is depends on the plugin's specific requirements.

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

    Njol

    getNearbyEntities() is likely faster than world.getEntitiesByClass() for all entities except for players, as both methods still loop through all entities of the world, while getOnlinePlayers() can basically copy an array that already exists.

    world.getPlayers() iterates over all entities of the world like world.getEntitiesbyClass(), but server.getOnlinePlayers() returns something like onlinePlayers.toArray(new Player[onlinePlayers.size()]).

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

    desht

    You are indeed correct! In which case, stick with server.getOnlinePlayers(), but be sure to check the players' worlds before getting the distanceSquared() between them.

    PHP:
    public List<PlayergetPlayersWithin(Player playerint distance) {
      List<
    Playerres = new ArrayList<Player>();
      
    int d2 distance distance;
      for (
    Player p Bukkit.getServer().getOnlinePlayers()) {
        if (
    p.getWorld() == player.getWorld() && p.getLocation().distanceSquared(player.getLocation()) <= d2) {
          
    res.add(p);
        }
      }
      return 
    res;
    }
     
  12. Offline

    Eistee²

    Thanks you all for helping! :)
     
Thread Status:
Not open for further replies.

Share This Page