From c6756050145538e220cf63ad1bd00967ee53f723 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Sat, 16 Aug 2014 14:01:07 +0200 Subject: [PATCH] Added item activation, zombie spawn egg --- src/pocketmine/block/Block.php | 11 ++++--- src/pocketmine/entity/Entity.php | 3 ++ src/pocketmine/entity/Zombie.php | 52 +++++++++++++++++++++++++++++++- src/pocketmine/item/SpawnEgg.php | 49 ++++++++++++++++++++++++++++-- src/pocketmine/level/Level.php | 8 ++++- 5 files changed, 114 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index 9c86e1e46..77b1ff017 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -24,6 +24,7 @@ */ namespace pocketmine\block; +use pocketmine\entity\Zombie; use pocketmine\item\Item; use pocketmine\level\Level; use pocketmine\level\Position; @@ -449,10 +450,10 @@ abstract class Block extends Position implements Metadatable{ [Item::COMPASS, 0], [Item::MINECART, 0], //TODO: Villager - [Item::SPAWN_EGG, 10], //Chicken - [Item::SPAWN_EGG, 11], //Cow - [Item::SPAWN_EGG, 12], //Pig - [Item::SPAWN_EGG, 13], //Sheep + //[Item::SPAWN_EGG, 10], //Chicken + //[Item::SPAWN_EGG, 11], //Cow + //[Item::SPAWN_EGG, 12], //Pig + //[Item::SPAWN_EGG, 13], //Sheep //TODO: Wolf //TODO: Mooshroom //TODO: Creeper @@ -460,7 +461,7 @@ abstract class Block extends Position implements Metadatable{ //TODO: Silverfish //TODO: Skeleton //TODO: Slime - //TODO: Zombie + [Item::SPAWN_EGG, Zombie::NETWORK_ID], //TODO: PigZombie //TODO: Replace with Entity constants diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 93d38f563..bc202163e 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -59,6 +59,9 @@ use pocketmine\plugin\Plugin; use pocketmine\Server; abstract class Entity extends Position implements Metadatable{ + + const NETWORK_ID = -1; + public static $entityCount = 1; /** diff --git a/src/pocketmine/entity/Zombie.php b/src/pocketmine/entity/Zombie.php index 6670ee65f..38b769f50 100644 --- a/src/pocketmine/entity/Zombie.php +++ b/src/pocketmine/entity/Zombie.php @@ -22,6 +22,56 @@ namespace pocketmine\entity; -class Zombie extends Monster{ +use pocketmine\network\protocol\AddMobPacket; +use pocketmine\network\protocol\SetEntityMotionPacket; +use pocketmine\Player; +class Zombie extends Monster{ + const NETWORK_ID = 32; + + public $width = 0.6; + public $length = 0.6; + public $height = 1.8; + + public function getName(){ + return "Zombie"; + } + + public function spawnTo(Player $player){ + if($player !== $this and !isset($this->hasSpawned[$player->getID()])){ + $this->hasSpawned[$player->getID()] = $player; + + $pk = new AddMobPacket(); + $pk->eid = $this->getID(); + $pk->type = Zombie::NETWORK_ID; + $pk->x = $this->x; + $pk->y = $this->y; + $pk->z = $this->z; + $pk->yaw = $this->yaw; + $pk->pitch = $this->pitch; + $pk->metadata = $this->getData(); + $player->dataPacket($pk); + + $pk = new SetEntityMotionPacket(); + $pk->entities = [ + [$this->getID(), $this->motionX, $this->motionY, $this->motionZ] + ]; + $player->dataPacket($pk); + } + } + + public function getData(){ //TODO + $flags = 0; + $flags |= $this->fireTicks > 0 ? 1 : 0; + //$flags |= ($this->crouched === true ? 0b10:0) << 1; + //$flags |= ($this->inAction === true ? 0b10000:0); + $d = array( + 0 => array("type" => 0, "value" => $flags), + 1 => array("type" => 1, "value" => $this->airTicks), + 16 => array("type" => 0, "value" => 0), + 17 => array("type" => 6, "value" => array(0, 0, 0)), + ); + + return $d; + } } \ No newline at end of file diff --git a/src/pocketmine/item/SpawnEgg.php b/src/pocketmine/item/SpawnEgg.php index 547be3082..1c640e2fe 100644 --- a/src/pocketmine/item/SpawnEgg.php +++ b/src/pocketmine/item/SpawnEgg.php @@ -22,8 +22,15 @@ namespace pocketmine\item; use pocketmine\block\Block; -use pocketmine\Entity; +use pocketmine\entity\Entity; +use pocketmine\entity\Zombie; +use pocketmine\level\format\FullChunk; use pocketmine\level\Level; +use pocketmine\nbt\tag\Compound; +use pocketmine\nbt\tag\Double; +use pocketmine\nbt\tag\Enum; +use pocketmine\nbt\tag\Float; +use pocketmine\nbt\tag\Short; use pocketmine\Player; class SpawnEgg extends Item{ @@ -34,7 +41,37 @@ class SpawnEgg extends Item{ } public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){ + $entity = null; + $chunk = $level->getChunkAt($block->getX() >> 4, $block->getZ() >> 4); + + if(!($chunk instanceof FullChunk)){ + return false; + } + + $nbt = new Compound("", [ + "Pos" => new Enum("Pos", [ + new Double("", $block->getX()), + new Double("", $block->getY() + 1), + new Double("", $block->getZ()) + ]), + //TODO: add random motion with physics + "Motion" => new Enum("Motion", [ + new Double("", 0), + new Double("", 0), + new Double("", 0) + ]), + "Rotation" => new Enum("Rotation", [ + new Float("", lcg_value() * 360), + new Float("", 0) + ]), + ]); + switch($this->meta){ + case Zombie::NETWORK_ID: + $nbt->Health = new Short("Health", 20); + $entity = new Zombie($chunk, $nbt); + break; + /* //TODO: use entity constants case 10: case 11: @@ -51,7 +88,15 @@ class SpawnEgg extends Item{ --$this->count; } - return true; + return true;*/ + } + + if($entity instanceof Entity){ + if(($player->gamemode & 0x01) === 0){ + --$this->count; + } + $entity->spawnToAll(); + return true; } return false; } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 8d1e64915..abccf58ca 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -917,6 +917,13 @@ class Level implements ChunkManager, Metadatable{ return true; } } + + if($item->isActivable and $item->onActivate($this, $player, $block, $target, $face, $fx, $fy, $fz)){ + if($item->getCount() <= 0){ + $item = Item::get(Item::AIR, 0, 0); + return true; + } + } }elseif($target->isActivable === true and $target->onActivate($item, $player) === true){ return true; } @@ -926,7 +933,6 @@ class Level implements ChunkManager, Metadatable{ $hand->position($block); }elseif($block->getID() === Item::FIRE){ $this->setBlock($block, new Air(), true, false, true); - return false; }else{ return false;