From d9ebe6f3210750e0b24f31ab8bc6d04ec6eb9996 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Oct 2018 15:54:13 +0100 Subject: [PATCH 1/5] Level: Added API method getChunkAtPosition() This returns the chunk containing the given vector. --- src/pocketmine/level/Level.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index f9b217b26..c64ada77a 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -2338,6 +2338,18 @@ class Level implements ChunkManager, Metadatable{ return null; } + /** + * Returns the chunk containing the given Vector3 position. + * + * @param Vector3 $pos + * @param bool $create + * + * @return null|Chunk + */ + public function getChunkAtPosition(Vector3 $pos, bool $create = false) : ?Chunk{ + return $this->getChunk($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4, $create); + } + /** * Returns the chunks adjacent to the specified chunk. * From 9f8a2dc61aebd6f71ce0d04197d40e3acbd01835 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Oct 2018 15:58:29 +0100 Subject: [PATCH 2/5] Make use of new API method getChunkAtPosition() --- src/pocketmine/entity/Entity.php | 2 +- src/pocketmine/level/Level.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 7a49ae904..75f193699 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -516,7 +516,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0); $this->recalculateBoundingBox(); - $this->chunk = $this->level->getChunk($this->getFloorX() >> 4, $this->getFloorZ() >> 4, false); + $this->chunk = $this->level->getChunkAtPosition($this, false); if($this->chunk === null){ throw new \InvalidStateException("Cannot create entities in unloaded chunks"); } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index c64ada77a..f3b03e291 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1554,7 +1554,7 @@ class Level implements ChunkManager, Metadatable{ $this->timings->setBlock->startTiming(); - if($this->getChunk($pos->x >> 4, $pos->z >> 4, true)->setBlock($pos->x & 0x0f, $pos->y, $pos->z & 0x0f, $block->getId(), $block->getDamage())){ + if($this->getChunkAtPosition($pos, true)->setBlock($pos->x & 0x0f, $pos->y, $pos->z & 0x0f, $block->getId(), $block->getDamage())){ if(!($pos instanceof Position)){ $pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z); } @@ -2859,7 +2859,7 @@ class Level implements ChunkManager, Metadatable{ $max = $this->worldHeight; $v = $spawn->floor(); - $chunk = $this->getChunk($v->x >> 4, $v->z >> 4, false); + $chunk = $this->getChunkAtPosition($v, false); $x = (int) $v->x; $z = (int) $v->z; if($chunk !== null and $chunk->isGenerated()){ From 3028832cd35c53937bb6502f74d3ad53646b12a7 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Oct 2018 16:24:46 +0100 Subject: [PATCH 3/5] Entity: remove redundant check from spawnTo() this won't be reached if the player isn't using this chunk anyway. --- src/pocketmine/entity/Entity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 75f193699..9f2389200 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1952,7 +1952,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ * @param Player $player */ public function spawnTo(Player $player) : void{ - if(!isset($this->hasSpawned[$player->getLoaderId()]) and $this->chunk !== null and isset($player->usedChunks[Level::chunkHash($this->chunk->getX(), $this->chunk->getZ())])){ + if(!isset($this->hasSpawned[$player->getLoaderId()])){ $this->hasSpawned[$player->getLoaderId()] = $player; $this->sendSpawnPacket($player); From 43426a4c5c107907d178ff09f1f62fc7d609a97b Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Oct 2018 16:25:56 +0100 Subject: [PATCH 4/5] Level: Add API method getViewersForPosition() This returns all players who have the given position within their view radius. --- src/pocketmine/level/Level.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index f3b03e291..73774899a 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -595,6 +595,16 @@ class Level implements ChunkManager, Metadatable{ return $this->chunkLoaders[Level::chunkHash($chunkX, $chunkZ)] ?? []; } + /** + * Returns an array of players who have the target position within their view distance. + * @param Vector3 $pos + * + * @return Player[] + */ + public function getViewersForPosition(Vector3 $pos) : array{ + return $this->getChunkPlayers($pos->getFloorX() >> 4, $pos->getFloorZ() >> 4); + } + /** * Queues a DataPacket to be sent to all players using the chunk at the specified X/Z coordinates at the end of the * current tick. From 4aef9919dc4468bb520006312bfd1229281359fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 20 Oct 2018 16:26:10 +0100 Subject: [PATCH 5/5] Use newly added API method --- src/pocketmine/entity/Entity.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index 9f2389200..756817f61 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -1804,7 +1804,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ $this->chunk = $this->level->getChunk($chunkX, $chunkZ, true); if(!$this->justCreated){ - $newChunk = $this->level->getChunkPlayers($chunkX, $chunkZ); + $newChunk = $this->level->getViewersForPosition($this); foreach($this->hasSpawned as $player){ if(!isset($newChunk[$player->getLoaderId()])){ $this->despawnFrom($player); @@ -1963,7 +1963,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ if($this->chunk === null or $this->closed){ return; } - foreach($this->level->getChunkPlayers($this->chunk->getX(), $this->chunk->getZ()) as $player){ + foreach($this->level->getViewersForPosition($this) as $player){ if($player->isOnline()){ $this->spawnTo($player); }