1.12.2 Iterating through all blocks inside a cubiod region. (Java 11)

Discussion in 'Spigot Plugin Development' started by jusjus112, Jul 20, 2020.

  1. Hi Guys,

    I am trying to figure out something weird and I am unable to achieve it while also used some resources from the internet without success. This is one of the small issues I've never been able to solve ever because of all the Math going on.


    I am basically trying to iterate through all blocks inside my own cuboid region.
    I have one class called "Region.java" and inside the class there is a function:
    Code (Java):
        public Iterator<Block> blockList() {
            final ArrayList<Block> bL = new ArrayList<>(this.getTotalBlockSize());
            for(int x = this.xMin; x <= this.xMax; ++x) {
                for(int y = this.yMin; y <= this.yMax; ++y) {
                    for(int z = this.zMin; z <= this.zMax; ++z) {
                        final Block b = this.world.getBlockAt(x, y, z);
                        bL.add(b);
                    }
                }
            }
            return bL.iterator();
        }
    My problem is that I keep getting large sizes back inside my debug such as "12373314" when I debug "...size"
    I looked through some other threads such as https://www.spigotmc.org/threads/how-to-get-all-blocks-around-two-locations.189289/
    But it keeps getting back large numbers of blocks when I select literally a line of 6 blocks.
    I hope you guys can think with me what I am missing.

    Thanks in advance,
    JusJus
     
  2. How is totalBlockSize calculated? Did you debug the min and max values?
     
  3. Oh yeah, my bad. totalBlockSize is calculated like this:

    Code (Java):
        public int getTotalBlockSize() {
            return this.getHeight() * this.getXWidth() * this.getZWidth();
        }
    The debug of the min and max values are:
    Code (Text):
    xMin = -255.5
    zMin - 504.5

    xMax = -255.5
    zMax = -498.5

    Loc1 = -255, 96, -504
    Loc2 = -255, 96, -498
     
  4. Well, this should just be zero, if getHeight() returns the difference between min and max (or the absolute value). How are the single components calculated?
    Is only the site faulty or does the whole array-list contain too mich elements?
     
  5. I'll have here the entire class, because I believe I'm not providing everything to get the right support. I'm sorry.
    https://hastebin.com/azovubaxep.java
     
  6. The same for this piece of code:

    Code (Java):
    public static List<Block> blocksFromTwoPoints(Location loc1, Location loc2)
        {
            List<Block> blocks = new ArrayList<Block>();
            int topBlockX = (loc1.getBlockX() < loc2.getBlockX() ? loc2.getBlockX() : loc1.getBlockX());
            int bottomBlockX = (loc1.getBlockX() > loc2.getBlockX() ? loc2.getBlockX() : loc1.getBlockX());
            int topBlockY = (loc1.getBlockY() < loc2.getBlockY() ? loc2.getBlockY() : loc1.getBlockY());
            int bottomBlockY = (loc1.getBlockY() > loc2.getBlockY() ? loc2.getBlockY() : loc1.getBlockY());
            int topBlockZ = (loc1.getBlockZ() < loc2.getBlockZ() ? loc2.getBlockZ() : loc1.getBlockZ());
            int bottomBlockZ = (loc1.getBlockZ() > loc2.getBlockZ() ? loc2.getBlockZ() : loc1.getBlockZ());
            for(int x = bottomBlockX; x <= topBlockX; x++)
            {
                for(int z = bottomBlockZ; z <= topBlockZ; z++)
                {
                    for(int y = bottomBlockY; y <= topBlockY; y++)
                    {
                        Block block = loc1.getWorld().getBlockAt(x, y, z);
                     
                        blocks.add(block);
                    }
                }
            }
         
            return blocks;
        }
    It returns a size of million of blocks?
     
  7. how are you seeing the size? u printing it to console when you load up your server?
     
  8. No, when I select the region of 6 blocks and then print out the size of the list that this function returns.
     
  9. thats what i meant. if you were using your server has a test development environment and printing to console. strange that it allocates at the millions. youll likely stackoverflow, but could you print the values you get and just upload the entire server log to wherever possible? the server might crash if there are truly millions of entries in it. be sure that any relevant information is printed before you print the contents of the list in the event it crashes. if it ends up showing something repetitive, you can force stop the server with ctrl + c in the console.

    additionally, can we see the code of where you are printing this value, as well as the value itself in the server log with the information above?

    /e i see your issue. when you are declaring your mins and maxes, you are only ever using less than or greater than. what if its equal? nothing is set. it stays at 0. so in the event you have x both are 350, both xs stay at zero. this would make a line, which could potentially be massive. one of your values must have an 'or equal to'. couldnt tell you why it does in your original method of Math#min/Math#max, as that looks fine.

    /e2 now that im thinking about the math of it mentally, even with that mistake, i dont think its possible to get millions of blocks. if your xs are both set to zero, but your z range is from 340-346, you would just have 0,340 to 0,346 * height count. there must be something going on. that information is still needed then

    /e3 i ran this:
    Code (Java):
    import java.util.ArrayList;
    import java.util.List;

    public class Test {
     
       public static void main(String[] args) {
          Test region = new Test(-255, 96, -504, -255, 96, -498);
          System.out.println(region.getTotalBlockSize());
          System.out.println(region.blockList().size());
       }
     
       private final int xMin;
       private final int xMax;
       private final int yMin;
       private final int yMax;
       private final int zMin;
       private final int zMax;
     
       public Test(int x1, int y1, int z1, int x2, int y2, int z2) {
          this.xMin = Math.min(x1, x2);
          this.xMax = Math.max(x1, x2);
          this.yMin = Math.min(y1, y2);
          this.yMax = Math.max(y1, y2);
          this.zMin = Math.min(z1, z2);
          this.zMax = Math.max(z1, z2);
       }
     
       public List<int[]> blockList() {
          List<int[]> bL = new ArrayList<>(this.getTotalBlockSize());
          for (int x = xMin; x <= xMax; ++x) {
             for (int y = yMin; y <= yMax; ++y) {
                for (int z = zMin; z <= zMax; ++z) {
                   bL.add(new int[] {x, y, z});
                }
             }
          }
          return bL;
       }
     
       public int getHeight() {
          return this.yMax - this.yMin + 1;
       }
     
       public int getXWidth() {
          return this.xMax - this.xMin + 1;
       }
     
       public int getZWidth() {
          return this.zMax - this.zMin + 1;
       }
     
       public int getTotalBlockSize() {
          return this.getHeight() * this.getXWidth() * this.getZWidth();
       }
     
    }
    as a quick test.
    this was the output:
    Code (Text):
    "C:\Program Files\Java\jdk1.8.0_231\bin\java.exe"
    ...
    Connected to the target VM, address: '127.0.0.1:64347', transport: 'socket'
    7
    7
    Disconnected from the target VM, address: '127.0.0.1:64347', transport: 'socket'
    Process finished with exit code 0
    its simply gotta be something youre overlooking
     
    #9 Warren1001, Jul 21, 2020
    Last edited: Jul 21, 2020