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

How to reliably remove blocks in a cuboidal region?

Discussion in 'Help' started by Muqsit, Dec 22, 2016.

  1. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    I want to remove a set of blocks in a cuboidal region. And at the same time, instead of spawning ItemEntity, I want to move them directly to the player's inventory.
    Here's my code:
    PHP:
            //$ev = BlockBreakEvent
            //$lev = Level
            //$player  = $ev->getPlayer();
            
    $radius 2;
            
    $xo $block->$radius;
            
    $xp $block->$radius;
            
    $yo $block->$radius;
            
    $yp $block->$radius;
            
    $zo $block->$radius;
            
    $zp $block->$radius;
            
    $drops = [];
            for (
    $x $xo$x <= $xp$x++) {
                for (
    $y $yo$y <= $yp$y++) {
                    for (
    $z $zo$z <= $zp$z++) {
                        if (
    $lev->getBlockIdAt($x$y$z) !== 7) {
                            if ((
    $b $lev->getBlock(new Vector3($x$y$z)))->isSolid()) {
                                
    $lev->setBlock($b, new Air());
                                
    $drops[] = $b->getDrops($item);
                            }
                        }
                    }
                }
            }
            if (!empty(
    $drops)) {
                foreach (
    $drops as $drop) {
                    foreach (
    $drop as $ite) {
                        
    $player->getInventory()->addItem(Item::get($ite[0], $ite[1], $ite[2]));
                    }
                }
            }
            
    $ev->setDrops([]);
    Average Time:0.0053859272003174

    Is there an easier way to do this? Performance on priority.
     
  2. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    This is already the best method if you want to do it through the "normal" and "stable" way.
    You can of course also refer to MineReset by @falk, which unloads the chunks, processes and writes them asynchronously and loads them back in main thread and resend to clients. This is quite complicated, and I don't recommend it for anyone not completely familiar with PocketMine chunk loading and sending mechanism.
    You may also want to edit a limited amount of blocks per tick. You can refer to WorldEditArt for how it can be done.
    It is also possible to edit it like how it is done in the world generator, using setBlockId() etc., and then use sendBlocks(), but I don't think it is effective in updating client reference and may not really have great performance boost.
    After all, the main lag comes from sending the data to clients, not from editing the blocks server-side.
     
    Muqsit and HimbeersaftLP like this.
  3. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    Wow, thanks a lot for that information.
     
  4. falk

    falk Slime Poggit Reviewer

    Messages:
    75
    GitHub:
    falkirks
  5. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    You are here too, OMG!
    GG on the MineReset Asynchronous task. I am still trying to understand that and I hope the blog makes it easier :shoghi:
     
    Last edited: Dec 24, 2016
    Legoboy0215 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.