private void updateBlocks(Location origin) { Location minimum = origin.clone().subtract(BLOCK_RANGE, BLOCK_RANGE, BLOCK_RANGE); Location maximum = origin.clone().add(BLOCK_RANGE, BLOCK_RANGE, BLOCK_RANGE); Map snapshotList = new HashMap<>(); for (int x = minimum.getBlockX(); x <= maximum.getBlockX() + 16; x+=16) { for (int z = minimum.getBlockZ(); z <= maximum.getBlockZ() + 16; z+=16) { snapshotList.put(new ChunkPosition(x >> 4, z >> 4), origin.getWorld().getChunkAt(new Location(origin.getWorld(), x, 1, z)).getChunkSnapshot()); } } Vector originVector = origin.toVector(); for(ChunkPosition chunkPosition : snapshotList.keySet()) { ChunkSnapshot snapshot = snapshotList.get(chunkPosition); new Thread(() -> { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = (int) (origin.getY() - BLOCK_RANGE); y < origin.getY() + BLOCK_RANGE; y++) { int realX = chunkPosition.getChunkX() << 4 | x; int realZ = chunkPosition.getChunkZ() << 4 | z; Vector position = new Vector(realX, y, realZ); if (position.distance(originVector) > BLOCK_RANGE) continue; Material type = snapshot.getBlockType(x & 0xF, y, z & 0xF); if(shouldBreak(type)) synchronized (blockList) { blockList.add(new Location(origin.getWorld(), chunkPosition.getChunkX() << 4 | x, y, chunkPosition.getChunkZ() << 4 | z)); } } } } }).start(); } }