PocketMine-MP 5.32.2 git-237b304ef9858756b018e44e8f298093f66f823b
Loading...
Searching...
No Matches
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;
28use pocketmine\block\utils\ColoredTrait;
29use pocketmine\block\utils\DyeColor;
31use pocketmine\block\utils\HorizontalFacingTrait;
32use pocketmine\block\utils\SupportType;
45
46class Bed extends Transparent implements Colored, HorizontalFacing{
47 use ColoredTrait;
48 use HorizontalFacingTrait;
49
50 protected bool $occupied = false;
51 protected bool $head = false;
52
53 protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
54 $w->horizontalFacing($this->facing);
55 $w->bool($this->occupied);
56 $w->bool($this->head);
57 }
58
59 public function readStateFromWorld() : Block{
60 parent::readStateFromWorld();
61 //read extra state information from the tile - this is an ugly hack
62 $tile = $this->position->getWorld()->getTile($this->position);
63 if($tile instanceof TileBed){
64 $this->color = $tile->getColor();
65 }else{
66 $this->color = DyeColor::RED; //legacy pre-1.1 beds don't have tiles
67 }
68
69 return $this;
70 }
71
72 public function writeStateToWorld() : void{
73 parent::writeStateToWorld();
74 //extra block properties storage hack
75 $tile = $this->position->getWorld()->getTile($this->position);
76 if($tile instanceof TileBed){
77 $tile->setColor($this->color);
78 }
79 }
80
81 protected function recalculateCollisionBoxes() : array{
82 return [AxisAlignedBB::one()->trim(Facing::UP, 7 / 16)];
83 }
84
85 public function getSupportType(int $facing) : SupportType{
86 return SupportType::NONE;
87 }
88
89 public function isHeadPart() : bool{
90 return $this->head;
91 }
92
94 public function setHead(bool $head) : self{
95 $this->head = $head;
96 return $this;
97 }
98
99 public function isOccupied() : bool{
100 return $this->occupied;
101 }
102
104 public function setOccupied(bool $occupied = true) : self{
105 $this->occupied = $occupied;
106 return $this;
107 }
108
109 private function getOtherHalfSide() : int{
110 return $this->head ? Facing::opposite($this->facing) : $this->facing;
111 }
112
113 public function getOtherHalf() : ?Bed{
114 $other = $this->getSide($this->getOtherHalfSide());
115 if($other instanceof Bed && $other->head !== $this->head && $other->facing === $this->facing){
116 return $other;
117 }
118
119 return null;
120 }
121
122 public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
123 if($player !== null){
124 $other = $this->getOtherHalf();
125 $playerPos = $player->getPosition();
126 if($other === null){
127 $player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
128
129 return true;
130 }elseif($playerPos->distanceSquared($this->position) > 4 && $playerPos->distanceSquared($other->position) > 4){
131 $player->sendMessage(KnownTranslationFactory::tile_bed_tooFar()->prefix(TextFormat::GRAY));
132 return true;
133 }
134
135 $time = $this->position->getWorld()->getTimeOfDay();
136
137 $isNight = ($time >= World::TIME_NIGHT && $time < World::TIME_SUNRISE);
138
139 if(!$isNight){
140 $player->sendMessage(KnownTranslationFactory::tile_bed_noSleep()->prefix(TextFormat::GRAY));
141
142 return true;
143 }
144
145 $b = ($this->isHeadPart() ? $this : $other);
146
147 if($b->occupied){
148 $player->sendMessage(KnownTranslationFactory::tile_bed_occupied()->prefix(TextFormat::GRAY));
149
150 return true;
151 }
152
153 $player->sleepOn($b->position);
154 }
155
156 return true;
157
158 }
159
160 public function onNearbyBlockChange() : void{
161 if(!$this->head && ($other = $this->getOtherHalf()) !== null && $other->occupied !== $this->occupied){
162 $this->occupied = $other->occupied;
163 $this->position->getWorld()->setBlock($this->position, $this);
164 }
165 }
166
167 public function onEntityLand(Entity $entity) : ?float{
168 if($entity instanceof Living && $entity->isSneaking()){
169 return null;
170 }
171 $entity->fallDistance *= 0.5;
172 return $entity->getMotion()->y * -3 / 4; // 2/3 in Java, according to the wiki
173 }
174
175 public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
176 if($this->canBeSupportedAt($blockReplace)){
177 $this->facing = $player !== null ? $player->getHorizontalFacing() : Facing::NORTH;
178
179 $next = $this->getSide($this->getOtherHalfSide());
180 if($next->canBeReplaced() && $this->canBeSupportedAt($next)){
181 $nextState = clone $this;
182 $nextState->head = true;
183 $tx->addBlock($blockReplace->position, $this)->addBlock($next->position, $nextState);
184 return true;
185 }
186 }
187
188 return false;
189 }
190
191 public function getDrops(Item $item) : array{
192 if($this->head){
193 return parent::getDrops($item);
194 }
195
196 return [];
197 }
198
199 public function getAffectedBlocks() : array{
200 if(($other = $this->getOtherHalf()) !== null){
201 return [$this, $other];
202 }
203
204 return parent::getAffectedBlocks();
205 }
206
207 private function canBeSupportedAt(Block $block) : bool{
208 return $block->getAdjacentSupportType(Facing::DOWN) !== SupportType::NONE;
209 }
210
211 public function getMaxStackSize() : int{ return 1; }
212}
onEntityLand(Entity $entity)
Definition Bed.php:167
getDrops(Item $item)
Definition Bed.php:191
describeBlockOnlyState(RuntimeDataDescriber $w)
Definition Bed.php:53
setHead(bool $head)
Definition Bed.php:94
recalculateCollisionBoxes()
Definition Bed.php:81
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player=null)
Definition Bed.php:175
onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player=null, array &$returnedItems=[])
Definition Bed.php:122
getSupportType(int $facing)
Definition Bed.php:85
setOccupied(bool $occupied=true)
Definition Bed.php:104
addBlock(Vector3 $pos, Block $state)