Advertisement
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

How to set drops?

Comments in 'Plugin Development' started by mclab, Feb 3, 2015.

  1. mclab
    Offline

    mclab Active Member

    Joined:
    Dec 24, 2014
    Posts:
    49
    Minecraft User:
    Dragonflex
    How to set drops when player break block?
  2. Samueljh1
    Offline

    Samueljh1 Active Member Plugin Developer

    Joined:
    Jan 9, 2015
    Posts:
    316
    Plugins:
    5
    Minecraft User:
    Samueljh1_
    Import:

    PHP:

    use pocketmine\event\BlockBreakEvent;

    Now do...

    PHP:

    public function onBreak(BlockBreakEvent $bb){

      
    $player $bb->getPlayer();
      
    $player->getLevel()->dropItem($player,Item::get(<myId>));

    }
    But.. I'm guessing you want to replace the default block drop.. so use:

    PHP:

    public function onBreak(BlockBreakEvent $bb){

      
    $player $bb->getPlayer();

      if(
    $bb->getBlock->getId() == <myId>){

        
    $bb->setCancelled();
        
    $player->getLevel()->dropItem($player,Item::get(<myId>));

      }

    }
    Last edited: Feb 4, 2015
    PEMapModder likes this.
  3. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,325
    Plugins:
    11
    Minecraft User:
    PEMapModder
    Note that the block itself must be broken via a schedule.
    iksaku likes this.
  4. Samueljh1
    Offline

    Samueljh1 Active Member Plugin Developer

    Joined:
    Jan 9, 2015
    Posts:
    316
    Plugins:
    5
    Minecraft User:
    Samueljh1_
    Oh yea, xD (The set cancelled will stop the actual break @mclab) xD
  5. Samueljh1
    Offline

    Samueljh1 Active Member Plugin Developer

    Joined:
    Jan 9, 2015
    Posts:
    316
    Plugins:
    5
    Minecraft User:
    Samueljh1_
    Why not just use setBlock() ?
  6. iksaku
    Offline

    iksaku Notable Member Plugin Developer

    Joined:
    Sep 2, 2013
    Posts:
    1,132
    Plugins:
    4
    Minecraft User:
    iksaku
    Because we just wanna modify the dropped item, not to change the block xD
  7. Samueljh1
    Offline

    Samueljh1 Active Member Plugin Developer

    Joined:
    Jan 9, 2015
    Posts:
    316
    Plugins:
    5
    Minecraft User:
    Samueljh1_
    set it to air xD what up with all these fancy schedulers? :p
  8. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,325
    Plugins:
    11
    Minecraft User:
    PEMapModder
    I didn't test it, but from what I suppose, when you cancel an event, it doesn't get instantly cancelled. I mean, the things that PocketMine does for a cancelled event (such as sending the old block back to the client) are done after all event handlers (or at least yours) have finished.
    So:
    Code:
    Player breaks the block
      => MCPE client would instantly set the block to air for the player, visually
      => MCPE client sends a packet to PocketMine, saying that that block is broken
    ↓
    PocketMine receives the break block packet
    => PocketMine internally fires a BlockBreakEvent
    => your plugin receives the event
    ↓
    Your plugin cancels the event. HOWEVER, IT ONLY MARKS THE EVENT AS CANCELLED, AND DOESN'T DO ANYTHING ELSE
    Your plugin calls setBlock()
      => PocketMine internally changes the block in the level
      => ★ PocketMine broadcasts about the change of the block
    ↓
    (Other handlers, if exist, but we ignore them right now)
    PocketMine finishes firing the BlockBreakEvent
    PocketMine checks if the event is cancelled.
      => it is cancelled.
      => ★ so, PocketMine sends a packet to the block breaking player, setting the block broken to its original type
    
    So let's see... What did the clients receive?
    • Block breaking player
      1. A packet setting the block to air as at the first ★
      2. A packet setting the block to its original value as at the second ★
    • Other players
      1. A packet setting the block to air as at the first ★
    Now, what about PocketMine itself? What happens to the world?
    • It only sees your setBlock() call, making the final block Air
    Also, suppose your event handler is at the HIGH priority, handlers at the HIGHEST priority and the MONITOR priority with @ignoreCancelled on will not listen to the event
    To summarize:
    To fix the first problem, you can call setBlock() in a delayed task.
    To fix the second problem, you can change priority to MONITOR to minimize the issue, but still, some plugins may still not know about the cancel.
    TigerHix likes this.

Share This Page

Advertisement