'Radius' expert needed

Discussion in 'Plugin Development' started by ivquit, Jun 19, 2013.

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

    ivquit

    I'm trying to create a player tracking system whereby if a player is standing on a diamond block & has a diamond within their inventory, it will show the coordinates of their target player, BUT i would like it to only look within a 5000 block radius, to make it less over powered as its a raid server.
    This is the working code so far, I need help implementing this radius check though:

    Code:java
    1.  
    2. if(commandLabel.equalsIgnoreCase("track")){
    3. if(args.length == 0){
    4. player.sendMessage(ChatColor.DARK_RED + "Correcct use: /track (player)");
    5. }else if(args.length == 1){
    6. Player player2 = Bukkit.getPlayer(args[0]);
    7. Block block = player.getLocation().getBlock().getRelative(BlockFace.DOWN);
    8. Location tpl = player2.getLocation();
    9. if( player2 != null && player2.isOnline() ) {
    10. if(block.getType().equals(Material.DIAMOND_BLOCK)){
    11. if(pinv.contains(Material.DIAMOND)){
    12. player.sendMessage(ChatColor.RED + args[0] + ChatColor.GREEN + " X: " + ChatColor.WHITE + Math.round(tpl.getX())
    13. + ChatColor.GREEN + " Y: " +ChatColor.WHITE + Math.round(tpl.getY()) +ChatColor.GREEN + " Z: " +
    14. ChatColor.WHITE + Math.round(tpl.getZ()));
    15. pinv.removeItem(new ItemStack(Material.DIAMOND, 1));
    16. }else{
    17. player.sendMessage(ChatColor.DARK_RED + "It costs 1 diamond to attempt to track players!");
    18. }
    19. }else{
    20. player.sendMessage (ChatColor.DARK_RED + "You must be on a Diamond Block to track players!");
    21. player.setHealth(player.getHealth()-3);
    22. }
    23. }else{
    24. player.sendMessage(ChatColor.DARK_RED + "Player is not online or does not exist");
    25. }
    26. }
    27. }
    28. [/syntax=java]
     
  2. Offline

    minoneer

    That's actually pretty straight forward.

    Code:java
    1. if (player1.getLocation().getDistance(player2.getLocation()) < 5000)


    should get you there.
     
  3. Offline

    iKanak

    sqrt((player1x - player2x)^2 + (player1z-player2z)^2) <= 5000

    Or what minoneer said.
     
  4. Offline

    chasechocolate

    minoneer player1.getLocation().distance(player2.getLocation()).
     
  5. Offline

    nitrousspark

    do if (player1.getLocation().distanceSquared(players.getLocation()) <= 25000000)
    if uses less memory
     
    AmShaegar likes this.
  6. Offline

    desht

    Good advice, but the pedant in me has to point out: It doesn't use less memory, but it does use less CPU (Math.sqrt() is a fairly expensive calculation).
     
  7. Offline

    minoneer

    Good point, although I don't think it makes a huge difference in this case, since he's only doing 1 calculation per command.
     
  8. Offline

    ivquit

    Thanks guys, Implementing now, Didn't think it was that straight forward :)

    EDIT: it works great! any idea how to list all players within a radius? I've heard about getNearbyEntities() but am having trouble using it.
     
  9. Offline

    foodyling

    Code:
    List<Player> Players = new Arraylist<>();
    for (Entity entity : player.getNearbyEntities(2500, 128, 2500)) {
      if (entity instanceof Player) {
        Players.add((Player) entity);
      }
    }
     
  10. Offline

    ivquit

    Thanks! that worked great other than
    List<Player> Players = new Arraylist<>();
    needed to be
    ArrayList<Player> Players = new ArrayList<Player>();
    Thanks to everyone thet helped :)
     
  11. Offline

    foodyling

    Hm, I use NetBeans, it suggest to just use a diamond interface (just ArrayList<>()), thought that was universal on all IDE's
     
  12. Offline

    desht

    The diamond operator is a Java 7 construct. If you want your code to be backwards compatible (generally a good idea), you need to include the parameterised type too.
     
  13. Offline

    foodyling

    Ah, thank you, I did not know.
     
  14. Offline

    ivquit

    One final thing, I'm trying to 'list players' in chat - for the sender, and this is my code
    Code:java
    1.  
    2. if(block.getType().equals(Material.DIAMOND_BLOCK)){
    3. ArrayList<Player> Players = new ArrayList<Player>();
    4. for (Entity entity : player.getNearbyEntities(1000, 256, 1000)) {
    5. if (entity instanceof Player) {
    6. Players.add((Player) entity);
    7. }
    8. }
    9. player.sendMessage(ChatColor.GREEN + "Players Within Range: " + ChatColor.WHITE + Players);
    10. pinv.removeItem(new ItemStack(Material.DIAMOND, 5));
    11. player.sendMessage(ChatColor.GREEN + "Operation costed 5 Diamonds.");
    12. }
    13.  

    Which works all fine, but when it lists the player it comes up like: [CraftPlayer{name=ambyboo}] and thats looks very unprofessional so is there anyway of only displaying their IGN? i've tried .getDisplayName() - did not work.
     
  15. Offline

    minoneer

    Player.getDisplayName() gives you the name, including all prefixes. If you just want the name itselv, use Player.getName(). In order to show all online Players, you have to loop through the list and add them all, i.e.

    Code:java
    1. StringBuilder sb = new StringBuilder()
    2. for (Player p : players) {
    3. sb.append(p.getName()).append(' ');
    4. }
    5. player.sendMessage(ChatColor.GREEN + "Players Within Range: " + ChatColor.WHITE + sb.toString());
    6.  
     
  16. Offline

    foodyling

    'Players' is a ArrayList of Player, if you want to create a List of their names do this:
    Code:
     ArrayList<String> Players = new ArrayList<String>();
    for (Entity entity : player.getNearbyEntities(1000, 256, 1000)) {
    if (entity instanceof Player) {
    Players.add(((Player) entity).getName());
    }
    }
    player.sendMessage(ChatColor.GREEN + "Players Within Range: " + ChatColor.WHITE + StringUtils.join(Players, ", "));
    pinv.removeItem(new ItemStack(Material.DIAMOND, 5));
    player.sendMessage(ChatColor.GREEN + "Operation costed 5 Diamonds.");
     
  17. Offline

    ivquit

    It seems to work with minoneers suggestion:
    Code:java
    1.  
    2. if(pinv.contains(Material.DIAMOND, 5)){
    3. ArrayList<Player> Players = new ArrayList<Player>();
    4. for (Entity entity : player.getNearbyEntities(1000, 256, 1000)) {
    5. if (entity instanceof Player) {
    6. Players.add((Player) entity);
    7. }
    8. }
    9. for (Player p : Players) {
    10. sb.append(p.getName()).append(' ');
    11. }
    12. player.sendMessage(ChatColor.GREEN + "Players Within Range: " + ChatColor.WHITE + sb.toString());
    13. pinv.removeItem(new ItemStack(Material.DIAMOND, 5));
    14. player.sendMessage(ChatColor.GREEN + "Operation costed 5 Diamonds.");
    15. }else{
    16. player.sendMessage(ChatColor.RED + "This operation costs 5 diamonds!");
    17. }
    18.  

    - Anyways the system is almost complete just a final bug that i've been scouting the forums for an answer to for at least an hour now.
    Code:java
    1.  
    2. //onCommand
    3. if(player2 != null && player2.isOnline()) {
    4. //code
    5. }else{
    6. player.sendMessage(ChatColor.RED + "player isn't online");
    7.  

    But when i use the command and the player IS NOT online it says 'an internal error occured...'
    Any ideas?
     
Thread Status:
Not open for further replies.

Share This Page