Solved ChunkGenerator, how to call super.generateChunkData()

Discussion in 'Plugin Development' started by Banjer_HD, Nov 15, 2019.

  1. Offline

    Banjer_HD

    Hey there,

    I am trying to make a 'grid' like world with a chunk row every other chunk.
    Example:
    0|0|0
    0|0|0
    0|0|0
    Where 0 is 16x16 normal chunk
    And | is 16x16 void chunk

    What I am trying just for testing is:
    Code:
        @Override
        public ChunkData generateChunkData(World world, Random random, int chunkX, int chunkZ, BiomeGrid biome) {
    
           
            ChunkData gen = null;
            try {
                gen = super.generateChunkData(world, random, chunkX, chunkZ, biome);
            } catch (Exception e) {
                Bukkit.broadcastMessage("Can't super");
            }
    
    
            return createChunkData(world);
        }
    Which is returning: 'Can't super'
    If I don't at the try,catch it will give 'UnsupportedOperationException: Custom generator is missing required method generateChunkData'

    If I look at the source of ChunkGenerator the function generateChunkData() is:
    Code:
        @NotNull
        public ChunkData generateChunkData(@NotNull World world, @NotNull Random random, int x, int z, @NotNull BiomeGrid biome) {
            throw new UnsupportedOperationException("Custom generator is missing required method generateChunkData");
        }
    Is there just no way that I can achieve this with?
     
  2. Offline

    knokko

    You will need to define the generator you want to use for generating the normal chunks. It's probably possible to get the default generators from somewhere (but I don't know how). Once you have it, just call its generateChunkData.
     
  3. Offline

    Banjer_HD

    Thanks for your reply!!
    I tried to get the default world generator by doing:
    1.
    Code:
    plugin.getDefaultWorldGenerator("world", null)
    2.
    Code:
    WorldCreator worldcreator = new WorldCreator("WORLDNAME");
            worldcreator.environment(Environment.NORMAL);
            worldcreator.generator();
    and 3.
    Code:
    ChunkGenerator test = new ChunkGenerator();
    1 and 2 returned null (Docs: 'This may be null, in which case the "natural" generator for this environment will be used.')
    and 3 isn't possible because ChunkGenerator is an abstract class.

    Do you have any idea's how I could do this?
    Thanks!
     
  4. Offline

    caderapee

    @Banjer_HD
    If you want to change the default world generator
    If you create a custom one, use worldCreator.generator(new yourGeneratorClass());

    Then you can manage each chunk, use the x and y coordinate .
    the code below turn a flat word into a void world.

    Code:
    public class yourGeneratorClass extends ChunkGenerator {
    
      
        @Override
        public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) {
            ChunkData chunk = createChunkData(world);
          
          
            for (int X = 0; X < 16; X++) {
                for (int Z = 0; Z < 16; Z++) {
                    for (int y = 0; y <= 10; y++) {
                        chunk.setBlock(X, y, Z, Material.AIR);
                    }
                }
            }
          
            return chunk;
        }
    }
    
     
  5. Offline

    knokko

    @Banjer_HD
    If you aren't manipulating the main world "world" itself, you could try Bukkit.getWorld("world").getGenerator(). I haven't tested it, but this might return the generator for the overworld. Then just invoke its generateChunkData() method. I hope that works because it's the last idea I have. If it doesn't, you could try another approach: abuse the ChunkPopulateEvent to destroy half of the chunks.

    @caderapee I think Banjer is trying to get the default (the one created by Mojang) chunk generator for the overworld. I think he wants to use the default chunk generator to generate the 'normal' chunks.
     
    Banjer_HD likes this.
  6. Offline

    Banjer_HD

    @knokko Bukkit.getWorld("world").getGenerator() also returns null

    I tried doing this for both ChunkPopulateEvent and ChunkLoadEvent(only new chunks) but it takes AGES.
    Code:
                    Bukkit.getScheduler().runTask(plugin, new Runnable() {
                        public void run() {
    
    
    
    
    
    
    
                            for(int x = 0; x < 16; x++) {
    
                                int actualX = x + eve.getChunk().getX() * 16;
    
                                for(int z = 0; z < 16; z++) {
    
                                    int actualZ = z + eve.getChunk().getZ() * 16;
    
                                    for(int y = 0; y < eve.getWorld().getHighestBlockAt(actualX, actualZ).getY(); y++) {
    
                                        if(eve.getWorld().getBlockAt(actualX, y, actualZ).getType() != Material.AIR) {
                                            eve.getWorld().getBlockAt(actualX, y, actualZ).setType(Material.AIR);
                                        }
    
                                    }
                                }
                            }
    
    
    
    
    
                        }
                    });
    
    I don't think it is possible in bukkit.... :(

    Still thanks for helping me!
     
  7. Offline

    knokko

    @Banjer_HD This should be possible and not take extremely long. I think you might introduce a cycle somewhere, but I'm not sure if and where.
    Have you tried hardcoding the maximum y to 2 instead of the highest block (just for testing)? If that works, you should be able to see the result by flying below your world (and this should definitely not take ages).
    If the time it takes is really the problem, you could alternatively prepare the world in advance and destroy the chunks step by step (destroying a fixed amount of blocks per tick in a repeating task until it's done).
     
  8. Offline

    caderapee

    @Banjer_HD
    It's possible, i gave you the link. Define in your bukkit.yml the generator to use for the world you want, like 'world' or 'world_nether'. You will have to create a plugin that load on startup and put the name of your plugin in the bukkit.yml. Your main class must have the defaultWorldGenerator Method, then call your generator class from it.
     
  9. Offline

    Banjer_HD

    That is not what I am trying to achieve

    Thank you so much for you help!

    I managed to do it by doing chunk.getBlock(x, y, z).setType(Material.AIR, false)
    That false was needed to not update other chunks, that created an infinite loop and that's why it didn't work.

    It create's a world now in around 1:45, still not very fast, but okay...

    Thanks again! Marked it as Solved

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Nov 20, 2019

Share This Page