Tile: remove createNBT(), add create(), createFromData(), createFromItem()

This commit is contained in:
Dylan K. Taylor 2018-12-10 19:40:37 +00:00
parent 6dbceda3e8
commit d72e4cb9a1
15 changed files with 105 additions and 95 deletions

View File

@ -86,9 +86,12 @@ class Bed extends Transparent{
public function writeStateToWorld() : void{
parent::writeStateToWorld();
//extra block properties storage hack
$tile = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this));
if($tile instanceof TileBed){
$tile->setColor($this->color);
$tile = Tile::create(Tile::BED, $this->getLevel(), $this->asVector3());
if($tile !== null){
if($tile instanceof TileBed){
$tile->setColor($this->color);
}
$this->level->addTile($tile);
}
}

View File

@ -92,7 +92,10 @@ class Chest extends Transparent{
}
if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){
$tile = Tile::createTile(Tile::CHEST, $this->getLevel(), TileChest::createNBT($this, $item));
$tile = Tile::createFromItem(Tile::CHEST, $this->getLevel(), $this->asVector3(), $item);
if($tile !== null){
$this->level->addTile($tile);
}
if($chest instanceof TileChest and $tile instanceof TileChest){
$chest->pairWith($tile);

View File

@ -30,7 +30,6 @@ use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Facing;
use pocketmine\math\Vector3;
use pocketmine\Player;
use pocketmine\tile\EnchantTable as TileEnchantTable;
use pocketmine\tile\Tile;
class EnchantingTable extends Transparent{
@ -43,7 +42,9 @@ class EnchantingTable extends Transparent{
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){
Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevel(), TileEnchantTable::createNBT($this, $item));
if(($tile = Tile::createFromItem(Tile::ENCHANT_TABLE, $this->getLevel(), $this->asVector3(), $item)) !== null){
$this->level->addTile($tile);
}
return true;
}

View File

@ -66,7 +66,9 @@ class EnderChest extends Chest{
}
if(Block::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){
Tile::createTile(Tile::ENDER_CHEST, $this->getLevel(), TileEnderChest::createNBT($this, $item));
if(($tile = Tile::createFromItem(Tile::ENDER_CHEST, $this->getLevel(), $this->asVector3(), $item)) !== null){
$this->level->addTile($tile);
}
return true;
}

View File

@ -69,7 +69,9 @@ class FlowerPot extends Flowable{
}
if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){
Tile::createTile(Tile::FLOWER_POT, $this->getLevel(), TileFlowerPot::createNBT($this, $item));
if(($tile = Tile::createFromItem(Tile::FLOWER_POT, $this->getLevel(), $this->asVector3(), $item)) !== null){
$this->level->addTile($tile);
}
return true;
}

View File

@ -99,7 +99,9 @@ class Furnace extends Solid{
$this->facing = Facing::opposite($player->getHorizontalFacing());
}
if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){
Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $item));
if(($tile = Tile::createFromItem(Tile::FURNACE, $this->getLevel(), $this->asVector3(), $item)) !== null){
$this->level->addTile($tile);
}
return true;
}

View File

@ -85,7 +85,9 @@ class ItemFrame extends Flowable{
$this->facing = $face;
if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){
Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), TileItemFrame::createNBT($this, $item));
if(($tile = Tile::createFromItem(Tile::ITEM_FRAME, $this->getLevel(), $this->asVector3(), $item)) !== null){
$this->level->addTile($tile);
}
return true;
}

View File

@ -28,7 +28,6 @@ use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Facing;
use pocketmine\math\Vector3;
use pocketmine\Player;
use pocketmine\tile\Sign as TileSign;
use pocketmine\tile\Tile;
class SignPost extends Transparent{
@ -83,7 +82,9 @@ class SignPost extends Transparent{
}
if($ret){
Tile::createTile(Tile::SIGN, $this->getLevel(), TileSign::createNBT($this, $item));
if(($tile = Tile::createFromItem(Tile::SIGN, $this->getLevel(), $this->asVector3(), $item)) !== null){
$this->level->addTile($tile);
}
return true;
}
}

View File

@ -70,10 +70,13 @@ class Skull extends Flowable{
public function writeStateToWorld() : void{
parent::writeStateToWorld();
$tile = Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this));
if($tile instanceof TileSkull){
$tile->setRotation($this->rotation);
$tile->setType($this->type);
$tile = Tile::create(Tile::SKULL, $this->getLevel(), $this->asVector3());
if($tile !== null){
if($tile instanceof TileSkull){
$tile->setRotation($this->rotation);
$tile->setType($this->type);
}
$this->level->addTile($tile);
}
}

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\item\Banner as ItemBanner;
use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\math\AxisAlignedBB;
@ -83,7 +84,17 @@ class StandingBanner extends Transparent{
}
if($ret){
Tile::createTile(Tile::BANNER, $this->getLevel(), TileBanner::createNBT($this, $item));
$tile = Tile::createFromItem(Tile::BANNER, $this->getLevel(), $this->asVector3(), $item);
if($tile !== null){
if($tile instanceof TileBanner and $item instanceof ItemBanner){
$tile->setBaseColor($item->getBaseColor());
if(($patterns = $item->getPatterns()) !== null){
$tile->setPatterns($patterns);
}
}
$this->level->addTile($tile);
}
return true;
}
}
@ -105,8 +116,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->getPatterns())->empty()){
$drop->setNamedTagEntry(clone $patterns);
if($tile instanceof TileBanner and $drop instanceof ItemBanner and !($patterns = $tile->getPatterns())->empty()){
$drop->setPatterns($patterns);
}
return [$drop];

View File

@ -206,6 +206,20 @@ class Banner extends Item{
return $this->getNamedTag()->getListTag(self::TAG_PATTERNS)->count();
}
/**
* @return ListTag|null
*/
public function getPatterns() : ?ListTag{
return $this->getNamedTag()->getListTag(self::TAG_PATTERNS);
}
/**
* @param ListTag $patterns
*/
public function setPatterns(ListTag $patterns) : void{
$this->setNamedTagEntry(clone $patterns);
}
public function correctNBT() : void{
$tag = $this->getNamedTag();
if(!$tag->hasTag(self::TAG_BASE, IntTag::class)){

View File

@ -618,7 +618,9 @@ class Chunk{
continue;
}
if(Tile::createTile($nbt->getString(Tile::TAG_ID), $level, $nbt) === null){
if(($tile = Tile::createFromData($nbt->getString(Tile::TAG_ID), $level, $nbt)) !== null){
$level->addTile($tile);
}else{
$changed = true;
continue;
}

View File

@ -23,8 +23,6 @@ declare(strict_types=1);
namespace pocketmine\tile;
use pocketmine\item\Banner as ItemBanner;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag;
@ -35,7 +33,6 @@ use pocketmine\nbt\tag\StringTag;
class Banner extends Spawnable implements Nameable{
use NameableTrait {
addAdditionalSpawnData as addNameSpawnData;
createAdditionalNBT as createNameNBT;
}
public const TAG_BASE = "Base";
@ -274,17 +271,9 @@ class Banner extends Spawnable implements Nameable{
return $this->patterns;
}
protected static function createAdditionalNBT(CompoundTag $nbt, ?Item $item = null) : void{
if($item instanceof ItemBanner){
$nbt->setInt(self::TAG_BASE, $item->getBaseColor());
//TODO: clean this mess up
if($item->getNamedTag()->hasTag(self::TAG_PATTERNS, ListTag::class)){
$nbt->setTag($item->getNamedTag()->getListTag(self::TAG_PATTERNS));
}
self::createNameNBT($nbt, $item);
}
public function setPatterns(ListTag $patterns) : void{
$this->patterns = clone $patterns;
$this->onChanged();
}
public function getDefaultName() : string{

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\tile;
use pocketmine\item\Item;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\StringTag;
@ -64,12 +63,6 @@ trait NameableTrait{
return $this->customName !== null;
}
protected static function createAdditionalNBT(CompoundTag $nbt, ?Item $item = null) : void{
if($item !== null and $item->hasCustomName()){
$nbt->setString(Nameable::TAG_CUSTOM_NAME, $item->getCustomName());
}
}
public function addAdditionalSpawnData(CompoundTag $nbt) : void{
if($this->customName !== null){
$nbt->setString(Nameable::TAG_CUSTOM_NAME, $this->customName);

View File

@ -33,8 +33,6 @@ use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\timings\Timings;
use pocketmine\timings\TimingsHandler;
use pocketmine\utils\Utils;
@ -88,21 +86,52 @@ abstract class Tile extends Position{
* @param string $type
* @param Level $level
* @param CompoundTag $nbt
* @param $args
*
* @return Tile|null
*/
public static function createTile($type, Level $level, CompoundTag $nbt, ...$args) : ?Tile{
public static function createFromData($type, Level $level, CompoundTag $nbt) : ?Tile{
$tile = self::create($type, $level, new Vector3($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z)));
if($tile !== null){
$tile->readSaveData($nbt);
}
return $tile;
}
/**
* @param string $type
* @param Level $level
* @param Vector3 $pos
* @param Item $item
*
* @return Tile|null
*/
public static function createFromItem(string $type, Level $level, Vector3 $pos, Item $item) : ?Tile{
$tile = self::create($type, $level, $pos);
if($tile !== null and $item->hasCustomBlockData()){
$tile->readSaveData($item->getCustomBlockData());
}
if($tile instanceof Nameable and $item->hasCustomName()){ //this should take precedence over saved NBT
$tile->setName($item->getCustomName());
}
return $tile;
}
/**
* @param string $type
* @param Level $level
* @param Vector3 $pos
*
* @return Tile|null
*/
public static function create(string $type, Level $level, Vector3 $pos) : ?Tile{
if(isset(self::$knownTiles[$type])){
$pos = new Vector3($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z));
$class = self::$knownTiles[$type];
/**
* @var Tile $tile
* @see Tile::__construct()
*/
$tile = new $class($level, $pos);
$tile->readSaveData($nbt);
$level->addTile($tile);
return $tile;
}
@ -176,53 +205,6 @@ abstract class Tile extends Position{
return $tag->getCount() > 0 ? $tag : null;
}
/**
* Creates and returns a CompoundTag containing the necessary information to spawn a tile of this type.
*
* @param Vector3 $pos
* @param Item|null $item
*
* @return CompoundTag
* @throws \BadMethodCallException
* @throws \InvalidArgumentException
* @throws \InvalidStateException
*/
public static function createNBT(Vector3 $pos, ?Item $item = null) : CompoundTag{
if(static::class === self::class){
throw new \BadMethodCallException(__METHOD__ . " must be called from the scope of a child class");
}
$nbt = new CompoundTag("", [
new StringTag(self::TAG_ID, static::getSaveId()),
new IntTag(self::TAG_X, (int) $pos->x),
new IntTag(self::TAG_Y, (int) $pos->y),
new IntTag(self::TAG_Z, (int) $pos->z)
]);
static::createAdditionalNBT($nbt, $item);
if($item !== null){
$customBlockData = $item->getCustomBlockData();
if($customBlockData !== null){
foreach($customBlockData as $customBlockDataTag){
$nbt->setTag(clone $customBlockDataTag);
}
}
}
return $nbt;
}
/**
* Called by createNBT() to allow descendent classes to add their own base NBT using the parameters provided.
* TODO: remove this and add a hook for setting data from items post-place
*
* @param CompoundTag $nbt
* @param Item|null $item
*/
protected static function createAdditionalNBT(CompoundTag $nbt, ?Item $item = null) : void{
}
/**
* @return Block
*/