From 7b17bf416e04a8f43e204be8059806a7de9d65ff Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Sun, 7 Jun 2015 21:08:46 +0200 Subject: [PATCH] Fixed Arrows not hitting entities, added new movement system --- src/pocketmine/Player.php | 54 ++++++++----------- src/pocketmine/entity/Entity.php | 12 ++--- src/pocketmine/level/Level.php | 37 ++++++++++++- .../network/protocol/MovePlayerPacket.php | 6 ++- 4 files changed, 65 insertions(+), 44 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 09403afc0..c428929f9 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -160,9 +160,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade protected $sendIndex = 0; - protected $moveToSend; - protected $motionToSend; - /** @var Vector3 */ public $speed = null; @@ -508,11 +505,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->newPosition = new Vector3(0, 0, 0); $this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0); - $this->motionToSend = new SetEntityMotionPacket(); - $this->moveToSend = new MoveEntityPacket(); - $this->motionToSend->setChannel(Network::CHANNEL_MOVEMENT); - $this->moveToSend->setChannel(Network::CHANNEL_MOVEMENT); - $this->uuid = Utils::dataToUUID($ip, $port, $clientID); $this->creationTime = microtime(true); @@ -1206,12 +1198,18 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade return []; } + /** + * @deprecated + */ public function addEntityMotion($entityId, $x, $y, $z){ - $this->motionToSend->entities[$entityId] = [$entityId, $x, $y, $z]; + } + /** + * @deprecated + */ public function addEntityMovement($entityId, $x, $y, $z, $yaw, $pitch, $headYaw = null){ - $this->moveToSend->entities[$entityId] = [$entityId, $x, $y, $z, $yaw, $headYaw === null ? $yaw : $headYaw, $pitch]; + } public function setDataProperty($id, $type, $value){ @@ -1392,9 +1390,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade if($to->distanceSquared($ev->getTo()) > 0.01){ //If plugins modify the destination $this->teleport($ev->getTo()); }else{ - foreach($this->hasSpawned as $player){ - $player->addEntityMovement($this->id, $this->x, $this->y + $this->getEyeHeight(), $this->z, $this->yaw, $this->pitch, $this->yaw); - } + $this->sendPosition($this, null, null, MovePlayerPacket::MODE_NORMAL, Network::CHANNEL_MOVEMENT, $this->hasSpawned); } } } @@ -1431,7 +1427,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade public function setMotion(Vector3 $mot){ if(parent::setMotion($mot)){ - $this->addEntityMotion($this->getId(), $this->motionX, $this->motionY, $this->motionZ); + if($this->chunk !== null){ + $this->level->addEntityMotion($this->chunk->getX(), $this->chunk->getZ(), $this->getId(), $this->motionX, $this->motionY, $this->motionZ); + } + if($this->motionY > 0){ $this->startAirTicks = (-(log($this->gravity / ($this->gravity + $this->drag * $this->motionY))) / $this->drag) * 2 + 5; } @@ -1521,19 +1520,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->sendNextChunk(); } - if(count($this->moveToSend->entities) > 0){ - $this->dataPacket($this->moveToSend); - $this->moveToSend->entities = []; - $this->moveToSend->isEncoded = false; - } - - - if(count($this->motionToSend->entities) > 0){ - $this->dataPacket($this->motionToSend); - $this->motionToSend->entities = []; - $this->motionToSend->isEncoded = false; - } - if(count($this->batchedPackets) > 0){ foreach($this->batchedPackets as $channel => $list){ $this->server->batchPackets([$this], $list, false, $channel); @@ -3142,7 +3128,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade } } - public function sendPosition(Vector3 $pos, $yaw = null, $pitch = null, $mode = 0, $channel = Network::CHANNEL_PRIORITY){ + public function sendPosition(Vector3 $pos, $yaw = null, $pitch = null, $mode = 0, $channel = Network::CHANNEL_PRIORITY, array $targets = null){ $yaw = $yaw === null ? $this->yaw : $yaw; $pitch = $pitch === null ? $this->pitch : $pitch; @@ -3155,7 +3141,12 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $pk->pitch = $pitch; $pk->yaw = $yaw; $pk->mode = $mode; - $this->dataPacket($pk->setChannel($channel)); + + if($targets !== null){ + Server::broadcastPacket($targets, $pk); + }else{ + $this->dataPacket($pk->setChannel($channel)); + } } protected function checkChunks(){ @@ -3180,10 +3171,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade //TODO HACK: Minecraft: PE does not like moving a player from old chunks. //Player entities get stuck in unloaded chunks and the client does not accept position updates. - foreach($reload as $player){ - $player->despawnFrom($player); - $player->spawnTo($player); - } + $this->sendPosition($this, null, null, MovePlayerPacket::MODE_RESET, Network::CHANNEL_MOVEMENT, $reload); foreach($newChunk as $player){ $this->spawnTo($player); diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index de9c35f64..4695121ac 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -850,9 +850,7 @@ abstract class Entity extends Location implements Metadatable{ $this->lastYaw = $this->yaw; $this->lastPitch = $this->pitch; - foreach($this->hasSpawned as $player){ - $player->addEntityMovement($this->id, $this->x, $this->y + $this->getEyeHeight(), $this->z, $this->yaw, $this->pitch, $this->yaw); - } + $this->level->addEntityMovement($this->chunk->getX(), $this->chunk->getZ(), $this->id, $this->x, $this->y + $this->getEyeHeight(), $this->z, $this->yaw, $this->pitch, $this->yaw); } if($diffMotion > 0.0025 or ($diffMotion > 0.0001 and $this->getMotion()->lengthSquared() <= 0.0001)){ //0.05 ** 2 @@ -860,9 +858,7 @@ abstract class Entity extends Location implements Metadatable{ $this->lastMotionY = $this->motionY; $this->lastMotionZ = $this->motionZ; - foreach($this->hasSpawned as $player){ - $player->addEntityMotion($this->id, $this->motionX, $this->motionY, $this->motionZ); - } + $this->level->addEntityMotion($this->chunk->getX(), $this->chunk->getZ(), $this->id, $this->motionX, $this->motionY, $this->motionZ); } } @@ -1446,9 +1442,7 @@ abstract class Entity extends Location implements Metadatable{ $this->lastYaw = $this->yaw; $this->lastPitch = $this->pitch; - foreach($this->hasSpawned as $player){ - $player->addEntityMovement($this->getId(), $this->x, $this->y + $this->getEyeHeight(), $this->z, $this->yaw, $this->pitch, $this->yaw); - } + $this->updateMovement(); return true; } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index f7cd9c3db..d2f1fc69e 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -90,6 +90,8 @@ use pocketmine\nbt\tag\String; use pocketmine\network\Network; use pocketmine\network\protocol\DataPacket; use pocketmine\network\protocol\LevelEventPacket; +use pocketmine\network\protocol\MoveEntityPacket; +use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetTimePacket; use pocketmine\network\protocol\UpdateBlockPacket; use pocketmine\Player; @@ -132,6 +134,9 @@ class Level implements ChunkManager, Metadatable{ /** @var Tile[] */ private $tiles = []; + private $motionToSend = []; + private $moveToSend = []; + /** @var Player[] */ private $players = []; @@ -709,6 +714,22 @@ class Level implements ChunkManager, Metadatable{ $this->checkSleep(); } + foreach($this->moveToSend as $index => $entry){ + Level::getXZ($index, $chunkX, $chunkZ); + $pk = new MoveEntityPacket(); + $pk->entities = $entry; + Server::broadcastPacket($this->getChunkPlayers($chunkX, $chunkZ), $pk->setChannel(Network::CHANNEL_MOVEMENT)); + } + $this->moveToSend = []; + + foreach($this->motionToSend as $index => $entry){ + Level::getXZ($index, $chunkX, $chunkZ); + $pk = new SetEntityMotionPacket(); + $pk->entities = $entry; + Server::broadcastPacket($this->getChunkPlayers($chunkX, $chunkZ), $pk->setChannel(Network::CHANNEL_MOVEMENT)); + } + $this->motionToSend = []; + $this->timings->doTick->stopTiming(); } @@ -1699,7 +1720,7 @@ class Level implements ChunkManager, Metadatable{ for($x = $minX; $x <= $maxX; ++$x){ for($z = $minZ; $z <= $maxZ; ++$z){ foreach($this->getChunkEntities($x, $z) as $ent){ - if(($entity === null or ($ent !== $entity and $ent->canCollideWith($entity))) and $ent->boundingBox->intersectsWith($bb)){ + if(($entity === null or ($ent !== $entity and $entity->canCollideWith($ent))) and $ent->boundingBox->intersectsWith($bb)){ $nearby[] = $ent; } } @@ -2729,4 +2750,18 @@ class Level implements ChunkManager, Metadatable{ public function removeMetadata($metadataKey, Plugin $plugin){ $this->server->getLevelMetadata()->removeMetadata($this, $metadataKey, $plugin); } + + public function addEntityMotion($chunkX, $chunkZ, $entityId, $x, $y, $z){ + if(!isset($this->motionToSend[$index = Level::chunkHash($chunkX, $chunkZ)])){ + $this->motionToSend[$index] = []; + } + $this->motionToSend[$index][$entityId] = [$entityId, $x, $y, $z]; + } + + public function addEntityMovement($chunkX, $chunkZ, $entityId, $x, $y, $z, $yaw, $pitch, $headYaw = null){ + if(!isset($this->moveToSend[$index = Level::chunkHash($chunkX, $chunkZ)])){ + $this->moveToSend[$index] = []; + } + $this->moveToSend[$index][$entityId] = [$entityId, $x, $y, $z, $yaw, $headYaw === null ? $yaw : $headYaw, $pitch]; + } } diff --git a/src/pocketmine/network/protocol/MovePlayerPacket.php b/src/pocketmine/network/protocol/MovePlayerPacket.php index d5f5b4785..74d9c2589 100644 --- a/src/pocketmine/network/protocol/MovePlayerPacket.php +++ b/src/pocketmine/network/protocol/MovePlayerPacket.php @@ -27,6 +27,10 @@ namespace pocketmine\network\protocol; class MovePlayerPacket extends DataPacket{ const NETWORK_ID = Info::MOVE_PLAYER_PACKET; + const MODE_NORMAL = 0; + const MODE_RESET = 1; + const MODE_ROTATION = 2; + public $eid; public $x; public $y; @@ -34,7 +38,7 @@ class MovePlayerPacket extends DataPacket{ public $yaw; public $bodyYaw; public $pitch; - public $mode = 0; + public $mode = self::MODE_NORMAL; public $onGround; public function clean(){