1. The forums will be archived and moved to a read only mode in about 2 weeks (mid march).

SetBlock in not generated Chunk

Discussion in 'Development' started by DanDen, Jun 10, 2018.

  1. DanDen

    DanDen Spider

    Messages:
    11
    Hello,
    I would need to generate chunks in ($x, $z) and then set blocks in ($x, $z)
    I had planned to do:
    - Generate chunks with generateChunkCallback ()
    - Once AsyncTask is completed with ChunkPopulating event do the SetBlock ()
    I wait for your help.
     
  2. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    PocketMine has a generator API that supports chunk population. Register a custom generator class during startup.
    https://github.com/pmmp/PocketMine-MP/blob/master/src/pocketmine/level/generator/Generator.php#L70
     
  3. DanDen

    DanDen Spider

    Messages:
    11
  4. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    If all you want to do is set one block, then you can use Level::setBlock() or Level::setBlockIdAt()
    PHP:
    /** @var Level $level */
    $block Block::get(Block::GRASS);

    $x 128;
    $y 128;
    $z 128;
    $pos = new Vector3($x$y$z);

    $level->setBlock($pos$block);
    //OR
    $level->setBlockIdAt($x$y$z$block->getId());
    $level->setBlockDataAt($x$y$z$block->getDamage());
    There are ongoing changes to chunk generation in the async-chunk-io-work branch. Once the changes are implemented, it might become easier for you to do what you want to do.
    PHP:
    #FOR async-chunk-io-work branch
    /** @var Level $level */
    /** @var int $chunkX */
    /** @var int $chunkZ */
    $level->loadChunk(
        
    $chunkX$chunkZ,
        function(
    Chunk $chunk) : void{
            
    $chunk->setBlock(11282Block::GRASS0);//x=1,y=128,z=2,blockId=GRASS,blockMetadata=0
        
    }
    );
     
  5. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    Another way would by using ChunkLoaders.
    Create a class that implements pocketmine\level\ChunkLoader.
    PHP:
    $chunk_loader = new MyChunkLoader();
    Register the ChunkLoader.
    PHP:
    /** @var Level $level */
    /** @var int $chunkX */
    /** @var int $chunkZ */
    $level->registerChunkLoader($chunk_loader$chunkX$chunkZtrue);
    // true autoloads the chunk.
    In the MyChunkLoader class, do what you want to do in the onChunkPopulated method. The method gets called after the Chunk finishes populating.
    PHP:
    class MyChunkLoader implements ChunkLoader{
        public function 
    onChunkPopulated(Chunk $chunk) : void{
            
    $chunk->setBlock(11282Block::GRASS0);
        }
    }
    After you're done, you'll need to unregister the chunk loader by calling Level::unregisterChunkLoader(). ChunkLoaders will keep the chunk loaded even when the chunk has no players (P.S. players are a type of chunk loaders themselves), so make sure you unregister the chunk loader.
     
    Last edited: Mar 1, 2019
  6. DanDen

    DanDen Spider

    Messages:
    11
    Hi, I found the best way to spawn blocks on an un-generated chunk.
    I had to necessarily wait for it to be explored,
    this allows you to see when the chunk is loaded and send everything to a function:
    PHP:
        public function onChunk(ChunkPopulateEvent $event){
            
    $level $event->getLevel();
            
    $x = (int) $event->getChunk()->getX();
            
    $z = (int) $event->getChunk()->getZ();
            
    $this->getPlugin()->util_class->onPopulatingCreate($x$z$level);
        }
    this adds blocks:
    PHP:
        public function onPopulatingCreate($x$zLevel $level) {
            
    $nlevel $level->getName();
            
    $x1 $x << 4;
            
    $z2 $z << 4;
            for (
    $xx $x1$xx $x1 16$xx ++) {
                for (
    $zz $z2$zz $z2 16$zz ++) {
                    for (
    $y 0$y 15$y++) {
                        if (isset(
    $this->getPlugin()->block[$nlevel][$xx][$y][$zz])) {
                            
    $arr $this->getPlugin()->block[$nlevel][$xx][$y][$zz];
                            
    $block Item::get($arr[0], $arr[1])->getBlock();
                            
    $level->setBlock(new Vector3($xx$y$zz), $blockfalsefalse);
                            unset(
    $this->getPlugin()->block[$nlevel][$xx][$y][$zz]);
                        }
                    }
                }
            }
        }
     
    Muqsit likes this.
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.