diff --git a/src/pocketmine/block/Bed.php b/src/pocketmine/block/Bed.php index 0ddceb3c78..420b19496a 100644 --- a/src/pocketmine/block/Bed.php +++ b/src/pocketmine/block/Bed.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\Color; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\lang\TranslationContainer; @@ -50,6 +51,8 @@ class Bed extends Transparent{ protected $occupied = false; /** @var bool */ protected $head = false; + /** @var int */ + protected $color = Color::RED; public function __construct(){ @@ -71,6 +74,16 @@ class Bed extends Transparent{ return 0b1111; } + public function updateState() : void{ + parent::updateState(); + //read extra state information from the tile - this is an ugly hack + //TODO: extend this hack to setting block as well so we don't have to deal with tile hacks in the main code + $tile = $this->level->getTile($this); + if($tile instanceof TileBed){ + $this->color = $tile->getColor(); + } + } + public function getHardness() : float{ return 0.2; } @@ -161,6 +174,7 @@ class Bed extends Transparent{ } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ + $this->color = $item->getDamage(); //TODO: replace this with a proper colour getter $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ $this->facing = $player !== null ? Bearing::toFacing($player->getDirection()) : Facing::NORTH; @@ -172,8 +186,15 @@ class Bed extends Transparent{ $nextState->head = true; $this->getLevel()->setBlock($next, $nextState); - Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this, $face, $item, $player)); - Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($next, $face, $item, $player)); + //TODO: make this happen automatically on block set + $tile1 = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this)); + if($tile1 instanceof TileBed){ + $tile1->setColor($this->color); + } + $tile2 = Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($next)); + if($tile2 instanceof TileBed){ + $tile2->setColor($this->color); + } return true; } @@ -191,12 +212,7 @@ class Bed extends Transparent{ } public function getItem() : Item{ - $tile = $this->getLevel()->getTile($this); - if($tile instanceof TileBed){ - return ItemFactory::get($this->getItemId(), $tile->getColor()); - } - - return ItemFactory::get($this->getItemId(), 14); //Red + return ItemFactory::get($this->getItemId(), $this->color); } public function isAffectedBySilkTouch() : bool{ diff --git a/src/pocketmine/block/Chest.php b/src/pocketmine/block/Chest.php index ce41b7a7bf..8b4fea601c 100644 --- a/src/pocketmine/block/Chest.php +++ b/src/pocketmine/block/Chest.php @@ -93,7 +93,7 @@ class Chest extends Transparent{ } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - $tile = Tile::createTile(Tile::CHEST, $this->getLevel(), TileChest::createNBT($this, $face, $item, $player)); + $tile = Tile::createTile(Tile::CHEST, $this->getLevel(), TileChest::createNBT($this, $item)); if($chest instanceof TileChest and $tile instanceof TileChest){ $chest->pairWith($tile); diff --git a/src/pocketmine/block/EnchantingTable.php b/src/pocketmine/block/EnchantingTable.php index 6a8b68d907..416ec54594 100644 --- a/src/pocketmine/block/EnchantingTable.php +++ b/src/pocketmine/block/EnchantingTable.php @@ -43,7 +43,7 @@ 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, $face, $item, $player)); + Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevel(), TileEnchantTable::createNBT($this, $item)); return true; } diff --git a/src/pocketmine/block/EnderChest.php b/src/pocketmine/block/EnderChest.php index e2d273d4a7..eab6beaffe 100644 --- a/src/pocketmine/block/EnderChest.php +++ b/src/pocketmine/block/EnderChest.php @@ -67,7 +67,7 @@ class EnderChest extends Chest{ } if(Block::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::ENDER_CHEST, $this->getLevel(), TileEnderChest::createNBT($this, $face, $item, $player)); + Tile::createTile(Tile::ENDER_CHEST, $this->getLevel(), TileEnderChest::createNBT($this, $item)); return true; } diff --git a/src/pocketmine/block/FlowerPot.php b/src/pocketmine/block/FlowerPot.php index 0399fd26e2..14e48dec40 100644 --- a/src/pocketmine/block/FlowerPot.php +++ b/src/pocketmine/block/FlowerPot.php @@ -69,7 +69,7 @@ class FlowerPot extends Flowable{ } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::FLOWER_POT, $this->getLevel(), TileFlowerPot::createNBT($this, $face, $item, $player)); + Tile::createTile(Tile::FLOWER_POT, $this->getLevel(), TileFlowerPot::createNBT($this, $item)); return true; } diff --git a/src/pocketmine/block/Furnace.php b/src/pocketmine/block/Furnace.php index 820195d6e6..0a7295515e 100644 --- a/src/pocketmine/block/Furnace.php +++ b/src/pocketmine/block/Furnace.php @@ -94,7 +94,7 @@ class Furnace extends Solid{ $this->facing = Bearing::toFacing(Bearing::opposite($player->getDirection())); } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $face, $item, $player)); + Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $item)); return true; } diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index ca9dab19f3..772665c60d 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -85,7 +85,7 @@ 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, $face, $item, $player)); + Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), TileItemFrame::createNBT($this, $item)); return true; } diff --git a/src/pocketmine/block/SignPost.php b/src/pocketmine/block/SignPost.php index c55f70662b..8dd99035e5 100644 --- a/src/pocketmine/block/SignPost.php +++ b/src/pocketmine/block/SignPost.php @@ -83,7 +83,7 @@ class SignPost extends Transparent{ } if($ret){ - Tile::createTile(Tile::SIGN, $this->getLevel(), TileSign::createNBT($this, $face, $item, $player)); + Tile::createTile(Tile::SIGN, $this->getLevel(), TileSign::createNBT($this, $item)); return true; } } diff --git a/src/pocketmine/block/Skull.php b/src/pocketmine/block/Skull.php index d19815f4db..c0e42bc9c7 100644 --- a/src/pocketmine/block/Skull.php +++ b/src/pocketmine/block/Skull.php @@ -39,6 +39,10 @@ class Skull extends Flowable{ /** @var int */ protected $facing = Facing::NORTH; + protected $type = TileSkull::TYPE_SKELETON; + /** @var int */ + protected $rotation = 0; //TODO: split this into floor skull and wall skull handling + public function __construct(){ } @@ -55,6 +59,15 @@ class Skull extends Flowable{ return 0b111; } + public function updateState() : void{ + parent::updateState(); + $tile = $this->level->getTile($this); + if($tile instanceof TileSkull){ + $this->type = $tile->getType(); + $this->rotation = $tile->getRotation(); + } + } + public function getHardness() : float{ return 1; } @@ -74,8 +87,17 @@ class Skull extends Flowable{ } $this->facing = $face; + $this->type = $item->getDamage(); //TODO: replace this with a proper variant getter + if($player !== null and $face === Facing::UP){ + $this->rotation = ((int) floor(($player->yaw * 16 / 360) + 0.5)) & 0xf; + } if(parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player)){ - Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this, $face, $item, $player)); + //TODO: make this automatic on block set + $tile = Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this)); + if($tile instanceof TileSkull){ + $tile->setRotation($this->rotation); + $tile->setType($this->type); + } return true; } @@ -83,8 +105,7 @@ class Skull extends Flowable{ } public function getItem() : Item{ - $tile = $this->level->getTile($this); - return ItemFactory::get(Item::SKULL, $tile instanceof TileSkull ? $tile->getType() : 0); + return ItemFactory::get(Item::SKULL, $this->type); } public function isAffectedBySilkTouch() : bool{ diff --git a/src/pocketmine/block/StandingBanner.php b/src/pocketmine/block/StandingBanner.php index e4b3ecc3d9..28898faa45 100644 --- a/src/pocketmine/block/StandingBanner.php +++ b/src/pocketmine/block/StandingBanner.php @@ -83,7 +83,7 @@ class StandingBanner extends Transparent{ } if($ret){ - Tile::createTile(Tile::BANNER, $this->getLevel(), TileBanner::createNBT($this, $face, $item, $player)); + Tile::createTile(Tile::BANNER, $this->getLevel(), TileBanner::createNBT($this, $item)); return true; } } diff --git a/src/pocketmine/tile/Banner.php b/src/pocketmine/tile/Banner.php index e538f58194..6227446193 100644 --- a/src/pocketmine/tile/Banner.php +++ b/src/pocketmine/tile/Banner.php @@ -23,13 +23,12 @@ declare(strict_types=1); namespace pocketmine\tile; +use pocketmine\item\Banner as ItemBanner; use pocketmine\item\Item; -use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\Player; class Banner extends Spawnable implements Nameable{ use NameableTrait { @@ -268,15 +267,16 @@ class Banner extends Spawnable implements Nameable{ return $this->patterns; } - protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{ - $nbt->setInt(self::TAG_BASE, $item !== null ? $item->getDamage() & 0x0f : 0); + protected static function createAdditionalNBT(CompoundTag $nbt, ?Item $item = null) : void{ + if($item instanceof ItemBanner){ + $nbt->setInt(self::TAG_BASE, $item->getBaseColor()); - if($item !== null){ + //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, $pos, $face, $item, $player); + self::createNameNBT($nbt, $item); } } diff --git a/src/pocketmine/tile/Bed.php b/src/pocketmine/tile/Bed.php index b53c3de271..ebcd291f70 100644 --- a/src/pocketmine/tile/Bed.php +++ b/src/pocketmine/tile/Bed.php @@ -23,11 +23,7 @@ declare(strict_types=1); namespace pocketmine\tile; - -use pocketmine\item\Item; -use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\Player; class Bed extends Spawnable{ public const TAG_COLOR = "color"; @@ -54,10 +50,4 @@ class Bed extends Spawnable{ protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ $nbt->setByte(self::TAG_COLOR, $this->color); } - - protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{ - if($item !== null){ - $nbt->setByte(self::TAG_COLOR, $item->getDamage()); - } - } } diff --git a/src/pocketmine/tile/NameableTrait.php b/src/pocketmine/tile/NameableTrait.php index d1a62593c1..b623df8db8 100644 --- a/src/pocketmine/tile/NameableTrait.php +++ b/src/pocketmine/tile/NameableTrait.php @@ -24,10 +24,8 @@ declare(strict_types=1); namespace pocketmine\tile; use pocketmine\item\Item; -use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\Player; /** * This trait implements most methods in the {@link Nameable} interface. It should only be used by Tiles. @@ -66,7 +64,7 @@ trait NameableTrait{ 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, ?Item $item = null) : void{ if($item !== null and $item->hasCustomName()){ $nbt->setString(Nameable::TAG_CUSTOM_NAME, $item->getCustomName()); } diff --git a/src/pocketmine/tile/Skull.php b/src/pocketmine/tile/Skull.php index bfe0df385f..e49460bdf2 100644 --- a/src/pocketmine/tile/Skull.php +++ b/src/pocketmine/tile/Skull.php @@ -23,11 +23,7 @@ declare(strict_types=1); namespace pocketmine\tile; -use pocketmine\item\Item; -use pocketmine\math\Facing; -use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\Player; class Skull extends Spawnable{ public const TYPE_SKELETON = 0; @@ -66,18 +62,17 @@ class Skull extends Spawnable{ return $this->skullType; } + public function getRotation() : int{ + return $this->skullRotation; + } + + public function setRotation(int $rotation) : void{ + $this->skullRotation = $rotation; + $this->onChanged(); + } + protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ $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{ - $nbt->setByte(self::TAG_SKULL_TYPE, $item !== null ? $item->getDamage() : self::TYPE_SKELETON); - - $rot = 0; - if($face === Facing::UP and $player !== null){ - $rot = floor(($player->yaw * 16 / 360) + 0.5) & 0x0F; - } - $nbt->setByte(self::TAG_ROT, $rot); - } } diff --git a/src/pocketmine/tile/Tile.php b/src/pocketmine/tile/Tile.php index 2964c8c76c..abe5df44f7 100644 --- a/src/pocketmine/tile/Tile.php +++ b/src/pocketmine/tile/Tile.php @@ -35,7 +35,6 @@ use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\Player; use pocketmine\Server; use pocketmine\timings\Timings; use pocketmine\timings\TimingsHandler; @@ -183,14 +182,15 @@ abstract class Tile extends Position{ /** * Creates and returns a CompoundTag containing the necessary information to spawn a tile of this type. * - * @param Vector3 $pos - * @param int|null $face - * @param Item|null $item - * @param Player|null $player + * @param Vector3 $pos + * @param Item|null $item * * @return CompoundTag + * @throws \BadMethodCallException + * @throws \InvalidArgumentException + * @throws \InvalidStateException */ - public static function createNBT(Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : CompoundTag{ + 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"); } @@ -201,7 +201,7 @@ abstract class Tile extends Position{ new IntTag(self::TAG_Z, (int) $pos->z) ]); - static::createAdditionalNBT($nbt, $pos, $face, $item, $player); + static::createAdditionalNBT($nbt, $item); if($item !== null){ $customBlockData = $item->getCustomBlockData(); @@ -217,14 +217,12 @@ abstract class Tile extends Position{ /** * 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 Vector3 $pos - * @param int|null $face * @param Item|null $item - * @param Player|null $player */ - protected static function createAdditionalNBT(CompoundTag $nbt, Vector3 $pos, ?int $face = null, ?Item $item = null, ?Player $player = null) : void{ + protected static function createAdditionalNBT(CompoundTag $nbt, ?Item $item = null) : void{ }