Solved setBlock not working (Automatically breaks the flower instead of placing it)

Discussion in 'Development' started by VincBros, Mar 25, 2020.

  1. VincBros

    VincBros Silverfish

    Messages:
    15
    GitHub:
    vincbros
    I am making this plugin that places a block on top of the other.

    Basically, when I place a coarse dirt, I want it to place a flower or tall grass on top of the coarse dirt.
    Code:
     public function onBlockPlace(BlockPlaceEvent $event) {
            $block = $event->getBlock();
            $player = $event->getPlayer();
            $level = $player->getLevel();
            $above = $block->add(0, 1, 0);
            if ($block->getId() == Block::DIRT) {
                if($block->getDamage() === 1){
                    if($block->getLevel()->getBlock($above)->getId() === Block::AIR){
                        switch(mt_rand(1, 50)) {
                        case 1:
                            $block->getLevel()->setBlock($above, Block::get(31, 1));
                            break;
                        case 2:
                            $block->getLevel()->setBlock($above, Block::get(31, 1));
                            break;
                        case 3:
                            $block->getLevel()->setBlock($above, Block::get(31, 1));
                            break;
                        case 4:
                            $block->getLevel()->setBlock($above, Block::get(31, 1));
                            break;
                        case 5:
                            $block->getLevel()->setBlock($above, Block::get(38, 1));
                            break;
                        case 6:
                            $block->getLevel()->setBlock($above, Block::get(38, 2));
                            break;
                        case 7:
                            $block->getLevel()->setBlock($above, Block::get(31, 1));
                            break;
                       // [...]
                        case 50:
                            $block->getLevel()->setBlock($above, Block::get(31, 1));
                            break;
                    }
                }
            }
        }
    }
    
    Instead of placing a flower (38,2 and 38,1), it only drops the item. It also dosen't place tall grass(31,1) on top of the coarse dirt, nothing happens.

    I don't know what to do. I tested it by replacing the flowers and the tall grass with stone and it worked. It was placing stone on top of the coarse dirt.
    Sorry for my bad english, I am french.
     
  2. GamakCZ

    GamakCZ Zombie Pigman

    Messages:
    439
    GitHub:
    GamakCZ
    Have you registered listener?
     
  3. VincBros

    VincBros Silverfish

    Messages:
    15
    GitHub:
    vincbros
    Yup
    Code:
        public function onEnable() {
            $this->getServer()->getPluginManager()->registerEvents($this, $this);
      }
    
    I think that the tall grass/flowers automatically breaks themselves because they don't detect that there is a block of coarse dirt under them.
    Is there a way I could prevent the block from breaking themselves?
     
  4. VincBros

    VincBros Silverfish

    Messages:
    15
    GitHub:
    vincbros
    Anyone knows what's the problem here?
     
  5. GamakCZ

    GamakCZ Zombie Pigman

    Messages:
    439
    GitHub:
    GamakCZ
    Add debug after every if()
     
  6. wolfdale

    wolfdale Zombie Pigman

    Messages:
    403
    When BlockPlaceEvent is called, the coarse dirt is not set in the level yet, you need to delay the setblock of the flower by using task eg ClosureTask
     
  7. VincBros

    VincBros Silverfish

    Messages:
    15
    GitHub:
    vincbros
    Like this?
    Code:
      public function onBlockPlace(BlockPlaceEvent $event) {
            $block = $event->getBlock();
            $player = $event->getPlayer();
            $level = $player->getLevel();
            $above = $block->add(0, 1, 0);
            if ($block->getId() == Block::DIRT) {
                if($block->getDamage() === 1){
                    if($block->getLevel()->getBlock($above)->getId() === Block::AIR){
                            $this->getScheduler()->scheduleDelayedTask(new ClosureTask(
                               function(int $currentTick){
                                switch(mt_rand(1, 50)) {
                                    case 1:
                                        $block->getLevel()->setBlock($above, Block::get(31, 1));
                                        break;
                                    case 2:
                                        $block->getLevel()->setBlock($above, Block::get(31, 1));
                                        break;
                                    case 3:
                                        $block->getLevel()->setBlock($above, Block::get(31, 1));
                                        break;
                                    case 4:
                                        $block->getLevel()->setBlock($above, Block::get(31, 1));
                                        break;
                                    case 5:
                                        $block->getLevel()->setBlock($above, Block::get(38, 1));
                                        break;
                                    case 6:
                                        $block->getLevel()->setBlock($above, Block::get(38, 2));
                                        break;
                                    case 7:
                                        $block->getLevel()->setBlock($above, Block::get(31, 1));
                                        break;
                                    // [...]
                                    case 50:
                                        $block->getLevel()->setBlock($above, Block::get(31, 1));
                                        break;
                               }
                            }
                            ), 20);
                         }
                    }
                }
            }
    
     
    Last edited: Mar 26, 2020
  8. VincBros

    VincBros Silverfish

    Messages:
    15
    GitHub:
    vincbros
    Not working...
     
  9. wolfdale

    wolfdale Zombie Pigman

    Messages:
    403
    change
    PHP:
    function(int $currentTick){
    to
    PHP:
    function(int $currentTick) use ($block,$above){
    and it should work
    Also be sure to check the level is not closed before setting the block to prevent setblock on null
     
    VincBros likes this.
  10. VincBros

    VincBros Silverfish

    Messages:
    15
    GitHub:
    vincbros
    How exactly am I doing that? I don't understand...
    [01:46:19] [Server thread/CRITICAL]: Error: "Class 'Vinc\Generator\ClosureTask' not found" (EXCEPTION) in "plugins/Generator/src/Vinc/Generator/Main" at line 216
     
  11. RoyalMCPE

    RoyalMCPE Slime

    Messages:
    87
    You're not importing pocketmine\scheduler\ClosureTask
     
    VincBros likes this.
  12. Invy55

    Invy55 Witch

    Messages:
    52
    GitHub:
    invy55
    What about simply set the block without updates like this
    PHP:
    $block->getLevel()->setBlock($aboveBlock::get(311), falsefalse);
    Check here to understand why: https://github.com/pmmp/PocketMine-MP/blob/stable/src/pocketmine/level/Level.php#L1590
     
  13. VincBros

    VincBros Silverfish

    Messages:
    15
    GitHub:
    vincbros
    What's this now?

    [16:09:34] [Server thread/CRITICAL]: TypeError: "Declaration of callable `function ( int $currentTick )` must be compatible with `function ( int $currentTick ) : void`" (EXCEPTION) in "src/pocketmine/utils/Utils" at line 714
     
  14. VincBros

    VincBros Silverfish

    Messages:
    15
    GitHub:
    vincbros
    Thanks guys it's now working!
     

Share This Page

  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.