mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 08:44:01 +00:00
Kill entity runtime NBT (#2361)
This commit is contained in:
parent
4b7300de8d
commit
0273e2484e
@ -1885,18 +1885,18 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->server->addOnlinePlayer($this);
|
||||
}
|
||||
|
||||
protected function initHumanData() : void{
|
||||
protected function initHumanData(CompoundTag $nbt) : void{
|
||||
$this->setNameTag($this->username);
|
||||
}
|
||||
|
||||
protected function initEntity() : void{
|
||||
parent::initEntity();
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
$this->addDefaultWindows();
|
||||
|
||||
$this->firstPlayed = $this->namedtag->getLong("firstPlayed", $now = (int) (microtime(true) * 1000));
|
||||
$this->lastPlayed = $this->namedtag->getLong("lastPlayed", $now);
|
||||
$this->firstPlayed = $nbt->getLong("firstPlayed", $now = (int) (microtime(true) * 1000));
|
||||
$this->lastPlayed = $nbt->getLong("lastPlayed", $now);
|
||||
|
||||
$this->gamemode = $this->namedtag->getInt("playerGameType", self::SURVIVAL) & 0x03;
|
||||
$this->gamemode = $nbt->getInt("playerGameType", self::SURVIVAL) & 0x03;
|
||||
if($this->server->getForceGamemode()){
|
||||
$this->gamemode = $this->server->getGamemode();
|
||||
}
|
||||
@ -1912,15 +1912,15 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->setCanClimb();
|
||||
|
||||
$this->achievements = [];
|
||||
$achievements = $this->namedtag->getCompoundTag("Achievements") ?? [];
|
||||
$achievements = $nbt->getCompoundTag("Achievements") ?? [];
|
||||
/** @var ByteTag $achievement */
|
||||
foreach($achievements as $achievement){
|
||||
$this->achievements[$achievement->getName()] = $achievement->getValue() !== 0;
|
||||
}
|
||||
|
||||
if(!$this->hasValidSpawnPosition()){
|
||||
if(($level = $this->server->getLevelByName($this->namedtag->getString("SpawnLevel", ""))) instanceof Level){
|
||||
$this->spawnPosition = new Position($this->namedtag->getInt("SpawnX"), $this->namedtag->getInt("SpawnY"), $this->namedtag->getInt("SpawnZ"), $level);
|
||||
if(($level = $this->server->getLevelByName($nbt->getString("SpawnLevel", ""))) instanceof Level){
|
||||
$this->spawnPosition = new Position($nbt->getInt("SpawnX"), $nbt->getInt("SpawnY"), $nbt->getInt("SpawnZ"), $level);
|
||||
}else{
|
||||
$this->spawnPosition = $this->level->getSafeSpawn();
|
||||
}
|
||||
@ -2916,21 +2916,21 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
throw new \InvalidStateException("Tried to save closed player");
|
||||
}
|
||||
|
||||
parent::saveNBT();
|
||||
$nbt = $this->saveNBT();
|
||||
|
||||
if($this->isValid()){
|
||||
$this->namedtag->setString("Level", $this->level->getFolderName());
|
||||
$nbt->setString("Level", $this->level->getFolderName());
|
||||
}
|
||||
|
||||
if($this->hasValidSpawnPosition()){
|
||||
$this->namedtag->setString("SpawnLevel", $this->spawnPosition->getLevel()->getFolderName());
|
||||
$this->namedtag->setInt("SpawnX", $this->spawnPosition->getFloorX());
|
||||
$this->namedtag->setInt("SpawnY", $this->spawnPosition->getFloorY());
|
||||
$this->namedtag->setInt("SpawnZ", $this->spawnPosition->getFloorZ());
|
||||
$nbt->setString("SpawnLevel", $this->spawnPosition->getLevel()->getFolderName());
|
||||
$nbt->setInt("SpawnX", $this->spawnPosition->getFloorX());
|
||||
$nbt->setInt("SpawnY", $this->spawnPosition->getFloorY());
|
||||
$nbt->setInt("SpawnZ", $this->spawnPosition->getFloorZ());
|
||||
|
||||
if(!$this->isAlive()){
|
||||
//hack for respawn after quit
|
||||
$this->namedtag->setTag(new ListTag("Pos", [
|
||||
$nbt->setTag(new ListTag("Pos", [
|
||||
new DoubleTag("", $this->spawnPosition->x),
|
||||
new DoubleTag("", $this->spawnPosition->y),
|
||||
new DoubleTag("", $this->spawnPosition->z)
|
||||
@ -2942,13 +2942,13 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
foreach($this->achievements as $achievement => $status){
|
||||
$achievements->setByte($achievement, $status ? 1 : 0);
|
||||
}
|
||||
$this->namedtag->setTag($achievements);
|
||||
$nbt->setTag($achievements);
|
||||
|
||||
$this->namedtag->setInt("playerGameType", $this->gamemode);
|
||||
$this->namedtag->setLong("firstPlayed", $this->firstPlayed);
|
||||
$this->namedtag->setLong("lastPlayed", (int) floor(microtime(true) * 1000));
|
||||
$nbt->setInt("playerGameType", $this->gamemode);
|
||||
$nbt->setLong("firstPlayed", $this->firstPlayed);
|
||||
$nbt->setLong("lastPlayed", (int) floor(microtime(true) * 1000));
|
||||
|
||||
$this->server->saveOfflinePlayerData($this->username, $this->namedtag, $async);
|
||||
$this->server->saveOfflinePlayerData($this->username, $nbt, $async);
|
||||
}
|
||||
|
||||
public function kill() : void{
|
||||
|
@ -436,8 +436,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
public $lastUpdate;
|
||||
/** @var int */
|
||||
public $fireTicks = 0;
|
||||
/** @var CompoundTag */
|
||||
public $namedtag;
|
||||
/** @var bool */
|
||||
public $canCollide = true;
|
||||
|
||||
@ -495,13 +493,12 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
}
|
||||
|
||||
$this->id = Entity::$entityCount++;
|
||||
$this->namedtag = $nbt;
|
||||
$this->server = $level->getServer();
|
||||
|
||||
/** @var float[] $pos */
|
||||
$pos = $this->namedtag->getListTag("Pos")->getAllValues();
|
||||
$pos = $nbt->getListTag("Pos")->getAllValues();
|
||||
/** @var float[] $rotation */
|
||||
$rotation = $this->namedtag->getListTag("Rotation")->getAllValues();
|
||||
$rotation = $nbt->getListTag("Rotation")->getAllValues();
|
||||
|
||||
parent::__construct($pos[0], $pos[1], $pos[2], $rotation[0], $rotation[1], $level);
|
||||
assert(!is_nan($this->x) and !is_infinite($this->x) and !is_nan($this->y) and !is_infinite($this->y) and !is_nan($this->z) and !is_infinite($this->z));
|
||||
@ -514,15 +511,15 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
throw new \InvalidStateException("Cannot create entities in unloaded chunks");
|
||||
}
|
||||
|
||||
if($this->namedtag->hasTag("Motion", ListTag::class)){
|
||||
if($nbt->hasTag("Motion", ListTag::class)){
|
||||
/** @var float[] $motion */
|
||||
$motion = $this->namedtag->getListTag("Motion")->getAllValues();
|
||||
$motion = $nbt->getListTag("Motion")->getAllValues();
|
||||
$this->setMotion($this->temporalVector->setComponents(...$motion));
|
||||
}
|
||||
|
||||
$this->resetLastMovements();
|
||||
|
||||
$this->fallDistance = $this->namedtag->getFloat("FallDistance", 0.0);
|
||||
$this->fallDistance = $nbt->getFloat("FallDistance", 0.0);
|
||||
|
||||
$this->propertyManager = new DataPropertyManager();
|
||||
|
||||
@ -534,14 +531,14 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
$this->propertyManager->setFloat(self::DATA_BOUNDING_BOX_WIDTH, $this->width);
|
||||
$this->propertyManager->setFloat(self::DATA_BOUNDING_BOX_HEIGHT, $this->height);
|
||||
|
||||
$this->fireTicks = $this->namedtag->getShort("Fire", 0);
|
||||
$this->fireTicks = $nbt->getShort("Fire", 0);
|
||||
if($this->isOnFire()){
|
||||
$this->setGenericFlag(self::DATA_FLAG_ONFIRE);
|
||||
}
|
||||
|
||||
$this->propertyManager->setShort(self::DATA_AIR, $this->namedtag->getShort("Air", 300));
|
||||
$this->onGround = $this->namedtag->getByte("OnGround", 0) !== 0;
|
||||
$this->invulnerable = $this->namedtag->getByte("Invulnerable", 0) !== 0;
|
||||
$this->propertyManager->setShort(self::DATA_AIR, $nbt->getShort("Air", 300));
|
||||
$this->onGround = $nbt->getByte("OnGround", 0) !== 0;
|
||||
$this->invulnerable = $nbt->getByte("Invulnerable", 0) !== 0;
|
||||
|
||||
$this->attributeMap = new AttributeMap();
|
||||
$this->addAttributes();
|
||||
@ -549,7 +546,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
$this->setGenericFlag(self::DATA_FLAG_AFFECTED_BY_GRAVITY, true);
|
||||
$this->setGenericFlag(self::DATA_FLAG_HAS_COLLISION, true);
|
||||
|
||||
$this->initEntity();
|
||||
$this->initEntity($nbt);
|
||||
$this->propertyManager->clearDirtyProperties(); //Prevents resending properties that were set during construction
|
||||
|
||||
$this->chunk->addEntity($this);
|
||||
@ -838,54 +835,52 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
return current(self::$saveNames[static::class]);
|
||||
}
|
||||
|
||||
public function saveNBT() : void{
|
||||
public function saveNBT() : CompoundTag{
|
||||
$nbt = new CompoundTag();
|
||||
if(!($this instanceof Player)){
|
||||
$this->namedtag->setString("id", $this->getSaveId(), true);
|
||||
$nbt->setString("id", $this->getSaveId(), true);
|
||||
|
||||
if($this->getNameTag() !== ""){
|
||||
$this->namedtag->setString("CustomName", $this->getNameTag());
|
||||
$this->namedtag->setByte("CustomNameVisible", $this->isNameTagVisible() ? 1 : 0);
|
||||
}else{
|
||||
$this->namedtag->removeTag("CustomName", "CustomNameVisible");
|
||||
$nbt->setString("CustomName", $this->getNameTag());
|
||||
$nbt->setByte("CustomNameVisible", $this->isNameTagVisible() ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
$this->namedtag->setTag(new ListTag("Pos", [
|
||||
$nbt->setTag(new ListTag("Pos", [
|
||||
new DoubleTag("", $this->x),
|
||||
new DoubleTag("", $this->y),
|
||||
new DoubleTag("", $this->z)
|
||||
]));
|
||||
|
||||
$this->namedtag->setTag(new ListTag("Motion", [
|
||||
$nbt->setTag(new ListTag("Motion", [
|
||||
new DoubleTag("", $this->motion->x),
|
||||
new DoubleTag("", $this->motion->y),
|
||||
new DoubleTag("", $this->motion->z)
|
||||
]));
|
||||
|
||||
$this->namedtag->setTag(new ListTag("Rotation", [
|
||||
$nbt->setTag(new ListTag("Rotation", [
|
||||
new FloatTag("", $this->yaw),
|
||||
new FloatTag("", $this->pitch)
|
||||
]));
|
||||
|
||||
$this->namedtag->setFloat("FallDistance", $this->fallDistance);
|
||||
$this->namedtag->setShort("Fire", $this->fireTicks);
|
||||
$this->namedtag->setShort("Air", $this->propertyManager->getShort(self::DATA_AIR));
|
||||
$this->namedtag->setByte("OnGround", $this->onGround ? 1 : 0);
|
||||
$this->namedtag->setByte("Invulnerable", $this->invulnerable ? 1 : 0);
|
||||
$nbt->setFloat("FallDistance", $this->fallDistance);
|
||||
$nbt->setShort("Fire", $this->fireTicks);
|
||||
$nbt->setShort("Air", $this->propertyManager->getShort(self::DATA_AIR));
|
||||
$nbt->setByte("OnGround", $this->onGround ? 1 : 0);
|
||||
$nbt->setByte("Invulnerable", $this->invulnerable ? 1 : 0);
|
||||
|
||||
return $nbt;
|
||||
}
|
||||
|
||||
protected function initEntity() : void{
|
||||
assert($this->namedtag instanceof CompoundTag);
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
if($nbt->hasTag("CustomName", StringTag::class)){
|
||||
$this->setNameTag($nbt->getString("CustomName"));
|
||||
|
||||
if($this->namedtag->hasTag("CustomName", StringTag::class)){
|
||||
$this->setNameTag($this->namedtag->getString("CustomName"));
|
||||
|
||||
if($this->namedtag->hasTag("CustomNameVisible", StringTag::class)){
|
||||
if($nbt->hasTag("CustomNameVisible", StringTag::class)){
|
||||
//Older versions incorrectly saved this as a string (see 890f72dbf23a77f294169b79590770470041adc4)
|
||||
$this->setNameTagVisible($this->namedtag->getString("CustomNameVisible") !== "");
|
||||
$this->namedtag->removeTag("CustomNameVisible");
|
||||
$this->setNameTagVisible($nbt->getString("CustomNameVisible") !== "");
|
||||
}else{
|
||||
$this->setNameTagVisible($this->namedtag->getByte("CustomNameVisible", 1) !== 0);
|
||||
$this->setNameTagVisible($nbt->getByte("CustomNameVisible", 1) !== 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2036,7 +2031,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
$this->setLevel(null);
|
||||
}
|
||||
|
||||
$this->namedtag = null;
|
||||
$this->lastDamageCause = null;
|
||||
}
|
||||
}
|
||||
|
@ -578,13 +578,15 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
|
||||
/**
|
||||
* For Human entities which are not players, sets their properties such as nametag, skin and UUID from NBT.
|
||||
*
|
||||
* @param CompoundTag $nbt
|
||||
*/
|
||||
protected function initHumanData() : void{
|
||||
if($this->namedtag->hasTag("NameTag", StringTag::class)){
|
||||
$this->setNameTag($this->namedtag->getString("NameTag"));
|
||||
protected function initHumanData(CompoundTag $nbt) : void{
|
||||
if($nbt->hasTag("NameTag", StringTag::class)){
|
||||
$this->setNameTag($nbt->getString("NameTag"));
|
||||
}
|
||||
|
||||
$skin = $this->namedtag->getCompoundTag("Skin");
|
||||
$skin = $nbt->getCompoundTag("Skin");
|
||||
if($skin !== null){
|
||||
$this->setSkin(new Skin(
|
||||
$skin->getString("Name"),
|
||||
@ -598,17 +600,17 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
$this->uuid = UUID::fromData((string) $this->getId(), $this->skin->getSkinData(), $this->getNameTag());
|
||||
}
|
||||
|
||||
protected function initEntity() : void{
|
||||
parent::initEntity();
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
$this->setPlayerFlag(self::DATA_PLAYER_FLAG_SLEEP, false);
|
||||
$this->propertyManager->setBlockPos(self::DATA_PLAYER_BED_POSITION, null);
|
||||
|
||||
$this->inventory = new PlayerInventory($this);
|
||||
$this->enderChestInventory = new EnderChestInventory();
|
||||
$this->initHumanData();
|
||||
$this->initHumanData($nbt);
|
||||
|
||||
$inventoryTag = $this->namedtag->getListTag("Inventory");
|
||||
$inventoryTag = $nbt->getListTag("Inventory");
|
||||
if($inventoryTag !== null){
|
||||
$armorListener = $this->armorInventory->getEventProcessor();
|
||||
$this->armorInventory->setEventProcessor(null);
|
||||
@ -628,7 +630,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
$this->armorInventory->setEventProcessor($armorListener);
|
||||
}
|
||||
|
||||
$enderChestInventoryTag = $this->namedtag->getListTag("EnderChestInventory");
|
||||
$enderChestInventoryTag = $nbt->getListTag("EnderChestInventory");
|
||||
if($enderChestInventoryTag !== null){
|
||||
/** @var CompoundTag $item */
|
||||
foreach($enderChestInventoryTag as $i => $item){
|
||||
@ -636,21 +638,21 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
}
|
||||
}
|
||||
|
||||
$this->inventory->setHeldItemIndex($this->namedtag->getInt("SelectedInventorySlot", 0), false);
|
||||
$this->inventory->setHeldItemIndex($nbt->getInt("SelectedInventorySlot", 0), false);
|
||||
|
||||
$this->inventory->setEventProcessor(new EntityInventoryEventProcessor($this));
|
||||
|
||||
$this->setFood((float) $this->namedtag->getInt("foodLevel", (int) $this->getFood(), true));
|
||||
$this->setExhaustion($this->namedtag->getFloat("foodExhaustionLevel", $this->getExhaustion(), true));
|
||||
$this->setSaturation($this->namedtag->getFloat("foodSaturationLevel", $this->getSaturation(), true));
|
||||
$this->foodTickTimer = $this->namedtag->getInt("foodTickTimer", $this->foodTickTimer, true);
|
||||
$this->setFood((float) $nbt->getInt("foodLevel", (int) $this->getFood(), true));
|
||||
$this->setExhaustion($nbt->getFloat("foodExhaustionLevel", $this->getExhaustion(), true));
|
||||
$this->setSaturation($nbt->getFloat("foodSaturationLevel", $this->getSaturation(), true));
|
||||
$this->foodTickTimer = $nbt->getInt("foodTickTimer", $this->foodTickTimer, true);
|
||||
|
||||
$this->setXpLevel($this->namedtag->getInt("XpLevel", $this->getXpLevel(), true));
|
||||
$this->setXpProgress($this->namedtag->getFloat("XpP", $this->getXpProgress(), true));
|
||||
$this->totalXp = $this->namedtag->getInt("XpTotal", $this->totalXp, true);
|
||||
$this->setXpLevel($nbt->getInt("XpLevel", $this->getXpLevel(), true));
|
||||
$this->setXpProgress($nbt->getFloat("XpP", $this->getXpProgress(), true));
|
||||
$this->totalXp = $nbt->getInt("XpTotal", $this->totalXp, true);
|
||||
|
||||
if($this->namedtag->hasTag("XpSeed", IntTag::class)){
|
||||
$this->xpSeed = $this->namedtag->getInt("XpSeed");
|
||||
if($nbt->hasTag("XpSeed", IntTag::class)){
|
||||
$this->xpSeed = $nbt->getInt("XpSeed");
|
||||
}else{
|
||||
$this->xpSeed = random_int(INT32_MIN, INT32_MAX);
|
||||
}
|
||||
@ -764,21 +766,21 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
), function(Item $item) : bool{ return !$item->hasEnchantment(Enchantment::VANISHING); });
|
||||
}
|
||||
|
||||
public function saveNBT() : void{
|
||||
parent::saveNBT();
|
||||
public function saveNBT() : CompoundTag{
|
||||
$nbt = parent::saveNBT();
|
||||
|
||||
$this->namedtag->setInt("foodLevel", (int) $this->getFood(), true);
|
||||
$this->namedtag->setFloat("foodExhaustionLevel", $this->getExhaustion(), true);
|
||||
$this->namedtag->setFloat("foodSaturationLevel", $this->getSaturation(), true);
|
||||
$this->namedtag->setInt("foodTickTimer", $this->foodTickTimer);
|
||||
$nbt->setInt("foodLevel", (int) $this->getFood(), true);
|
||||
$nbt->setFloat("foodExhaustionLevel", $this->getExhaustion(), true);
|
||||
$nbt->setFloat("foodSaturationLevel", $this->getSaturation(), true);
|
||||
$nbt->setInt("foodTickTimer", $this->foodTickTimer);
|
||||
|
||||
$this->namedtag->setInt("XpLevel", $this->getXpLevel());
|
||||
$this->namedtag->setFloat("XpP", $this->getXpProgress());
|
||||
$this->namedtag->setInt("XpTotal", $this->totalXp);
|
||||
$this->namedtag->setInt("XpSeed", $this->xpSeed);
|
||||
$nbt->setInt("XpLevel", $this->getXpLevel());
|
||||
$nbt->setFloat("XpP", $this->getXpProgress());
|
||||
$nbt->setInt("XpTotal", $this->totalXp);
|
||||
$nbt->setInt("XpSeed", $this->xpSeed);
|
||||
|
||||
$inventoryTag = new ListTag("Inventory", [], NBT::TAG_Compound);
|
||||
$this->namedtag->setTag($inventoryTag);
|
||||
$nbt->setTag($inventoryTag);
|
||||
if($this->inventory !== null){
|
||||
//Normal inventory
|
||||
$slotCount = $this->inventory->getSize() + $this->inventory->getHotbarSize();
|
||||
@ -797,7 +799,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
}
|
||||
}
|
||||
|
||||
$this->namedtag->setInt("SelectedInventorySlot", $this->inventory->getHeldItemIndex());
|
||||
$nbt->setInt("SelectedInventorySlot", $this->inventory->getHeldItemIndex());
|
||||
}
|
||||
|
||||
if($this->enderChestInventory !== null){
|
||||
@ -812,11 +814,11 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
}
|
||||
}
|
||||
|
||||
$this->namedtag->setTag(new ListTag("EnderChestInventory", $items, NBT::TAG_Compound));
|
||||
$nbt->setTag(new ListTag("EnderChestInventory", $items, NBT::TAG_Compound));
|
||||
}
|
||||
|
||||
if($this->skin !== null){
|
||||
$this->namedtag->setTag(new CompoundTag("Skin", [
|
||||
$nbt->setTag(new CompoundTag("Skin", [
|
||||
new StringTag("Name", $this->skin->getSkinId()),
|
||||
new ByteArrayTag("Data", $this->skin->getSkinData()),
|
||||
new ByteArrayTag("CapeData", $this->skin->getCapeData()),
|
||||
@ -824,6 +826,8 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
new ByteArrayTag("GeometryData", $this->skin->getGeometryData())
|
||||
]));
|
||||
}
|
||||
|
||||
return $nbt;
|
||||
}
|
||||
|
||||
public function spawnTo(Player $player) : void{
|
||||
|
@ -74,8 +74,8 @@ abstract class Living extends Entity implements Damageable{
|
||||
|
||||
abstract public function getName() : string;
|
||||
|
||||
protected function initEntity() : void{
|
||||
parent::initEntity();
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
$this->armorInventory = new ArmorInventory($this);
|
||||
//TODO: load/save armor inventory contents
|
||||
@ -83,21 +83,17 @@ abstract class Living extends Entity implements Damageable{
|
||||
|
||||
$health = $this->getMaxHealth();
|
||||
|
||||
if($this->namedtag->hasTag("HealF", FloatTag::class)){
|
||||
$health = $this->namedtag->getFloat("HealF");
|
||||
$this->namedtag->removeTag("HealF");
|
||||
}elseif($this->namedtag->hasTag("Health")){
|
||||
$healthTag = $this->namedtag->getTag("Health");
|
||||
if($nbt->hasTag("HealF", FloatTag::class)){
|
||||
$health = $nbt->getFloat("HealF");
|
||||
}elseif($nbt->hasTag("Health")){
|
||||
$healthTag = $nbt->getTag("Health");
|
||||
$health = (float) $healthTag->getValue(); //Older versions of PocketMine-MP incorrectly saved this as a short instead of a float
|
||||
if(!($healthTag instanceof FloatTag)){
|
||||
$this->namedtag->removeTag("Health");
|
||||
}
|
||||
}
|
||||
|
||||
$this->setHealth($health);
|
||||
|
||||
/** @var CompoundTag[]|ListTag $activeEffectsTag */
|
||||
$activeEffectsTag = $this->namedtag->getListTag("ActiveEffects");
|
||||
$activeEffectsTag = $nbt->getListTag("ActiveEffects");
|
||||
if($activeEffectsTag !== null){
|
||||
foreach($activeEffectsTag as $e){
|
||||
$effect = Effect::getEffect($e->getByte("Id"));
|
||||
@ -150,9 +146,9 @@ abstract class Living extends Entity implements Damageable{
|
||||
$this->attributeMap->getAttribute(Attribute::ABSORPTION)->setValue($absorption);
|
||||
}
|
||||
|
||||
public function saveNBT() : void{
|
||||
parent::saveNBT();
|
||||
$this->namedtag->setFloat("Health", $this->getHealth(), true);
|
||||
public function saveNBT() : CompoundTag{
|
||||
$nbt = parent::saveNBT();
|
||||
$nbt->setFloat("Health", $this->getHealth(), true);
|
||||
|
||||
if(count($this->effects) > 0){
|
||||
$effects = [];
|
||||
@ -166,10 +162,10 @@ abstract class Living extends Entity implements Damageable{
|
||||
]);
|
||||
}
|
||||
|
||||
$this->namedtag->setTag(new ListTag("ActiveEffects", $effects));
|
||||
}else{
|
||||
$this->namedtag->removeTag("ActiveEffects");
|
||||
$nbt->setTag(new ListTag("ActiveEffects", $effects));
|
||||
}
|
||||
|
||||
return $nbt;
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,6 +28,7 @@ use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\network\mcpe\protocol\EntityEventPacket;
|
||||
|
||||
class Squid extends WaterAnimal{
|
||||
@ -42,9 +43,9 @@ class Squid extends WaterAnimal{
|
||||
|
||||
private $switchDirectionTicker = 0;
|
||||
|
||||
public function initEntity() : void{
|
||||
public function initEntity(CompoundTag $nbt) : void{
|
||||
$this->setMaxHealth(10);
|
||||
parent::initEntity();
|
||||
parent::initEntity($nbt);
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
|
@ -23,6 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\entity;
|
||||
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
|
||||
class Villager extends Creature implements NPC, Ageable{
|
||||
public const PROFESSION_FARMER = 0;
|
||||
public const PROFESSION_LIBRARIAN = 1;
|
||||
@ -39,11 +41,11 @@ class Villager extends Creature implements NPC, Ageable{
|
||||
return "Villager";
|
||||
}
|
||||
|
||||
protected function initEntity() : void{
|
||||
parent::initEntity();
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
/** @var int $profession */
|
||||
$profession = $this->namedtag->getInt("Profession", self::PROFESSION_FARMER);
|
||||
$profession = $nbt->getInt("Profession", self::PROFESSION_FARMER);
|
||||
|
||||
if($profession > 4 or $profession < 0){
|
||||
$profession = self::PROFESSION_FARMER;
|
||||
@ -52,9 +54,11 @@ class Villager extends Creature implements NPC, Ageable{
|
||||
$this->setProfession($profession);
|
||||
}
|
||||
|
||||
public function saveNBT() : void{
|
||||
parent::saveNBT();
|
||||
$this->namedtag->setInt("Profession", $this->getProfession());
|
||||
public function saveNBT() : CompoundTag{
|
||||
$nbt = parent::saveNBT();
|
||||
$nbt->setInt("Profession", $this->getProfession());
|
||||
|
||||
return $nbt;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\entity\object;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Human;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\nbt\tag\ShortTag;
|
||||
use pocketmine\Player;
|
||||
@ -100,28 +101,30 @@ class ExperienceOrb extends Entity{
|
||||
*/
|
||||
protected $targetPlayerRuntimeId = null;
|
||||
|
||||
protected function initEntity() : void{
|
||||
parent::initEntity();
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
$this->age = $this->namedtag->getShort("Age", 0);
|
||||
$this->age = $nbt->getShort("Age", 0);
|
||||
|
||||
$value = 0;
|
||||
if($this->namedtag->hasTag(self::TAG_VALUE_PC, ShortTag::class)){ //PC
|
||||
$value = $this->namedtag->getShort(self::TAG_VALUE_PC);
|
||||
}elseif($this->namedtag->hasTag(self::TAG_VALUE_PE, IntTag::class)){ //PE save format
|
||||
$value = $this->namedtag->getInt(self::TAG_VALUE_PE);
|
||||
if($nbt->hasTag(self::TAG_VALUE_PC, ShortTag::class)){ //PC
|
||||
$value = $nbt->getShort(self::TAG_VALUE_PC);
|
||||
}elseif($nbt->hasTag(self::TAG_VALUE_PE, IntTag::class)){ //PE save format
|
||||
$value = $nbt->getInt(self::TAG_VALUE_PE);
|
||||
}
|
||||
|
||||
$this->setXpValue($value);
|
||||
}
|
||||
|
||||
public function saveNBT() : void{
|
||||
parent::saveNBT();
|
||||
public function saveNBT() : CompoundTag{
|
||||
$nbt = parent::saveNBT();
|
||||
|
||||
$this->namedtag->setShort("Age", $this->age);
|
||||
$nbt->setShort("Age", $this->age);
|
||||
|
||||
$this->namedtag->setShort(self::TAG_VALUE_PC, $this->getXpValue());
|
||||
$this->namedtag->setInt(self::TAG_VALUE_PE, $this->getXpValue());
|
||||
$nbt->setShort(self::TAG_VALUE_PC, $this->getXpValue());
|
||||
$nbt->setInt(self::TAG_VALUE_PE, $this->getXpValue());
|
||||
|
||||
return $nbt;
|
||||
}
|
||||
|
||||
public function getXpValue() : int{
|
||||
|
@ -32,6 +32,7 @@ use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Position;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
|
||||
class FallingBlock extends Entity{
|
||||
@ -50,24 +51,23 @@ class FallingBlock extends Entity{
|
||||
|
||||
public $canCollide = false;
|
||||
|
||||
protected function initEntity() : void{
|
||||
parent::initEntity();
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
$blockId = 0;
|
||||
|
||||
//TODO: 1.8+ save format
|
||||
if($this->namedtag->hasTag("TileID", IntTag::class)){
|
||||
$blockId = $this->namedtag->getInt("TileID");
|
||||
}elseif($this->namedtag->hasTag("Tile", ByteTag::class)){
|
||||
$blockId = $this->namedtag->getByte("Tile");
|
||||
$this->namedtag->removeTag("Tile");
|
||||
if($nbt->hasTag("TileID", IntTag::class)){
|
||||
$blockId = $nbt->getInt("TileID");
|
||||
}elseif($nbt->hasTag("Tile", ByteTag::class)){
|
||||
$blockId = $nbt->getByte("Tile");
|
||||
}
|
||||
|
||||
if($blockId === 0){
|
||||
throw new \UnexpectedValueException("Invalid " . get_class($this) . " entity: block ID is 0 or missing");
|
||||
}
|
||||
|
||||
$damage = $this->namedtag->getByte("Data", 0);
|
||||
$damage = $nbt->getByte("Data", 0);
|
||||
|
||||
$this->block = BlockFactory::get($blockId, $damage);
|
||||
|
||||
@ -133,9 +133,11 @@ class FallingBlock extends Entity{
|
||||
return $this->block->getDamage();
|
||||
}
|
||||
|
||||
public function saveNBT() : void{
|
||||
parent::saveNBT();
|
||||
$this->namedtag->setInt("TileID", $this->block->getId(), true);
|
||||
$this->namedtag->setByte("Data", $this->block->getDamage());
|
||||
public function saveNBT() : CompoundTag{
|
||||
$nbt = parent::saveNBT();
|
||||
$nbt->setInt("TileID", $this->block->getId(), true);
|
||||
$nbt->setByte("Data", $this->block->getDamage());
|
||||
|
||||
return $nbt;
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ use pocketmine\event\entity\ItemDespawnEvent;
|
||||
use pocketmine\event\entity\ItemSpawnEvent;
|
||||
use pocketmine\event\inventory\InventoryPickupItemEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\network\mcpe\protocol\AddItemEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\TakeItemEntityPacket;
|
||||
use pocketmine\Player;
|
||||
@ -53,18 +54,18 @@ class ItemEntity extends Entity{
|
||||
|
||||
public $canCollide = false;
|
||||
|
||||
protected function initEntity() : void{
|
||||
parent::initEntity();
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
$this->setMaxHealth(5);
|
||||
$this->setHealth($this->namedtag->getShort("Health", (int) $this->getHealth()));
|
||||
$this->age = $this->namedtag->getShort("Age", $this->age);
|
||||
$this->pickupDelay = $this->namedtag->getShort("PickupDelay", $this->pickupDelay);
|
||||
$this->owner = $this->namedtag->getString("Owner", $this->owner);
|
||||
$this->thrower = $this->namedtag->getString("Thrower", $this->thrower);
|
||||
$this->setHealth($nbt->getShort("Health", (int) $this->getHealth()));
|
||||
$this->age = $nbt->getShort("Age", $this->age);
|
||||
$this->pickupDelay = $nbt->getShort("PickupDelay", $this->pickupDelay);
|
||||
$this->owner = $nbt->getString("Owner", $this->owner);
|
||||
$this->thrower = $nbt->getString("Thrower", $this->thrower);
|
||||
|
||||
|
||||
$itemTag = $this->namedtag->getCompoundTag("Item");
|
||||
$itemTag = $nbt->getCompoundTag("Item");
|
||||
if($itemTag === null){
|
||||
throw new \UnexpectedValueException("Invalid " . get_class($this) . " entity: expected \"Item\" NBT tag not found");
|
||||
}
|
||||
@ -114,18 +115,20 @@ class ItemEntity extends Entity{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function saveNBT() : void{
|
||||
parent::saveNBT();
|
||||
$this->namedtag->setTag($this->item->nbtSerialize(-1, "Item"));
|
||||
$this->namedtag->setShort("Health", (int) $this->getHealth());
|
||||
$this->namedtag->setShort("Age", $this->age);
|
||||
$this->namedtag->setShort("PickupDelay", $this->pickupDelay);
|
||||
public function saveNBT() : CompoundTag{
|
||||
$nbt = parent::saveNBT();
|
||||
$nbt->setTag($this->item->nbtSerialize(-1, "Item"));
|
||||
$nbt->setShort("Health", (int) $this->getHealth());
|
||||
$nbt->setShort("Age", $this->age);
|
||||
$nbt->setShort("PickupDelay", $this->pickupDelay);
|
||||
if($this->owner !== null){
|
||||
$this->namedtag->setString("Owner", $this->owner);
|
||||
$nbt->setString("Owner", $this->owner);
|
||||
}
|
||||
if($this->thrower !== null){
|
||||
$this->namedtag->setString("Thrower", $this->thrower);
|
||||
$nbt->setString("Thrower", $this->thrower);
|
||||
}
|
||||
|
||||
return $nbt;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,20 +70,22 @@ class Painting extends Entity{
|
||||
parent::__construct($level, $nbt);
|
||||
}
|
||||
|
||||
protected function initEntity() : void{
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
$this->setMaxHealth(1);
|
||||
$this->setHealth(1);
|
||||
parent::initEntity();
|
||||
parent::initEntity($nbt);
|
||||
}
|
||||
|
||||
public function saveNBT() : void{
|
||||
parent::saveNBT();
|
||||
$this->namedtag->setInt("TileX", (int) $this->blockIn->x);
|
||||
$this->namedtag->setInt("TileY", (int) $this->blockIn->y);
|
||||
$this->namedtag->setInt("TileZ", (int) $this->blockIn->z);
|
||||
public function saveNBT() : CompoundTag{
|
||||
$nbt = parent::saveNBT();
|
||||
$nbt->setInt("TileX", (int) $this->blockIn->x);
|
||||
$nbt->setInt("TileY", (int) $this->blockIn->y);
|
||||
$nbt->setInt("TileZ", (int) $this->blockIn->z);
|
||||
|
||||
$this->namedtag->setByte("Facing", (int) $this->direction);
|
||||
$this->namedtag->setByte("Direction", (int) $this->direction); //Save both for full compatibility
|
||||
$nbt->setByte("Facing", (int) $this->direction);
|
||||
$nbt->setByte("Direction", (int) $this->direction); //Save both for full compatibility
|
||||
|
||||
return $nbt;
|
||||
}
|
||||
|
||||
public function kill() : void{
|
||||
|
@ -28,6 +28,7 @@ use pocketmine\entity\Explosive;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\event\entity\ExplosionPrimeEvent;
|
||||
use pocketmine\level\Explosion;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\ShortTag;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
@ -53,11 +54,11 @@ class PrimedTNT extends Entity implements Explosive{
|
||||
}
|
||||
}
|
||||
|
||||
protected function initEntity() : void{
|
||||
parent::initEntity();
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
if($this->namedtag->hasTag("Fuse", ShortTag::class)){
|
||||
$this->fuse = $this->namedtag->getShort("Fuse");
|
||||
if($nbt->hasTag("Fuse", ShortTag::class)){
|
||||
$this->fuse = $nbt->getShort("Fuse");
|
||||
}else{
|
||||
$this->fuse = 80;
|
||||
}
|
||||
@ -73,9 +74,11 @@ class PrimedTNT extends Entity implements Explosive{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function saveNBT() : void{
|
||||
parent::saveNBT();
|
||||
$this->namedtag->setShort("Fuse", $this->fuse, true); //older versions incorrectly saved this as a byte
|
||||
public function saveNBT() : CompoundTag{
|
||||
$nbt = parent::saveNBT();
|
||||
$nbt->setShort("Fuse", $this->fuse, true); //older versions incorrectly saved this as a byte
|
||||
|
||||
return $nbt;
|
||||
}
|
||||
|
||||
public function entityBaseTick(int $tickDiff = 1) : bool{
|
||||
|
@ -66,16 +66,16 @@ class Arrow extends Projectile{
|
||||
$this->setCritical($critical);
|
||||
}
|
||||
|
||||
protected function initEntity() : void{
|
||||
parent::initEntity();
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
$this->pickupMode = $this->namedtag->getByte(self::TAG_PICKUP, self::PICKUP_ANY, true);
|
||||
$this->pickupMode = $nbt->getByte(self::TAG_PICKUP, self::PICKUP_ANY, true);
|
||||
}
|
||||
|
||||
public function saveNBT() : void{
|
||||
parent::saveNBT();
|
||||
|
||||
$this->namedtag->setByte(self::TAG_PICKUP, $this->pickupMode, true);
|
||||
public function saveNBT() : CompoundTag{
|
||||
$nbt = parent::saveNBT();
|
||||
$nbt->setByte(self::TAG_PICKUP, $this->pickupMode);
|
||||
return $nbt;
|
||||
}
|
||||
|
||||
public function isCritical() : bool{
|
||||
|
@ -69,33 +69,33 @@ abstract class Projectile extends Entity{
|
||||
}
|
||||
}
|
||||
|
||||
protected function initEntity() : void{
|
||||
parent::initEntity();
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
$this->setMaxHealth(1);
|
||||
$this->setHealth(1);
|
||||
$this->age = $this->namedtag->getShort("Age", $this->age);
|
||||
$this->damage = $this->namedtag->getDouble("damage", $this->damage);
|
||||
$this->age = $nbt->getShort("Age", $this->age);
|
||||
$this->damage = $nbt->getDouble("damage", $this->damage);
|
||||
|
||||
do{
|
||||
$blockHit = null;
|
||||
$blockId = null;
|
||||
$blockData = null;
|
||||
|
||||
if($this->namedtag->hasTag("tileX", IntTag::class) and $this->namedtag->hasTag("tileY", IntTag::class) and $this->namedtag->hasTag("tileZ", IntTag::class)){
|
||||
$blockHit = new Vector3($this->namedtag->getInt("tileX"), $this->namedtag->getInt("tileY"), $this->namedtag->getInt("tileZ"));
|
||||
if($nbt->hasTag("tileX", IntTag::class) and $nbt->hasTag("tileY", IntTag::class) and $nbt->hasTag("tileZ", IntTag::class)){
|
||||
$blockHit = new Vector3($nbt->getInt("tileX"), $nbt->getInt("tileY"), $nbt->getInt("tileZ"));
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
|
||||
if($this->namedtag->hasTag("blockId", IntTag::class)){
|
||||
$blockId = $this->namedtag->getInt("blockId");
|
||||
if($nbt->hasTag("blockId", IntTag::class)){
|
||||
$blockId = $nbt->getInt("blockId");
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
|
||||
if($this->namedtag->hasTag("blockData", ByteTag::class)){
|
||||
$blockData = $this->namedtag->getByte("blockData");
|
||||
if($nbt->hasTag("blockData", ByteTag::class)){
|
||||
$blockData = $nbt->getByte("blockData");
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
@ -141,21 +141,23 @@ abstract class Projectile extends Entity{
|
||||
return (int) ceil($this->motion->length() * $this->damage);
|
||||
}
|
||||
|
||||
public function saveNBT() : void{
|
||||
parent::saveNBT();
|
||||
public function saveNBT() : CompoundTag{
|
||||
$nbt = parent::saveNBT();
|
||||
|
||||
$this->namedtag->setShort("Age", $this->age);
|
||||
$this->namedtag->setDouble("damage", $this->damage);
|
||||
$nbt->setShort("Age", $this->age);
|
||||
$nbt->setDouble("damage", $this->damage);
|
||||
|
||||
if($this->blockHit !== null){
|
||||
$this->namedtag->setInt("tileX", $this->blockHit->x);
|
||||
$this->namedtag->setInt("tileY", $this->blockHit->y);
|
||||
$this->namedtag->setInt("tileZ", $this->blockHit->z);
|
||||
$nbt->setInt("tileX", $this->blockHit->x);
|
||||
$nbt->setInt("tileY", $this->blockHit->y);
|
||||
$nbt->setInt("tileZ", $this->blockHit->z);
|
||||
|
||||
//we intentionally use different ones to PC because we don't have stringy IDs
|
||||
$this->namedtag->setInt("blockId", $this->blockHitId);
|
||||
$this->namedtag->setByte("blockData", $this->blockHitData);
|
||||
$nbt->setInt("blockId", $this->blockHitId);
|
||||
$nbt->setByte("blockData", $this->blockHitData);
|
||||
}
|
||||
|
||||
return $nbt;
|
||||
}
|
||||
|
||||
protected function applyDragBeforeGravity() : bool{
|
||||
|
@ -31,6 +31,7 @@ use pocketmine\event\entity\ProjectileHitEntityEvent;
|
||||
use pocketmine\event\entity\ProjectileHitBlockEvent;
|
||||
use pocketmine\event\entity\ProjectileHitEvent;
|
||||
use pocketmine\item\Potion;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
|
||||
use pocketmine\utils\Color;
|
||||
@ -42,15 +43,17 @@ class SplashPotion extends Throwable{
|
||||
protected $gravity = 0.05;
|
||||
protected $drag = 0.01;
|
||||
|
||||
protected function initEntity() : void{
|
||||
parent::initEntity();
|
||||
protected function initEntity(CompoundTag $nbt) : void{
|
||||
parent::initEntity($nbt);
|
||||
|
||||
$this->setPotionId($this->namedtag->getShort("PotionId", 0));
|
||||
$this->setPotionId($nbt->getShort("PotionId", 0));
|
||||
}
|
||||
|
||||
public function saveNBT() : void{
|
||||
parent::saveNBT();
|
||||
$this->namedtag->setShort("PotionId", $this->getPotionId());
|
||||
public function saveNBT() : CompoundTag{
|
||||
$nbt = parent::saveNBT();
|
||||
$nbt->setShort("PotionId", $this->getPotionId());
|
||||
|
||||
return $nbt;
|
||||
}
|
||||
|
||||
public function getResultDamage() : int{
|
||||
|
@ -464,8 +464,7 @@ class LevelDB extends BaseLevelProvider{
|
||||
/** @var CompoundTag[] $entities */
|
||||
$entities = [];
|
||||
foreach($chunk->getSavableEntities() as $entity){
|
||||
$entity->saveNBT();
|
||||
$entities[] = $entity->namedtag;
|
||||
$entities[] = $entity->saveNBT();
|
||||
}
|
||||
$this->writeTags($entities, $index . self::TAG_ENTITY);
|
||||
|
||||
|
@ -67,8 +67,7 @@ class Anvil extends McRegion{
|
||||
$entities = [];
|
||||
|
||||
foreach($chunk->getSavableEntities() as $entity){
|
||||
$entity->saveNBT();
|
||||
$entities[] = $entity->namedtag;
|
||||
$entities[] = $entity->saveNBT();
|
||||
}
|
||||
|
||||
$nbt->setTag(new ListTag("Entities", $entities, NBT::TAG_Compound));
|
||||
|
@ -86,8 +86,7 @@ class McRegion extends BaseLevelProvider{
|
||||
$entities = [];
|
||||
|
||||
foreach($chunk->getSavableEntities() as $entity){
|
||||
$entity->saveNBT();
|
||||
$entities[] = $entity->namedtag;
|
||||
$entities[] = $entity->saveNBT();
|
||||
}
|
||||
|
||||
$nbt->setTag(new ListTag("Entities", $entities, NBT::TAG_Compound));
|
||||
|
Loading…
x
Reference in New Issue
Block a user