From 5eee4f97715234a5643768042f2a88fddcac8652 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Sat, 16 Aug 2014 16:37:57 +0200 Subject: [PATCH] Fixed AddEntityPacket, added base Arrow --- src/pocketmine/Player.php | 90 +++++---------- src/pocketmine/entity/Arrow.php | 109 +++++++++++++++++- src/pocketmine/entity/Villager.php | 34 +++--- src/pocketmine/entity/Zombie.php | 35 +++--- src/pocketmine/item/SpawnEgg.php | 1 - .../network/protocol/AddEntityPacket.php | 2 +- 6 files changed, 171 insertions(+), 100 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index e98e5e9ce..5250afda9 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -23,6 +23,7 @@ namespace pocketmine; use pocketmine\block\Block; use pocketmine\command\CommandSender; +use pocketmine\entity\Arrow; use pocketmine\entity\DroppedItem; use pocketmine\entity\Entity; use pocketmine\entity\Human; @@ -65,6 +66,9 @@ use pocketmine\metadata\MetadataValue; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Compound; +use pocketmine\nbt\tag\Double; +use pocketmine\nbt\tag\Enum; +use pocketmine\nbt\tag\Float; use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\String; use pocketmine\network\protocol\AdventureSettingsPacket; @@ -1471,70 +1475,34 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $packet->eid = $this->id; switch($packet->action){ - /*case 5: //Shot arrow - if($this->entity->inAction === true){ - if($this->getSlot($this->getCurrentEquipment())->getID() === BOW){ - if($this->startAction !== false){ - $time = microtime(true) - $this->startAction; - $d = array( - "x" => $this->entity->x, - "y" => $this->entity->y + 1.6, - "z" => $this->entity->z, - ); - $e = $this->server->api->entity->add($this->getLevel(), ENTITY_OBJECT, OBJECT_ARROW, $d); - $e->yaw = $this->entity->yaw; - $e->pitch = $this->entity->pitch; - $rotation = ($this->entity->yaw - 90) % 360; - if($rotation < 0){ - $rotation = (360 + $rotation); - } - $rotation = ($rotation + 180); - if($rotation >= 360){ - $rotation = ($rotation - 360); - } - $X = 1; - $Z = 1; - $overturn = false; - if(0 <= $rotation and $rotation < 90){ - - }elseif(90 <= $rotation and $rotation < 180){ - $rotation -= 90; - $X = (-1); - $overturn = true; - }elseif(180 <= $rotation and $rotation < 270){ - $rotation -= 180; - $X = (-1); - $Z = (-1); - }elseif(270 <= $rotation and $rotation < 360){ - $rotation -= 270; - $Z = (-1); - $overturn = true; - } - $rad = deg2rad($rotation); - $pitch = (-($this->entity->pitch)); - $speed = 80; - $speedY = (sin(deg2rad($pitch)) * $speed); - $speedXZ = (cos(deg2rad($pitch)) * $speed); - if($overturn){ - $speedX = (sin($rad) * $speedXZ * $X); - $speedZ = (cos($rad) * $speedXZ * $Z); - } - else{ - $speedX = (cos($rad) * $speedXZ * $X); - $speedZ = (sin($rad) * $speedXZ * $Z); - } - $e->speedX = $speedX; - $e->speedZ = $speedZ; - $e->speedY = $speedY; - $e->spawnToAll(); - } + case 5: //Shot arrow + //if($this->entity->inAction === true){ + if($this->inventory->getItemInHand()->getID() === Item::BOW){ + $f = 1 * 2 * 1.5; + $nbt = new Compound("", [ + "Pos" => new Enum("Pos", [ + new Double("", $this->x), + new Double("", $this->y + 1.62), + new Double("", $this->z) + ]), + "Motion" => new Enum("Motion", [ + new Double("", -sin($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI) * $f), + new Double("", -sin($this->pitch / 180 * M_PI) * $f), + new Double("", cos($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI) * $f) + ]), + "Rotation" => new Enum("Rotation", [ + new Float("", $this->yaw), + new Float("", $this->pitch) + ]), + ]); + $arrow = new Arrow($this->chunk, $nbt); + $arrow->spawnToAll(); } - } + //} $this->startAction = false; - $this->entity->inAction = false; - $this->entity->updateMetadata(); + //$this->entity->inAction = false; + //$this->entity->updateMetadata(); break; - */ case 6: //get out of the bed $this->stopSleep(); break; diff --git a/src/pocketmine/entity/Arrow.php b/src/pocketmine/entity/Arrow.php index 6e555cda5..adcbd5bf7 100644 --- a/src/pocketmine/entity/Arrow.php +++ b/src/pocketmine/entity/Arrow.php @@ -22,6 +22,113 @@ namespace pocketmine\entity; -class Arrow extends Projectile{ +use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\math\Vector3; +use pocketmine\nbt\tag\Short; +use pocketmine\network\protocol\AddEntityPacket; +use pocketmine\network\protocol\SetEntityMotionPacket; +use pocketmine\Player; +class Arrow extends Projectile{ + const NETWORK_ID = 80; + + public $width = 0.5; + public $length = 0.5; + public $height = 0.5; + protected $gravity = 0.05; + protected $drag = 0.01; + + protected function initEntity(){ + $this->setMaxHealth(1); + $this->setHealth(1); + if(isset($this->namedtag->Age)){ + $this->age = $this->namedtag["Age"]; + } + + + + + } + + public function onUpdate(){ + $this->entityBaseTick(); + + $this->motionY -= $this->gravity; + + $this->inBlock = $this->checkObstruction($this->x, ($this->boundingBox->minY + $this->boundingBox->maxY) / 2, $this->z); + $this->move($this->motionX, $this->motionY, $this->motionZ); + + $friction = 1 - $this->drag; + + if($this->onGround){ + $friction = $this->getLevel()->getBlock(new Vector3($this->getFloorX(), $this->getFloorY() - 1, $this->getFloorZ()))->frictionFactor * $friction; + } + + $this->motionX *= $friction; + $this->motionY *= 1 - $this->drag; + $this->motionZ *= $friction; + + if($this->onGround){ + $this->motionY *= -0.5; + } + + if(abs($this->motionX) < 0.01){ + $this->motionX = 0; + } + if(abs($this->motionZ) < 0.01){ + $this->motionZ = 0; + } + + if($this->age > 1200){ + $this->kill(); + } + $this->updateMovement(); + + //TODO: handle scheduled updates + return true; + } + + public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){ + + } + + public function heal($amount){ + + } + + public function saveNBT(){ + $this->namedtag->Age = new Short("Age", $this->age); + } + + public function getData(){ + $flags = 0; + $flags |= $this->fireTicks > 0 ? 1 : 0; + + return [ + 0 => array("type" => 0, "value" => $flags) + ]; + } + + public function canCollideWith(Entity $entity){ + return $entity instanceof Living; + } + + public function spawnTo(Player $player){ + $pk = new AddEntityPacket(); + $pk->type = Arrow::NETWORK_ID; + $pk->eid = $this->getID(); + $pk->x = $this->x; + $pk->y = $this->y; + $pk->z = $this->z; + $pk->did = 0; //TODO: send motion here + $player->dataPacket($pk); + + $pk = new SetEntityMotionPacket(); + $pk->entities = [ + [$this->getID(), $this->motionX, $this->motionY, $this->motionZ] + ]; + $player->dataPacket($pk); + + parent::spawnTo($player); + } } \ No newline at end of file diff --git a/src/pocketmine/entity/Villager.php b/src/pocketmine/entity/Villager.php index 1d026747a..3841c4f77 100644 --- a/src/pocketmine/entity/Villager.php +++ b/src/pocketmine/entity/Villager.php @@ -53,26 +53,24 @@ class Villager extends Creature implements NPC, Ageable{ } 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 = Villager::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 AddMobPacket(); - $pk->eid = $this->getID(); - $pk->type = Villager::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); - $pk = new SetEntityMotionPacket(); - $pk->entities = [ - [$this->getID(), $this->motionX, $this->motionY, $this->motionZ] - ]; - $player->dataPacket($pk); - } + parent::spawnTo($player); } public function getData(){ //TODO diff --git a/src/pocketmine/entity/Zombie.php b/src/pocketmine/entity/Zombie.php index 67e0ebbfe..cb25796ea 100644 --- a/src/pocketmine/entity/Zombie.php +++ b/src/pocketmine/entity/Zombie.php @@ -40,26 +40,25 @@ class Zombie extends Monster{ } 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 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); - } + $pk = new SetEntityMotionPacket(); + $pk->entities = [ + [$this->getID(), $this->motionX, $this->motionY, $this->motionZ] + ]; + $player->dataPacket($pk); + + parent::spawnTo($player); } public function getData(){ //TODO diff --git a/src/pocketmine/item/SpawnEgg.php b/src/pocketmine/item/SpawnEgg.php index 56a602d1b..b98e05739 100644 --- a/src/pocketmine/item/SpawnEgg.php +++ b/src/pocketmine/item/SpawnEgg.php @@ -55,7 +55,6 @@ class SpawnEgg extends Item{ new Double("", $block->getY()), new Double("", $block->getZ()) ]), - //TODO: add random motion with physics "Motion" => new Enum("Motion", [ new Double("", 0), new Double("", 0), diff --git a/src/pocketmine/network/protocol/AddEntityPacket.php b/src/pocketmine/network/protocol/AddEntityPacket.php index 4bc395078..aff5ae6cc 100644 --- a/src/pocketmine/network/protocol/AddEntityPacket.php +++ b/src/pocketmine/network/protocol/AddEntityPacket.php @@ -44,7 +44,7 @@ class AddEntityPacket extends DataPacket{ public function encode(){ $this->reset(); $this->putInt($this->eid); - $this->putByte($this->type); + $this->putInt($this->type); $this->putFloat($this->x); $this->putFloat($this->y); $this->putFloat($this->z);