22declare(strict_types=1);
27use pocketmine\block\utils\ColoredTrait;
28use pocketmine\block\utils\DyeColor;
29use pocketmine\block\utils\HorizontalFacingTrait;
30use pocketmine\block\utils\SupportType;
46 use HorizontalFacingTrait;
48 protected bool $occupied =
false;
49 protected bool $head =
false;
52 $w->horizontalFacing($this->facing);
53 $w->bool($this->occupied);
54 $w->bool($this->head);
58 parent::readStateFromWorld();
60 $tile = $this->position->getWorld()->getTile($this->position);
61 if($tile instanceof TileBed){
62 $this->color = $tile->getColor();
64 $this->color = DyeColor::RED;
71 parent::writeStateToWorld();
73 $tile = $this->position->getWorld()->getTile($this->position);
74 if($tile instanceof TileBed){
75 $tile->setColor($this->color);
87 return SupportType::NONE;
90 public function isHeadPart() : bool{
95 public function setHead(
bool $head) : self{
100 public function isOccupied() : bool{
101 return $this->occupied;
106 $this->occupied = $occupied;
110 private function getOtherHalfSide() : int{
111 return $this->head ?
Facing::opposite($this->facing) : $this->facing;
114 public function getOtherHalf() : ?Bed{
115 $other = $this->getSide($this->getOtherHalfSide());
116 if($other instanceof Bed && $other->head !== $this->head && $other->facing === $this->facing){
124 if($player !== null){
125 $other = $this->getOtherHalf();
126 $playerPos = $player->getPosition();
128 $player->sendMessage(TextFormat::GRAY .
"This bed is incomplete");
131 }elseif($playerPos->distanceSquared($this->position) > 4 && $playerPos->distanceSquared($other->position) > 4){
132 $player->sendMessage(KnownTranslationFactory::tile_bed_tooFar()->prefix(TextFormat::GRAY));
136 $time = $this->position->getWorld()->getTimeOfDay();
138 $isNight = ($time >= World::TIME_NIGHT && $time < World::TIME_SUNRISE);
141 $player->sendMessage(KnownTranslationFactory::tile_bed_noSleep()->prefix(TextFormat::GRAY));
146 $b = ($this->isHeadPart() ? $this : $other);
149 $player->sendMessage(KnownTranslationFactory::tile_bed_occupied()->prefix(TextFormat::GRAY));
154 $player->sleepOn($b->position);
162 if(!$this->head && ($other = $this->getOtherHalf()) !== null && $other->occupied !== $this->occupied){
163 $this->occupied = $other->occupied;
164 $this->position->getWorld()->setBlock($this->position, $this);
169 if($entity instanceof
Living && $entity->isSneaking()){
172 $entity->fallDistance *= 0.5;
173 return $entity->getMotion()->y * -3 / 4;
177 if($this->canBeSupportedAt($blockReplace)){
178 $this->facing = $player !==
null ? $player->getHorizontalFacing() : Facing::NORTH;
180 $next = $this->getSide($this->getOtherHalfSide());
181 if($next->canBeReplaced() && $this->canBeSupportedAt($next)){
182 $nextState = clone $this;
183 $nextState->head =
true;
184 $tx->
addBlock($blockReplace->position, $this)->addBlock($next->position, $nextState);
194 return parent::getDrops($item);
201 if(($other = $this->getOtherHalf()) !== null){
202 return [$this, $other];
205 return parent::getAffectedBlocks();
208 private function canBeSupportedAt(Block $block) : bool{
209 return $block->getAdjacentSupportType(Facing::DOWN) !== SupportType::NONE;
onEntityLand(Entity $entity)
describeBlockOnlyState(RuntimeDataDescriber $w)
recalculateCollisionBoxes()
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player=null)
onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player=null, array &$returnedItems=[])
getSupportType(int $facing)
setOccupied(bool $occupied=true)
addBlock(Vector3 $pos, Block $state)