From 6aaaaefd2f0d0033936a1c98ec7edb4d3aaedb6e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 3 Jun 2018 12:50:16 +0100 Subject: [PATCH] Make tiles less dependent on runtime NBT, use properties instead This will ultimately culminate in the complete removal of runtime NBT, so plugins should also follow these steps if they have custom data. --- src/pocketmine/block/StandingBanner.php | 4 +- src/pocketmine/tile/Banner.php | 62 ++++++++++++++----------- src/pocketmine/tile/Bed.php | 24 ++++++---- src/pocketmine/tile/Chest.php | 42 ++++++++++++----- src/pocketmine/tile/FlowerPot.php | 28 +++++------ src/pocketmine/tile/ItemFrame.php | 59 ++++++++++++----------- src/pocketmine/tile/Skull.php | 31 ++++++++----- src/pocketmine/tile/Spawnable.php | 7 +-- 8 files changed, 153 insertions(+), 104 deletions(-) diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index 8e4ac59e2..88520deb2 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -92,8 +92,8 @@ class StandingBanner extends Transparent{ $tile = $this->level->getTile($this); $drop = ItemFactory::get(Item::BANNER, ($tile instanceof TileBanner ? $tile->getBaseColor() : 0)); - if($tile instanceof TileBanner and ($patterns = $tile->namedtag->getListTag(TileBanner::TAG_PATTERNS)) !== null and !$patterns->empty()){ - $drop->setNamedTagEntry($patterns); + if($tile instanceof TileBanner and !($patterns = $tile->getPatterns())->empty()){ + $drop->setNamedTagEntry(clone $patterns); } return [$drop]; diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index dde23c8c2..647d8fc08 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -99,19 +99,30 @@ class Banner extends Spawnable implements Nameable{ public const COLOR_ORANGE = 14; public const COLOR_WHITE = 15; + /** @var int */ + private $baseColor; + /** + * @var ListTag + * TODO: break this down further and remove runtime NBT from here entirely + */ + private $patterns; + public function __construct(Level $level, CompoundTag $nbt){ - if(!$nbt->hasTag(self::TAG_BASE, IntTag::class)){ - $nbt->setInt(self::TAG_BASE, 0); - } - if(!$nbt->hasTag(self::TAG_PATTERNS, ListTag::class)){ - $nbt->setTag(new ListTag(self::TAG_PATTERNS)); - } + $this->baseColor = $nbt->getInt(self::TAG_BASE, self::COLOR_BLACK, true); + $this->patterns = $nbt->getListTag(self::TAG_PATTERNS) ?? new ListTag(self::TAG_PATTERNS); + $nbt->removeTag(self::TAG_BASE, self::TAG_PATTERNS); parent::__construct($level, $nbt); } + public function saveNBT() : void{ + parent::saveNBT(); + $this->namedtag->setInt(self::TAG_BASE, $this->baseColor); + $this->namedtag->setTag($this->patterns); + } + public function addAdditionalSpawnData(CompoundTag $nbt) : void{ - $nbt->setTag($this->namedtag->getTag(self::TAG_PATTERNS)); - $nbt->setTag($this->namedtag->getTag(self::TAG_BASE)); + $nbt->setInt(self::TAG_BASE, $this->baseColor); + $nbt->setTag($this->patterns); $this->addNameSpawnData($nbt); } @@ -121,7 +132,7 @@ class Banner extends Spawnable implements Nameable{ * @return int */ public function getBaseColor() : int{ - return $this->namedtag->getInt(self::TAG_BASE, 0); + return $this->baseColor; } /** @@ -130,7 +141,7 @@ class Banner extends Spawnable implements Nameable{ * @param int $color */ public function setBaseColor(int $color) : void{ - $this->namedtag->setInt(self::TAG_BASE, $color & 0x0f); + $this->baseColor = $color; $this->onChanged(); } @@ -143,15 +154,13 @@ class Banner extends Spawnable implements Nameable{ * @return int ID of pattern. */ public function addPattern(string $pattern, int $color) : int{ - $list = $this->namedtag->getListTag(self::TAG_PATTERNS); - assert($list !== null); - $list->push(new CompoundTag("", [ + $this->patterns->push(new CompoundTag("", [ new IntTag(self::TAG_PATTERN_COLOR, $color & 0x0f), new StringTag(self::TAG_PATTERN_NAME, $pattern) ])); $this->onChanged(); - return $list->count() - 1; //Last offset in the list + return $this->patterns->count() - 1; //Last offset in the list } /** @@ -162,7 +171,7 @@ class Banner extends Spawnable implements Nameable{ * @return bool */ public function patternExists(int $patternId) : bool{ - return $this->namedtag->getListTag(self::TAG_PATTERNS)->isset($patternId); + return $this->patterns->isset($patternId); } /** @@ -177,9 +186,7 @@ class Banner extends Spawnable implements Nameable{ return []; } - $list = $this->namedtag->getListTag(self::TAG_PATTERNS); - assert($list instanceof ListTag); - $patternTag = $list->get($patternId); + $patternTag = $this->patterns->get($patternId); assert($patternTag instanceof CompoundTag); return [ @@ -202,10 +209,7 @@ class Banner extends Spawnable implements Nameable{ return false; } - $list = $this->namedtag->getListTag(self::TAG_PATTERNS); - assert($list instanceof ListTag); - - $list->set($patternId, new CompoundTag("", [ + $this->patterns->set($patternId, new CompoundTag("", [ new IntTag(self::TAG_PATTERN_COLOR, $color & 0x0f), new StringTag(self::TAG_PATTERN_NAME, $pattern) ])); @@ -226,10 +230,7 @@ class Banner extends Spawnable implements Nameable{ return false; } - $list = $this->namedtag->getListTag(self::TAG_PATTERNS); - if($list !== null){ - $list->remove($patternId); - } + $this->patterns->remove($patternId); $this->onChanged(); return true; @@ -259,7 +260,14 @@ class Banner extends Spawnable implements Nameable{ * @return int */ public function getPatternCount() : int{ - return $this->namedtag->getListTag(self::TAG_PATTERNS)->count(); + return $this->patterns->count(); + } + + /** + * @return ListTag + */ + public function getPatterns() : ListTag{ + return $this->patterns; } protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{ diff --git a/src/pocketmine/tile/Bed.php b/src/pocketmine/tile/Bed.php index 58c1d57a5..ad7694b02 100644 --- a/src/pocketmine/tile/Bed.php +++ b/src/pocketmine/tile/Bed.php @@ -27,34 +27,42 @@ namespace pocketmine\tile; use pocketmine\item\Item; use pocketmine\level\Level; use pocketmine\math\Vector3; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\Player; class Bed extends Spawnable{ public const TAG_COLOR = "color"; + /** @var int */ + private $color = 14; //default to old red public function __construct(Level $level, CompoundTag $nbt){ - if(!$nbt->hasTag(self::TAG_COLOR, ByteTag::class)){ //TODO: check PC format - $nbt->setByte(self::TAG_COLOR, 14, true); //default to old red - } + $this->color = $nbt->getByte(self::TAG_COLOR, 14, true); + $nbt->removeTag(self::TAG_COLOR); + parent::__construct($level, $nbt); } public function getColor() : int{ - return $this->namedtag->getByte(self::TAG_COLOR); + return $this->color; } public function setColor(int $color){ - $this->namedtag->setByte(self::TAG_COLOR, $color & 0x0f); + $this->color = $color & 0xf; $this->onChanged(); } public function addAdditionalSpawnData(CompoundTag $nbt) : void{ - $nbt->setTag($this->namedtag->getTag(self::TAG_COLOR)); + $nbt->setByte(self::TAG_COLOR, $this->color); + } + + public function saveNBT() : void{ + parent::saveNBT(); + $this->namedtag->setByte(self::TAG_COLOR, $this->color); } protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{ - $nbt->setByte(self::TAG_COLOR, $item !== null ? $item->getDamage() : 14); //default red + if($item !== null){ + $nbt->setByte(self::TAG_COLOR, $item->getDamage()); + } } } diff --git a/src/pocketmine/tile/Chest.php b/src/pocketmine/tile/Chest.php index 4f08f1ff3..7fd3f3add 100644 --- a/src/pocketmine/tile/Chest.php +++ b/src/pocketmine/tile/Chest.php @@ -28,6 +28,7 @@ use pocketmine\inventory\DoubleChestInventory; use pocketmine\inventory\InventoryHolder; use pocketmine\level\Level; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\IntTag; class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ use NameableTrait { @@ -44,8 +45,19 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ /** @var DoubleChestInventory */ protected $doubleInventory = null; + /** @var int|null */ + private $pairX; + /** @var int|null */ + private $pairZ; + public function __construct(Level $level, CompoundTag $nbt){ + if($nbt->hasTag(self::TAG_PAIRX, IntTag::class) and $nbt->hasTag(self::TAG_PAIRZ, IntTag::class)){ + $this->pairX = $nbt->getInt(self::TAG_PAIRX); + $this->pairZ = $nbt->getInt(self::TAG_PAIRZ); + } + $nbt->removeTag(self::TAG_PAIRX, self::TAG_PAIRZ); parent::__construct($level, $nbt); + $this->inventory = new ChestInventory($this); $this->loadItems(); } @@ -68,6 +80,12 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ public function saveNBT() : void{ parent::saveNBT(); + if($this->isPaired()){ + $this->namedtag->setInt(self::TAG_PAIRX, $this->pairX); + $this->namedtag->setInt(self::TAG_PAIRZ, $this->pairZ); + }else{ + $this->namedtag->removeTag(self::TAG_PAIRX, self::TAG_PAIRZ); + } $this->saveItems(); } @@ -89,7 +107,7 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ } protected function checkPairing(){ - if($this->isPaired() and !$this->getLevel()->isChunkLoaded($this->namedtag->getInt(self::TAG_PAIRX) >> 4, $this->namedtag->getInt(self::TAG_PAIRZ) >> 4)){ + if($this->isPaired() and !$this->getLevel()->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ //paired to a tile in an unloaded chunk $this->doubleInventory = null; @@ -107,7 +125,7 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ } }else{ $this->doubleInventory = null; - $this->namedtag->removeTag(self::TAG_PAIRX, self::TAG_PAIRZ); + $this->pairX = $this->pairZ = null; } } @@ -119,7 +137,7 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ } public function isPaired(){ - return $this->namedtag->hasTag(self::TAG_PAIRX) and $this->namedtag->hasTag(self::TAG_PAIRZ); + return $this->pairX !== null and $this->pairZ !== null; } /** @@ -127,7 +145,7 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ */ public function getPair() : ?Chest{ if($this->isPaired()){ - $tile = $this->getLevel()->getTileAt($this->namedtag->getInt(self::TAG_PAIRX), $this->y, $this->namedtag->getInt(self::TAG_PAIRZ)); + $tile = $this->getLevel()->getTileAt($this->pairX, $this->y, $this->pairZ); if($tile instanceof Chest){ return $tile; } @@ -151,11 +169,11 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ } private function createPair(Chest $tile){ - $this->namedtag->setInt(self::TAG_PAIRX, $tile->x); - $this->namedtag->setInt(self::TAG_PAIRZ, $tile->z); + $this->pairX = $tile->x; + $this->pairZ = $tile->z; - $tile->namedtag->setInt(self::TAG_PAIRX, $this->x); - $tile->namedtag->setInt(self::TAG_PAIRZ, $this->z); + $tile->pairX = $this->x; + $tile->pairZ = $this->z; } public function unpair(){ @@ -164,12 +182,12 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ } $tile = $this->getPair(); - $this->namedtag->removeTag(self::TAG_PAIRX, self::TAG_PAIRZ); + $this->pairX = $this->pairZ = null; $this->onChanged(); if($tile instanceof Chest){ - $tile->namedtag->removeTag(self::TAG_PAIRX, self::TAG_PAIRZ); + $tile->pairX = $tile->pairZ = null; $tile->checkPairing(); $tile->onChanged(); } @@ -180,8 +198,8 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ public function addAdditionalSpawnData(CompoundTag $nbt) : void{ if($this->isPaired()){ - $nbt->setTag($this->namedtag->getTag(self::TAG_PAIRX)); - $nbt->setTag($this->namedtag->getTag(self::TAG_PAIRZ)); + $nbt->setInt(self::TAG_PAIRX, $this->pairX); + $nbt->setInt(self::TAG_PAIRZ, $this->pairZ); } $this->addNameSpawnData($nbt); diff --git a/src/pocketmine/tile/FlowerPot.php b/src/pocketmine/tile/FlowerPot.php index c2f6f0cb0..e4c7eb734 100644 --- a/src/pocketmine/tile/FlowerPot.php +++ b/src/pocketmine/tile/FlowerPot.php @@ -27,24 +27,27 @@ use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\level\Level; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\ShortTag; class FlowerPot extends Spawnable{ public const TAG_ITEM = "item"; public const TAG_ITEM_DATA = "mData"; + /** @var Item */ + private $item; + public function __construct(Level $level, CompoundTag $nbt){ //TODO: check PC format - if(!$nbt->hasTag(self::TAG_ITEM, ShortTag::class)){ - $nbt->setShort(self::TAG_ITEM, 0, true); - } - if(!$nbt->hasTag(self::TAG_ITEM_DATA, IntTag::class)){ - $nbt->setInt(self::TAG_ITEM_DATA, 0, true); - } + $this->item = ItemFactory::get($nbt->getShort(self::TAG_ITEM, 0, true), $nbt->getInt(self::TAG_ITEM_DATA, 0, true), 1); + $nbt->removeTag(self::TAG_ITEM, self::TAG_ITEM_DATA); + parent::__construct($level, $nbt); } + public function saveNBT() : void{ + $this->namedtag->setShort(self::TAG_ITEM, $this->item->getId()); + $this->namedtag->setInt(self::TAG_ITEM_DATA, $this->item->getDamage()); + } + public function canAddItem(Item $item) : bool{ if(!$this->isEmpty()){ return false; @@ -69,12 +72,11 @@ class FlowerPot extends Spawnable{ } public function getItem() : Item{ - return ItemFactory::get($this->namedtag->getShort(self::TAG_ITEM), $this->namedtag->getInt(self::TAG_ITEM_DATA), 1); + return clone $this->item; } public function setItem(Item $item){ - $this->namedtag->setShort(self::TAG_ITEM, $item->getId()); - $this->namedtag->setInt(self::TAG_ITEM_DATA, $item->getDamage()); + $this->item = clone $item; $this->onChanged(); } @@ -87,7 +89,7 @@ class FlowerPot extends Spawnable{ } public function addAdditionalSpawnData(CompoundTag $nbt) : void{ - $nbt->setTag($this->namedtag->getTag(self::TAG_ITEM)); - $nbt->setTag($this->namedtag->getTag(self::TAG_ITEM_DATA)); + $nbt->setShort(self::TAG_ITEM, $this->item->getId()); + $nbt->setInt(self::TAG_ITEM_DATA, $this->item->getDamage()); } } diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/tile/ItemFrame.php index 6cae86e32..39f715121 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/tile/ItemFrame.php @@ -26,73 +26,78 @@ namespace pocketmine\tile; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\level\Level; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\FloatTag; class ItemFrame extends Spawnable{ public const TAG_ITEM_ROTATION = "ItemRotation"; public const TAG_ITEM_DROP_CHANCE = "ItemDropChance"; public const TAG_ITEM = "Item"; - public function __construct(Level $level, CompoundTag $nbt){ - if(!$nbt->hasTag(self::TAG_ITEM_ROTATION, ByteTag::class)){ - $nbt->setByte(self::TAG_ITEM_ROTATION, 0, true); - } + /** @var Item */ + private $item; + /** @var int */ + private $itemRotation; + /** @var float */ + private $itemDropChance; - if(!$nbt->hasTag(self::TAG_ITEM_DROP_CHANCE, FloatTag::class)){ - $nbt->setFloat(self::TAG_ITEM_DROP_CHANCE, 1.0, true); + public function __construct(Level $level, CompoundTag $nbt){ + if(($itemTag = $nbt->getCompoundTag(self::TAG_ITEM)) !== null){ + $this->item = Item::nbtDeserialize($itemTag); + }else{ + $this->item = ItemFactory::get(Item::AIR, 0, 0); } + $this->itemRotation = $nbt->getByte(self::TAG_ITEM_ROTATION, 0, true); + $this->itemDropChance = $nbt->getFloat(self::TAG_ITEM_DROP_CHANCE, 1.0, true); + $nbt->removeTag(self::TAG_ITEM, self::TAG_ITEM_ROTATION, self::TAG_ITEM_DROP_CHANCE); parent::__construct($level, $nbt); } + public function saveNBT() : void{ + parent::saveNBT(); + $this->namedtag->setFloat(self::TAG_ITEM_DROP_CHANCE, $this->itemDropChance); + $this->namedtag->setByte(self::TAG_ITEM_ROTATION, $this->itemRotation); + $this->namedtag->setTag($this->item->nbtSerialize(-1, self::TAG_ITEM)); + } + public function hasItem() : bool{ - return !$this->getItem()->isNull(); + return !$this->item->isNull(); } public function getItem() : Item{ - $c = $this->namedtag->getCompoundTag(self::TAG_ITEM); - if($c !== null){ - return Item::nbtDeserialize($c); - } - - return ItemFactory::get(Item::AIR, 0, 0); + return clone $this->item; } public function setItem(Item $item = null){ if($item !== null and !$item->isNull()){ - $this->namedtag->setTag($item->nbtSerialize(-1, self::TAG_ITEM)); + $this->item = clone $item; }else{ - $this->namedtag->removeTag(self::TAG_ITEM); + $this->item = ItemFactory::get(Item::AIR, 0, 0); } $this->onChanged(); } public function getItemRotation() : int{ - return $this->namedtag->getByte(self::TAG_ITEM_ROTATION); + return $this->itemRotation; } public function setItemRotation(int $rotation){ - $this->namedtag->setByte(self::TAG_ITEM_ROTATION, $rotation); + $this->itemRotation = $rotation; $this->onChanged(); } public function getItemDropChance() : float{ - return $this->namedtag->getFloat(self::TAG_ITEM_DROP_CHANCE); + return $this->itemDropChance; } public function setItemDropChance(float $chance){ - $this->namedtag->setFloat(self::TAG_ITEM_DROP_CHANCE, $chance); + $this->itemDropChance = $chance; $this->onChanged(); } public function addAdditionalSpawnData(CompoundTag $nbt) : void{ - $nbt->setTag($this->namedtag->getTag(self::TAG_ITEM_DROP_CHANCE)); - $nbt->setTag($this->namedtag->getTag(self::TAG_ITEM_ROTATION)); - - if($this->hasItem()){ - $nbt->setTag($this->namedtag->getTag(self::TAG_ITEM)); - } + $nbt->setFloat(self::TAG_ITEM_DROP_CHANCE, $this->itemDropChance); + $nbt->setByte(self::TAG_ITEM_ROTATION, $this->itemRotation); + $nbt->setTag($this->item->nbtSerialize(-1, self::TAG_ITEM)); } } diff --git a/src/pocketmine/tile/Skull.php b/src/pocketmine/tile/Skull.php index 68edd7579..1b24eb534 100644 --- a/src/pocketmine/tile/Skull.php +++ b/src/pocketmine/tile/Skull.php @@ -26,7 +26,6 @@ namespace pocketmine\tile; use pocketmine\item\Item; use pocketmine\level\Level; use pocketmine\math\Vector3; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\Player; @@ -43,28 +42,36 @@ class Skull extends Spawnable{ public const TAG_MOUTH_MOVING = "MouthMoving"; //TAG_Byte public const TAG_MOUTH_TICK_COUNT = "MouthTickCount"; //TAG_Int + /** @var int */ + private $skullType; + /** @var int */ + private $skullRotation; + public function __construct(Level $level, CompoundTag $nbt){ - if(!$nbt->hasTag(self::TAG_SKULL_TYPE, ByteTag::class)){ - $nbt->setByte(self::TAG_SKULL_TYPE, 0, true); - } - if(!$nbt->hasTag(self::TAG_ROT, ByteTag::class)){ - $nbt->setByte(self::TAG_ROT, 0, true); - } + $this->skullType = $nbt->getByte(self::TAG_SKULL_TYPE, self::TYPE_SKELETON, true); + $this->skullRotation = $nbt->getByte(self::TAG_ROT, 0, true); + $nbt->removeTag(self::TAG_SKULL_TYPE, self::TAG_ROT); parent::__construct($level, $nbt); } + public function saveNBT() : void{ + parent::saveNBT(); + $this->namedtag->setByte(self::TAG_SKULL_TYPE, $this->skullType); + $this->namedtag->setByte(self::TAG_ROT, $this->skullRotation); + } + public function setType(int $type){ - $this->namedtag->setByte(self::TAG_SKULL_TYPE, $type); + $this->skullType = $type; $this->onChanged(); } public function getType() : int{ - return $this->namedtag->getByte(self::TAG_SKULL_TYPE); + return $this->skullType; } public function addAdditionalSpawnData(CompoundTag $nbt) : void{ - $nbt->setTag($this->namedtag->getTag(self::TAG_SKULL_TYPE)); - $nbt->setTag($this->namedtag->getTag(self::TAG_ROT)); + $nbt->setByte(self::TAG_SKULL_TYPE, $this->skullType); + $nbt->setByte(self::TAG_ROT, $this->skullRotation); } protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{ @@ -74,6 +81,6 @@ class Skull extends Spawnable{ if($face === Vector3::SIDE_UP and $player !== null){ $rot = floor(($player->yaw * 16 / 360) + 0.5) & 0x0F; } - $nbt->setByte("Rot", $rot); + $nbt->setByte(self::TAG_ROT, $rot); } } diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index 4c1bced23..1937c7d00 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -26,6 +26,7 @@ namespace pocketmine\tile; use pocketmine\level\Level; use pocketmine\nbt\NetworkLittleEndianNBTStream; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\Player; @@ -105,9 +106,9 @@ abstract class Spawnable extends Tile{ final public function getSpawnCompound() : CompoundTag{ $nbt = new CompoundTag("", [ new StringTag(self::TAG_ID, static::getSaveId()), - $this->namedtag->getTag(self::TAG_X), - $this->namedtag->getTag(self::TAG_Y), - $this->namedtag->getTag(self::TAG_Z) + new IntTag(self::TAG_X, $this->x), + new IntTag(self::TAG_Y, $this->y), + new IntTag(self::TAG_Z, $this->z) ]); $this->addAdditionalSpawnData($nbt); return $nbt;