PocketMine-MP 5.23.3 git-976fc63567edab7a6fb6aeae739f43cf9fe57de4
Loading...
Searching...
No Matches
BaseSign.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\Sign as TileSign;
27use pocketmine\block\utils\DyeColor;
29use pocketmine\block\utils\SupportType;
30use pocketmine\block\utils\WoodType;
31use pocketmine\block\utils\WoodTypeTrait;
43use function array_map;
44use function assert;
45use function strlen;
46
47abstract class BaseSign extends Transparent{
48 use WoodTypeTrait;
49
50 protected SignText $text;
51 private bool $waxed = false;
52
53 protected ?int $editorEntityRuntimeId = null;
54
56 private \Closure $asItemCallback;
57
61 public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo, WoodType $woodType, \Closure $asItemCallback){
62 $this->woodType = $woodType;
63 parent::__construct($idInfo, $name, $typeInfo);
64 $this->text = new SignText();
65 $this->asItemCallback = $asItemCallback;
66 }
67
68 public function readStateFromWorld() : Block{
69 parent::readStateFromWorld();
70 $tile = $this->position->getWorld()->getTile($this->position);
71 if($tile instanceof TileSign){
72 $this->text = $tile->getText();
73 $this->waxed = $tile->isWaxed();
74 $this->editorEntityRuntimeId = $tile->getEditorEntityRuntimeId();
75 }
76
77 return $this;
78 }
79
80 public function writeStateToWorld() : void{
81 parent::writeStateToWorld();
82 $tile = $this->position->getWorld()->getTile($this->position);
83 assert($tile instanceof TileSign);
84 $tile->setText($this->text);
85 $tile->setWaxed($this->waxed);
86 $tile->setEditorEntityRuntimeId($this->editorEntityRuntimeId);
87 }
88
89 public function isSolid() : bool{
90 return false;
91 }
92
93 public function getMaxStackSize() : int{
94 return 16;
95 }
96
97 protected function recalculateCollisionBoxes() : array{
98 return [];
99 }
100
101 public function getSupportType(int $facing) : SupportType{
102 return SupportType::NONE;
103 }
104
105 abstract protected function getSupportingFace() : int;
106
107 public function onNearbyBlockChange() : void{
108 if($this->getSide($this->getSupportingFace())->getTypeId() === BlockTypeIds::AIR){
109 $this->position->getWorld()->useBreakOn($this->position);
110 }
111 }
112
113 public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
114 if($player !== null){
115 $this->editorEntityRuntimeId = $player->getId();
116 }
117 return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
118 }
119
120 public function onPostPlace() : void{
121 $player = $this->editorEntityRuntimeId !== null ?
122 $this->position->getWorld()->getEntity($this->editorEntityRuntimeId) :
123 null;
124 if($player instanceof Player){
125 $player->openSignEditor($this->position);
126 }
127 }
128
129 private function doSignChange(SignText $newText, Player $player, Item $item) : bool{
130 $ev = new SignChangeEvent($this, $player, $newText);
131 $ev->call();
132 if(!$ev->isCancelled()){
133 $this->text = $ev->getNewText();
134 $this->position->getWorld()->setBlock($this->position, $this);
135 $item->pop();
136 return true;
137 }
138
139 return false;
140 }
141
142 private function changeSignGlowingState(bool $glowing, Player $player, Item $item) : bool{
143 if($this->text->isGlowing() !== $glowing && $this->doSignChange(new SignText($this->text->getLines(), $this->text->getBaseColor(), $glowing), $player, $item)){
144 $this->position->getWorld()->addSound($this->position, new InkSacUseSound());
145 return true;
146 }
147 return false;
148 }
149
150 private function wax(Player $player, Item $item) : bool{
151 if($this->waxed){
152 return false;
153 }
154
155 $this->waxed = true;
156 $this->position->getWorld()->setBlock($this->position, $this);
157 $item->pop();
158
159 return true;
160 }
161
162 public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
163 if($player === null){
164 return false;
165 }
166 if($this->waxed){
167 return true;
168 }
169
170 $dyeColor = $item instanceof Dye ? $item->getColor() : match($item->getTypeId()){
171 ItemTypeIds::BONE_MEAL => DyeColor::WHITE,
172 ItemTypeIds::LAPIS_LAZULI => DyeColor::BLUE,
173 ItemTypeIds::COCOA_BEANS => DyeColor::BROWN,
174 default => null
175 };
176 if($dyeColor !== null){
177 $color = $dyeColor === DyeColor::BLACK ? new Color(0, 0, 0) : $dyeColor->getRgbValue();
178 if(
179 $color->toARGB() !== $this->text->getBaseColor()->toARGB() &&
180 $this->doSignChange(new SignText($this->text->getLines(), $color, $this->text->isGlowing()), $player, $item)
181 ){
182 $this->position->getWorld()->addSound($this->position, new DyeUseSound());
183 return true;
184 }
185 }elseif(match($item->getTypeId()){
186 ItemTypeIds::INK_SAC => $this->changeSignGlowingState(false, $player, $item),
187 ItemTypeIds::GLOW_INK_SAC => $this->changeSignGlowingState(true, $player, $item),
188 ItemTypeIds::HONEYCOMB => $this->wax($player, $item),
189 default => false
190 }){
191 return true;
192 }
193
194 $player->openSignEditor($this->position);
195
196 return true;
197 }
198
202 public function getText() : SignText{
203 return $this->text;
204 }
205
207 public function setText(SignText $text) : self{
208 $this->text = $text;
209 return $this;
210 }
211
215 public function isWaxed() : bool{ return $this->waxed; }
216
218 public function setWaxed(bool $waxed) : self{
219 $this->waxed = $waxed;
220 return $this;
221 }
222
228 public function getEditorEntityRuntimeId() : ?int{ return $this->editorEntityRuntimeId; }
229
231 public function setEditorEntityRuntimeId(?int $editorEntityRuntimeId) : self{
232 $this->editorEntityRuntimeId = $editorEntityRuntimeId;
233 return $this;
234 }
235
242 public function updateText(Player $author, SignText $text) : bool{
243 $size = 0;
244 foreach($text->getLines() as $line){
245 $size += strlen($line);
246 }
247 if($size > 1000){
248 throw new \UnexpectedValueException($author->getName() . " tried to write $size bytes of text onto a sign (bigger than max 1000)");
249 }
250 $ev = new SignChangeEvent($this, $author, new SignText(array_map(function(string $line) : string{
251 return TextFormat::clean($line, false);
252 }, $text->getLines()), $this->text->getBaseColor(), $this->text->isGlowing()));
253 if($this->waxed || $this->editorEntityRuntimeId !== $author->getId()){
254 $ev->cancel();
255 }
256 $ev->call();
257 if(!$ev->isCancelled()){
258 $this->setText($ev->getNewText());
259 $this->setEditorEntityRuntimeId(null);
260 $this->position->getWorld()->setBlock($this->position, $this);
261 return true;
262 }
263
264 return false;
265 }
266
267 public function asItem() : Item{
268 return ($this->asItemCallback)();
269 }
270
271 public function getFuelTime() : int{
272 return $this->woodType->isFlammable() ? 200 : 0;
273 }
274}
setEditorEntityRuntimeId(?int $editorEntityRuntimeId)
Definition BaseSign.php:231
updateText(Player $author, SignText $text)
Definition BaseSign.php:242
onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player=null, array &$returnedItems=[])
Definition BaseSign.php:162
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player=null)
Definition BaseSign.php:113
getSupportType(int $facing)
Definition BaseSign.php:101
setText(SignText $text)
Definition BaseSign.php:207
__construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo, WoodType $woodType, \Closure $asItemCallback)
Definition BaseSign.php:61