Solved Getting The Location Of New Chunks

Discussion in 'Spigot Plugin Development' started by Hello1231, Mar 8, 2020.

  1. I am trying to figure out where each new chunk is, and I'm using this code:
    Code (Text):
    @Override
        public void onEnable()
        {
            PluginManager pm = Bukkit.getServer().getPluginManager();
            pm.registerEvents(new ListenerClass(), this);
            Bukkit.getLogger().info("More Ores Loaded Successfully! :-D");
        }
        @Override
        public void onDisable()
        {
            Bukkit.getLogger().info("More Ores Loaded Successfully! :-D");
        }
    Code (Text):
    @EventHandler
        public void newChunkEvent(ChunkLoadEvent e) {
            if (e.isNewChunk()) {
                int x = e.getChunk().getX();
                int z = e.getChunk().getZ();
                Bukkit.broadcastMessage("A New Chunk Generated at Z:" +z+ "X:" +x);
            }
        }
    The code is sending me numbers from seemingly random parts of each chunk, but it does only seem to be giving me numbers once per chunk and numbers that are always along the perimiter of a chunk. It also seems to be putting out broadcasts for chunks that aren't new, but only sometimes.
     
  2. the same chunk can be unloaded and loaded again.. so it wont be unique. you're looking for generated chunks. dont know if theres an event for that, but pretty sure theres a hasBeenGenerated-like method somewhere
     
    • Like Like x 1
    • Agree Agree x 1
  3. #3 notjacob1, Mar 8, 2020
    Last edited: Mar 8, 2020
    • Like Like x 1
    • Like Like x 1
  4. I tried using this in my original code, but that didn't seem to work.
    I tried using the chunk populate event here:
    Code (Text):
    public class ListenerClass implements Listener{
        @EventHandler
        public void newChunkEvent(ChunkPopulateEvent e) {
                int x = e.getChunk().getX();
                int z = e.getChunk().getZ();
                e.getWorld().getBlockAt(x, 100, z).setType(Material.BEDROCK);
                Bukkit.getServer().broadcastMessage(x + "z:" + z);
        }
    }
    but I just ended up with:
    [​IMG]Which almost fills an entire chunk, there was just a corner missing, and spills into a couple of other chunks. All of these chunks had already been generated.
    Code (Text):
    public class ListenerClass implements Listener{
        @EventHandler
        public void newChunkEvent(ChunkPopulateEvent e) {
                int x = e.getChunk().getX();
                int z = e.getChunk().getZ();
                e.getWorld().getBlockAt(x, 100, z).setType(Material.GLASS);
                if (e.getChunk().isLoaded() && e.getWorld().isChunkGenerated(x, z)) {
                    Bukkit.getServer().broadcastMessage("isGenerated, isLoaded X: "+x + "z:" + z);
                }
                else if (e.getChunk().isLoaded()) {
                    Bukkit.getServer().broadcastMessage("isLoaded X: "+x + "z:" + z);
                }
                else if (e.getWorld().isChunkGenerated(x, z)) {
                    Bukkit.getServer().broadcastMessage("isGenerated X: "+x + "z:" + z);
                } else {
                Bukkit.getServer().broadcastMessage(x + "z:" + z);
                }}
    }
    When I tried this, isGenerated, isLoaded X: "+x + "z:" + z is all that was broadcasted, so both e.getChunk().isLoaded() and e.getWorld().isChunkGenerated(x, z) must be true every time. Here is what it looked like: [​IMG]So pretty much the same as last time. It is also in a chunk that was previously generated, as can be seen by the house.
    I don't understand how it picks these seemingly random chunks.
     
  5. The returned x and z values are the chunk coordinates, not the player / block coordinates to get the player / block coordinates of a chunk you must multiple the values with 16.
     
    • Useful Useful x 1
  6. So I changed the code to this:
    Code (Text):
    public class ListenerClass implements Listener{
        @EventHandler
        public void newChunkEvent(ChunkPopulateEvent e) {
                int x = e.getChunk().getX();
                int z = e.getChunk().getZ();
                int xx = x*16;
                int zz = z*16;
                e.getWorld().getBlockAt(xx, 100, zz).setType(Material.OBSIDIAN);
                if (e.getChunk().isLoaded() && e.getWorld().isChunkGenerated(x, z)) {
                    Bukkit.getServer().broadcastMessage("isGenerated, isLoaded X: "+xx + "z:" + zz);
                }
                else if (e.getChunk().isLoaded()) {
                    Bukkit.getServer().broadcastMessage("isLoaded X: "+xx + "z:" + z);
                }
                else if (e.getWorld().isChunkGenerated(x, z)) {
                    Bukkit.getServer().broadcastMessage("isGenerated X: "+xx + "z:" + zz);
                } else {
                Bukkit.getServer().broadcastMessage(xx + "z:" + zz);
                }}
    }
    and it is putting obsidian in the corner, but first it crashes the server with a crash report that is probably the longest I've ever seen:
    https://pastebin.com/BXxSUNVD
    What I can get from it is that it is caused by listener class line 18, which is e.getWorld().getBlockAt(xx, 100, zz).setType(Material.OBSIDIAN);. I'm not entirely sure if the obsidian is only generating in new chunks, but I haven't seen any reason to think it's generating in old chunks.
    The obsidian is in the northwest corner, so the lowest x and the lowest z of the chunk.
     
  7. Use e.getWorld().getBlockAt(xx, 100, zz).setType(Material.OBSIDIAN, false); When you not add false, the block triggers a Block update around it and since you place the block at the corner, it triggers a chunk Load on the two chunks next to the block, which are probably not generated. And triggers therefore a new ChunkPopulateEvent for the two chunks. -> an endless loop
     
    • Winner Winner x 1
  8. That worked perfectly! Thanks so much.