Fixed Arrows not hitting entities, added new movement system

This commit is contained in:
Shoghi Cervantes 2015-06-07 21:08:46 +02:00
parent d0f743a99e
commit 7b17bf416e
No known key found for this signature in database
GPG Key ID: 78464DB0A7837F89
4 changed files with 65 additions and 44 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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];
}
}

View File

@ -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(){