Solved Searching for nearby blocks?

Discussion in 'Plugin Development' started by PimpDuck, Sep 16, 2013.

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

    PimpDuck

    I'm trying to search and see if there is a water or lava block within 20 blocks of the senders location If so, don't let them use the command. I have everything set up, just don't know how to search and see if there's a water or lava block nearby.

    My code:
    Code:java
    1. package me.PimpDuck.AntiGlitch;
    2.  
    3. import java.util.ArrayList;
    4. import java.util.Arrays;
    5. import java.util.List;
    6.  
    7. import org.bukkit.*;
    8. import org.bukkit.block.Block;
    9. import org.bukkit.command.*;
    10. import org.bukkit.entity.Player;
    11. import org.bukkit.event.EventHandler;
    12. import org.bukkit.event.EventPriority;
    13. import org.bukkit.event.Listener;
    14. import org.bukkit.event.player.PlayerCommandPreprocessEvent;
    15.  
    16. public class AGCommands implements CommandExecutor, Listener{
    17. Player player;
    18.  
    19. private List<Material> liquid = Arrays.asList(new Material[] {
    20. Material.WATER,
    21. Material.STATIONARY_WATER,
    22. Material.LAVA,
    23. Material.STATIONARY_LAVA
    24. });
    25.  
    26. private List<String> block = Arrays.asList(new String[] {
    27. "tpa",
    28. "etpa",
    29. "back",
    30. "eback",
    31. "tpahere",
    32. "etpahere",
    33. "tpyes",
    34. "etpyes",
    35. "sethome",
    36. "esethome",
    37. "tpaccept",
    38. "etpaccept",
    39. });
    40.  
    41. @EventHandler(priority = EventPriority.LOW)
    42. public void blockCommand(PlayerCommandPreprocessEvent evt) {
    43. Player player = evt.getPlayer();
    44. Material material = player.getPlayer().getLocation().getBlock().getType();
    45. String command = evt.getMessage();
    46. command = command.split(" ")[0];
    47. command = command.replace("/", "");
    48. if(liquid.contains(material) && block.contains(command)){
    49. evt.setCancelled(true);
    50. player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "You can't use this command here!");
    51. }
    52. }
    53.  
    54. @Override
    55. public boolean onCommand(CommandSender sender, Command cmd, String command, String[] args)
    56. {
    57. Player player = (Player) sender;
    58. if(sender instanceof Player){
    59.  
    60. }else{
    61. player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "Only in game players can use these commands!");
    62. }
    63. return false;
    64. }
    65.  
    66. }
    67.  


    Anyone? :I

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

    metalhedd

    a 23 minute bump? have some patience.

    There's nothing difficult about this, you have 3 axes, loop through all the blocks in the area until you find water or lava, its just 3 nested for loops:
    Code:java
    1.  
    2. // let X, Y, Z be player postion and r be radius
    3. for (int x = X-r; x < X+r; x++) {
    4. for (int z = Z-r; z < Z+r; z++) {
    5. for (int y = Y-r; y < Y+r;y++) {
    6. //if block at x,y,z is water or lava, break;
    7. }
    8. }
    9. }
    10.  
     
  3. Offline

    PimpDuck

    Sorry :I and okay, I'll try this.

    metalhedd So would it look like this? Sorry, I'm very bad at for loops :/
    Code:java
    1. @EventHandler(priority = EventPriority.LOW)
    2. public void blockCommand(PlayerCommandPreprocessEvent evt) {
    3. Player player = evt.getPlayer();
    4. Material material = player.getPlayer().getLocation().getBlock().getType();
    5. String command = evt.getMessage();
    6. command = command.split(" ")[0];
    7. command = command.replace("/", "");
    8. // let X, Y, Z be player postion and r be radius
    9. for (int x = X-r; x < X+r; x++) {
    10. for (int z = Z-r; z < Z+r; z++) {
    11. for (int y = Y-r; y < Y+r;y++) {
    12. if(liquid.contains(material) && block.contains(command)){
    13. evt.setCancelled(true);
    14. player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "You can't use this command here!");
    15. }
    16. }
    17. }
    18. }
    19. }


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

    metalhedd

    You never defined liquid or block, so I don't know if your check will work. and you never defined, or initialized X, Y or Z to the players current coordinates, so the code won't even compile. but if you fix those 2 issues it should work.
     
  5. Offline

    PimpDuck

    metalhedd I did? I didn't show my whole code, sorry.
    Code:java
    1. public class AGCommands implements CommandExecutor, Listener{
    2. Player player;
    3.  
    4.  
    5. private List<Material> liquid = Arrays.asList(new Material[] {
    6. Material.WATER,
    7. Material.STATIONARY_WATER,
    8. Material.LAVA,
    9. Material.STATIONARY_LAVA
    10. });
    11.  
    12. private List<String> blockCommands = Arrays.asList(new String[] {
    13. "tpa",
    14. "etpa",
    15. "back",
    16. "eback",
    17. "tpahere",
    18. "etpahere",
    19. "tpyes",
    20. "etpyes",
    21. "sethome",
    22. "esethome",
    23. "tpaccept",
    24. "etpaccept",
    25. });
    26.  
    27. @EventHandler(priority = EventPriority.LOW)
    28. public void blockCommand(PlayerCommandPreprocessEvent evt) {
    29. Location loc = player.getLocation();
    30. Player player = evt.getPlayer();
    31. Material material = player.getPlayer().getLocation().getBlock().getType();
    32. String command = evt.getMessage();
    33. command = command.split(" ")[0];
    34. command = command.replace("/", "");
    35. // let X, Y, Z be player postion and r be radius
    36. for (int x = X-r; x < X+r; x++) {
    37. for (int z = Z-r; z < Z+r; z++) {
    38. for (int y = Y-r; y < Y+r;y++) {
    39. if(liquid.contains(material) && blockCommands.contains(command)){
    40. evt.setCancelled(true);
    41. player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "You can't use this command here!");
    42. }
    43. }
    44. }
    45. }
    46. }
    47. @Override
    48. public boolean onCommand(CommandSender sender, Command cmd, String command, String[] args)
    49. {
    50. Player player = (Player) sender;
    51. if(sender instanceof Player){
    52.  
    53. }else{
    54. player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "Only in game players can use these commands!");
    55. }
    56. return false;
    57. }
    58.  
    59. }
    60.  
     
  6. Offline

    metalhedd

    Ok, that shows 'liquid', but the rest of the variables are still undefined. (X, Y and Z)
     
  7. Offline

    PimpDuck

    How would I do that? replace X with loc.getX() ?

    metalhedd ^

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

    metalhedd

    yes. and you'll have to replace r with an actual value too.
     
  9. Offline

    PimpDuck

    So r would be the distance? metalhedd
     
  10. Offline

    metalhedd

  11. Offline

    PimpDuck

    I have a feeling I'm doing this wrong. Should one of these be the block, metalhedd ?
    Code:java
    1. for (int x = (int) (loc.getX()-20); x < loc.getX()+20; x++) {
    2. for (int z = (int) (loc.getZ()-20); z < loc.getZ()+20; z++) {
    3. for (int y = (int) (loc.getY()-20); y < loc.getY()+20;y++) {
     
  12. Offline

    metalhedd

    That looks fine to me... Your 2nd paste doesn't even have a variable called 'block' you renamed it to 'blockCommands' when you repasted the full code.
     
  13. Offline

    EdenCampo

    PimpDuck

    Another method that may work is getting the player's location, adding values to it and getting the block at the exact coords.

    Code:
    Location playerloc = player.getWorld().getLocation();
     
    // X, Y, Z 
    Location radius = playerloc.add(0.00D, 0.00D, 0.00D);
    
    But it will only work for the exact radius.
     
  14. Offline

    PimpDuck

    metalhedd Well, I thought that might be confusing. Because I changed it to "blockCommand" because that's the commands I want to block. I didn't mean that as the material block.
     
  15. Offline

    metalhedd


    Ok, then, no, the block itself shouldn't be anywhere in those lines, what you have there is a loop of every x,y,z coordinate in a 20 block radius of the player. inside the loop, you just need to check if the block at that location matches your criteria.
     
  16. Offline

    PimpDuck

    metalhedd How would I do that? :confused:

    metalhedd
    Code:
    if(liquid.contains(material) && blockCommands.contains(command)){
                    evt.setCancelled(true);
                    player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "You can't use this command here!");
                }
    this checks if the player is in the water or lava trying the command.

    EdenCampo The other way I was trying seems to not be working. How would I set this way up?

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

    metalhedd

    PimpDuck I've handed you every piece of code you need to solve the problem, and I even walked you through putting it together. At some point you need to do something yourself. You've got 99% of the way there, now if you trace your code you'll see that the 'material' you're checking never changes because you only ever assign it a value once, before the loop starts. you need to set it each time though the loop, to the value of the material at x,y,z.

    don't switch tactics now, EdenCampo's method will get you nowhere useful, read your code carefully, and try inserting some logging statements to see what's going on.
     
  18. Offline

    EdenCampo

    PimpDuck

    Code:java
    1. int radius = 0;
    2.  
    3. Location playerloc = player.getWorld().getLocation();
    4.  
    5. while(radius < 300(for example))
    6. {
    7. Location radius = playerloc.add(radiusD, 0.00D, radiusD);
    8.  
    9. Block block = Bukkit.getServer().getWorld(player.getWorld()).getBlockAt(playerloc);
    10.  
    11. if(block.getType() == MATERIAL.WATER || block.getType() == MATERIAL.LAVA)
    12. {
    13. // do stuff?
    14. }
    15.  
    16. radius++;
    17. }
     
  19. Offline

    PimpDuck

    Using this
    Code:java
    1.  
    2. @EventHandler(priority = EventPriority.LOW)
    3. public void blockCommand(PlayerCommandPreprocessEvent evt) {
    4. Location loc = player.getLocation();
    5. Player player = evt.getPlayer();
    6. Material material = player.getPlayer().getLocation().getBlock().getType();
    7. String command = evt.getMessage();
    8. command = command.split(" ")[0];
    9. command = command.replace("/", "");
    10. // let X, Y, Z be player postion and r be radius
    11. for (int x = (int) (loc.getX()-20); x < loc.getX()+20; x++) {
    12. for (int z = (int) (loc.getZ()-20); z < loc.getZ()+20; z++) {
    13. for (int y = (int) (loc.getY()-20); y < loc.getY()+20;y++) {
    14. if(liquid.contains(material) && blockCommands.contains(command)){
    15. evt.setCancelled(true);
    16. player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "You can't use this command here!");
    17. }
    18. }
    19. }
    20. }
    21. }
    doesn't seem to even do anything when they're in the water or out? :eek:
     
  20. Offline

    metalhedd

    because you didn't listen to what I said:

    #1) You need to set the 'material' variable INSIDE The loop. TO the material at location x,y,z
    #2) add some debug logging so that you can provide more useful feedback than "Doesn't work". you could tell us exactly which line it gets to and where it fails to do what you expect, if you just add a couple of logger entries.
     
  21. Offline

    PimpDuck

    metalhedd Inside the loop like this?
    Code:java
    1. @EventHandler(priority = EventPriority.LOW)
    2. public void blockCommand(PlayerCommandPreprocessEvent evt) {
    3. Location loc = player.getLocation();
    4. Player player = evt.getPlayer();
    5. String command = evt.getMessage();
    6. command = command.split(" ")[0];
    7. command = command.replace("/", "");
    8. // let X, Y, Z be player postion and r be radius
    9. for (int x = (int) (loc.getX()-20); x < loc.getX()+20; x++) {
    10. for (int z = (int) (loc.getZ()-20); z < loc.getZ()+20; z++) {
    11. for (int y = (int) (loc.getY()-20); y < loc.getY()+20;y++) {
    12. Material material = player.getPlayer().getLocation().getBlock().getType();
    13. if(liquid.contains(material) && blockCommands.contains(command)){
    14. evt.setCancelled(true);
    15. player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "You can't use this command here!");
    16. }
    17. }
    18. }
    19. }
    20. }
     
  22. Offline

    metalhedd

    No, you ignored the 2nd half of that point. you need to set 'material' TO the material at location x,y,z. you're setting it to the material at the players current location and checking that same material 8000 times.
     
  23. Offline

    PimpDuck

    metalhedd I'm not good with for loops at all >< I've been reading this over and over again for 10 mins... So do I like replace x,y, and z with material.lava or idk :/
     
  24. Offline

    metalhedd

    Code:java
    1.  
    2. @EventHandler(priority = EventPriority.LOW)
    3. public void blockCommand(PlayerCommandPreprocessEvent evt) {
    4. Location loc = player.getLocation();
    5. Player player = evt.getPlayer();
    6. String command = evt.getMessage();
    7. World world = loc.getWorld();
    8. command = command.split(" ")[0];
    9. command = command.replace("/", "");
    10. // let X, Y, Z be player postion and r be radius
    11. for (int x = (int) (loc.getX()-20); x < loc.getX()+20; x++) {
    12. for (int z = (int) (loc.getZ()-20); z < loc.getZ()+20; z++) {
    13. for (int y = (int) (loc.getY()-20); y < loc.getY()+20;y++) {
    14. Material material = world.getBlockAt(x,y,z).getType();
    15. if(liquid.contains(material) && blockCommands.contains(command)){
    16. evt.setCancelled(true);
    17. player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "You can't use this command here!");
    18. }
    19. }
    20. }
    21. }
    22. }
    23.  
     
  25. Offline

    PimpDuck

    metalhedd Ohhhh! Now I see what you mean xD I would have never understood that without seeing it though. Okay, that's done. I get a NPE on Location loc = player.getLocation();
    ? My error: http://pastebin.com/Sjp4NSye
    My whole class:
    Code:java
    1. package me.PimpDuck.AntiGlitch;
    2.  
    3. import java.util.Arrays;
    4. import java.util.List;
    5.  
    6.  
    7.  
    8. import org.bukkit.*;
    9. import org.bukkit.command.*;
    10. import org.bukkit.entity.Player;
    11. import org.bukkit.event.EventHandler;
    12. import org.bukkit.event.EventPriority;
    13. import org.bukkit.event.Listener;
    14. import org.bukkit.event.player.PlayerCommandPreprocessEvent;
    15.  
    16. public class AGCommands implements CommandExecutor, Listener{
    17. Player player;
    18.  
    19. private List<Material> liquid = Arrays.asList(new Material[] {
    20. Material.WATER,
    21. Material.STATIONARY_WATER,
    22. Material.LAVA,
    23. Material.STATIONARY_LAVA
    24. });
    25.  
    26. private List<String> blockCommands = Arrays.asList(new String[] {
    27. "tpa",
    28. "etpa",
    29. "back",
    30. "eback",
    31. "tpahere",
    32. "etpahere",
    33. "tpyes",
    34. "etpyes",
    35. "sethome",
    36. "esethome",
    37. "tpaccept",
    38. "etpaccept",
    39. });
    40.  
    41. @EventHandler(priority = EventPriority.LOW)
    42. public void blockCommand(PlayerCommandPreprocessEvent evt) {
    43. Location loc = player.getLocation();
    44. Player player = evt.getPlayer();
    45. String command = evt.getMessage();
    46. World world = loc.getWorld();
    47. command = command.split(" ")[0];
    48. command = command.replace("/", "");
    49. // let X, Y, Z be player postion and r be radius
    50. for (int x = (int) (loc.getX()-20); x < loc.getX()+20; x++) {
    51. for (int z = (int) (loc.getZ()-20); z < loc.getZ()+20; z++) {
    52. for (int y = (int) (loc.getY()-20); y < loc.getY()+20;y++) {
    53. Material material = world.getBlockAt(x,y,z).getType();
    54. if(liquid.contains(material) && blockCommands.contains(command)){
    55. evt.setCancelled(true);
    56. player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "You can't use this command here!");
    57. }
    58. }
    59. }
    60. }
    61. }
    62. @Override
    63. public boolean onCommand(CommandSender sender, Command cmd, String command, String[] args)
    64. {
    65. Player player = (Player) sender;
    66. if(sender instanceof Player){
    67.  
    68. }else{
    69. player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "Only in game players can use these commands!");
    70. }
    71. return false;
    72. }
    73.  
    74. }
    75.  


    I understand how to read it and everything, I just don't know what I'm doing wrong to get this error.
     
  26. Offline

    metalhedd

    the 'player' variable is null when you're assigning loc. switch the order of those 2 lines.
     
  27. Offline

    PimpDuck

    metalhedd Okay, it works. Is there a reason it's spamming me with the message? http://puu.sh/4sUJ6.png
     
  28. Offline

    metalhedd

    you need to add a 'break' or 'return' statement inside the loop just after you cancel the event.
     
  29. Offline

    PimpDuck

    metalhedd I added it here, but it still does the same thing?
    Code:java
    1. for (int x = (int) (loc.getX()-20); x < loc.getX()+20; x++) {
    2. for (int z = (int) (loc.getZ()-20); z < loc.getZ()+20; z++) {
    3. for (int y = (int) (loc.getY()-20); y < loc.getY()+20;y++) {
    4. Material material = world.getBlockAt(x,y,z).getType();
    5. if(liquid.contains(material) && blockedCommands.contains(command)){
    6. evt.setCancelled(true);
    7. player.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + "You can't use this command here!");
    8. break;
    9. }
    10. }
    11. }


    Btw, when I try to return false it says I have to change from void to boolean?
     
  30. Offline

    metalhedd

    use return instead of break. you don't need to return false. just return
     
    PimpDuck likes this.
Thread Status:
Not open for further replies.

Share This Page