Replace chunk with another chunk

Discussion in 'Plugin Development' started by alu-, Jan 24, 2014.

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

    alu-

    Hi!
    I need some guidance in replacing a chunk with another chunk. I want to have a "preset" chunk, let's say a chunk with only air in it, and replace another chunk with data from my preset. What is the fastest way of doing this without iterating thru all the blocks in my target chunk and setting it to air?
    Basically currentChunkInMyWorld.replace( myPresetChunk );
    This present chunk does not need to exist in my world. I would, in some way, "hardcode" it in my plugin.
     
  2. Offline

    Maurdekye

    There really is no faster way than looping through the blocks individually. Changing minecraft worlds on a large scale is always time consuming.
     
  3. Offline

    beastman3226

    Maurdekye
    Please stop giving these suggestions that are incorrect and/or very resource intensive. I would suggest you learn a little more about the bukkit API.

    Anyway, alu- I suggest that you look around in the World class and see if you can find a method called setChunk (or something similar) with coordinates and just use the coordinates of the chunk you are trying to replace.
     
  4. Offline

    alu-

    I'm no expert in how chunks are stored in regions, but it occurs to me that if that data is simply stored in the file there has to be a way to just replace it with a predefined data faster than calling a bunch of functions to get the block and then set the block. Off course bukkit might not have this functionality, I just don't know.

    A convenience method to like replaceChunkWithChunk would have been nice thou. Guess I'm going to have to write it, block by block.

    Me not being a java-kinda-guy, what would be the simplest way to store a "preset" of a Chunk in java? For my purpose I don't really need any more data than the block id's/block names. Do metadata or anything really, just the block ids.
     
  5. Offline

    Maurdekye

    beastman3226 Please, stop accusing me of giving so-called 'incorrect' responses. I'm trying to help people find the answer as much as you are; at least give me some credit. I found a method Chunk.getChunkSnapshot(), you might be able to use that.
     
  6. Offline

    alu-

    beastman3226
    I did look into both Chunk and World in the javadocs, jd.bukkit.org, but could not find anything really useful. (I might be blind ;) )
    The closest I got was the World.getEmptyChunkSnapshot() which I could use to get an air chunk easy. I could then iterate thru that chunk and setting each block in my target chunk to, air. All tough it would be faster to just iterate thru the blocks and settings them to air, eliminating the need to get a empty snapshot.. :p
    A method called something like setChunkToChunkSnapshot would be what I'm looking for.

    Maurdekye beastman3226 please be friends :)
    As I just replied to beastman3226, a method called setChunkToChunkSnapshot would be what I'm looking for.
    After reading some more about the ChunkSnapshot class it seems to be more of a thread safety feature of doing read operations on a thread more than actually doing write operations.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 6, 2016
  7. Offline

    beastman3226

    Doesn't World have a createChunk or setChunk method? If you don't find anything that will work try a three dimensional array (perhaps create a wrapper to easily add and subtract blocks to and from the array). Should become fairly interesting towards the end.
     
  8. Offline

    Maurdekye

    beastman3226 He's not looking for a way to copy chunks, he just want to know if there's a faster way to empty out a large amount of them at once. You don't need to store anything in a tree dimensional array.
     
  9. Offline

    beastman3226

    Maurdekye
    I said the portion about the three dimensional array for hardcoding his chunk for replacing. Perhaps see if there is a chunk.delete() or World.deleteChunk(). I am away from my IDE so I can't play around with what each function actually does.
     
  10. Offline

    alu-

    beastman3226
    I'm afraid it does not. I guess I have to iterate thru blocks individually to achieve my goal. Two methods, one for making a "preset" array, and the other to overwrite the chunk with the preset.

    I guess there is also the possibility of parsing and rewriting the region files manually, when the server hasn't got a read/write lock on the region/world-files. But quite honestly I can't be bothered making something like that right now. :|
     
  11. Offline

    Maurdekye

    If you were to set an entire chunk to the same block, you wouldn't need to know what each block's type would be, just the one. A triple nested for loop structure with Block.setType(Material.AIR); should be fine.
     
    alu- likes this.
  12. Offline

    alu-

    Maurdekye
    Actually, as a matter of curiosity, I'm looking for both. ;)
    Collect all the thing!

    True true, but this would still require multiple getBlockAt (or whatever) operations to the bukkit API. And if, only if, there was a replaceChunks feature or alike, this would perhaps be faster and more optimized. I'm just looking for the fastest way. I've already got simple loops the achieve my goal, it's just trivial to make a few for loops.. Doing it in a optimized way however..

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 6, 2016
  13. Offline

    Maurdekye

    Well, if you want to copy chunks, you still might not need an array, but say, if you wanted to save them for later, you would. I would show code, but its not so easy on mobile.
     
  14. Offline

    beastman3226

    Ugh, that sucks.
    Try this:
    Code:java
    1. int x = 16*<chunk x coord>
    2. int max = x + 16;
    3. while(x < max) {
    4. int y = 0;
    5. while(y < 255) {
    6. int z = 16*<chunk z coord);
    7. int zmax = z +16;
    8. while(z < zmax) {
    9. Block b = new Location(world, x, y, z).getBlock();
    10. b.set(air);
    11. z++;
    12. }
    13. y++;
    14. }
    15. x++;
    16. }
     
  15. Offline

    alu-

    That kinda brings me to another question, which if I was a "java-kinda-guy" I probably could benchmark myself.
    What is faster, Block block = chunk.getBlock(x, y, z); or Block b = new Location(world, x, y, z).getBlock(); ? :)

    I might be splitting hairs here, I know. But if this operation is going to be called a million times each millisecond counts.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 6, 2016
  16. Offline

    Maurdekye

    Its probably negligible.
    Edit: they likely both derive from the same method, and so therefore wouldn't take much longer than each other.
     
  17. Offline

    alu-

    Maurdekye
    I've not beachmarked it, but I've read some code in craftbukkit. Using getBlock avoid using Location, so that path is faster (Again, without benchmarking). So I'm going that road.

    Guys, thanks for your input. It means alot getting answers this fast. <3
     
  18. Offline

    Maurdekye

    Back at my comp. Here's some possible code for copying one chunk to another,
    Code:java
    1. public void copyChunk(Chunk from, Chunk to) {
    2. for (int x = 0 ; x < 16 ; x++ ) {
    3. for (int z = 0 ; z < 16 ; z++) {
    4. for (int y = 0; y < 256 ; y++) {
    5. to.getBlock(x, y, z).setType(from.getBlock(x, y, x).getType());
    6. to.getBlock(x, y, z).setData(from.getBlock(x, y, x).getData());
    7. }
    8. }
    9. }
    10. }
     
    alu- likes this.
  19. Offline

    alu-

    Maurdekye
    Modifying your first argument to a ChunkSnapshot ( as we discussed before ) would probably make a snapshot restore easy. You have my thanks good sir.
     
Thread Status:
Not open for further replies.

Share This Page