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

EntityMovement (Packet)

Comments in 'Plugin Development' started by ImagicalGamer, May 14, 2016.

  1. ImagicalGamer
    Offline

    ImagicalGamer Active Member

    Joined:
    Feb 25, 2016
    Posts:
    141
    Minecraft User:
    ImagicalGamer
    I'm working on a BlockHunt "AI", It spawns falling sand entitys as packets with a command (for now), how can I change the "entity's" position to follow the player?
    CODE:
    PHP:
    const NETWORK_ID 66;

    public function 
    spawnTo($player){
              foreach(
    $this->getServer()->getOnlinePlayers() as $p){
            
    $pk = new AddEntityPacket();
            
    $pk->eid Entity::$entityCount++;
            
    $pk->type self::NETWORK_ID;
            
    $pk->$player->.2;
            
    $pk->$player->1;
            
    $pk->$player->z;
            
    $pk->yaw $player->yaw;
            
    $pk->pitch $player->pitch;
            
    $pk->metadata = [
                
    15 => [01],
                
    20 => [2rand(1,20)]
            ];
            
    $p->dataPacket($pk);
          }
        }
  2. TheKnightGamer
    Offline

    TheKnightGamer New Member

    Joined:
    Dec 25, 2015
    Posts:
    34
    Minecraft User:
    TheKnightGamerYT
    It like the pet plugin from LBCore the pet follow you so if you can change it up you can let the block follow you.
  3. ImagicalGamer
    Offline

    ImagicalGamer Active Member

    Joined:
    Feb 25, 2016
    Posts:
    141
    Minecraft User:
    ImagicalGamer
    I tried using that method but since this is on a command it didn't work the same.
  4. TheKnightGamer
    Offline

    TheKnightGamer New Member

    Joined:
    Dec 25, 2015
    Posts:
    34
    Minecraft User:
    TheKnightGamerYT
    Hmm that going to be a little hard.
  5. Legoboy0215
    Offline

    Legoboy0215 Notable Member

    Joined:
    Nov 1, 2014
    Posts:
    1,724
    Minecraft User:
    Legoboy0215
    It's quite easy. Change the entity id of the sand to the player. Then despawnToAll the player. After that, if you want the player back then respawn to all... BTW, if you don't understand please don't use the leaked lbcore's example. :) Thanks.
    ImagicalGamer likes this.
  6. ImagicalGamer
    Offline

    ImagicalGamer Active Member

    Joined:
    Feb 25, 2016
    Posts:
    141
    Minecraft User:
    ImagicalGamer
    OK, but wouldn't that crash the player having 2 entitys with tjhe same ID?
  7. ImagicalGamer
    Offline

    ImagicalGamer Active Member

    Joined:
    Feb 25, 2016
    Posts:
    141
    Minecraft User:
    ImagicalGamer
    ahh nvm Thats why we despawn the player
    Legoboy0215 likes this.
  8. Driesboy1
    Offline

    Driesboy1 Active Member

    Joined:
    Oct 28, 2015
    Posts:
    102
    Minecraft User:
    Driesboy
    use the slapper methode to spawn and the slapper methode tp for movement
  9. Primus
    Offline

    Primus Notable Member

    Joined:
    Apr 7, 2015
    Posts:
    1,470
    Minecraft User:
    PrimusLV
  10. Legoboy0215
    Offline

    Legoboy0215 Notable Member

    Joined:
    Nov 1, 2014
    Posts:
    1,724
    Minecraft User:
    Legoboy0215
    TP? Slapper does not have movement anyways. The entity ID solves everything XD
  11. Driesboy1
    Offline

    Driesboy1 Active Member

    Joined:
    Oct 28, 2015
    Posts:
    102
    Minecraft User:
    Driesboy
    yes but it teleport it to you
    place that on playermovement
  12. Legoboy0215
    Offline

    Legoboy0215 Notable Member

    Joined:
    Nov 1, 2014
    Posts:
    1,724
    Minecraft User:
    Legoboy0215
    Why would you want to teleport a block every tick to you? that is very inefficient.
    ImagicalGamer likes this.
  13. Primus
    Offline

    Primus Notable Member

    Joined:
    Apr 7, 2015
    Posts:
    1,470
    Minecraft User:
    PrimusLV
    Spawning entity with same eId will synchronize movement, except.. block will be spawned on player eye height.
  14. ImagicalGamer
    Offline

    ImagicalGamer Active Member

    Joined:
    Feb 25, 2016
    Posts:
    141
    Minecraft User:
    ImagicalGamer
  15. Primus
    Offline

    Primus Notable Member

    Joined:
    Apr 7, 2015
    Posts:
    1,470
    Minecraft User:
    PrimusLV
    The answer for this thread is in the code I show there.

    Juggling bug fix:
    PHP:
    // Add this to onUpdate() function to avoid entity jumping
    /** @var Player $this->owner */
    $this->level->addEntityMovement($this->owner->>> 4$this->owner->>> 4$this->getId(), $this->owner->x$this->owner->0.49000001$this->z$this->owner->yaw$this->owner->pitch$this->owner->yaw);
    Disguise code:
    PHP:
    // Use this code to change player entity to FallingSand or custom like my Block entity class
    // Which basically extends FallingSand
    /**
    * Will turn player into block!
    * Hiding block should be done with function Block::hide();
    *
    * @param Player $player player to change
    * @param Integer $id Block id
    * @param Integer $damage and Block meta data
    */
    public function disguise(Player $player$id$damage){
    # Hide
    foreach($this->getServer()->getOnlinePlayers() as $for){
    if(
    $player !== $for$for->hidePlayer($player);

    }
    # Add Block entity
    $entity Entity::createEntity("Block"$player->getLevel()->getChunk($player->>> 4$player->>> 4), new CompoundTag("", [
    "Pos" => new ListTag("Pos", [
    new 
    DoubleTag(""$player->x),
    new 
    DoubleTag(""$player->y),
    new 
    DoubleTag(""$player->z)
    ]),
    "Motion" => new ListTag("Motion", [
    new 
    DoubleTag(""0),
    new 
    DoubleTag(""0),
    new 
    DoubleTag(""0)
    ]),
    "Rotation" => new ListTag("Rotation", [
    new 
    FloatTag(""0),
    new 
    FloatTag(""0)
    ]),
    "TileID" => new IntTag("TileID"$id),"Data" => new ByteTag("Data"$damage),"Owner" => new LongTag("Owner"$player),
    ]));

    foreach(
    $this->getServer()->getOnlinePlayers() as $for){
    $entity->spawnTo($for);
    }

    return 
    true;
    }
    This is class I made for my BlockHunt
    PHP:
    <?php
    namespace sbh\Entity;

    use 
    sc\Utils\SupremeTextFormat as Text;

    use 
    pocketmine\entity\Living;
    use 
    pocketmine\entity\Entity;
    use 
    pocketmine\entity\FallingSand;
    use 
    pocketmine\block\Block as BlockBlock;

    use 
    pocketmine\event\entity\EntityBlockChangeEvent;
    use 
    pocketmine\event\entity\EntityDamageEvent;

    use 
    pocketmine\item\Item as ItemItem;
    use 
    pocketmine\math\Vector3;
    use 
    pocketmine\nbt\tag\ByteTag;
    use 
    pocketmine\nbt\tag\IntTag;
    use 
    pocketmine\nbt\tag\LongTag;
    use 
    pocketmine\network\Network;
    use 
    pocketmine\network\protocol\AddEntityPacket;
    use 
    pocketmine\network\protocol\RemoveEntityPacket;
    use 
    pocketmine\network\protocol\SetEntityMotionPacket;
    use 
    pocketmine\Player;

    class 
    Block extends Living {

       const 
    NETWORK_ID 66;

       const 
    DATA_BLOCK_INFO 20;

       public 
    $width 0.98;
       public 
    $length 0.98;
       public 
    $height 0.98;

       protected 
    $blockId 0;
       protected 
    $damage;
       protected 
    $solid false;
      protected 
    $solidBlocks = [];
       protected 
    $solidBlock null;
       protected 
    $hide false;
       protected 
    $replaced 0// What block did this entity cover when turning into solid block ?

       
    protected $petrifaction 1;
       protected 
    $maxPetrifaction 100;
       private 
    $hided false;

       public 
    $canCollide false;
      private 
    $owner;

      public function 
    setOwner(Player $player){
         
    $this->owner $player;
         
    $this->id $player->getId();
       }

       public function 
    setSolid($value){
         
    $this->solid = (bool) $value;
       }

       public function 
    onUpdate($currentTick){
         
    $this->level->addEntityMovement($this->owner->>> 4$this->owner->>> 4$this->getId(), $this->owner->x$this->owner->0.49000001$this->z$this->owner->yaw$this->owner->pitch$this->owner->yaw);
         if(!
    $this->owner instanceof Player or !$this->owner->isAlive() or !$this->owner->isConnected()){
           unset(
    $this->owner->entityBlock);
           foreach(
    $this->solidBlocks as $k => $pos) {
             if(
    $this->level->getBlock($pos) === $this->solidBlock){
               
    $this->level->setBlock($posBlockBlock::get(0));
               unset(
    $this->solidBlocks[$k]);
               
    $this->solidBlock null;
             }
           }
           
    $this->close();
           return;
         }
         if(
    $this->x  != $this->lastX or $this->!= $this->lastY or $this->!= $this->lastZ){
           
    $this->resetPetrifaction();
         }

           
    $this->lastX $this->x;
           
    $this->lastY $this->y;
           
    $this->lastZ $this->z;
     
         if(
    $this->solid){
           if(!
    $this->isOnEdge()){
             
    $pos = new Vector3($this->getFloorX(), $this->getFloorY() + 0.6$this->getFloorZ());
             if(
    $this->isPlaceTaken($pos) === false) {
               
    $this->hide true;
               
    $block BlockBlock::get($this->getBlock(), $this->getDamage());
               
    $this->replaced $this->level->getBlock($pos);
               
    $this->level->setBlock($posBlockBlock::get($this->getBlock(), $this->getDamage()));
               
    $this->solidBlocks[] = $pos;
               
    $this->solidBlock $this->level->getBlock($pos);
               
    $this->level->setBlock($pos$block);
               if (
    $this->hided === false$this->getOwner()->sendMessage("> You are now solid");
             } else {
               
    $this->owner->sendTip(Text::GRAY."You can't hide here");
               
    $this->solid false;
               --
    $this->petrifaction;
             }
           } else {
             
    $this->owner->sendTip(Text::GRAY."You are standing on edge");
           }
         } else {
           
    $this->hide false;
         }
         if(
    $this->hide){
           if(!
    $this->hided){
             
    $pk = new RemoveEntityPacket();
             
    $pk->eid $this->getId();

             
    $this->server->broadcastPacket($this->server->getOnlinePlayers(), $pk);
             
    $this->hided true;
           }
         } else {
           if(
    $this->hided){
             
    $this->spawnToAll();
             foreach(
    $this->solidBlocks as $k => $pos) {
               if(
    $this->level->getBlock($pos) === $this->solidBlock){
                 
    $this->level->setBlock($pos$this->replaced);
                 unset(
    $this->solidBlocks[$k]);
                 
    $this->solidBlock null;
               }
             }
             
    $this->hided false;
           }
         }

         if(
    $this->solid){
           if(
    $this->petrifaction $this->maxPetrifaction){
             
    $this->solid false;
           }
         } else {
           if(
    $this->petrifaction >= $this->maxPetrifaction){
             
    $this->solid true;
           } else {
             
    $this->getOwner()->setXpProgress($this->petrifaction $this->maxPetrifaction);
             
    $this->petrifaction++;
           }
         }
         
    $this->setPosition($this->getOwner()->getPosition());
         return 
    true;
       }

       protected function 
    initEntity(){
         
    parent::initEntity();

         if(isset(
    $this->namedtag->TileID)){
           
    $this->blockId $this->namedtag["TileID"];
         }elseif(isset(
    $this->namedtag->Tile)){
           
    $this->blockId $this->namedtag["Tile"];
           
    $this->namedtag["TileID"] = new IntTag("TileID"$this->blockId);
         }

         if(isset(
    $this->namedtag->Data)){
           
    $this->damage $this->namedtag["Data"];
         }

         if(isset(
    $this->namedtag->Owner)){
           
    $this->setOwner($this->namedtag["Owner"]);
           if(
    $this->owner instanceof Player === false){
             
    $this->close();
           }
         } else {
           
    $this->close();
           return;
         }

         if(isset (
    $this->owner->entityBlock)){
           
    // Remove old Owner's entity block
           
    $this->owner->entityBlock->close();
         } else {
           
    $this->owner->entityBlock $this;
         }

         if(
    $this->blockId === 0){
           
    $this->close();
           return;
         }
         
    $this->lastX $this->x;
         
    $this->lastY $this->y;
         
    $this->lastZ $this->z;
         
    $this->setDataProperty(self::DATA_BLOCK_INFOself::DATA_TYPE_INT$this->getBlock() | ($this->getDamage() << 8));
         
    $this->spawnToALl();
       }

       public function 
    isPlaceTaken(Vector3 $pos){
         
    $b $this->level->getBlockIdAt($pos->x$pos->y$pos->z);
         
    $ignore = [0897859]; // Air, Water, Snow etc. should be ignored :)
         
    return in_array($b$ignoretrue) === false;
       }

       public function 
    canCollideWith(Entity $entity){
         return 
    false;
       }

       public function 
    changeBlock($id$damage){
         
    $this->resetPetrifaction();
         
    $this->blockId $id;
         
    $this->damage $damage;
         
    $pk = new RemoveEntityPacket();
         
    $pk->eid $this->getId();

         
    $this->server->broadcastPacket($this->server->getOnlinePlayers(), $pk);
         
    $this->spawnToAll();
       }

       public function 
    attack($damageEntityDamageEvent $source){
         if(
    $source->getCause() === EntityDamageEvent::CAUSE_VOID){
           
    parent::attack($damage$source);
         }
       }

       public function 
    getBlock(){
         return 
    $this->blockId;
       }

       public function 
    getOwner() : Player {
         return 
    $this->owner;
       }

       public function 
    getDamage(){
         return 
    $this->damage;
       }

       public function 
    saveNBT(){
         
    $this->namedtag->TileID = new IntTag("TileID"$this->blockId);
         
    $this->namedtag->Data = new ByteTag("Data"$this->damage);
         
    $this->namedtag->Owner = new LongTag("Owner"$this->owner);
       }

       public function 
    spawnTo(Player $player){
         
    $pk = new AddEntityPacket();
         
    $pk->type FallingSand::NETWORK_ID;
         
    $pk->eid $this->getId();
         
    $pk->$this->x;
         
    $pk->$this->1.62;
         
    $pk->$this->z;
         
    $pk->speedX $this->motionX;
         
    $pk->speedY $this->motionY;
         
    $pk->speedZ $this->motionZ;
         
    $pk->yaw $this->yaw;
         
    $pk->pitch $this->pitch;
         
    $pk->metadata = [FallingSand::DATA_BLOCK_INFO => [Entity::DATA_TYPE_INT$this->getBlock() | $this->getDamage() << 8]];
         
    $player->dataPacket($pk);

         
    parent::spawnTo($player);
       }

       public function 
    spawnToAll(){
         foreach(
    $this->getViewers() as $e){
           
    $this->spawnTo($e);
         }
       }

       public function 
    getName(){
         return 
    BlockBlock::get($this->getBlock(), $this->getDamage(), 1)->getName()." Entity";
       }

       public function 
    resetPetrifaction(){
         
    $this->petrifaction 1// It can not be zero or it will cause errors
       
    }

       public function 
    isOnEdge(){
         
    $flX $this->x;
         
    $flZ $this->z;
         
    $newX $flX 0.20;
         
    $newZ $flZ 0.20;
         if(
    intval($flX) < intval($newX) or intval($flX) > intval($newX) or intval($flZ) < intval($newZ) or intval($flZ) > intval($newZ)) return true;
         return 
    false;
       }

       public function 
    __destruct(){
         if(
    $this->owner->isConnected()){
           foreach(
    $this->server->getOnlinePlayers() as $player){
             
    $player->showPlayer($player);
           }
         }
         
    $this->close();
       }

    }

    All I want to say: Use the same eId and PocketMine will handle movement, except.. the entity juggling bug must be fixed by yourself.

    Similar thread: http://forums.pocketmine.net/threads/disquising-players-entity.12531/#post-125969
    Last edited: May 17, 2016
    ImagicalGamer likes this.
  16. iksaku
    Offline

    iksaku Notable Member Plugin Developer

    Joined:
    Sep 2, 2013
    Posts:
    1,130
    Plugins:
    4
    Minecraft User:
    iksaku
    You can look into @Falk MobDisguise code, and use similar packet hacks to properly animate falling sand.
    Just remember to add a "No AI" tag to the disguise, so sand can properly move with the player without falling inside ground ;)
    Legoboy0215 and ImagicalGamer like this.

Share This Page

Advertisement