Solved Delaying a nested For-Loop

Discussion in 'Plugin Development' started by sander_blaadjes, Jul 23, 2015.

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

    sander_blaadjes

    I have been trying for way too long to solve this, I am quite sure someone knows an easy solution ;)
    So, I have this code, which builds a home from a schematic, but I want to have a delay, so it looks cool. I already tried different things, including Thread.sleep() (Which obviously crashed my server). Below is the current code using a Bukkit SyncRepeatingTask. Obviously this is broken, because it builds the house again every second.

    Code:java
    1. public static void pasteSchematic(final World world, final Location loc, Schematic schematic)
    2. {
    3. final short[] blocks = schematic.getBlocks();
    4. final byte[] blockData = schematic.getData();
    5. final short length = schematic.getLenght();
    6. final short width = schematic.getWidth();
    7. final short height = schematic.getHeight();
    8. Bukkit.getScheduler().scheduleSyncRepeatingTask(Garrison.getPlugin(), new Runnable() {
    9. public void run() {
    10. for (int x = 0; x < width; ++x) {
    11. for (int y = 0; y < height; ++y) {
    12. for (int z = 0; z < length; ++z) {
    13. final int xi = x;
    14. final int yi = y;
    15. final int zi = z;
    16. int index = yi * width * length + zi * width + xi;
    17. Block block = new Location(world, xi + loc.getX(), yi + loc.getY(), zi + loc.getZ()).getBlock();
    18. block.setTypeIdAndData(blocks[index], blockData[index], true);
    19. loc.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, blockData[index]);
    20. }
    21. }
    22. }
    23. }
    24. }, 20L, 20L);
    25. }
     
  2. Offline

    MisterErwin

    Instead of declaring the x,y and z variable each time, I would declare them once for your class.
    (So they are persistent)

    Then use a counter variable, if you reach a certain amount of operations, "return".
    When the Runnable is "executed" the next time, it will continue where it left ;)
     
  3. Offline

    sander_blaadjes

    @MisterErwin
    I don't quite understand what you mean by this :/
     
  4. Offline

    MisterErwin

    @sander_blaadjes inside the run method, have a local variable.

    And each time you set a block, increase it by one.

    And if it is higher than a treshhold. exit the method (via return)
     
  5. Offline

    sander_blaadjes

    @MisterErwin Won't the local variable inisde the run method, reset each time it repeats?
     
  6. Offline

    MisterErwin

    @sander_blaadjes It will. But you have to use something that "pauses" the action after x block changes, otherwise all will be done within one run.

    And something I forgot: When the job finishes (the loops end/after the last closing bracket of the loops): Cancel the runnable ;)
     
  7. Offline

    sander_blaadjes

    I solved it by adding it to a list first, and then a delayed loop throught that list ;) If anyone is looking for the solution:
    Code:java
    1. public static List<Blok> schematicToList(final World world, final Location loc,
    2. Schematic schematic) {
    3. List<Blok> blokken = new ArrayList<Blok>();
    4. final short[] blocks = schematic.getBlocks();
    5. final byte[] blockData = schematic.getData();
    6.  
    7. final short length = schematic.getLenght();
    8. final short width = schematic.getWidth();
    9. final short height = schematic.getHeight();
    10.  
    11.  
    12. for (int x = 0; x < width; ++x) {
    13. for (int y = 0; y < height; ++y) {
    14. for (int z = 0; z < length; ++z) {
    15. int index = y * width * length + z * width + x;
    16. blokken.add(new Blok(new Location(world, x + loc.getX(), y
    17. + loc.getY(), z + loc.getZ()), blocks[index], blockData [index]));
    18. }
    19. }
    20. }
    21. return blokken;
    22. }
    23. static int taskID = 50;
    24. public static void smoothPaste(final List<Blok> blokken){
    25. final MutableInt x = new MutableInt(0);
    26. taskID = Bukkit.getScheduler().scheduleSyncRepeatingTask(Garrison.getPlugin(), new Runnable(){
    27. @SuppressWarnings("deprecation")
    28. public void run(){
    29. final int i = x.toInteger();
    30. Blok blok = blokken.get(i);
    31. Block block = blok.getLocation().getBlock();
    32. block.setTypeIdAndData(blok.getId(), blok.getData(),true);
    33. blok.getLocation().getWorld().playEffect(blok.getLocation(), Effect.STEP_SOUND, blok.getId());
    34.  
    35. x.add(1);
    36. if(i >= blokken.size()-1){
    37. StopTimer(taskID);
    38. }
    39. }
    40. }, 1L, 1L);
    41. }
     
Thread Status:
Not open for further replies.

Share This Page