PocketMine-MP 5.14.2 git-50e2c469a547a16a23b2dc691e70a51d34e29395
Bed.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
24namespace pocketmine\block;
25
26use pocketmine\block\tile\Bed as TileBed;
27use pocketmine\block\utils\ColoredTrait;
28use pocketmine\block\utils\DyeColor;
29use pocketmine\block\utils\HorizontalFacingTrait;
30use pocketmine\block\utils\SupportType;
43
44class Bed extends Transparent{
45 use ColoredTrait;
46 use HorizontalFacingTrait;
47
48 protected bool $occupied = false;
49 protected bool $head = false;
50
51 protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
52 $w->horizontalFacing($this->facing);
53 $w->bool($this->occupied);
54 $w->bool($this->head);
55 }
56
57 public function readStateFromWorld() : Block{
58 parent::readStateFromWorld();
59 //read extra state information from the tile - this is an ugly hack
60 $tile = $this->position->getWorld()->getTile($this->position);
61 if($tile instanceof TileBed){
62 $this->color = $tile->getColor();
63 }else{
64 $this->color = DyeColor::RED; //legacy pre-1.1 beds don't have tiles
65 }
66
67 return $this;
68 }
69
70 public function writeStateToWorld() : void{
71 parent::writeStateToWorld();
72 //extra block properties storage hack
73 $tile = $this->position->getWorld()->getTile($this->position);
74 if($tile instanceof TileBed){
75 $tile->setColor($this->color);
76 }
77 }
78
82 protected function recalculateCollisionBoxes() : array{
83 return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 16)];
84 }
85
86 public function getSupportType(int $facing) : SupportType{
87 return SupportType::NONE;
88 }
89
90 public function isHeadPart() : bool{
91 return $this->head;
92 }
93
95 public function setHead(bool $head) : self{
96 $this->head = $head;
97 return $this;
98 }
99
100 public function isOccupied() : bool{
101 return $this->occupied;
102 }
103
105 public function setOccupied(bool $occupied = true) : self{
106 $this->occupied = $occupied;
107 return $this;
108 }
109
110 private function getOtherHalfSide() : int{
111 return $this->head ? Facing::opposite($this->facing) : $this->facing;
112 }
113
114 public function getOtherHalf() : ?Bed{
115 $other = $this->getSide($this->getOtherHalfSide());
116 if($other instanceof Bed && $other->head !== $this->head && $other->facing === $this->facing){
117 return $other;
118 }
119
120 return null;
121 }
122
123 public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
124 if($player !== null){
125 $other = $this->getOtherHalf();
126 $playerPos = $player->getPosition();
127 if($other === null){
128 $player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
129
130 return true;
131 }elseif($playerPos->distanceSquared($this->position) > 4 && $playerPos->distanceSquared($other->position) > 4){
132 $player->sendMessage(KnownTranslationFactory::tile_bed_tooFar()->prefix(TextFormat::GRAY));
133 return true;
134 }
135
136 $time = $this->position->getWorld()->getTimeOfDay();
137
138 $isNight = ($time >= World::TIME_NIGHT && $time < World::TIME_SUNRISE);
139
140 if(!$isNight){
141 $player->sendMessage(KnownTranslationFactory::tile_bed_noSleep()->prefix(TextFormat::GRAY));
142
143 return true;
144 }
145
146 $b = ($this->isHeadPart() ? $this : $other);
147
148 if($b->occupied){
149 $player->sendMessage(KnownTranslationFactory::tile_bed_occupied()->prefix(TextFormat::GRAY));
150
151 return true;
152 }
153
154 $player->sleepOn($b->position);
155 }
156
157 return true;
158
159 }
160
161 public function onNearbyBlockChange() : void{
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);
165 }
166 }
167
168 public function onEntityLand(Entity $entity) : ?float{
169 if($entity instanceof Living && $entity->isSneaking()){
170 return null;
171 }
172 $entity->fallDistance *= 0.5;
173 return $entity->getMotion()->y * -3 / 4; // 2/3 in Java, according to the wiki
174 }
175
176 public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
177 if($this->canBeSupportedAt($blockReplace)){
178 $this->facing = $player !== null ? $player->getHorizontalFacing() : Facing::NORTH;
179
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);
185 return true;
186 }
187 }
188
189 return false;
190 }
191
192 public function getDrops(Item $item) : array{
193 if($this->head){
194 return parent::getDrops($item);
195 }
196
197 return [];
198 }
199
200 public function getAffectedBlocks() : array{
201 if(($other = $this->getOtherHalf()) !== null){
202 return [$this, $other];
203 }
204
205 return parent::getAffectedBlocks();
206 }
207
208 private function canBeSupportedAt(Block $block) : bool{
209 return $block->getAdjacentSupportType(Facing::DOWN) !== SupportType::NONE;
210 }
211
212 public function getMaxStackSize() : int{ return 1; }
213}
onEntityLand(Entity $entity)
Definition: Bed.php:168
getDrops(Item $item)
Definition: Bed.php:192
describeBlockOnlyState(RuntimeDataDescriber $w)
Definition: Bed.php:51
setHead(bool $head)
Definition: Bed.php:95
recalculateCollisionBoxes()
Definition: Bed.php:82
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player=null)
Definition: Bed.php:176
onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player=null, array &$returnedItems=[])
Definition: Bed.php:123
getSupportType(int $facing)
Definition: Bed.php:86
setOccupied(bool $occupied=true)
Definition: Bed.php:105
addBlock(Vector3 $pos, Block $state)