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

Item interact with block

Discussion in 'Facepalm' started by SergeyIvanov, Jul 22, 2017.

  1. SergeyIvanov

    SergeyIvanov Witch

    Messages:
    59
    GitHub:
    sergeyivanov14
    Hi, i want to create Melon Launcher but i don't know how to get the item who was interact with block.
     
  2. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    describe the melon launcher
     
    XdmingXD and Sandertv like this.
  3. SergeyIvanov

    SergeyIvanov Witch

    Messages:
    59
    GitHub:
    sergeyivanov14
    I click with melon block and launch the melon and when melon hit the block melon despawn and create a lot of diamonds.
     
  4. Muqsit

    Muqsit Chicken

    Messages:
    1,548
    GitHub:
    muqsit
    You'll need to create and register a new projectile for this, let's name it "MelonBullet".
    PHP:
    <?php
    namespace space\name;

    use 
    pocketmine\entity\Projectile;

    class 
    MelonBullet extends Projectile {

        const 
    NETWORK_ID 64;//item id of DroppedItem in MCPE. Refer: http://minecraft.gamepedia.com/Pocket_Edition_data_values#Entity_IDs
    }
    As you've given only one condition, and that is when it collides with the ground, we'll need to make MelonBullet::canCollideWith(Entity) always return false. We don't want the bullet die after colliding with any entity.
    PHP:
    //class MelonBullet
    //If you are reading this in the future, @dktapps has probably
    //type-hinted this function, so please avoid quoting this message
    //with a "Declaration of Projectile::canCollideWith()..." error.
    public function canCollideWith(Entity $entity){
        return 
    false;
    }
    Now we need to create A LOT of diamonds when the bullet collides with the ground. For this, we'll use Level::dropItem() function and override Projectile:: onUpdate().
    PHP:
    //class MelonBullet

    const NUMBER_OF_DIAMONDS = [510];//we will choose a random number between 5 and 10

    //This method might get type-hinted too, in the future.
    public function onUpdate($currentTick){
        
    $result parent::onUpdate($currentTick);
        if(
    $this->hadCollision){//$hadCollision = projectile has hit the ground. I think $onGround does the same thing, not sure.
            
    $level $this->getLevel();
            if(
    $level !== null){
                
    $numberOfDiamonds mt_rand(...MelonBullet::NUMBER_OF_DIAMONDS);
                
    //TIP: Try calling as less methods as possible in loops. Loops aren't meant to be abused.
                
    $diamond Item::get(Item::DIAMOND);
                for(
    $i 0$i $numberOfDiamonds$i++){
                    
    $level->dropItem($this$diamond);
                }
            }
            
    //now we need to despawn the bullet as we do not need it anymore.
            
    $this->close();
        }
        return 
    $result;
    }
    Now the graphics part. This function is responsible for how the projectile will look like. MelonBullet is actually an item entity.
    PHP:
    //class MelonBullet
    public function spawnTo(Player $player){
        
    //YES, this if statement is important. parent::spawnTo() does it and calling it instead is okay...not!
        //We want to avoid double or triple spawning. Aside from that, the close() function is useless without
        //this if statement as there is gonna be no way to detect whom the projectile has been spawned to,
        //while despawning it.
        
    if(!isset($this->hasSpawned[$player->getLoaderId()]) and isset($player->usedChunks[Level::chunkHash($this->chunk->getX(), $this->chunk->getZ())])){
            
    $pk = new AddItemEntityPacket();
            
    $pk->entityRuntimeId $player->getId();
            
    $pk->item Item::get(Item::MELON_SLICE);//Hey, glistering melons would look better :D
            
    $pk->$this->x;
            
    $pk->$this->y;
            
    $pk->$this->z;
            
    $pk->metadata $this->dataProperties;
            
    $this->hasSpawned[$player->getLoaderId()] = $player;
        }
    }
    Now that you've done it, you'll need to register the class on startup. Make sure this is executed BEFORE we throw the entity. Try calling this in Plugin:: onEnable()
    PHP:
        Entity::registerEntity(MelonBullet::class);
    Now listen to PlayerInteractEvent and create the entity and set it's motion to what ever you prefer.
    PHP:
    /** @var PlayerInteractEvent $event */
    if($event->getItem()->getId() === Item::MELON_BLOCK){
        
    $pos $event->getPlayer()->getLocation();//location where the bullet will be spawned at.
        
    $bullet Entity::createEntity("MelonBullet"$pos->getLevel(), new CompoundTag("", [
            new 
    ListTag("Pos", [
                new 
    DoubleTag(""$pos->x),
                new 
    DoubleTag(""$pos->$event->getPlayer()->getEyeHeight()),
                new 
    DoubleTag(""$pos->z),
            ]),
            new 
    ListTag("Motion", [
                new 
    DoubleTag("", -sin($pos->yaw 180 M_PI) * cos($pos->pitch 180 M_PI)),
                new 
    DoubleTag("", -sin($pos->pitch 180 M_PI)),
                new 
    DoubleTag(""cos($pos->yaw 180 M_PI) * cos($pos->pitch 180 M_PI)),
            ]),
            new 
    ListTag("Rotation", [
                new 
    FloatTag(""$pos->yaw),
                new 
    FloatTag(""$pos->pitch),
            ]),
        ]));
        
    $force 1.4;//this is your preference.
        
    $bullet->setMotion($bullet->getMotion()->multiply($force));
        
    $bullet->spawnToAll();//spawns the bullet to everyone.
    }
     
    Thunder33345 and XdmingXD like this.
  5. XdmingXD

    XdmingXD Baby Zombie

    Messages:
    158
    GitHub:
    xdmingxd
    Nice tutorial : D
     
  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.