Tile: make ContainerTrait and NameableTrait non-dependent on context-retained NBT

This commit is contained in:
Dylan K. Taylor 2018-06-03 16:32:05 +01:00
parent 7b7917939a
commit b1cb63ebd6
6 changed files with 53 additions and 30 deletions

View File

@ -111,6 +111,7 @@ class Banner extends Spawnable implements Nameable{
$this->baseColor = $nbt->getInt(self::TAG_BASE, self::COLOR_BLACK, true); $this->baseColor = $nbt->getInt(self::TAG_BASE, self::COLOR_BLACK, true);
$this->patterns = $nbt->getListTag(self::TAG_PATTERNS) ?? new ListTag(self::TAG_PATTERNS); $this->patterns = $nbt->getListTag(self::TAG_PATTERNS) ?? new ListTag(self::TAG_PATTERNS);
$nbt->removeTag(self::TAG_BASE, self::TAG_PATTERNS); $nbt->removeTag(self::TAG_BASE, self::TAG_PATTERNS);
$this->loadName($nbt);
parent::__construct($level, $nbt); parent::__construct($level, $nbt);
} }
@ -118,6 +119,7 @@ class Banner extends Spawnable implements Nameable{
parent::saveNBT(); parent::saveNBT();
$this->namedtag->setInt(self::TAG_BASE, $this->baseColor); $this->namedtag->setInt(self::TAG_BASE, $this->baseColor);
$this->namedtag->setTag($this->patterns); $this->namedtag->setTag($this->patterns);
$this->saveName($this->namedtag);
} }
public function addAdditionalSpawnData(CompoundTag $nbt) : void{ public function addAdditionalSpawnData(CompoundTag $nbt) : void{

View File

@ -59,7 +59,8 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{
parent::__construct($level, $nbt); parent::__construct($level, $nbt);
$this->inventory = new ChestInventory($this); $this->inventory = new ChestInventory($this);
$this->loadItems(); $this->loadItems($this->namedtag);
$this->loadName($this->namedtag);
} }
public function close() : void{ public function close() : void{
@ -86,7 +87,8 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{
}else{ }else{
$this->namedtag->removeTag(self::TAG_PAIRX, self::TAG_PAIRZ); $this->namedtag->removeTag(self::TAG_PAIRX, self::TAG_PAIRZ);
} }
$this->saveItems(); $this->saveItems($this->namedtag);
$this->saveName($this->namedtag);
} }
/** /**

View File

@ -37,16 +37,14 @@ trait ContainerTrait{
/** @var string|null */ /** @var string|null */
private $lock; private $lock;
abstract public function getNBT() : CompoundTag;
/** /**
* @return Inventory * @return Inventory
*/ */
abstract public function getRealInventory(); abstract public function getRealInventory();
protected function loadItems() : void{ protected function loadItems(CompoundTag $tag) : void{
if($this->getNBT()->hasTag(Container::TAG_ITEMS, ListTag::class)){ if($tag->hasTag(Container::TAG_ITEMS, ListTag::class)){
$inventoryTag = $this->getNBT()->getListTag(Container::TAG_ITEMS); $inventoryTag = $tag->getListTag(Container::TAG_ITEMS);
$inventory = $this->getRealInventory(); $inventory = $this->getRealInventory();
/** @var CompoundTag $itemNBT */ /** @var CompoundTag $itemNBT */
@ -55,21 +53,21 @@ trait ContainerTrait{
} }
} }
if($this->getNBT()->hasTag(Container::TAG_LOCK, StringTag::class)){ if($tag->hasTag(Container::TAG_LOCK, StringTag::class)){
$this->lock = $this->getNBT()->getString(Container::TAG_LOCK); $this->lock = $tag->getString(Container::TAG_LOCK);
} }
} }
protected function saveItems() : void{ protected function saveItems(CompoundTag $tag) : void{
$items = []; $items = [];
foreach($this->getRealInventory()->getContents() as $slot => $item){ foreach($this->getRealInventory()->getContents() as $slot => $item){
$items[] = $item->nbtSerialize($slot); $items[] = $item->nbtSerialize($slot);
} }
$this->getNBT()->setTag(new ListTag(Container::TAG_ITEMS, $items, NBT::TAG_Compound)); $tag->setTag(new ListTag(Container::TAG_ITEMS, $items, NBT::TAG_Compound));
if($this->lock !== null){ if($this->lock !== null){
$this->getNBT()->setString(Container::TAG_LOCK, $this->lock); $tag->setString(Container::TAG_LOCK, $this->lock);
} }
} }

View File

@ -23,9 +23,22 @@ declare(strict_types=1);
namespace pocketmine\tile; namespace pocketmine\tile;
use pocketmine\level\Level;
use pocketmine\nbt\tag\CompoundTag;
class EnchantTable extends Spawnable implements Nameable{ class EnchantTable extends Spawnable implements Nameable{
use NameableTrait; use NameableTrait;
public function __construct(Level $level, CompoundTag $nbt){
$this->loadName($nbt);
parent::__construct($level, $nbt);
}
public function saveNBT() : void{
parent::saveNBT();
$this->saveName($this->namedtag);
}
/** /**
* @return string * @return string
*/ */

View File

@ -70,7 +70,8 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
parent::__construct($level, $nbt); parent::__construct($level, $nbt);
$this->inventory = new FurnaceInventory($this); $this->inventory = new FurnaceInventory($this);
$this->loadItems(); $this->loadItems($this->namedtag);
$this->loadName($this->namedtag);
if($this->burnTime > 0){ if($this->burnTime > 0){
$this->scheduleUpdate(); $this->scheduleUpdate();
@ -99,7 +100,8 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
$this->namedtag->setShort(self::TAG_COOK_TIME, $this->cookTime); $this->namedtag->setShort(self::TAG_COOK_TIME, $this->cookTime);
$this->namedtag->setShort(self::TAG_MAX_TIME, $this->maxTime); $this->namedtag->setShort(self::TAG_MAX_TIME, $this->maxTime);
$this->saveItems(); $this->saveItems($this->namedtag);
$this->saveName($this->namedtag);
} }
/** /**

View File

@ -26,50 +26,44 @@ namespace pocketmine\tile;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\Player; use pocketmine\Player;
/** /**
* This trait implements most methods in the {@link Nameable} interface. It should only be used by Tiles. * This trait implements most methods in the {@link Nameable} interface. It should only be used by Tiles.
*/ */
trait NameableTrait{ trait NameableTrait{
/** @var string|null */
private $customName;
/** /**
* @return string * @return string
*/ */
abstract public function getDefaultName() : string; abstract public function getDefaultName() : string;
/**
* @return CompoundTag
*/
abstract public function getNBT() : CompoundTag;
/** /**
* @return string * @return string
*/ */
public function getName() : string{ public function getName() : string{
$nbt = $this->getNBT(); return $this->customName ?? $this->getDefaultName();
return $nbt->getString(Nameable::TAG_CUSTOM_NAME) ?? $this->getDefaultName();
} }
/** /**
* @param string $name * @param string $name
*/ */
public function setName(string $name) : void{ public function setName(string $name) : void{
$nbt = $this->getNBT();
if($name === ""){ if($name === ""){
$nbt->removeTag(Nameable::TAG_CUSTOM_NAME); $this->customName = null;
}else{
return; $this->customName = $name;
} }
$nbt->setString(Nameable::TAG_CUSTOM_NAME, $name);
} }
/** /**
* @return bool * @return bool
*/ */
public function hasName() : bool{ public function hasName() : bool{
return $this->getNBT()->hasTag(Nameable::TAG_CUSTOM_NAME); return $this->customName !== null;
} }
protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{ protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{
@ -79,8 +73,20 @@ trait NameableTrait{
} }
public function addAdditionalSpawnData(CompoundTag $nbt) : void{ public function addAdditionalSpawnData(CompoundTag $nbt) : void{
if($this->hasName()){ if($this->customName !== null){
$nbt->setString(Nameable::TAG_CUSTOM_NAME, $this->getName()); $nbt->setString(Nameable::TAG_CUSTOM_NAME, $this->customName);
}
}
protected function loadName(CompoundTag $tag) : void{
if($tag->hasTag(Nameable::TAG_CUSTOM_NAME, StringTag::class)){
$this->customName = $tag->getString(Nameable::TAG_CUSTOM_NAME);
}
}
protected function saveName(CompoundTag $tag) : void{
if($this->customName !== null){
$tag->setString(Nameable::TAG_CUSTOM_NAME, $this->customName);
} }
} }
} }