baseColor = DyeColor::BLACK(); $this->patterns = new Deque(); } public function __clone(){ parent::__clone(); //pattern objects are considered immutable, so they don't need to be copied $this->patterns = $this->patterns->copy(); } public function getId() : int{ return $this->facing === Facing::UP ? parent::getId() : $this->idInfo->getSecondId(); } protected function writeStateToMeta() : int{ if($this->facing === Facing::UP){ return $this->rotation; } return BlockDataSerializer::writeHorizontalFacing($this->facing); } public function readStateFromData(int $id, int $stateMeta) : void{ if($id === $this->idInfo->getSecondId()){ $this->facing = BlockDataSerializer::readHorizontalFacing($stateMeta); }else{ $this->facing = Facing::UP; $this->rotation = $stateMeta; } } public function getStateBitmask() : int{ return 0b1111; } public function readStateFromWorld() : void{ parent::readStateFromWorld(); $tile = $this->pos->getWorld()->getTile($this->pos); if($tile instanceof TileBanner){ $this->baseColor = $tile->getBaseColor(); $this->setPatterns($tile->getPatterns()); } } public function writeStateToWorld() : void{ parent::writeStateToWorld(); $tile = $this->pos->getWorld()->getTile($this->pos); assert($tile instanceof TileBanner); $tile->setBaseColor($this->baseColor); $tile->setPatterns($this->patterns); } public function isSolid() : bool{ return false; } /** * TODO: interface method? this is only the BASE colour... * @return DyeColor */ public function getColor() : DyeColor{ return $this->baseColor; } /** * @return Deque|BannerPattern[] */ public function getPatterns() : Deque{ return $this->patterns; } /** * @param Deque|BannerPattern[] $patterns */ public function setPatterns(Deque $patterns) : void{ $checked = $patterns->filter(function($v){ return $v instanceof BannerPattern; }); if($checked->count() !== $patterns->count()){ throw new \TypeError("Deque must only contain " . BannerPattern::class . " objects"); } $this->patterns = $checked; } /** * @return AxisAlignedBB[] */ protected function recalculateCollisionBoxes() : array{ return []; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($item instanceof ItemBanner){ $this->baseColor = $item->getColor(); $this->setPatterns($item->getPatterns()); } if($face !== Facing::DOWN){ $this->facing = $face; if($face === Facing::UP){ $this->rotation = $player !== null ? ((int) floor((($player->getLocation()->getYaw() + 180) * 16 / 360) + 0.5)) & 0x0f : 0; } return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; } public function onNearbyBlockChange() : void{ if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){ $this->pos->getWorld()->useBreakOn($this->pos); } } public function asItem() : Item{ return ItemFactory::get(ItemIds::BANNER, $this->baseColor->getInvertedMagicNumber()); } public function getDropsForCompatibleTool(Item $item) : array{ $drop = $this->asItem(); if($drop instanceof ItemBanner and !$this->patterns->isEmpty()){ $drop->setPatterns($this->patterns); } return [$drop]; } public function getPickedItem(bool $addUserData = false) : Item{ $result = $this->asItem(); if($addUserData and $result instanceof ItemBanner and !$this->patterns->isEmpty()){ $result->setPatterns($this->patterns); } return $result; } public function isAffectedBySilkTouch() : bool{ return false; } }