For loop help

Discussion in 'Plugin Development' started by Signatured, Feb 27, 2015.

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

    Signatured

    I'm trying to set a block at a location right above ground level of where the player is standing. So if the player is flying, it would get the block right above ground level, and set a block at that location. Here's what I have now:
    Code:java
    1.  
    2. int x = player.getLocation().getBlockX();
    3. int y = player.getLocation().getBlockY();
    4. int z = player.getLocation().getBlockZ();
    5. World world = player.getLocation().getWorld();
    6.  
    7. Location loc = new Location(world, x, y, z);
    8.  
    9. Material air = new ItemStack(Material.AIR).getType();
    10. Block block = player.getWorld().getBlockAt(loc);
    11. if (block.getType() == air) {
    12. System.out.println("worked1");
    13. Block below = block.getRelative(BlockFace.DOWN);
    14. if (below.getType() == Material.AIR) {
    15. for (int i = below.getY(); below.getType() == Material.AIR; i--) {
    16. System.out.println("worked2");
    17. if (!(below.getType() == Material.AIR)) {
    18. below.setType(Material.CARPET);
    19. }
    20. Bukkit.getServer().getScheduler().runTaskLater(Main.getInstance(), new Runnable() {
    21. public void run() {
    22. below.setType(air);
    23. System.out.println("worked3");
    24. }
    25. }, 20 * 10);
    26. }
    27. }
    28. else {
    29. block.setType(Material.CARPET);
    30. }
    31. Bukkit.getServer().getScheduler().runTaskLater(Main.getInstance(), new Runnable() {
    32. public void run() {
    33. block.setType(air);
    34. System.out.println("worked3");
    35. }
    36. }, 20 * 10);
    37. }
    However, the loop just continues on forever and never stops, crashing the server. Any help is appreciated!
     
  2. Offline

    uksspy

    I'm gonna guess that below.getType() always returns AIR. Also you shouldn't be using a for loop if you are using a condition like that. Instead you would want to use a sentinel loop like while or do while.

    Edit: If all you are doing is trying to get the highest block at the player's position, simply use World.getHighestBlockAt(playerLocation);
     
  3. Offline

    Signatured

    Thanks, I'll look into using a while loop.

    I cant use getHighestBlockAt since they could be in a building, etc.

    New code with while loop:
    Code:java
    1.  
    2. int x = player.getLocation().getBlockX();
    3. int y = player.getLocation().getBlockY();
    4. int z = player.getLocation().getBlockZ();
    5. World world = player.getLocation().getWorld();
    6.  
    7. Location loc = new Location(world, x, y, z);
    8.  
    9. Material air = new ItemStack(Material.AIR).getType();
    10. Block block = player.getWorld().getBlockAt(loc);
    11. if (block.getType() == air) {
    12. System.out.println("worked1");
    13. Block below = block.getRelative(BlockFace.DOWN);
    14. if (below.getType() == Material.AIR) {
    15. System.out.println("worked2");
    16. while (below.getType() == Material.AIR) {
    17. System.out.println("worked3");
    18. int belowy = below.getY();
    19. belowy--;
    20. }
    21. }
    22. else {
    23. block.setType(Material.CARPET);
    24. }
    25. Bukkit.getServer().getScheduler().runTaskLater(Main.getInstance(), new Runnable() {
    26. public void run() {
    27. block.setType(air);
    28. System.out.println("worked4");
    29. }
    30. }, 20 * 10);
    31. }
    Same result, it just repeats the while loop over and over and crashes the server.
    @uksspy

    New code @uksspy
    Code:java
    1.  
    2. int x = player.getLocation().getBlockX();
    3. int y = player.getLocation().getBlockY();
    4. int z = player.getLocation().getBlockZ();
    5. World world = player.getLocation().getWorld();
    6.  
    7. Location loc = new Location(world, x, y, z);
    8.  
    9. int by = y - 1;
    10.  
    11. Location bloc = new Location(world, x, by, z);
    12.  
    13. Material air = new ItemStack(Material.AIR).getType();
    14. Block block = player.getWorld().getBlockAt(loc);
    15. Block below = player.getWorld().getBlockAt(bloc);
    16. if (block.getType() == air) {
    17. System.out.println("worked1");
    18. if (below.getType() == Material.AIR) {
    19. System.out.println("worked2");
    20. while (below.getType() == Material.AIR) {
    21.  
    22. by = by - 1;
    23.  
    24. System.out.println("worked3");
    25. if (below.getType() != Material.AIR) {
    26. by++;
    27. }
    28. }
    29. }
    30. else {
    31. block.setType(Material.CARPET);
    32. }
    33. Bukkit.getServer().getScheduler().runTaskLater(Main.getInstance(), new Runnable() {
    34. @Override
    35. public void run() {
    36. block.setType(air);
    37. System.out.println("worked4");
    38. }
    39. }, 20 * 10);
    40. }
    Same issue.
     
    Last edited by a moderator: Feb 28, 2015
  4. Offline

    uksspy

    @Signatured
    Of course there is!
    This code runs over and over again if below is AIR:
    Code:
       while (below.getType() == Material.AIR) {
                        by = by - 1;
                        System.out.println("worked3");
                        if (below.getType() != Material.AIR) {
                            by++;
                        }
                    }
    Inside the loop you must somehow modify the variable below.
     
  5. Offline

    Signatured

    That's why when I check if below is air, if it is, it subtracts 1 from the y, and continues to do so until below does not equal air.
     
  6. Offline

    uksspy

    You need to to below.setY(by);
     
  7. Offline

    Signatured

    Did that, didn't help.
    Code:java
    1.  
    2. int x = player.getLocation().getBlockX();
    3. int y = player.getLocation().getBlockY();
    4. int z = player.getLocation().getBlockZ();
    5. World world = player.getLocation().getWorld();
    6.  
    7. Location loc = new Location(world, x, y, z);
    8.  
    9. int by = y - 1;
    10.  
    11. Location bloc = new Location(world, x, by, z);
    12.  
    13. Material air = new ItemStack(Material.AIR).getType();
    14. Block block = player.getWorld().getBlockAt(loc);
    15. Block below = player.getWorld().getBlockAt(bloc);
    16. if (block.getType() == air) {
    17. System.out.println("worked1");
    18. if (below.getType() == Material.AIR) {
    19. System.out.println("worked2");
    20. while (below.getType() == Material.AIR) {
    21.  
    22. by = by - 1;
    23. bloc.setY(by);
    24.  
    25. System.out.println("worked3");
    26. }
    27. if (below.getType() != Material.AIR) {
    28. by++;
    29. bloc.setY(by);
    30. }
    31. }
    32. else {
    33. block.setType(Material.CARPET);
    34. }
    35. Bukkit.getServer().getScheduler().runTaskLater(Main.getInstance(), new Runnable() {
    36. @Override
    37. public void run() {
    38. block.setType(air);
    39. System.out.println("worked4");
    40. }
    41. }, 20 * 30);
    42. }


    Code:java
    1. int x = player.getLocation().getBlockX();
    2. int y = player.getLocation().getBlockY();
    3. int z = player.getLocation().getBlockZ();
    4. World world = player.getLocation().getWorld();
    5.  
    6. Location loc = new Location(world, x, y, z);
    7.  
    8. int by = y - 1;
    9.  
    10. Location bloc = new Location(world, x, by, z);
    11.  
    12. Material air = new ItemStack(Material.AIR).getType();
    13. Block block = player.getWorld().getBlockAt(loc);
    14. Block below = player.getWorld().getBlockAt(bloc);
    15. if (block.getType() == air) {
    16. System.out.println("worked1");
    17. if (below.getType() == Material.AIR) {
    18. System.out.println("worked2");
    19. for (int i = by; player.getWorld().getBlockAt(bloc).getType() == Material.AIR; i--) {
    20. by = i;
    21. player.getWorld().getBlockAt(bloc).setType(Material.CARPET);
    22. }
    23. }
    24. else {
    25. block.setType(Material.CARPET);
    26. }
    27. Bukkit.getServer().getScheduler().runTaskLater(Main.getInstance(), new Runnable() {
    28. @Override
    29. public void run() {
    30. block.setType(air);
    31. System.out.println("worked4");
    32. }
    33. }, 20 * 30);
    34. }
    We're getting somewhere. It no longer gets stuck and lags out the server. However, if I'm in the air, it sets a carpet and the block under my player location (even though it's still air) and doesn't put it on the ground. Any ideas?
     
    Last edited by a moderator: Feb 28, 2015
  8. Offline

    uksspy

    @Signatured
    Changing the value of by does NOTHING to change anything else! You NEED to do Location.setY(by); for any effect. When you initialize an integer it basically clones it, so modifying it only helps to modify it in that one specific place, if that makes sense.
     
Thread Status:
Not open for further replies.

Share This Page