Hey all, I have a region manager where you do stuff similar to worldedit in the sense of settigs blocks. I currently store 2 locations and grab all the blocks inside that location in a List<Block>. I was wondering how do I go about pasting the blocks "1 by 1"? I heard you can do it with block states or something along those lines, but how would I go about doing this? I basically want it to place blocks one by one when they type /set <block>.
If this is merely for a visual effect (and not for speeding things up) just use a repeating or a delayed task
Not quite sure what you're trying to achieve (probably me just being dumb) If you're trying to do it so the server isn't being overloaded I'd do it in several broken up async tasks so the main thread isn't hindered, and split up in however many parts based on the amount of blocks being edited
Oh okay then I would go about it like I said before; use a delayed task like so: Make a list of "to-do" blocks -> add all of the blocks to this. Then, make a task that runs (however long you want) - While to-do isn't empty, run the delayed task which will get the next block from the "to-do" list, change it, and remove it. Alternatively this can be done with a repeating task too
So this is how I currently get my locations, Code (Text): public static List<Block> blocksFromTwoPoints(Location loc1, Location loc2) { List<Block> blocks = new ArrayList<>(); int topBlockX = (Math.max(loc1.getBlockX(), loc2.getBlockX())); int bottomBlockX = (Math.min(loc1.getBlockX(), loc2.getBlockX())); int topBlockY = (Math.max(loc1.getBlockY(), loc2.getBlockY())); int bottomBlockY = (Math.min(loc1.getBlockY(), loc2.getBlockY())); int topBlockZ = (Math.max(loc1.getBlockZ(), loc2.getBlockZ())); int bottomBlockZ = (Math.min(loc1.getBlockZ(), loc2.getBlockZ())); for (int x = bottomBlockX; x <= topBlockX; x++) { for (int z = bottomBlockZ; z <= topBlockZ; z++) { for (int y = bottomBlockY; y <= topBlockY; y++) { // Grab all blocks in the middle Block block = loc1.getWorld().getBlockAt(x, y, z); blocks.add(block); } } } return blocks; } then I grab it from here Code (Text): List<Block> blocks = LocationMethod.blocksFromTwoPoints(FactionWorldedit.selectedLocations.get(p).get(0), FactionWorldedit.selectedLocations.get(p).get(1)); I thought this would work but is your way the only way for it really to work? Code (Text): Bukkit.getScheduler().scheduleSyncRepeatingTask(FactionWorldedit.getInstance(), () -> { b.getState().update(true, false); b.getLocation().getWorld().spawnParticle(Particle.CLOUD, b.getLocation(), 6); }, 0L, 20L);
You don't really need to store all your blocks in a list. All you need to know is the min and max for x, y and z. You've already calculated those. Then what you can do is create a new Runnable that has member fields for x, y and z that start from the minimum. In the run method that runnable gets the block at the location and does whatever it needs and then increments x. If x is bigger than its max, set it to its min and increment z. If z is bigger than its max set it to its min and increment y. The order of the coordinates does not matter. But bare in mind that if you only ever do 1 block in a tick, you're going to have a horrible time changing large regions. You see, a 10x10x10 block region is 1000 blocks and would take 50 seconds to change. Whereas a 100x10x100 would take more than an hour. You'd be better off doing a number of different changes in a single tick.