facing) | ($this->occupied ? self::BITFLAG_OCCUPIED : 0) | ($this->head ? self::BITFLAG_HEAD : 0); } public function readStateFromMeta(int $meta) : void{ $this->facing = Bearing::toFacing($meta & 0x03); $this->occupied = ($meta & self::BITFLAG_OCCUPIED) !== 0; $this->head = ($meta & self::BITFLAG_HEAD) !== 0; } public function getStateBitmask() : int{ return 0b1111; } public function getHardness() : float{ return 0.2; } public function getName() : string{ return "Bed Block"; } protected function recalculateBoundingBox() : ?AxisAlignedBB{ return new AxisAlignedBB(0, 0, 0, 1, 0.5625, 1); } public function isHeadPart() : bool{ return $this->head; } /** * @return bool */ public function isOccupied() : bool{ return $this->occupied; } public function setOccupied(bool $occupied = true){ $this->occupied = $occupied; $this->level->setBlock($this, $this, false, false); if(($other = $this->getOtherHalf()) !== null){ $other->occupied = $occupied; $this->level->setBlock($other, $other, false, false); } } /** * @return int */ private function getOtherHalfSide() : int{ return $this->head ? Facing::opposite($this->facing) : $this->facing; } /** * @return Bed|null */ public function getOtherHalf() : ?Bed{ $other = $this->getSide($this->getOtherHalfSide()); if($other instanceof Bed and $other->head !== $this->head and $other->facing === $this->facing){ return $other; } return null; } public function onActivate(Item $item, Player $player = null) : bool{ if($player !== null){ $other = $this->getOtherHalf(); if($other === null){ $player->sendMessage(TextFormat::GRAY . "This bed is incomplete"); return true; }elseif($player->distanceSquared($this) > 4 and $player->distanceSquared($other) > 4){ $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.tooFar")); return true; } $time = $this->getLevel()->getTime() % Level::TIME_FULL; $isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE); if(!$isNight){ $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.noSleep")); return true; } $b = ($this->isHeadPart() ? $this : $other); if($b->isOccupied()){ $player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.occupied")); return true; } $player->sleepOn($b); } return true; } public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{ $down = $this->getSide(Facing::DOWN); if(!$down->isTransparent()){ $this->facing = $player !== null ? Bearing::toFacing($player->getDirection()) : Facing::NORTH; $next = $this->getSide($this->getOtherHalfSide()); if($next->canBeReplaced() and !$next->getSide(Facing::DOWN)->isTransparent()){ parent::place($item, $blockReplace, $blockClicked, $face, $clickVector, $player); $nextState = clone $this; $nextState->head = true; $this->getLevel()->setBlock($next, $nextState, true, true); Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this, $face, $item, $player)); Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($next, $face, $item, $player)); return true; } } return false; } public function getDropsForCompatibleTool(Item $item) : array{ if($this->isHeadPart()){ return parent::getDropsForCompatibleTool($item); } return []; } 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 } public function isAffectedBySilkTouch() : bool{ return false; } public function getAffectedBlocks() : array{ if(($other = $this->getOtherHalf()) !== null){ return [$this, $other]; } return parent::getAffectedBlocks(); } }