diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 2dc3a4371..b37d0b6c7 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -50,6 +50,7 @@ use pocketmine\event\player\PlayerItemConsumeEvent; use pocketmine\event\player\PlayerJoinEvent; use pocketmine\event\player\PlayerKickEvent; use pocketmine\event\player\PlayerLoginEvent; +use pocketmine\event\player\PlayerMoveEvent; use pocketmine\event\player\PlayerPreLoginEvent; use pocketmine\event\player\PlayerQuitEvent; use pocketmine\event\player\PlayerRespawnEvent; @@ -69,6 +70,7 @@ use pocketmine\item\Item; use pocketmine\level\format\FullChunk; use pocketmine\level\format\LevelProvider; use pocketmine\level\Level; +use pocketmine\level\Location; use pocketmine\level\Position; use pocketmine\math\Vector3; use pocketmine\metadata\MetadataValue; @@ -1082,9 +1084,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ return; } $oldPos = new Vector3($this->x, $this->y, $this->z); - if(($distance = $oldPos->distance($this->newPosition)) == 0){ - return; - } + $distance = $oldPos->distance($this->newPosition); $revert = false; @@ -1099,7 +1099,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ } } - if(!$revert){ + if(!$revert and $distance != 0){ $dx = $this->newPosition->x - $this->x; $dy = $this->newPosition->y - $this->y; $dz = $this->newPosition->z - $this->z; @@ -1130,24 +1130,68 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ } } + $from = new Location($this->lastX, $this->lastY, $this->lastZ, $this->lastYaw, $this->lastPitch, $this->level); + $to = $this->getLocation(); + + $delta = pow($this->lastX - $to->x, 2) + pow($this->lastY - $to->y, 2) + pow($this->lastZ - $to->z, 2); + $deltaAngle = abs($this->lastYaw - $to->yaw) + abs($this->lastPitch - $to->pitch); + + if(!$revert and ($delta > (1 / 16) or $deltaAngle > 10)){ + $this->lastX = $to->x; + $this->lastY = $to->y; + $this->lastZ = $to->z; + + $this->lastYaw = $to->yaw; + $this->lastPitch = $to->pitch; + + $ev = new PlayerMoveEvent($this, $from, $to); + if($revert){ + $ev->setCancelled(); + } + + $this->server->getPluginManager()->callEvent($ev); + + if(!($revert = $ev->isCancelled())){ //Yes, this is intended + if($to->distance($ev->getTo()) > 0.1){ //If plugins modify the destination + $this->teleport($ev->getTo()); + }else{ + $pk = new MovePlayerPacket; + $pk->eid = $this->id; + $pk->x = $this->x; + $pk->y = $this->y; + $pk->z = $this->z; + $pk->yaw = $this->yaw; + $pk->pitch = $this->pitch; + $pk->bodyYaw = $this->yaw; + + foreach($this->hasSpawned as $player){ + $player->dataPacket($pk); + } + } + } + } + if($revert){ - $pk = new MovePlayerPacket(); + $pk = new MovePlayerPacket; $pk->eid = 0; - $pk->x = $this->x; - $pk->y = $this->y + $this->getEyeHeight(); - $pk->z = $this->z; - $pk->bodyYaw = $this->yaw; - $pk->pitch = $this->pitch; - $pk->yaw = $this->yaw; + $pk->x = $from->x; + $pk->y = $from->y + $this->getEyeHeight(); + $pk->z = $from->z; + $pk->bodyYaw = $from->yaw; + $pk->pitch = $from->pitch; + $pk->yaw = $from->yaw; $pk->teleport = true; $this->directDataPacket($pk); - $this->forceMovement = new Vector3($this->x, $this->y, $this->z); + $this->forceMovement = new Vector3($from->x, $from->y, $from->z); }else{ - $this->updateMovement(); $this->forceMovement = null; } } + public function updateMovement(){ + + } + public function onUpdate(){ if($this->spawned === false or $this->dead === true){ return true; diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 5a6b79960..1a001363d 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -37,6 +37,7 @@ use pocketmine\event\Timings; use pocketmine\level\format\Chunk; use pocketmine\level\format\FullChunk; use pocketmine\level\Level; +use pocketmine\level\Location; use pocketmine\level\Position; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Math; @@ -60,7 +61,7 @@ use pocketmine\Player; use pocketmine\plugin\Plugin; use pocketmine\Server; -abstract class Entity extends Position implements Metadatable{ +abstract class Entity extends Location implements Metadatable{ const NETWORK_ID = -1; @@ -97,8 +98,6 @@ abstract class Entity extends Position implements Metadatable{ public $lastMotionY; public $lastMotionZ; - public $yaw; - public $pitch; public $lastYaw; public $lastPitch; @@ -738,6 +737,10 @@ abstract class Entity extends Position implements Metadatable{ return new Position($this->x, $this->y, $this->z, $this->getLevel()); } + public function getLocation(){ + return new Location($this->x, $this->y, $this->z, $this->yaw, $this->pitch, $this->getLevel()); + } + public function isInsideOfWater(){ $block = $this->getLevel()->getBlock($pos = (new Vector3($this->x, $y = ($this->y + $this->getEyeHeight()), $this->z))->floor()); @@ -880,7 +883,7 @@ abstract class Entity extends Position implements Metadatable{ $this->boundingBox->setBB($axisalignedbb); - $list = $this->getLevel()->getCollisionCubes($this, $this->boundingBox->getOffsetBoundingBox($movX, $dy, $movZ), false); + $list = $this->level->getCollisionCubes($this, $this->boundingBox->getOffsetBoundingBox($movX, $dy, $movZ), false); foreach($list as $bb){ $dy = $bb->calculateYOffset($this->boundingBox, $dy); @@ -950,10 +953,10 @@ abstract class Entity extends Position implements Metadatable{ }else{ if($this instanceof Player){ - if(($this->onGround and $movY != 0) or (!$this->onGround and $movY <= 0)){ + if(($this->onGround and $movY != 0) or (!$this->onGround and $movY < 0)){ $bb = clone $this->boundingBox; $bb->maxY = $bb->minY + 0.5; - if(count($this->getLevel()->getCollisionBlocks($bb->expand(0.01, 0.01, 0.01))) > 0){ + if(count($this->level->getCollisionBlocks($bb->expand(0.01, 0.01, 0.01))) > 0){ $isColliding = true; }else{ $isColliding = false; @@ -1020,8 +1023,8 @@ abstract class Entity extends Position implements Metadatable{ } } - public function setPositionAndRotation(Vector3 $pos, $yaw, $pitch, $force = false){ - if($this->setPosition($pos, $force) === true){ + public function setPositionAndRotation(Vector3 $pos, $yaw, $pitch){ + if($this->setPosition($pos) === true){ $this->setRotation($yaw, $pitch); return true; @@ -1036,22 +1039,13 @@ abstract class Entity extends Position implements Metadatable{ $this->scheduleUpdate(); } - public function setPosition(Vector3 $pos, $force = false){ + public function setPosition(Vector3 $pos){ if($pos instanceof Position and $pos->level instanceof Level and $pos->level !== $this->level){ if($this->switchLevel($pos->getLevel()) === false){ return false; } } - if(!$this->justCreated and $force !== true){ - $ev = new EntityMoveEvent($this, $pos); - - $this->server->getPluginManager()->callEvent($ev); - if($ev->isCancelled()){ - return false; - } - } - $this->x = $pos->x; $this->y = $pos->y; $this->z = $pos->z; @@ -1130,7 +1124,18 @@ abstract class Entity extends Position implements Metadatable{ $this->scheduleUpdate(); } + /** + * @param Vector3|Position|Location $pos + * @param float $yaw + * @param float $pitch + * + * @return bool + */ public function teleport(Vector3 $pos, $yaw = null, $pitch = null){ + if($pos instanceof Location){ + $yaw = $pos->yaw; + $pitch = $pos->pitch; + } $from = Position::fromObject($this, $this->getLevel()); $to = Position::fromObject($pos, $pos instanceof Position ? $pos->getLevel() : $this->getLevel()); $this->server->getPluginManager()->callEvent($ev = new EntityTeleportEvent($this, $from, $to)); diff --git a/src/pocketmine/event/player/PlayerMoveEvent.php b/src/pocketmine/event/player/PlayerMoveEvent.php new file mode 100644 index 000000000..bf29dd1c0 --- /dev/null +++ b/src/pocketmine/event/player/PlayerMoveEvent.php @@ -0,0 +1,55 @@ +player = $player; + $this->from = $from; + $this->to = $to; + } + + public function getFrom(){ + return $this->from; + } + + public function setFrom(Location $from){ + $this->from = $from; + } + + public function getTo(){ + return $this->to; + } + + public function setTo(Location $to){ + $this->to = $to; + } +} \ No newline at end of file diff --git a/src/pocketmine/level/Location.php b/src/pocketmine/level/Location.php new file mode 100644 index 000000000..e1dfb4488 --- /dev/null +++ b/src/pocketmine/level/Location.php @@ -0,0 +1,54 @@ +x = $x; + $this->y = $y; + $this->z = $z; + $this->yaw = $yaw; + $this->pitch = $pitch; + $this->level = $level; + } + + public function getYaw(){ + return $this->yaw; + } + + public function getPitch(){ + return $this->pitch; + } + +} diff --git a/src/pocketmine/level/Position.php b/src/pocketmine/level/Position.php index 91f2bd95a..8e5f63af1 100644 --- a/src/pocketmine/level/Position.php +++ b/src/pocketmine/level/Position.php @@ -33,16 +33,15 @@ class Position extends Vector3{ * @param int $y * @param int $z * @param Level $level - * @param bool $strong */ - public function __construct($x = 0, $y = 0, $z = 0, Level $level = null, $strong = false){ + public function __construct($x = 0, $y = 0, $z = 0, Level $level = null){ $this->x = $x; $this->y = $y; $this->z = $z; $this->level = $level; } - public static function fromObject(Vector3 $pos, Level $level = null, $strong = false){ + public static function fromObject(Vector3 $pos, Level $level = null){ return new Position($pos->x, $pos->y, $pos->z, $level); }