From 9ec609d02562e61c70798c67cd98609518d98ee9 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Sun, 3 May 2015 13:42:54 +0200 Subject: [PATCH] Improved Player flight detection after setMotion(), other method improvement --- src/pocketmine/Player.php | 23 +++++++++++++++++-- src/pocketmine/block/Fallable.php | 2 +- src/pocketmine/entity/Entity.php | 20 +++++++++-------- src/pocketmine/entity/FallingSand.php | 5 ++--- src/pocketmine/level/Explosion.php | 2 +- src/pocketmine/level/Level.php | 32 ++++++++++++--------------- src/pocketmine/math/Vector3.php | 6 ++--- 7 files changed, 52 insertions(+), 38 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 04271dec7..947703934 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -215,6 +215,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ private $spawnPosition = null; protected $inAirTicks = 0; + protected $startAirTicks = 5; protected $autoJump = true; @@ -376,6 +377,9 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ public function resetFallDistance(){ parent::resetFallDistance(); + if($this->inAirTicks !== 0){ + $this->startAirTicks = 5; + } $this->inAirTicks = 0; } @@ -1333,7 +1337,19 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->newPosition = null; } - public function updateMovement(){ + public function setMotion(Vector3 $mot){ + if(parent::setMotion($mot)){ + if($this->motionY > 0){ + $this->addEntityMotion($this->getId(), $this->motionX, $this->motionY, $this->motionZ); + $this->startAirTicks = (-(log($this->gravity / ($this->gravity + $this->drag * $this->motionY))) / $this->drag) * 2 + 5; + } + + return true; + } + return false; + } + + protected function updateMovement(){ } @@ -1369,10 +1385,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ if(!$this->isSpectator()){ if($this->onGround){ + if($this->inAirTicks !== 0){ + $this->startAirTicks = 5; + } $this->inAirTicks = 0; }else{ if(!$this->allowFlight and $this->inAirTicks > 10 and !$this->isSleeping() and $this->getDataProperty(self::DATA_NO_AI) !== 1){ - $expectedVelocity = (-$this->gravity) / $this->drag - ((-$this->gravity) / $this->drag) * exp(-$this->drag * ($this->inAirTicks - 5)); + $expectedVelocity = (-$this->gravity) / $this->drag - ((-$this->gravity) / $this->drag) * exp(-$this->drag * ($this->inAirTicks - $this->startAirTicks)); $diff = sqrt(abs($this->speed->y - $expectedVelocity)); if(!$this->hasEffect(Effect::JUMP) and $diff > 0.6 and $expectedVelocity < $this->speed->y and !$this->server->getAllowFlight()){ diff --git a/src/pocketmine/block/Fallable.php b/src/pocketmine/block/Fallable.php index 5a7417531..ba0afe03a 100644 --- a/src/pocketmine/block/Fallable.php +++ b/src/pocketmine/block/Fallable.php @@ -47,7 +47,7 @@ abstract class Fallable extends Solid{ $fall = Entity::createEntity("FallingSand", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [ "Pos" => new Enum("Pos", [ new Double("", $this->x + 0.5), - new Double("", $this->y), + new Double("", $this->y + 0.5), new Double("", $this->z + 0.5) ]), "Motion" => new Enum("Motion", [ diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 1fc91c93a..51e5ef53a 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -161,11 +161,11 @@ abstract class Entity extends Location implements Metadatable{ protected $stepHeight = 0; public $keepMovement = false; - public $fallDistance; - public $ticksLived; + public $fallDistance = 0; + public $ticksLived = 0; public $lastUpdate; public $maxFireTicks; - public $fireTicks; + public $fireTicks = 0; public $namedtag; public $canCollide = true; @@ -784,8 +784,13 @@ abstract class Entity extends Location implements Metadatable{ return $hasUpdate; } - public function updateMovement(){ - if($this->x !== $this->lastX or $this->y !== $this->lastY or $this->z !== $this->lastZ or $this->yaw !== $this->lastYaw or $this->pitch !== $this->lastPitch){ + protected function updateMovement(){ + $diffPosition = ($this->x - $this->lastX) ** 2 + ($this->y - $this->lastY) ** 2 + ($this->z - $this->lastZ) ** 2; + $diffRotation = ($this->yaw - $this->lastYaw) ** 2 + ($this->pitch - $this->lastPitch) ** 2; + + $diffMotion = ($this->motionX - $this->lastMotionX) ** 2 + ($this->motionY - $this->lastMotionY) ** 2 + ($this->motionZ - $this->lastMotionZ) ** 2; + + if($diffPosition > 0.04 or $diffRotation > 2.25){ //0.2 ** 2, 1.5 ** 2 $this->lastX = $this->x; $this->lastY = $this->y; $this->lastZ = $this->z; @@ -800,7 +805,7 @@ abstract class Entity extends Location implements Metadatable{ } } - if(($this->lastMotionX != $this->motionX or $this->lastMotionY != $this->motionY or $this->lastMotionZ != $this->motionZ)){ + if($diffMotion > 0.0025){ //0.05 ** 2 $this->lastMotionX = $this->motionX; $this->lastMotionY = $this->motionY; $this->lastMotionZ = $this->motionZ; @@ -1361,9 +1366,6 @@ abstract class Entity extends Location implements Metadatable{ $this->motionZ = $motion->z; if(!$this->justCreated){ - if($this instanceof Player){ - $this->addEntityMotion($this->getId(), $this->motionX, $this->motionY, $this->motionZ); - } $this->updateMovement(); } diff --git a/src/pocketmine/entity/FallingSand.php b/src/pocketmine/entity/FallingSand.php index d0583cd91..dd2cc4185 100644 --- a/src/pocketmine/entity/FallingSand.php +++ b/src/pocketmine/entity/FallingSand.php @@ -96,13 +96,12 @@ class FallingSand extends Entity{ if(!$this->dead){ if($this->ticksLived === 1){ - $block = $this->level->getBlock($pos = (new Vector3($this->x, $this->y, $this->z))->floor()); - if($block->getId() != $this->blockId){ + $block = $this->level->getBlock($pos = (new Vector3($this->x - 0.5, $this->y - 0.5, $this->z - 0.5))->floor()); + if($block->getId() !== $this->blockId){ $this->kill(); return true; } $this->level->setBlock($pos, Block::get(0), true); - } $this->motionY -= $this->gravity; diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index cd5d3a0b8..7d3ded1e2 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -130,7 +130,7 @@ class Explosion{ public function explodeB(){ $send = []; - $source = (new Vector3($this->source->x, $this->source->y, $this->source->z))->floor(); + $source = (new Vector3($this->source->x, $this->source->y, $this->source->z))->round(); $yield = (1 / $this->size) * 100; if($this->what instanceof Entity){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 19bbd1924..c45c63a7f 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -847,16 +847,6 @@ class Level implements ChunkManager, Metadatable{ * @param Vector3 $pos */ public function updateAround(Vector3 $pos){ - $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x - 1, $pos->y, $pos->z)))); - if(!$ev->isCancelled()){ - $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); - } - - $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x + 1, $pos->y, $pos->z)))); - if(!$ev->isCancelled()){ - $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); - } - $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y - 1, $pos->z)))); if(!$ev->isCancelled()){ $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); @@ -867,6 +857,16 @@ class Level implements ChunkManager, Metadatable{ $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); } + $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x - 1, $pos->y, $pos->z)))); + if(!$ev->isCancelled()){ + $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); + } + + $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x + 1, $pos->y, $pos->z)))); + if(!$ev->isCancelled()){ + $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); + } + $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y, $pos->z - 1)))); if(!$ev->isCancelled()){ $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); @@ -1081,7 +1081,7 @@ class Level implements ChunkManager, Metadatable{ */ public function getBlock(Vector3 $pos, $cached = true){ $index = Level::blockHash($pos->x, $pos->y, $pos->z); - if($cached === true and isset($this->blockCache[$index])){ + if($cached and isset($this->blockCache[$index])){ return $this->blockCache[$index]; }elseif($pos->y >= 0 and $pos->y < 128 and isset($this->chunks[$chunkIndex = Level::chunkHash($pos->x >> 4, $pos->z >> 4)])){ $fullState = $this->chunks[$chunkIndex]->getFullBlock($pos->x & 0x0f, $pos->y & 0x7f, $pos->z & 0x0f); @@ -1232,10 +1232,6 @@ class Level implements ChunkManager, Metadatable{ $this->sendBlocks($this->getUsingChunk($pos->x >> 4, $pos->z >> 4), [$block], UpdateBlockPacket::FLAG_ALL_PRIORITY); unset($this->chunkCache[$index]); }else{ - if(!($pos instanceof Position)){ - $pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z); - } - $block->position($pos); if(!isset($this->changedBlocks[$index])){ $this->changedBlocks[$index] = []; } @@ -1248,10 +1244,10 @@ class Level implements ChunkManager, Metadatable{ $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($block)); if(!$ev->isCancelled()){ - $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); - foreach($this->getNearbyEntities(new AxisAlignedBB($block->x - 1, $block->y - 1, $block->z - 1, $block->x + 2, $block->y + 2, $block->z + 2)) as $entity){ + foreach($this->getNearbyEntities(new AxisAlignedBB($block->x - 1, $block->y - 1, $block->z - 1, $block->x + 1, $block->y + 1, $block->z + 1)) as $entity){ $entity->scheduleUpdate(); } + $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); } $this->updateAround($pos); @@ -2291,7 +2287,7 @@ class Level implements ChunkManager, Metadatable{ $spawn = $this->getSpawnLocation(); } if($spawn instanceof Vector3){ - $v = $spawn->floor(); + $v = $spawn->round(); $chunk = $this->getChunk($v->x >> 4, $v->z >> 4, false); $x = $v->x & 0x0f; $z = $v->z & 0x0f; diff --git a/src/pocketmine/math/Vector3.php b/src/pocketmine/math/Vector3.php index 7bc4883c4..a7f3871ee 100644 --- a/src/pocketmine/math/Vector3.php +++ b/src/pocketmine/math/Vector3.php @@ -127,13 +127,11 @@ class Vector3{ } public function floor(){ - $x = (int) $this->x; - $z = (int) $this->z; - return new Vector3($this->x >= $x ? $x : $x - 1, (int) round($this->y), $this->z >= $z ? $z : $z - 1); + return new Vector3((int) $this->x, (int) $this->y, (int) $this->z); } public function round(){ - return new Vector3(round($this->x), round($this->y), round($this->z)); + return new Vector3((int) round($this->x), (int) round($this->y), (int) round($this->z)); } public function abs(){