diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 8ac45bcb8..db1f9a1c5 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -86,6 +86,7 @@ use pocketmine\level\Level; use pocketmine\level\Location; use pocketmine\level\Position; use pocketmine\level\sound\LaunchSound; +use pocketmine\level\WeakPosition; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector2; use pocketmine\math\Vector3; @@ -228,7 +229,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade protected $viewDistance; protected $chunksPerTick; protected $spawnThreshold; - /** @var null|Position */ + /** @var null|WeakPosition */ private $spawnPosition = null; protected $inAirTicks = 0; @@ -680,7 +681,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade * @return Position */ public function getSpawn(){ - if($this->spawnPosition instanceof Position and $this->spawnPosition->getLevel() instanceof Level){ + if($this->hasValidSpawnPosition()){ return $this->spawnPosition; }else{ $level = $this->server->getDefaultLevel(); @@ -689,6 +690,13 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade } } + /** + * @return bool + */ + public function hasValidSpawnPosition() : bool{ + return $this->spawnPosition instanceof WeakPosition and $this->spawnPosition->isValid(); + } + public function sendChunk($x, $z, $payload, $ordering = FullChunkDataPacket::ORDER_COLUMNS){ if($this->connected === false){ return; @@ -1038,7 +1046,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade }else{ $level = $pos->getLevel(); } - $this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $level); + $this->spawnPosition = new WeakPosition($pos->x, $pos->y, $pos->z, $level); $pk = new SetSpawnPositionPacket(); $pk->x = (int) $this->spawnPosition->x; $pk->y = (int) $this->spawnPosition->y; @@ -1677,8 +1685,8 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->dataPacket(new ResourcePacksInfoPacket()); - if($this->spawnPosition === null and isset($this->namedtag->SpawnLevel) and ($level = $this->server->getLevelByName($this->namedtag["SpawnLevel"])) instanceof Level){ - $this->spawnPosition = new Position($this->namedtag["SpawnX"], $this->namedtag["SpawnY"], $this->namedtag["SpawnZ"], $level); + if(!$this->hasValidSpawnPosition() and isset($this->namedtag->SpawnLevel) and ($level = $this->server->getLevelByName($this->namedtag["SpawnLevel"])) instanceof Level){ + $this->spawnPosition = new WeakPosition($this->namedtag["SpawnX"], $this->namedtag["SpawnY"], $this->namedtag["SpawnZ"], $level); } $spawnPosition = $this->getSpawn(); @@ -3084,7 +3092,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade parent::saveNBT(); if($this->level instanceof Level){ $this->namedtag->Level = new StringTag("Level", $this->level->getName()); - if($this->spawnPosition instanceof Position and $this->spawnPosition->getLevel() instanceof Level){ + if($this->hasValidSpawnPosition()){ $this->namedtag["SpawnLevel"] = $this->spawnPosition->getLevel()->getName(); $this->namedtag["SpawnX"] = (int) $this->spawnPosition->x; $this->namedtag["SpawnY"] = (int) $this->spawnPosition->y; diff --git a/src/pocketmine/level/Position.php b/src/pocketmine/level/Position.php index d581ab0da..78f7b15f7 100644 --- a/src/pocketmine/level/Position.php +++ b/src/pocketmine/level/Position.php @@ -64,7 +64,7 @@ class Position extends Vector3{ * @return bool */ public function isValid(){ - return $this->level !== null; + return $this->getLevel() instanceof Level; } /** diff --git a/src/pocketmine/level/WeakPosition.php b/src/pocketmine/level/WeakPosition.php new file mode 100644 index 000000000..b8808ad48 --- /dev/null +++ b/src/pocketmine/level/WeakPosition.php @@ -0,0 +1,78 @@ +x = $x; + $this->y = $y; + $this->z = $z; + $this->levelId = ($level !== null ? $level->getId() : -1); + } + + public static function fromObject(Vector3 $pos, Level $level = null){ + return new WeakPosition($pos->x, $pos->y, $pos->z, $level); + } + + /** + * @return Level|null + */ + public function getLevel(){ + return Server::getInstance()->getLevel($this->levelId); + } + + public function setLevel(Level $level){ + $this->levelId = ($level !== null ? $level->getId() : -1); + return $this; + } + + /** + * Returns a side Vector + * + * @param int $side + * @param int $step + * + * @return WeakPosition + * + * @throws LevelException + */ + public function getSide($side, $step = 1){ + assert($this->isValid()); + + return WeakPosition::fromObject(parent::getSide($side, $step), $this->level); + } + + public function __toString(){ + return "Weak" . parent::__toString(); + } +} \ No newline at end of file