PocketMine-MP 5.33.2 git-1133d49c924b4358c79d44eeb97dcbf56cb4d1eb
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\HorizontalFacingOption;
32use pocketmine\block\utils\HorizontalFacingTrait;
33use pocketmine\block\utils\SupportType;
46
47class Bed extends Transparent implements Colored, HorizontalFacing{
48 use ColoredTrait;
49 use HorizontalFacingTrait;
50
51 protected bool $occupied = false;
52 protected bool $head = false;
53
54 protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
55 $w->enum($this->facing);
56 $w->bool($this->occupied);
57 $w->bool($this->head);
58 }
59
60 public function readStateFromWorld() : Block{
61 parent::readStateFromWorld();
62 //read extra state information from the tile - this is an ugly hack
63 $tile = $this->position->getWorld()->getTile($this->position);
64 if($tile instanceof TileBed){
65 $this->color = $tile->getColor();
66 }else{
67 $this->color = DyeColor::RED; //legacy pre-1.1 beds don't have tiles
68 }
69
70 return $this;
71 }
72
73 public function writeStateToWorld() : void{
74 parent::writeStateToWorld();
75 //extra block properties storage hack
76 $tile = $this->position->getWorld()->getTile($this->position);
77 if($tile instanceof TileBed){
78 $tile->setColor($this->color);
79 }
80 }
81
82 protected function recalculateCollisionBoxes() : array{
83 return [AxisAlignedBB::one()->trimmedCopy(Facing::UP, 7 / 16)];
84 }
85
86 public function getSupportType(Facing $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() : Facing{
111 return $this->head ? Facing::opposite($this->facing->toFacing()) : $this->facing->toFacing();
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, Facing $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, Facing $face, Vector3 $clickVector, ?Player $player = null) : bool{
177 if($this->canBeSupportedAt($blockReplace)){
178 if($player !== null){
179 $this->facing = HorizontalFacingOption::fromFacing($player->getHorizontalFacing());
180 }
181
182 $next = $this->getSide($this->getOtherHalfSide());
183 if($next->canBeReplaced() && $this->canBeSupportedAt($next)){
184 $nextState = clone $this;
185 $nextState->head = true;
186 $tx->addBlock($blockReplace->position, $this)->addBlock($next->position, $nextState);
187 return true;
188 }
189 }
190
191 return false;
192 }
193
194 public function getDrops(Item $item) : array{
195 if($this->head){
196 return parent::getDrops($item);
197 }
198
199 return [];
200 }
201
202 public function getAffectedBlocks() : array{
203 if(($other = $this->getOtherHalf()) !== null){
204 return [$this, $other];
205 }
206
207 return parent::getAffectedBlocks();
208 }
209
210 private function canBeSupportedAt(Block $block) : bool{
211 return $block->getAdjacentSupportType(Facing::DOWN) !== SupportType::NONE;
212 }
213
214 public function getMaxStackSize() : int{ return 1; }
215}
onEntityLand(Entity $entity)
Definition Bed.php:168
getDrops(Item $item)
Definition Bed.php:194
describeBlockOnlyState(RuntimeDataDescriber $w)
Definition Bed.php:54
setHead(bool $head)
Definition Bed.php:95
recalculateCollisionBoxes()
Definition Bed.php:82
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, Facing $face, Vector3 $clickVector, ?Player $player=null)
Definition Bed.php:176
getSupportType(Facing $facing)
Definition Bed.php:86
setOccupied(bool $occupied=true)
Definition Bed.php:105
onInteract(Item $item, Facing $face, Vector3 $clickVector, ?Player $player=null, array &$returnedItems=[])
Definition Bed.php:123
addBlock(Vector3 $pos, Block $state)